Class CipRequest
- java.lang.Object
-
- com.automation_pros.odva.cip.requests.CipRequest
-
- All Implemented Interfaces:
CipReplyConsumer,CipMessage,java.io.Externalizable,java.io.Serializable
- Direct Known Subclasses:
CxMgrReq,GetAttrListReq,GetGenericReq,GetInstAttrListReq,MultipleReq
public class CipRequest extends java.lang.Object implements java.io.Externalizable, CipMessage, CipReplyConsumer
A CIP Request cannot carry an exception. It has only a target path and a payload. Replies are consumed, reparsed by subclasses, and passed on to registered callbacks.- Author:
- philip
- See Also:
- Serialized Form
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classCipRequest.CallbackExceptionstatic classCipRequest.ChainedExceptionstatic classCipRequest.ReplyFutureA callback object that delivers its asynchronous CipReply to a Future for retrieval or synchronization.
-
Field Summary
Fields Modifier and Type Field Description protected java.lang.ExceptionacceptTracelongacceptTSprotected java.util.List<CipReplyConsumer>callbacksprotected java.lang.ExceptioncreationTracelongdeadlineprotected intforecastReplyintmaxreplyprotected CipPathpathprotected static java.util.concurrent.ScheduledThreadPoolExecutorschedulerlongsentTSstatic org.slf4j.LoggersLoggerprotected intsvccode
-
Constructor Summary
Constructors Constructor Description CipRequest()Externalizable types must have a public no-arg constructor.CipRequest(CipPath target, int service)Construct a new request for a given target and service code.CipRequest(CipPath target, int service, BaseDataType<?> data)Construct a request from a target, service, and data for the payload.CipRequest(CipPath target, int service, java.nio.ByteBuffer source)Construct a request from a target, service, and payload buffer.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaccept(CipException e)As a convenience to synchronous services, construct a CIP reply from a CIP Exception.voidaccept(CipReply reply)Applications and routers call this method with the actual reply to pass back up the chain of callers.voidaccept(java.nio.ByteBuffer reply)As a convenience to synchronous services, construct a success CIP reply from a given byte buffer.CipRequestaddCallback(int idx, CipReplyConsumer callback)Requests are expected to generate a reply some time after submission to an Origin.CipRequestaddCallback(CipReplyConsumer callback)Requests are expected to generate a reply some time after submission to an Origin.CipRequest.ReplyFutureaddFutureCallback()intbytes()CipRequestclone()static CipRequestdecode(java.nio.ByteBuffer source, CipReplyConsumer callback)Given a byte buffer expected to contain a CIP request in Message Router Request format, targeting a Message Router or in an Unconnected Message Manager, return the decoded request, with the given callback attached, rewrapping UCMM requests.voidforecast(int expectedReply)java.nio.ByteBuffergetPayload()Object services typically want to decode the payload into their own field(s).intgetServiceCode()CIP messages always have a service code, either requesting or replying.CipReplygetSyncReply(CipMsgProcessor msgproc)CipReplygetSyncReply(CipObject appContext, int nesting)CipPathgetTarget()Obtain the application path in this request.byte[]payloadBytes()Encode the message payload for transmission and return it as an array of bytes.intpayloadLength()Subclasses must override this unless they populate the payload and payloadActual fields.protected java.lang.StringpayloadString()voidput(java.nio.ByteBuffer dest)Encode the entire message for transmission.voidputPayload(java.nio.ByteBuffer dest)Subclasses that encode fields into their payloads must override this.voidputSyncReplyPayload(CipMsgProcessor msgproc, java.nio.ByteBuffer dest)voidputSyncReplyPayload(CipObject appContext, int nesting, java.nio.ByteBuffer dest)voidreadExternal(java.io.ObjectInput in)CIP requests are deserialized by retrieving the byte array and decoding it directly.intreplyLength()Subclasses that know how big a reply message will be may override this to enable automatic optimization into multiple request packets.static CipRequestrewrapRequest(CipRequest req)Given a request and optional port instance, convert instances that should be one of the subclasses into that subclass.java.util.concurrent.CompletableFuture<CipReply>service(CipMsgProcessor msgproc)Execute this request on a generic message processor, typically aPortor aMessaging Connection.java.util.concurrent.CompletableFuture<CipReply>service(CipObject appContext, int nesting)Execute this request on a given device hierarchy, optionally skipping some leading path elements.protected java.lang.StringserviceName()CipRequestset(java.nio.ByteBuffer source)voidsetPayload(java.nio.ByteBuffer source)Subclasses should override this method to permit reparsing of protocol packets into the desired request type.CipRequesttakeCallbacks(CipRequest other)When a request is wrapped in another request that will simply hand off the reply, the outer request must take the callbacks of the inner request.byte[]toBytes()Encode the entire message for transmission and return it as an array of bytes.java.lang.StringtoString()voidwriteExternal(java.io.ObjectOutput out)CIP requests may be placed "on the wire" in serialized form, but callbacks and any other information that is not explicitly part of the CIP Message Router Request format are discarded.
-
-
-
Field Detail
-
sLogger
public static final org.slf4j.Logger sLogger
-
scheduler
protected static java.util.concurrent.ScheduledThreadPoolExecutor scheduler
-
sentTS
public long sentTS
-
acceptTS
public long acceptTS
-
deadline
public long deadline
-
maxreply
public int maxreply
-
svccode
protected int svccode
-
path
protected CipPath path
-
callbacks
protected java.util.List<CipReplyConsumer> callbacks
-
creationTrace
protected java.lang.Exception creationTrace
-
acceptTrace
protected java.lang.Exception acceptTrace
-
forecastReply
protected int forecastReply
-
-
Constructor Detail
-
CipRequest
public CipRequest()
Externalizable types must have a public no-arg constructor.
-
CipRequest
public CipRequest(CipPath target, int service)
Construct a new request for a given target and service code. Suitable for requests that need no payload or for which the payload generation will be overridden.- Parameters:
target-service-
-
CipRequest
public CipRequest(CipPath target, int service, java.nio.ByteBuffer source)
Construct a request from a target, service, and payload buffer. Ideal for parsed requests that will be routed, needing no interpretation of the payload.- Parameters:
target-service-source-
-
CipRequest
public CipRequest(CipPath target, int service, BaseDataType<?> data)
Construct a request from a target, service, and data for the payload.- Parameters:
target-service-data-
-
-
Method Detail
-
rewrapRequest
public static CipRequest rewrapRequest(CipRequest req)
Given a request and optional port instance, convert instances that should be one of the subclasses into that subclass.- Parameters:
req-- Returns:
-
decode
public static CipRequest decode(java.nio.ByteBuffer source, CipReplyConsumer callback)
Given a byte buffer expected to contain a CIP request in Message Router Request format, targeting a Message Router or in an Unconnected Message Manager, return the decoded request, with the given callback attached, rewrapping UCMM requests.- Parameters:
source-callback-- Returns:
-
set
public CipRequest set(java.nio.ByteBuffer source)
-
getTarget
public CipPath getTarget()
Obtain the application path in this request. Unconnected messages may start with one or more port segments for routing.- Returns:
- A list of path segments.
-
getServiceCode
public int getServiceCode()
Description copied from interface:CipMessageCIP messages always have a service code, either requesting or replying. In the protocol, replies have bit seven turned on. In reply classes implementing this interface, the bit is stripped.- Specified by:
getServiceCodein interfaceCipMessage- Returns:
- The unsigned byte service code as an integer.
-
put
public void put(java.nio.ByteBuffer dest)
Description copied from interface:CipMessageEncode the entire message for transmission.- Specified by:
putin interfaceCipMessage- Parameters:
dest- Destination buffer for the encoded message.
-
bytes
public int bytes()
- Specified by:
bytesin interfaceCipMessage- Returns:
- The total byte length of the encoded message.
-
addCallback
public CipRequest addCallback(CipReplyConsumer callback)
Requests are expected to generate a reply some time after submission to an Origin. The caller must add the callbacks that will consume the corresponding reply. For the consumer's convenience, the reply will have this request attached.- Parameters:
callback-- Returns:
- Returns the request to allow method chaining.
-
addFutureCallback
public CipRequest.ReplyFuture addFutureCallback()
-
addCallback
public CipRequest addCallback(int idx, CipReplyConsumer callback)
Requests are expected to generate a reply some time after submission to an Origin. The caller must add the callbacks that will consume the corresponding reply. For the consumer's convenience, the reply will have this request attached. This overloaded form allows a callback to be inserted at any desired point.- Parameters:
idx-callback-- Returns:
- Returns the request to allow method chaining.
-
takeCallbacks
public CipRequest takeCallbacks(CipRequest other)
When a request is wrapped in another request that will simply hand off the reply, the outer request must take the callbacks of the inner request.When such an outer request is unwrapped to process the inner request, the inner request must take the callbacks of the outer request.
- Parameters:
other-- Returns:
-
clone
public CipRequest clone()
- Overrides:
clonein classjava.lang.Object
-
accept
public void accept(CipReply reply)
Applications and routers call this method with the actual reply to pass back up the chain of callers. Routers must embed some form of ID code in their protocol packets to associate requests with replies. DeviceNet uses originator node address and a 16-bit transaction ID. Ethernet/IP uses the 64-bit Sender Context field of its encapsulation header. CIP over DF1 uses the 16-bit Transaction Number inside of PCCC encapsulation.- Specified by:
acceptin interfaceCipReplyConsumer
-
accept
public void accept(java.nio.ByteBuffer reply)
As a convenience to synchronous services, construct a success CIP reply from a given byte buffer. Generally not overridden by subclasses.- Parameters:
reply-
-
accept
public void accept(CipException e)
As a convenience to synchronous services, construct a CIP reply from a CIP Exception. Generally not overridden by subclasses.- Parameters:
e-
-
service
public java.util.concurrent.CompletableFuture<CipReply> service(CipObject appContext, int nesting)
Execute this request on a given device hierarchy, optionally skipping some leading path elements.- Parameters:
appContext- The hierarchy root that will execute this request and will will be passed to any nested lookup operations.nesting- Number of path elements in the request target to skip.- Returns:
- A completable future that can be interrogated for the reply.
-
service
public java.util.concurrent.CompletableFuture<CipReply> service(CipMsgProcessor msgproc)
Execute this request on a generic message processor, typically aPortor aMessaging Connection.- Parameters:
msgproc-- Returns:
- A completable future that can be interrogated for the reply.
-
getSyncReply
public CipReply getSyncReply(CipMsgProcessor msgproc)
-
putSyncReplyPayload
public void putSyncReplyPayload(CipObject appContext, int nesting, java.nio.ByteBuffer dest)
-
putSyncReplyPayload
public void putSyncReplyPayload(CipMsgProcessor msgproc, java.nio.ByteBuffer dest)
-
setPayload
public void setPayload(java.nio.ByteBuffer source)
Subclasses should override this method to permit reparsing of protocol packets into the desired request type.- Specified by:
setPayloadin interfaceCipMessage- Parameters:
source- Source buffer containing the encoded new payload.
-
getPayload
public java.nio.ByteBuffer getPayload()
Object services typically want to decode the payload into their own field(s).- Returns:
- A buffer containing the payload ready to read. Callers should deliver it to ByteBuffersSoftCache.release() if known to not be used further.
-
putPayload
public void putPayload(java.nio.ByteBuffer dest)
Subclasses that encode fields into their payloads must override this.- Specified by:
putPayloadin interfaceCipMessage- Parameters:
dest- Destination buffer for the encoded payload.
-
payloadLength
public int payloadLength()
Subclasses must override this unless they populate the payload and payloadActual fields.- Specified by:
payloadLengthin interfaceCipMessage- Returns:
- The byte length of the encoded payload only.
-
replyLength
public int replyLength()
Subclasses that know how big a reply message will be may override this to enable automatic optimization into multiple request packets. Or fill the protected field "forecastReply".- Returns:
-
forecast
public void forecast(int expectedReply)
-
payloadString
protected java.lang.String payloadString()
-
payloadBytes
public byte[] payloadBytes()
Description copied from interface:CipMessageEncode the message payload for transmission and return it as an array of bytes.- Specified by:
payloadBytesin interfaceCipMessage- Returns:
- The encoded payload as a byte array.
-
toBytes
public byte[] toBytes()
Description copied from interface:CipMessageEncode the entire message for transmission and return it as an array of bytes.- Specified by:
toBytesin interfaceCipMessage- Returns:
- The entire encoded message as a byte array.
-
serviceName
protected java.lang.String serviceName()
-
toString
public java.lang.String toString()
- Overrides:
toStringin classjava.lang.Object
-
readExternal
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, java.lang.ClassNotFoundExceptionCIP requests are deserialized by retrieving the byte array and decoding it directly.- Specified by:
readExternalin interfacejava.io.Externalizable- Throws:
java.io.IOExceptionjava.lang.ClassNotFoundException
-
writeExternal
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOExceptionCIP requests may be placed "on the wire" in serialized form, but callbacks and any other information that is not explicitly part of the CIP Message Router Request format are discarded.- Specified by:
writeExternalin interfacejava.io.Externalizable- Throws:
java.io.IOException
-
-