This operation fetches and registers as an observer for the value of a simple resource. In this example, we fetch the state of the light resource. For more implementation details, see “Observing Resources in CoAP” listed in the referenced documents. (https://datatracker.ietf.org/doc/draft-ietf-core-observe/?include_text=1)
The handling of observation registration is application specific. It should not be assumed that a resource is observable, or a resource can handle any specific number of observers. If the server responds with a success (2.xx) code, the registration is considered successful.
Notifications from the server to the client may be confirmable or non-confirmable. If the client returns a RST message, the observation registration should be dropped immediately. If the client fails to acknowledge a number of confirmable requests, the server should assume that the client has abandoned the observation and drop the registration.
If the observed resource is removed, the server sends a NOTFOUND status to all observers.
If an observed resource fails to notify a client before the max-age of a resource value update, the client should attempt to re-register the observation.
The client application calls resource.observe(…) to retrieve a representation from the resources.
The call is marshalled to the stack which is either running in-process or out-of-process (daemon).
The C API
is called to dispatch the request. The call may look like this:
OCDoResource(OC_REST_GET | OC_REST_OBSERVE, "//192.168.1.11/light/1, 0, 0, OC_CONFIRMABLE, callback);
Where CoAP is used as a transport, the lower stack will send a GET request to the target server. The primary difference between a GET request and an observe request is that the observe request contains an observe option indicating that, in addition to querying this resource, the client wishes to get notifications if/when the resource state changes.
On the server side, the OCProcess() function (message pump) receives and parses the request from the socket, then dispatches it to the correct entity handler based on the URI
of the request. The request to the entity handler will indicate that the request is both a query and subscription request. The entity handler MAY take note of this, but it is not responsible to tracking the observers. The stack tracks the observers of record.
Where the C++ API
is used the C++ entity handler parses the payload and marshals it to the client application depending on if the server stack is running in-process or out-of-process (daemon).
The C++ SDK passes it up the C++ handler associated with the OCResource.
The handler returns the result code and representation to the SDK.
The SDK marshals the result code and representation to the C++ entity handler.
The entity handler returns the result code and representation to the CoAP protocol.
The CoAP protocol transport the results to the client device.
The results are returned to the OCDoResource callback.
The results are returned to the C++ client application's asyncResultCallback.
If the entity handler has registered observers, it will periodically be called with the observe flag set so that it may sample or poll underlying hardware to determine if the state has changes.
When the application has deemed that the resource state has changed either via polling (entity handler observe) or via external signal, the application should call OCNotifyObservers(). This tells the stack the observers need updating.
For each observer of a changed resource, the entity handler is called to generate a representation that is transmitted to the observing clients.
Where CoAP is used as a transport, a packet with content is sent to the devices that have observing clients. The packets may be confirmable or non-confirmable based on application needs.
The client-side OCProcess function (message pump) receives the message and matches it to the original request based on the CoAP token ID and dispatches the appropriate C API
The C API
callback passes the final results to the C++ client application's asyncResultCallback.
When the C++ client no longer desires to receive notifications from the server, it calls observation cancellation method cancelObserve().
The C++ cancellation method calls the OCCancel() function from the C API
OCCancel() finds the observation that is associated with the operation and sends an observe deregistration request to the server.
Once initialization has been setup on the server side, the server can declare resource property attributes to be observable and allow remote devices to subscribe to changes.
The simpleserver and simpleclient examples are a good place to learn about resource observation:
Step 1: The server declares the resource attribute as “OC_OBSERVABLE” when creating the resource.
uint8_t resourceFlag = OC_DISCOVERABLE | OC_OBSERVABLE;
result = OCPlatform::registerResource//
Step 2: The client sets observation on the resource.
OCResource::observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &observeHandler, qos);
The client specifies how it wants to observe via OBSERVE_TYPE_TO_USE. QueryParamsMap() us the map which can have the query parameter name and value. observeHandler is the callback that handles the observation result. qos is specifies the communication quality, e.g. specifying the notification to be confirmable or non-confirmable.
An example of observehandler can look like the following:
void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation& rep,
const int& eCode, const int& sequenceNumber)
* Function body