Skip to content

Development Guide

The IOT Platform SDK consists of Owner Companion Service (OCS) that can be implemented to integrate any other device management solution.

Both the OPS and To0Scheduler are bound to the OCS by a set of pre-defined contracts, as specified in the module libocs, that can be implemented to perform certain pre-defined tasks. The contract is backed by a set of REST APIs/interfaces, where each individual REST API/interface is tied to exactly one method from the pre-defined contract. Each REST API/interface carries out only the corresponding task, and accepts/returns only the corresponding Message Type object.

The implementation of these REST contracts in an OCS can be done in any programming language. A sample java-based reference implementation of OCS is provided by the module ocsfs that uses file-system as database. As such, both OPS and To0Scheduler will work out-of-the-box with any implementation of OCS that supports the pre-defined REST contracts.

Note

The implementation of the pre-defined contracts can be backed by non-REST interfaces as well. However, this would invlove updates to both OPS and To0Scheduler to facilitate communication with the newly defined interface at OCS. Such a change would involve, but is not limited to, updates to existing class RestClient.java at both OPS and To0Scheduler.

Rest Contracts between OCS(Server) and OPS/To0Scheduler(Client)

The following are the pre-defined REST API specifications for all the resource paths that must be implemented and exposed by an OCS implementation. Both, OPS and To0Scheduler make requests to the OCS implementation, as clients, using this format.

Operation Description Path/Query Parameters Request Body Response Body
GET /v1/devices/{deviceId}/voucher Get the ownership voucher corresponding to the deviceId. Path: deviceId: Device identifier OwnerVoucher
POST /v1/devices/voucher Store the ownership voucher. OwnerVoucher
GET /v1/devices/{deviceId}/state Get the state information corresponding to the deviceId. Path: deviceId: Device identifier DeviceState
POST /v1/devices/{deviceId}/state Store the state information corresponding to the deviceId. Path: deviceId: Device identifier DeviceState
GET /v1/devices/{deviceId}/msgs Get service info array corresponding to the deviceId. Path: deviceId: Device identifier [SviMessage]
POST /v1/devices/{deviceId}/msgs Store service info array corresponding to the deviceId. Path: deviceId: Device identifier [SviMessage]
PUT /v1/devices/{deviceId}/msgs Store module message info corresponding to the deviceId. Path: deviceId: Device identifier ModuleMessage
DELETE /v1/devices/{deviceId}/msgs Delete service info array corresponding to the deviceId. Path: deviceId: Device identifier
GET /v1/devices/{deviceId}/psi Get module message array corresponding to the deviceId. Path: deviceId: Device identifier [ModuleMessage]
GET /v1/ devices/{deviceId}/values/{valueId} Get the serviceinfo value corresponding to the valueId for the device identified by deviceId. Path: deviceId: Device identifier, valueId: Serviceinfo resource identifier
Query start: start index, end: end index
Byte Array
PUT /v1/ devices/{deviceId}/values/{valueId} Store the serviceinfo value corresponding to the valueId for the device identified by deviceId. Path: deviceId: Device identifier, valueId: Serviceinfo resource identifier Byte Array
DELETE /v1/ devices/{deviceId}/values/{valueId} Delete the serviceinfo value corresponding to the valueId for the device identified by deviceId. Path: deviceId: Device identifier, valueId: Serviceinfo resource identifier
GET /v1/devices/{deviceId}/setupinfo Get new setup information corresponding to the deviceId. Path: deviceId: Device identifier SetupInfoResponse
POST /v1/devices/{deviceId}/errors Store the error information corresponding to the deviceId. Path: deviceId: Device identifier DeviceState
POST /v1/signatures/{deviceId} Generate signature of input data and return it along with associated info, corresponding to the deviceId. Path: deviceId: Device identifier String
POST /v1/ciphers/{deviceId} Perform the operation and return data corresponding to the . Path: deviceId: Device identifier; Query: operation: encipher/decipher Byte Array Byte Array
DELETE /devices/{deviceId}/blob Delete the deviceId along with all the associated data. Path: deviceId: Device identifier
GET /v1/devices/{deviceId}/sessioninfo Get the TO2 session info corresponding to the deviceId. Path: deviceId: Device identifier To2DeviceSessionInfo
POST /v1/devices/{deviceId}/sessioninfo Update the TO2 session info corresponding to the deviceId. Path: deviceId: Device identifier To2DeviceSessionInfo
DELETE /v1/devices/{deviceId}/sessioninfo Delete the TO2 session info corresponding to the deviceId. Path: deviceId: Device identifier
GET /devices/{deviceId}/resale Get the resale flag indicating owner's support for resale of the corresponding deviceId. Path: deviceId: Device identifier Boolean

Rest Contracts between To0Scheduler(Server) and OCS(Client)

An OCS implementation must, also, act as a client to trigger TO0 for set of devices, by making the following request to To0Scheduler. To0Scheduler accepts the request from OCS to initiate TO0 for the list of devices.

Operation Description Path/Query Parameters Request Body Response Body
POST /v1/to0/devices Trigger TO0 for an array of devices. To0Request

Message Types

Following is a list of message types that are sent in the message body of each request/response. Each message type follows the standard JSON* schema. Statements after '#' inside the JavaScript* Object Notation (JSON), represents the purpose of the field.

