Skip to content

ETags for Resources

Daniel Adam edited this page Sep 6, 2023 · 7 revisions

Version: 2.2.5.7

ETags (Entity Tags) are a vital element of CoAP (Constrained Application Protocol), serving the critical purpose of uniquely identifying distinct versions of a resource. ETags are instrumental in optimizing resource caching and facilitating efficient communication between CoAP clients and servers.

Decoding ETags

At its core, an ETag is an opaque string that acts as a unique identifier for a resource's state or version on the server. Whenever a resource undergoes any alteration, its ETag value is updated to reflect the new state. ETags are employed by CoAP clients to determine if a resource has been modified since their last interaction. This mechanism aids in making resource updates more efficient. Rather than transmitting the entire resource with every request, servers can utilize ETags to assess the validity of the client's cached version. If the cached version remains valid, the server can respond with a concise message, resulting in both time and bandwidth savings.

Enabling ETag Feature

Using CMake

To activate the ETag feature during the CMake build process, utilize the OC_ETAG_ENABLED switch. By default, this feature is turned off. To enable it, add -DOC_ETAG_ENABLED=ON to your CMake command.

mkdir build && cd build
cmake .. -DOC_ETAG_ENABLED=ON

Using Make

When building with make, enabling the ETag feature requires the ETAG switch. Similar to CMake, this feature is also disabled by default. To enable it, include ETAG=1 in your make command or environment.

cd port/linux
make ETAG=1

Resource ETag in IoTivity-lite

Within the realm of IoTivity-lite, each resource is represented by an oc_resource_t structure. When the ETag feature is enabled, this structure is expanded to incorporate an etag member.

Internally, ETag values are determined using system time values returned by oc_clock_time() and the most recently used ETag value. These values are harnessed in calculating the new ETag, ensuring that each resource boasts a unique ETag.

Handling GET Requests

Regarding GET requests:

  • Without ETag CoAP Options: Clients sending a valid GET request without ETag CoAP options receive a 2.05 (Content) response containing the complete representation of the requested resource. Additionally, the CoAP response includes the ETag option, providing the current ETag of the queried resource.

  • With ETag CoAP Options: When clients send a valid GET request with ETag CoAP options, two possible scenarios emerge. If the ETag from the CoAP options matches the ETag of the queried resource, a 2.03 (Valid) response with empty content is issued as a response. Conversely, if the ETag from CoAP does not align with the current ETag of the queried resource, IoTivity sends a 2.05 (Content) response. This response comprises the complete representation of the resource, and the response options feature the current ETag of the resource.

Handling GET Requests with Batch Interface

The batch interface serves as a mechanism for interacting with a collection of resources using a single request. This interface is supported by collection resources, the Discovery (/oic/res) resource, and custom user-created resources that incorporate batch interface support. (As of version 2.2.5.7, the ETag feature for batch interface is fully implemented only for the Discovery resource.)

Discovery Resource

The discovery resource supports the batch interface when OC_RES_BATCH_SUPPORT is defined in your application's config.h or during compilation. When querying the discovery resource with the batch interface, it is treated as a collection of selected, discoverable, and accessible resources. In this context, "selected" denotes all resources except the discovery resource itself, the '/.well-known/core' resource, and secure vertical resources. "Inaccessible" signifies that for secure builds, the resource must have defined ACLs that grant access. The response payload to the batch request contains an array of the default interface payloads for the sub-resources. Each item in this array is enhanced by an "etag" property containing the ETag of the corresponding resource. The batch response ETag is calculated as the highest ETag value derived from the sub-resources and the ETag of the discovery resource itself.

Handling Observations

Clients can register for observing observable resources. IoTivity-lite sends notification messages to the client whenever an observed resource is updated. The payload of the notification is identical to the payload received in response to a GET request for that resource. The interface used for these notifications corresponds to the interface specified in the registration request. For observations registered with Batch interface the default interface of the resource is used.

Observation with the Batch interface is supported by the same set of resources as GET requests with the Batch interface. (As of version 2.2.5.7, the ETag feature for the Batch interface is fully implemented only for the Discovery resource.)

Observation of the Discovery Resource

By default, the discovery resource is not observable. To enable observation, you must enable it in your build configuration. In CMake, set -DOC_DISCOVERY_RESOURCE_OBSERVABLE_ENABLED=ON. In Make, use OICRES_OBSERVABLE=1. Alternatively, define OC_DISCOVERY_RESOURCE_OBSERVABLE in your config.h file.

Batch Observation of the Discovery Resource

To enable batch observations of the discovery resource, you must enable batch support for the resource using OC_RES_BATCH_SUPPORT (enabling Batch interface for the discovery resource).

The payload of the observation is similar to the payload of the batch GET response. For the registration request, the payload remains the same. However, the observation notification does not include the payloads of all sub-resources but only the payloads of resources that have been modified. The sending of batch observation notifications is asynchronous. It is possible that multiple resources observed by the same client are modified. In this case, only a single notification is sent, containing the payloads of all the modified resources.

Updating a Resource

When a resource is successfully updated by a POST or PUT request, the ETag of the resource is refreshed, and notifications are scheduled to be sent to the observers of the resource.

However, resources can also be modified through the API. Whenever you modify a resource within an event handler using the API, you must notify the library about the changes. To refresh the resource's ETag, use oc_resource_update_etag from oc_etag.h. To refresh the ETag and notify observers about the changes, use oc_notify_resource_changed from oc_api.h.