Skip to content
Simon edited this page Mar 4, 2024 · 11 revisions

The page regroups all information/questions relative to observation mechanism in LWM2M 1.0.

The spirit of observe feature

The LWM2M observation feature is based on CoAP Observe.
⚠️ With observation, the LWM2M server acts the CoAP client and the LWM2M client acts the CoAP server.

This is how Observing Resources in CoAP - RFC 7641 describes this feature :

This document specifies a simple protocol extension for CoAP that enables 
CoAP clients to "observe" resources, i.e., to retrieve a representation of 
a resource and keep this representation updated by the server over a period of
time.  The protocol follows a best-effort approach for sending new
representations to clients and provides eventual consistency between
the state observed by each client and the actual resource state at
the server.

This was not thought as a way to send data from device to server but more as a best-effort way for a peer to keep aware of foreign peer resource value over the time. In other words, RFC 7641 tries to sync the "most recent state" and doesn't care about a "complete history".

The fine detail is that the protocol could ignore some responses/notifications if they are older(out-of-date) than the last received. (This could happen with UDP as packet order is not warranty)

CoAP GET vs OBSERVE

An OBSERVE request is pretty much the same as a GET request. The response from one should be the same than the other. The exception is the observe option which is used to say : "ok the observe relation is established".

Notifications are just other responses to the original OBSERVE request.

Request/Notifications Matching

In all case token is used to match request and notification, but this is not the only data used.

For DTLS

The CoAP Observe RFC is very strict about request/notification matching over DTLS. Maybe a bit too strict. This brings to frictions with real world and some LWM2M features.
It says : "All notifications resulting from a GET request with an Observe Option MUST be returned within the same epoch of the same connection as the request." This means that if you lost the DTLS connection, observe relation is lost...

This problem is discussed at OMA (see here) and IETF (see there, corrclar#9).

At IETF, core team seems to be aware about the issue but we don't see any proposition to change this for now.

At OMA, the solution was to strictly linked session lifetime and registration lifetime which does not really respect the CoAP Observe RFC too. This allows notification to be handled after an abbreviated handshake but not after a full-handshake...

Faced with this situation, the Californium team chose to go with a fully customizable way to match requests and responses/notifications. (see EndpointContextMatcher)
At Leshan side, we chose to use the flexibility offered by Californium to relaxed by default the CoAP observe constraint(up to you to make it stricter if you prefer). We currently accept notifications if the DTLS identity is the same as the one linked to the registration. So this means if you do a full handshake, meaning having a new DTLS connection/session, we will accept your notification as long as you are using the good DTLS identity.

This allow to keep observation relationship after a restart even if you don't persist DTLS connection or session.
See Server Failover wiki page for more details.

For UDP (without security)

The CoAP Observe RFC is less explicit for unsecured channel but the CoAP 7252 RFC say :

Regardless of how a response is sent, it is matched to the request by
means of a token that is included by the client in the request, along
with additional address information of the corresponding endpoint.

So this means IP address/port must be the same. This is the default behavior of Californium and Leshan for UDP (without DTLS).

If you want to only use token for matching, you could use the NetworkConfig and set the RESPONSE_MATCHING from STRICT to RELAXED.

coapConfig = LeshanServerBuilder.createDefaultNetworkConfig();
coapConfig.set(NetworkConfig.Keys.RESPONSE_MATCHING, MatcherMode.RELAXED);
builder.setCoapConfig(coapConfig);

(You could also consider to implement your own EndpointContextMatcher)

My device receive RST CoAP Message ?

Generally the RST message is sent when a notification is received about an observe relation which does not exist at server side. What could happen ?

  1. the observe relation does not exist.
  2. the observe relation was cancelled. (and so does not exist anymore)
  3. the notification does not match (see Request/Notifications Matching above).

The 3. could happen if IP address/port change at client side (for unsecure connection) or if DTLS identity changes.
This could also be a bug/bad implementation at client or server side.

I want Leshan Client to send CON notifications

There is now way to configure the use of CON or NON by resource/object for now.
But there a way to configure this for whole system using californium NetworkConfig.

There is 2 parameters about that :
NOTIFICATION_CHECK_INTERVAL_COUNT (default 100) : number of NON (-1) notifications between 2 CON notifications.
NOTIFICATION_CHECK_INTERVAL(default 86400000ms = 1d) : number of seconds between 2 CON notifications.

coapConfig = LeshanServerBuilder.createDefaultNetworkConfig();
coapConfig.set(NetworkConfig.Keys.NOTIFICATION_CHECK_INTERVAL_COUNT, value);
coapConfig.set(NetworkConfig.Keys.NOTIFICATION_CHECK_INTERVAL, anotherValue);
builder.setCoapConfig(coapConfig);

(see #564)

I want to update the IP address/port of registration on notifications

See LWM2M-Devices-with-Dynamic-IP#is-the-update-request-mandatory--should-i-update-registration-on-notification-

Could I store notification when device is off-line ?

see : #595

Duplicate observation.

How we should handle several sending of the same observe request is not so clear.
Currently Leshan try to cancel previous request and send the new one but there is not clean API to do that in an atomic way in californium.
See californium#87 and leshan#332 for more details.