C Device Virtualization API Reference for Oracle Internet of Things Cloud Service Client Software Library. Release 21.1.1.0.0-3. E70343-26
Device Library overview

The device and enterprise client libraries simplify working with the Oracle IoT Cloud Service. These client libraries are a low-level abstraction over top of messages and REST APIs. Device clients are primarily concerned with sending data and alert messages to the cloud service, and acting upon requests from the cloud service. Enterprise clients are primarily concerned with monitor and control of device endpoints.

The Oracle Internet of Things C Client Library is a high level native library for accessing the Oracle IoT Cloud Service. Basically, Cloud Service supports only low level REST API and this library provides higher level abstraction on top of that making development of client applications easier and faster.

Trusted Assets

Trusted assets are defined as material that contribute to the chain of trust between the client and the server. The client library relies on an implementation of a TrustedAssetsManager to securely manage these assets on the client. The client-library has a default implementation of the TrustedAssetsManager which uses a trust-store to secure the trust assets. To create the trust-store for the default TrustedAssetsManager, the user must use the iotcs_tam.h methods.

Device Models

A device model is a predefined specification of the attributes, formats and resources of a device that can be accessed by the client-library. The attributes of a device model represent the basic variables that the device supports, such as temperature, humidity, flow rate, valve position, and so forth. The formats of a device model define the structure of a message payload. A format describes the message attributes by specifying the attribute names, types, optionality, and default values. The resources of a device model define additional, ad-hoc REST resources which provide richer REST support than what is possible with attributes and formats.

Device Client Quick Start

Note: C Posix library uses strlen(). Be sure tha you use a single byte chars and null terminated strings.

