User Tools

Site Tools


resource_find_registration

Registering Resources & Resource Discovery

Please read the initialize_setting page before continuing with Resource Discovery.

Overview

Resource Discovery is a key part of the IoTivity Base Layer. It consists of two main functionalities: Resource Registration and Resource finding.

Discovery is a client-server operation. A device acting in a server role regsters its public resources with the stack, making them discoverable by a device acting in a client role which sends multicast or unicast discovery requests. Note that all IoTivity devices are to some extent able to perform both client-type operations (sending RESTful requests and waiting for replies) and server-type operations (receiving RESTful requests and responding to them), so the “role” terminology is preferred for clarity.

For application developers, a set of simple and direct C++ APIs have been provided to initiate these operations.

Registering a resource requires two basic items:

  • URI path - an identifier used to unambiguously identify how to reach the resource.
  • Handler - a routine used to process requests from the stack for that resource.

The URI path should be rooted (in other words, starting with a slash). The stack will construct the fully qualified URI by adding the URI authority to the provided URI path.

For example, given a service running on port 5683 on a device at IP address 192.168.1.1, if a resource is registered with a URI path “/light/1”, the resulting fully qualified URI is

oc://192.168.1.1:5683/light/1

which uniquely identifies the resource's location (IP address, port, and path).

Note: Only one resource can be registered at a given URI.

Sequence Diagram

The following call sequence diagram outlines the operations performed in the stack when a resource is registered:

C SDK

Here are the relevant C API functions:

From iotivity/resource/csdk/stack/include/ocstack.h:

  • OCCreateResource (server) - creates a resource.
  • OCDoResponse (server) - Sends a response to a request.
  • OCDoResource (client) - Discovers or performs requests on a resource specified by a URI.

Please refer to the OC Stack section of the CSDK API documentation for more information.

OCCreateResource (server)

Here is an example of using OCCreateResource() to create a discoverable/observable light resource:

  OCStackResult res = OCCreateResource(&Light.handle,
                                       "core.light",
                                       OC_RSRVD_INTERFACE_DEFAULT,
                                       "/light/1",
                                       handleOCEntity,
                                       NULL,
                                       OC_DISCOVERABLE | OC_OBSERVABLE);
  • Light.handle is a pointer to hold the resource handle (filled in by the stack).
  • “core.light” is the name assigned to the resource.
  • OC_RSRVD_INTERFACE_DEFAULT is the default resource interface (“oic.if.baseline”).
  • The URI path (“/light/1”) is where the resource is located on this server. The URI path is unique; this call will fail if the application attempts to register another resource using an existing URI.
  • handleOCEntity is a callback function to be processed on incoming requests directed to this resource.
  • The flags control how the stack should handle the resource. The OC_DISCOVERABLE flag indicates that the resource should be reported if a client performs a resource discovery on this server. OC_OBSERVABLE allows clients to observe the resource.

OCDoResource (client)

After OCInit has run, the client can attempt to discover resources using:

 ret = OCDoResource(NULL, OC_REST_DISCOVER,
                    "/light/1", NULL, 0, connectivityType,
                     qos, &cbData, NULL, 0);
  • NULL is used when the caller has no use for the return value (normally the request handle)
  • The OC_REST_DISCOVER method tells the caller to carry out the discovery process.
  • “/light/1” is the URI of the resource.
  • NULL indicates no destination is given.
  • 0 indicates this request has no payload with it.
  • connectivityType can be set to determine OCConnectivityType; this is used when a destination is not given. It can be set to use the default settings by being set to CT_DEFAULT, or it can be set to use other protocols like GATT over Bluetooth LE, CoAP over TCP, NFC transport, or many more.
  • qos can be set to determine the OCQualityOfService, which can be low, medium, high, or set to be decided by the stack.
  • cdData is a callback object to call other functions.

cbData can then be used to call other functions:

OCCallbackData cbData = {NULL, NULL, NULL};
cbData.cb = handleDiscover;