DeviceState

This JSON* structure represents the state information of the device.

Message Body:

{
  "to2Error": ProtocolError Object,    # TO2 failure information
  "to2Timestamp": String,              # Successful TO2 completion time
  "g3": String,                        # Device Identifier/GUID
  "to0Error": String,                  # TO0 failure information
  "to0Timestamp": String,              # Successful TO0 completion time
  "to0Ws": Integer,                    # Number of seconds for which last successul TO0 is valid.
  "to2State": String                   # TO2 state
}

Every field is optional.

ProtocolError

This JSON* structure represents the device's error information that occurred during execution of the protocol.

Message Body:

{
  "ec": Integer,    # Error code
  "emsg": Integer,  # Message ID
  "em": String      # Error message
}

ModuleMessage

This JSON* structure contains the key-value pairs for a particular module name. It is used to store both the device's serviceinfo and the owner's pre-serviceinfo.

Message Body:

{
  "module": String,    # module name
  "msg": String,       # (pre-)serviceinfo key
  "value":  String     # (pre-)serviceinfo value
}

SviMessage

This JSON* structure represents information about the owner service info.

Message Body:

{
  "module":  String,     # Module name
  "msg": String,         # Message to be sent
  "valueLen": Integer,   # Length of the value of the message
  "valueId": String,     # Key to use when retrieving the serviceinfo value
  "enc": String          # Encoding expected to use when sending the value
}

SetupInfoResponse

This JSON* structure represents the new Device identifier and the Rendezvous information.

Message Body:

{
  "g3": String,                             # New device identifier/GUID
  "r3": [
          RendezvousInstruction Object      # Array of RendezvousInstruction objects
        ]
}

RendezvousInstruction

This JSON* structure represents the rendezvous information. Please refer to the RendezvousInfo to know about these values.

Message Body:

{
  "only": String,
  "ip": String,
  "po": Integer,
  "pow": Integer,
  "dn": String,
  "sch": String,
  "cch": String,
  "ui": Integer,
  "ss": String,
  "pw": String,
  "wsp": String,
  "me": String,
  "pr": String,
  "delaysec": Integer
}

SignatureResponse

This JSON* structure represents the response to the signature operation.

Message Body:

{
  "sg": String,    # Base-64 encoded signature information
  "pk": String,    # Base-64 encode public key information that can verify the signature
  "alg": String    # Algorithm of the public key
}

OwnerVoucher

This JSON* structure represents the Ownership voucher of the device. Please refer to the Ownership Voucher about the structure.

Message41Store

This JSON* structure represents the information from Secure Device Onboard protocol's request TO2.HelloDevice, Type 40 and its subsequent response TO2.ProveOPHdr, Type 41. This information is stored as a part of TO2 session information per device.

Message Body:

{
  "n6": String,                  # Nonce n6
  "kx": String,                  # Key exchange information
  "ownershipVoucher": String,    # ownership voucher
  "cs": String,                  # cipher suite
  "kxEcdhPublicKey": String,     # Public key being used for ECDH key exchange
  "kxEcdhPrivateKey": String,    # Private key being used for ECDH key exchange
  "kxEcdhRandom": String,        # Random being used for ECDH key exchange
  "kxDhPublicKey": String,       # Public key being used for DH key exchange
  "kxDhPrivateKey": String,      # Public key being used for DH key exchange
  "asymRandom": String           # Random being used for Asymmetric key exchange
}

Message45Store

This JSON* structure represents the information from Secure Device Onboard protocol's request TO2.ProveDevice, Type 44 and its subsequent response TO2.GetNextDeviceServiceInfo, Type 45. This information is stored as a part of TO2 session information per device.

Message Body:

{
  "n7": String,    # Nonce n7
  "nn": Integer,   # Total number of serviceinfo
  "xb": String     # Second part of key-exchange
}

Message47Store

This JSON* structure contains the new ownership voucher information, temporarily, until the end of TO2 protocol, created during response generation of TO2.SetupDevice, Type 47. This information is stored as a part of TO2 session information per device.

Message Body:

{
  "newOwnershipVoucher": String    # the new ownership voucher structure without hmac
}

DeviceCryptoInfo

This JSON* structure contains the nonce and counter of the Initialization Vector for the Secure Device Onboard TO2 cipher mode of operation.

Message Body:

{
  "ctrNonce": String,    # Nonce used for CTR mode
  "ctrCounter": Long     # Counter value used for CTR mode
}

To2DeviceSessionInfo

This JSON* structure represents the complete TO2 session information. It's a combination of multiple structures, where each structure is either null or contains values. If any of the structure is null, OCS treats the structure as non-updatable in its store, while OPS considers the same to be an erroneous case. If any of the structure contains appropriate information, OCS overrides the current content with the new content, while OPS processes the content during TO2 protocol execution.

Message Body:

{
  "messsage41Store": Message41Store Object,
  "messsage45Store": Message45Store Object,
  "messsage47Store": Message47Store Object,
  "deviceCryptoInfo": DeviceCryptoInfo Object
}

To0Request

This JSON* structure represents the request message that is sent from the OCS to schedule an array of devices for TO0.

Message Body:

{
  "guids": [
             String            # Array of Device Identifiers/GUID
           ],
  "waitSeconds": String        # Suggested number of seconds for which TO0 will be valid
}