The following steps must be taken to run a device-client application.

  1. Initialize device client
    // Initialize the library before any other calls. 
    // Initiate all subsystems like ssl, TAM, request dispatcher, 
    // async message dispatcher, etc which needed for correct library work.
    // Initialization require a path to trusted assets store and
    // a password for trusted assets store.
    iotcs_init(trusted_assets_store_path, trusted_assets_store_password);
     
  2. Activate the device
    // set supported device models by device
    if (!iotcs_is_activated()) {
        iotcs_activate(device_models);
    }
     
  3. Register indirectly-connected devices
    // create meta-data with the indirectly-connected device's
    // manufacturer, model, and serial number
    const static iotcs_key_value temp_metadata[] = {
        {"manufacturer", "A Manufacturer"},
        {"modelNumber", "MN-xxxx-xxxx"},
        {"serialNumber", "SN-yyyyyyyy"},
        {NULL, NULL}
    };
    // add any vendor-specific meta-data to the metaData Map
    // register it
    iotcs_register_device(hardware_id, metadata, device_models, output_endpoint_id);
     
  4. Create a virtual device implementing the device model
    iotcs_get_device_model_handle(device_model_urn, &device_model_handle);
    iotcs_get_virtual_device_handle(endpoint_id, device_model_handle, &device_handle);
     
  5. Monitor the device through the virtual device

    // set a callback for any changes to this virtual object
    iotcs_virtual_device_set_on_change(device_handle, on_change_callback);
    iotcs_virtual_device_set_on_error(device_handle, on_error_callback);
    // set a callback for any changes to attribute of this virtual object
    iotcs_virtual_device_attribute_set_on_change(device_handle, attribute_name, on_change_callback);
    iotcs_virtual_device_attribute_set_on_error(device_handle, attribute_name, on_error_callback);
    // set a callback for action
    iotcs_virtual_device_set_callback(device_handle, action_name, action_callback);
     
  6. Control the device through the virtual device
    // set a value for a particular attribute in this virtual device
    iotcs_virtual_device_set(device_handle, attribute_name, value, length);
    iotcs_virtual_device_set_string(device_handle, attribute_name, value);
    iotcs_virtual_device_set_integer(device_handle, attribute_name, value);
    iotcs_virtual_device_set_float(device_handle, attribute_name, value);
    iotcs_virtual_device_set_boolean(device_handle, attribute_name, value);
    iotcs_virtual_device_set_date_time(device_handle, attribute_name, value);
     
  7. Dispose the virtual device and the device model

    iotcs_free_virtual_device_handle(device_handle);
    iotcs_free_device_model_handle(device_model_handle);
     

    Storage Cloud Quick Start

    This shows how to use a virtual device attribute to upload content to, or download content from, the Oracle Storage Cloud Service. To upload or download content from a virtual device, there must be an attribute, field, or action in the device model with type URI. For the Oracle Storage Cloud Service, the URI type corresponds to the class oracle.iot.client.StorageObject. When the attribute, field, or action of type URI is set to a StorageObject instance, the content is automatically synchronized with the Storage Cloud Service.

    Uploading content

    An instance of iotcs_storage_object_handle is first needed to upload a file from a device client. The iotcs_storage_object_handle is created using the iotcs_create_storage_object_handle API in "iotcs_storage_object_handle.h". The iotcs_storage_object_handle names the object in storage, and provides the mime-type of the content. To set the input file, the iotcs_storage_object_handle API iotcs_storage_object_set_input_path(file_path) is used.

    iotcs_storage_object_handle storage_object;
    iotcs_create_storage_object_handle("mediaSnapshot.jpg", "image/jpg", &storage_object);
    iotcs_storage_object_set_input_path(storage_object, "../images/mediaSnapshot.jpg");
    iotcs_virtual_device_set_storage_object("snapshot", storage_object);
     

    A iotcs_storage_object_handle may also be set on an Alert field, or as an Action parameter, provided the type in the device model is URI.

    Downloading content

    In the virtualization API, the client is notified through an iotcs_virtual_device_change_event event, or a call callback for an action. The value in the event is a iotcs_storage_object_handle. To download the content, the output path is set on the iotcs_storage_object_handle, and the content is synchronized by calling the iotcs_storage_object_sync() API.

    Checking synchronization status

    A iotcs_storage_object_handle is a reference to some content in the Storage Cloud. The content can be in sync with the storage cloud, not in sync with the storage cloud, or in process of being sync'd with the storage cloud. The synchronization happens on a separate thread, but can be monitored by setting a iotcs_storage_object_sync_callback with iotcs_storage_object_set_callback.

    For the upload case, set the iotcs_storage_object_set_callback on the storage object before setting the virtual device attribute. For the download case, set the iotcs_storage_object_set_callback on the storage object from within the iotcs_virtual_device_changed_callback callback.

    This example shows the typical use case from an iotcs_virtual_device_change_event event.

    // include methods for device client
    #include "iotcs.h"
    // include iot cs device model APIs
    #include "iotcs_virtual_device.h"
    #include "iotcs_device.h"
    #include "iotcs_storage_object_handle.h"
    static void sync_callback(iotcs_storage_object_sync_event *event) {
        printf("\nOn change callback was called for %s with sync status: %d\n", event->name, iotcs_storage_object_get_sync_status(event->source));
        if (iotcs_storage_object_get_sync_status(event->source) == IOTCS_IN_SYNC) {
    // File was uploaded
        } else if (iotcs_storage_object_get_sync_status(event->source) == IOTCS_SYNC_FAILED) {
    // File was not uploaded, take action!
        }
    }
    static void changed_callback(iotcs_virtual_device_change_event *event) {
        printf("\nOn change callback was called for %s\n", event->named_value.name);
        iotcs_storage_object_handle hstorage = event->named_value.typed_value.value.storage_object;
        iotcs_storage_object_set_output_path(hstorage, "output_file.txt");
        iotcs_storage_object_set_callback(hstorage, sync_callback);
        iotcs_sync_storage_handle(hstorage);
    }
    ...
    main() {
        iotcs_storage_object_handle hstorage;
    // Create storage object
        iotcs_create_storage_object_handle("image", "application/x-www-form-urlencoded", &hstorage);
        iotcs_storage_object_set_callback(hstorage, sync_callback);
        iotcs_virtual_device_set_on_change(device_handle, changed_callback);
        iotcs_storage_object_set_input_path(hstorage, filename);
    // Set new object
        iotcs_virtual_device_set_storage_object_handle(device_handle, "image", hstorage);
    }
     
  8. Dispose the device client
    iotcs_finalize();