handleDiscover lists discovered resources that can be filtered and interacted with:

OCStackApplicationResult handleDiscover(void *ctx,
                                        OCDoHandle handle,
                                        OCClientResponse *clientResponse)
{
    OCStackResult result = OC_STACK_OK;

    if (!clientResponse)
    {
        OIC_LOG(ERROR,TAG,"Payload is NULL, No resources found");
        return OC_STACK_DELETE_TRANSACTION;
    }
    
    OIC_LOG_V(INFO, TAG,
              "Device =============> Discovered @ %s:%d",
              clientResponse->devAddr.addr,
              clientResponse->devAddr.port);
              
    OCDiscoveryPayload *payload = NULL;
    payload = (OCDiscoveryPayload*) clientResponse->payload;
    if (!payload)
    {
        return OC_STACK_DELETE_TRANSACTION;
    }
    OCResourcePayload *resource = NULL;
    resource = (OCResourcePayload*) payload->resources;

    while (resource)
    {
        if(resource->uri)
        {
            OIC_LOG_V(INFO, TAG, "uri: %s", resource->uri);
        }
        resource = resource->next;
    }

}

C++ SDK

Sample Application :

The simpleserver and simpleclient examples are a good place to learn about discovery and registration:

The following call sequence diagram outlines the operations performed in the stack when a resource is registered:

Register Resource (server)

Step 1: OC::OCPlatform::registerResource

Assuming the application has created a valid OCPlatform object, an application can register a new resource with the stack by calling OCPlatform::registerResource(…).

OCStackResult OC::OCPlatform::registerResource(
    OCResourceHandle & resourceHandle,
    std::string & resourceURI,
    const std::string & resourceTypeName,
    const std::string & resourceInterface,
    EntityHandler entityHandler,
    uint8_t resourceProperty)

In this example, the call would take the following form:

OCPlatform::registerResource(
    resourceHandle,
    “/light/1”, “core.light”, “oic.if.baseline”,
    entityHandlerCb,
    OC_DISCOVERABLE | OC_OBSERVABLE);
  • The handle is a reference to the resource that is used on other APIs.
  • The URI path (“/light/1”) is where the resource can be located on this server. The URI path is unique; this call will fail if the application attempts to register another resource using an existing URI.
  • The resource type (“core.light”) and interface (“core.if.baseline”) are properties of the resource used in the discovery process.
  • The handler is a function called from the stack to process requests.
  • The flags control how the stack should handle the resource. The OC_DISCOVERABLE flag indicates that the resource should be reported if a client performs a resource discovery on this server OC_OBSERVABLE allows the resource's properties to be observed.
Step 2:

The OCPlatform::registerResource(…) method delegates the call to the appropriate instance of the stack (in-process or out-of-process via IPC).

Step 3: OCCreateResource

The internal registerResource(…) method constructs a C++ entity handler and registers it with the C SDK using OCCreateResource(…).

In this example, the call would take the form:

                            
OCCreateResource(&handle,
                 "core.light", "oic.if.baseline", "/light/1",
                  handler, OC_DISCOVERABLE); 

Many of these parameters are passed through to the C SDK directly. However, the entity handler is a proxy function for the handler passed from OCPlatform::registerResource(…).

Register Resource in C++ [Server]

  OCResourceHandle resourceHandle;
  std::string resourceURI = "/light/1";
  std::string resourceTypeName = "alpha.light";
  std::string resourceInterface = DEFAULT_INTERFACE;
  uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
 
  OCStackResult result = platform.registerResource(resourceHandle, resourceURI,
     resourceTypeName, resourceInterface, &entityHandler, resourceProperty);
  if (OC_STACK_OK == result)
  {
     //Successfull
  } 

Next Steps

Once you've reviewed the materials of this document, the next step is to read the wiki page on querying resource states using [GET]

Resources

Previously published documentation which this (living) wiki page is based on :

resource_find_registration.txt · Last modified: 2017/08/06 18:04 by Mats Wichmann