Class Exchange
The framework internally uses the class Exchange to manage an exchange of
Request
s and Response
s. The Exchange only contains state, no
functionality. The CoAP Stack contains the functionality of the CoAP protocol
and modifies the exchange appropriately. The class Exchange and its fields
are NOT thread-safe. The setter methods must be called within a
Runnable
, which must be executed using execute(Runnable)
.
For convenience the executeComplete()
is provided to execute
setComplete()
accordingly. Methods, which are documented to throw a
ConcurrentModificationException
MUST comply to this execution
pattern!
If the exchange represents a "blockwise" transfer and if the transparent mode is used, the exchange keeps also the (original) request and use the current request for transfer the blocks. A request not using observe use the same token for easier tracking. A request using observe keeps the origin request with the origin token in store, but use a different token for the transfer of the left blocks. This enables to catch new notifies while a transfer is ongoing.
The class CoapExchange
provides the corresponding API for developers.
Proceed with caution when using this class directly, e.g., through
CoapExchange.advanced()
.
This class might change with the implementation of CoAP extensions.
Even if above mentions, that this class is not thread safe, its used from
several different threads! Generally the Exchanges are hand over via a
concurrent collections in the matcher and therefore establish a "happens
before" order (as long as threads accessing the exchange via the matcher).
But some methods are out of scope of that and use Exchange directly (e.g.
setEndpointContext(EndpointContext)
the "sender thread"). Therefore
some fields use at least volatile. This doesn't ensure, that Exchange is
thread safe, it only ensures the visibility of the states.
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic interface
Endpoint context operator.static enum
The origin of an exchange. -
Constructor Summary
ConstructorDescriptionExchange
(Request request, Object peersIdentity, Exchange.Origin origin, Executor executor) Creates a new exchange with the specified request and origin.Exchange
(Request request, Object peersIdentity, Exchange.Origin origin, Executor executor, org.eclipse.californium.elements.EndpointContext ctx, boolean notification) Creates a new exchange with the specified request, origin, context, and notification marker. -
Method Summary
Modifier and TypeMethodDescriptionvoid
assertIncomplete
(Object message) Assert, that the exchange is not complete and new messages could be send using this exchange.long
Calculates the RTT (round trip time) of this exchange.long
Calculate transmission round trip time.boolean
Check, if current thread owns this exchange.void
Execute a job serialized related to this exchange.boolean
Execute complete.Returns the block option of the last block of a blockwise sent request.Get caller.byte[]
Gets cryptoContextId.Returns the current request block.Returns the current response block.int
Get current timeout.Returns the endpoint which has created and processed this exchange.org.eclipse.californium.elements.EndpointContext
Gets transport layer specific information that can be used to correlate a response with this exchange's original request.int
Get failed transmissions count.long
Get the nano-timestamp of the creation of this exchange.Gets the number of the notification this exchange is associated with.Returns the other peer's identity.Returns the CoAP observe relation that this exchange has initially established.Get remote socket address.Returns the request that this exchange is associated with.Returns the response to the request ornull
, if no response has arrived yet.long
Get the realtime of the last sending of a message in nanoseconds.float
Get timeout scale factor for exponential back-off between retransmissions.boolean
Checks whether this exchange has an remove handler set.int
Increment the failed transmission count.boolean
Checks if this exchange has been marked as completed.boolean
Indicate a notification exchange.boolean
boolean
Indicated, that this exchange retransmission reached the timeout.boolean
Check, if ACK, RST or response for transmission is pending.boolean
Indicate to keep the original request in the exchange store.void
Remove past notifications from message exchange store.void
void
Prepare exchange for retransmit a response.void
Accept this exchange and therefore the request.void
sendAccept
(org.eclipse.californium.elements.EndpointContext context) Accept this exchange and therefore the request.void
Reject this exchange and therefore the request.void
sendReject
(org.eclipse.californium.elements.EndpointContext context) Reject this exchange and therefore the request.void
sendResponse
(Response response) Sends the specified response over the same endpoint as the request has arrived.void
setBlock1ToAck
(BlockOption block1ToAck) Sets the block option of the last block of a blockwise sent request.boolean
Marks this exchange as being completed.void
setCryptographicContextID
(byte[] cryptoContextId) Sets cryptoContextIdvoid
setCurrentRequest
(Request newCurrentRequest) Sets the current request block.void
setCurrentResponse
(Response newCurrentResponse) Sets the current response block.void
setCurrentTimeout
(int currentTimeout) Set current timeout.void
setEndpoint
(Endpoint endpoint) Set endpoint of received message.void
setEndpointContext
(org.eclipse.californium.elements.EndpointContext ctx) Sets additional information about the context this exchange's request has been sent in.void
Set endpoint context pre-operator.void
Set key mid used to register this exchange.void
setKeyToken
(KeyToken keyToken) Set key token used to register this exchange.void
setNotificationNumber
(int notificationNo) Sets the number of the notification this exchange is associated with.void
setRelation
(ObserveRelation relation) Sets the observe relation this exchange has established.void
setRemoveHandler
(RemoveHandler removeHandler) Sets an remove handler to be invoked when this exchange completes.void
setRequest
(Request newRequest) Sets the request that this exchange is associated with.void
setResponse
(Response response) Sets the response.void
setRetransmissionHandle
(ScheduledFuture<?> newRetransmissionHandle) Set retransmission handle.void
setSendNanoTimestamp
(long nanoTimestamp) Set the realtime of the last sending of a message in nanoseconds.void
setTimedOut
(Message message) Report transmission timeout for provided message to exchange.void
setTimeoutScale
(float scale) Set timeout scale factor for exponential back-off between retransmissions.void
Start transmission RTT.toString()
-
Constructor Details
-
Exchange
Creates a new exchange with the specified request and origin. Note: since 3.9null
as executor doesn't longer fail with aNullPointerException
. Usingnull
is still not supported and comes with risks, that especially requires your own responsibility.- Parameters:
request
- the request that starts the exchangepeersIdentity
- peer's identity. Usually that's the peer'sInetSocketAddress
.origin
- the origin of the request (LOCAL or REMOTE)executor
- executor to be used for exchanges.- Throws:
NullPointerException
- if request isnull
- Since:
- 3.0 (added peersIdentity, executor adapted to mandatory)
- See Also:
-
EndpointIdentityResolver
-
Exchange
public Exchange(Request request, Object peersIdentity, Exchange.Origin origin, Executor executor, org.eclipse.californium.elements.EndpointContext ctx, boolean notification) Creates a new exchange with the specified request, origin, context, and notification marker. Note: since 3.9null
as executor doesn't longer fail with aNullPointerException
. Usingnull
is still not supported and comes with risks, that especially requires your own responsibility.- Parameters:
request
- the request that starts the exchangepeersIdentity
- peer's identity. Usually that's the peer'sInetSocketAddress
.origin
- the origin of the request (LOCAL or REMOTE)executor
- executor to be used for exchanges.ctx
- the endpoint context of this exchangenotification
-true
for notification exchange,false
otherwise- Throws:
NullPointerException
- if request isnull
- Since:
- 3.0 (added peersIdentity, executor adapted to mandatory)
- See Also:
-
EndpointIdentityResolver
-
-
Method Details
-
toString
-
sendAccept
public void sendAccept()Accept this exchange and therefore the request. Only if the request's type was aCON
and the request has not been acknowledged yet, it sends an ACK to the client. Use the source endpoint context of the current request to send the ACK.- See Also:
-
sendAccept
public void sendAccept(org.eclipse.californium.elements.EndpointContext context) Accept this exchange and therefore the request. Only if the request's type was aCON
and the request has not been acknowledged yet, it sends an ACK to the client and prepares to send the response as separate response.- Parameters:
context
- endpoint context to send ack- See Also:
-
sendReject
public void sendReject()Reject this exchange and therefore the request. Sends an RST back to the client, if the request has not been already rejected. Use the source endpoint context of the current request to send the RST. Note: since 2.3, rejects for multicast requests are not sent. (SeeUdpMulticastConnector
for receiving multicast requests).- Since:
- 2.3 rejects for multicast requests are not sent
- See Also:
-
sendReject
public void sendReject(org.eclipse.californium.elements.EndpointContext context) Reject this exchange and therefore the request. Sends an RST back to the client, if the request has not been already rejected. Note: since 2.3, rejects for multicast requests are not sent. (SeeUdpMulticastConnector
for receiving multicast requests).- Parameters:
context
- endpoint context to send RST- Since:
- 2.3 rejects for multicast requests are not sent
- See Also:
-
sendResponse
Sends the specified response over the same endpoint as the request has arrived. If no destination context is provided, use the source context of the request. Note: since 2.3, error responses for multicast requests are not sent. (SeeUdpMulticastConnector
for receiving multicast requests). Note: since 3.0,NoResponseOption
is considered. That may cause to send error responses also for multicast requests.- Parameters:
response
- the response- Since:
- 2.3 error responses for multicast requests are not sent, 3.0
NoResponseOption
is considered
-
getOrigin
-
isOfLocalOrigin
public boolean isOfLocalOrigin() -
getRemoteSocketAddress
Get remote socket address. Get remote socket address of current request.- Returns:
- current remote socket address
- Throws:
IllegalArgumentException
- if corresponding endpoint context is missing- Since:
- 3.8
-
keepsRequestInStore
public boolean keepsRequestInStore()Indicate to keep the original request in the exchange store. Intended to be used for observe request with blockwise response to be able to react on newer notifies during an ongoing transfer.- Returns:
true
to keep it,false
, otherwise
-
isNotification
public boolean isNotification()Indicate a notification exchange.- Returns:
true
if notification is exchanged,false
, otherwise
-
getRequest
Returns the request that this exchange is associated with. If the request is sent blockwise, it might not have been assembled yet and this method returns null.- Returns:
- the complete request
- See Also:
-
setRequest
Sets the request that this exchange is associated with.- Parameters:
newRequest
- the request- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.- See Also:
-
getCurrentRequest
Returns the current request block. If a request is not being sent blockwise, the whole request counts as a single block and this method returns the same request asgetRequest()
. Call getRequest() to access the assembled request.- Returns:
- the current request block
-
setCurrentRequest
Sets the current request block. If a request is not being sent blockwise, the origin request (equal to getRequest()) should be set.- Parameters:
newCurrentRequest
- the current request block- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
getResponse
Returns the response to the request ornull
, if no response has arrived yet. If there is an observe relation, the last received notification is the response on the client side. On the server side, that is the last notification to be sent, but may differ from the current response, if that is in transit.- Returns:
- the response. or
null
,
-
setResponse
Sets the response.- Parameters:
response
- the response- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
getCurrentResponse
Returns the current response block. If a response is not being sent blockwise, the whole response counts as a single block and this method returns the same response asgetResponse()
. CallgetResponse()
to access the assembled response. On the server-side, this is the current notification in flight.- Returns:
- the current response block, or current notification in flight.
-
setCurrentResponse
Sets the current response block. If a response is not being sent blockwise, the origin response (equal to getResponse()) should be set.- Parameters:
newCurrentResponse
- the current response block- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
getKeyMID
-
setKeyMID
Set key mid used to register this exchange.- Parameters:
keyMID
- key mid.- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
setKeyToken
Set key token used to register this exchange.- Parameters:
keyToken
- key token- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
getKeyToken
-
getBlock1ToAck
Returns the block option of the last block of a blockwise sent request. When the server sends the response, this block option has to be acknowledged.- Returns:
- the block option of the last request block or null
-
setBlock1ToAck
Sets the block option of the last block of a blockwise sent request. When the server sends the response, this block option has to be acknowledged.- Parameters:
block1ToAck
- the block option of the last request block
-
getEndpoint
Returns the endpoint which has created and processed this exchange.- Returns:
- the endpoint
-
setEndpoint
Set endpoint of received message.- Parameters:
endpoint
- endpoint, which received the message.
-
getPeersIdentity
Returns the other peer's identity.- Returns:
- the other peer's identity
- Since:
- 3.0
- See Also:
-
EndpointIdentityResolver
-
isTimedOut
public boolean isTimedOut()Indicated, that this exchange retransmission reached the timeout.- Returns:
true
, transmission reached timeout,false
, otherwise
-
setTimedOut
Report transmission timeout for provided message to exchange.This method also cleans up the Matcher state by calling the exchange observer
setComplete()
. The timeout is forward to the provided message, and, for thecurrentRequest
, it is also forwarded to therequest
to timeout the blockwise transfer itself. If the exchange was already completed, this method doesn't forward the timeout calls to the requests.- Parameters:
message
- message, which transmission has reached the timeout.- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
getFailedTransmissionCount
public int getFailedTransmissionCount()Get failed transmissions count.- Returns:
- number of failed transmissions
-
incrementFailedTransmissionCount
public int incrementFailedTransmissionCount()Increment the failed transmission count.- Returns:
- incremented number of failed transmissions
- Since:
- 3.0
-
getTimeoutScale
public float getTimeoutScale()Get timeout scale factor for exponential back-off between retransmissions.- Returns:
- timeout scale factor for exponential back-off.
- Since:
- 3.0
-
setTimeoutScale
public void setTimeoutScale(float scale) Set timeout scale factor for exponential back-off between retransmissions.- Parameters:
scale
- timeout scale factor. Must be at least 1.0. If larger than 1.0, an exponential back-off between retransmissions is used.- Throws:
IllegalArgumentException
- if value is not at least 1.0.- Since:
- 3.0
-
getCurrentTimeout
public int getCurrentTimeout()Get current timeout. Timeout for retransmission, if no ACK, RST nor response is received.- Returns:
- current timeout in milliseconds
-
setCurrentTimeout
public void setCurrentTimeout(int currentTimeout) Set current timeout. Timeout for retransmission, if no ACK, RST nor response is received.- Parameters:
currentTimeout
- current timeout in milliseconds. Must be larger than 0.
-
isTransmissionPending
public boolean isTransmissionPending()Check, if ACK, RST or response for transmission is pending.- Returns:
true
, if ACK, RST or response is pending,false
, if not.- Since:
- 3.0 (was getRetransmissionHandle)
-
setRetransmissionHandle
Set retransmission handle.- Parameters:
newRetransmissionHandle
- new retransmission handle. May benull
, if no retransmission is required.- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
retransmitResponse
public void retransmitResponse()Prepare exchange for retransmit a response.- Throws:
IllegalStateException
- if exchange is not a REMOTE exchange.ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
setNotificationNumber
public void setNotificationNumber(int notificationNo) Sets the number of the notification this exchange is associated with.This number can be used to match responses of a blockwise transfer triggered by a notification.
- Parameters:
notificationNo
- The observe number of the notification.- Throws:
IllegalArgumentException
- if the given number is < 0 or > 2^24 - 1.
-
getNotificationNumber
Gets the number of the notification this exchange is associated with.This number can be used to match responses of a blockwise transfer triggered by a notification.
- Returns:
- The observe number of the notification or
null
if this exchange is not associated with a notification.
-
setRemoveHandler
Sets an remove handler to be invoked when this exchange completes.- Parameters:
removeHandler
- The remove handler.
-
hasRemoveHandler
public boolean hasRemoveHandler()Checks whether this exchange has an remove handler set.- Returns:
true
if an remove handler is set.- See Also:
-
isComplete
public boolean isComplete()Checks if this exchange has been marked as completed.- Returns:
true
, if this exchange has been completed.
-
getCaller
Get caller.- Returns:
- the caller's stacktrace.
-
setComplete
public boolean setComplete()Marks this exchange as being completed.This means that both request and response have been sent/received.
This method invokes the remove method on the observer registered on this exchange (if any).
Call this method to trigger a clean-up in the Matcher through its ExchangeObserverImpl. Usually, it is called automatically when reaching the StackTopAdapter in the
CoapStack
, when timing out, when rejecting a response, or when sending the (last) response.- Returns:
true
, if complete is set the first time,false
, if it is repeated.- Throws:
ExchangeCompleteException
- if exchange was already completed.ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
executeComplete
public boolean executeComplete()Execute complete. Schedules job for this exchange, if current thread is not already owner of it.- Returns:
true
, if exchange was not already completed,false
, if exchange is already completed.
-
getNanoTimestamp
public long getNanoTimestamp()Get the nano-timestamp of the creation of this exchange.- Returns:
- nano-timestamp
- See Also:
-
ClockUtil.nanoRealtime()
-
getSendNanoTimestamp
public long getSendNanoTimestamp()Get the realtime of the last sending of a message in nanoseconds. The realtime is just before sending this message to ensure, that the message wasn't sent up to this time. This will also contain the realtime for ACK or RST messages.- Returns:
- nano-time of last message sending.
0
, if no message was sent until now. In the extremely rare cases, that the realtime in nanosecond is actually0
, the value is adapted to-1
. - See Also:
-
ClockUtil.nanoRealtime()
-
setSendNanoTimestamp
public void setSendNanoTimestamp(long nanoTimestamp) Set the realtime of the last sending of a message in nanoseconds.- Parameters:
nanoTimestamp
- realtime in nanoseconds.0
, if no message was sent until now. In the extremely rare cases, that the realtime in nanosecond is actually0
, the value must be adapted to-1
.
-
startTransmissionRtt
public void startTransmissionRtt()Start transmission RTT.- Since:
- 3.0
-
calculateTransmissionRtt
public long calculateTransmissionRtt()Calculate transmission round trip time.startTransmissionRtt()
must be called before.- Returns:
- transmission round trip time in nanoseconds.
- Throws:
IllegalStateException
- ifstartTransmissionRtt()
wasn't called before.- Since:
- 3.0
-
calculateApplicationRtt
public long calculateApplicationRtt()Calculates the RTT (round trip time) of this exchange. MUST be called on receiving the response.- Returns:
- RTT in nanoseconds
- Since:
- 3.0 (was calculateRTT returning milliseconds)
-
getRelation
Returns the CoAP observe relation that this exchange has initially established.Note: in the meantime the relation may have been
ObserveRelation.cancel()
. Therefore it's important to check the current state of the relation usingObserveRelation.isCanceled()
orObserveRelation.isEstablished()
.- Returns:
- the observe relation, or
null
, if this exchange is not related to an observation.
-
setRelation
Sets the observe relation this exchange has established.- Parameters:
relation
- the CoAP observe relation- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.NullPointerException
- if provided relation isnull
IllegalStateException
- if relation was already set before
-
removeNotifications
public void removeNotifications()Remove past notifications from message exchange store. To be able to react on RST for notifications, the NON notifications are also kept in the message exchange store. This method removes the notification message from the store.- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.
-
setEndpointContext
public void setEndpointContext(org.eclipse.californium.elements.EndpointContext ctx) Sets additional information about the context this exchange's request has been sent in.The information is usually obtained from the
If aConnector
this exchange is using to send and receive data. The information contained in the context can be used in addition to the message ID and token of this exchange to increase security when matching an incoming response to this exchange's request.setEndpointContextPreOperator(EndpointContextOperator)
is used, this pre-operator is called before the endpoint context is set and forwarded.- Parameters:
ctx
- the endpoint context information
-
resetEndpointContext
public void resetEndpointContext() -
getEndpointContext
public org.eclipse.californium.elements.EndpointContext getEndpointContext()Gets transport layer specific information that can be used to correlate a response with this exchange's original request.- Returns:
- the endpoint context information or
null
, if no information is available.
-
setEndpointContextPreOperator
Set endpoint context pre-operator. Applied onsetEndpointContext(EndpointContext)
before the endpoint context is set and forwarded.- Parameters:
operator
- preprocessing operator for endoint context.
-
execute
Execute a job serialized related to this exchange. If exchange is already owned by the current thread, execute it synchronous. Otherwise schedule the execution.- Parameters:
command
- job
-
assertIncomplete
Assert, that the exchange is not complete and new messages could be send using this exchange.- Parameters:
message
- message to be send using this exchange.- Throws:
ConcurrentModificationException
- if not executed withinexecute(Runnable)
.ExchangeCompleteException
- if exchange is already completed
-
checkOwner
public boolean checkOwner()Check, if current thread owns this exchange.- Returns:
true
, if current thread owns this exchange,false
, otherwise.
-
setCryptographicContextID
public void setCryptographicContextID(byte[] cryptoContextId) Sets cryptoContextId- Parameters:
cryptoContextId
- a byte array used for mapping cryptographic contexts
-
getCryptographicContextID
public byte[] getCryptographicContextID()Gets cryptoContextId. Used by OSCORE.- Returns:
- byte array with crypto context id.
-