Octave Resource Protocol Reference Guide

This topic describes the Octave Resource Protocol, which is the protocol that facilitates communications between your assets, Octave edge device, and the cloud.

What is the Octave Resource Protocol?

Octave Resource Protocol (ORP) is a simple ASCII-based protocol that is built on top of HDLC-framed data sent via UART. Using ORP, a customer asset (asset) can interact with Octave by sending and receiving ASCII-based messages with an Octave edge device.

This page provides the specification of this protocol:

ORP Version Updates

ORP Version 2

ORP version 2 is supported by Octave edge firmware, version 3.0.0, released in June 2020. Version 2 is backward compatible with version 1 however, version 2 provides the following enhancements:

  • The fields of the general packet description have been updated to support sequence numbers.
  • A "hello message" was added (SYNC). This includes a version number and sent/received packet counts. This message can be ignored by assets which do not wish to support it. The hello message is sent by the module when the ORP service starts and may be used by the asset to decide when to create or recreate the Resources.
  • The path of ORP Resources has changed:
    • All ORP Resources are under a node named orp.
    • Customer-defined Resources are under a node named /orp/asset.
    • An asset has read/write access to Resources under /orp/asset. Other paths under /orp are read-only.
    • A read-only status Resource is available under /orp/status to report the connection state as well as packet statistics and errors

Packet Structure

Packets contain fixed-length and variable-length fields. Most fields contain ASCII characters but are not null-terminated strings. Packets must adhere to the following:

  • Fixed-length fields are located at the beginning of the packet, followed by any variable-length ones.
  • Fixed-length fields are mandatory. Their contents may be ignored when not needed for a given packet.
  • The first 4 bytes of a packet must be present, even if not all are applicable to the specific request.
  • Variable-length fields begin with a 1-byte identifier and end with a separator. The final variable-length field does not end with a separator.
  • Data values may contain the separator. Therefore, data must appear as the last field in any packet.

Request and Notification Structure

Protocol Version 1 - ASCII

<packet type[1]><data type[1]><sequence[2]><contents[variable]>
Fields:
packet type : Identifies request or notification, 1-byte
data type   : Identifies data type of request or notification, if needed. Ignored for some types. 1-byte
segment     : Unused, 2-bytes
contents    : Packet dependent, variable length

Protocol Version 2 - ASCII

Version 2 introduces a message for synchronization between the Octave edge device and the asset. Protocol Version 2 is backward compatible with Version 1. Devices which do not reply to the synchronization message or which report version 1 in the reply, can continue to follow version 1 of the protocol. Devices which report version 2 in the synchronization messages must use and increment the sequence field in any packet which specifies it. The packet sizes are unchanged but the use of some fields has been updated.

<packet type[1]><data type|version[1]><sequence[2]><contents[variable]>
Fields:
packet type       : Identifies request or notification, 1-byte
data type/version : Identifies data type or protocol version, if needed. Ignored for some types. 1-byte
sequence          : Packet number - count of packets sent by the sender since restart, including the current. 2-bytes, binary
contents          : Packet dependent, variable length

Response Structure

Protocol Version 1 - ASCII

<packet type[1]><status[1]><sequence[2]><contents[variable]>
Fields:
packet type : Identifies response, 1-byte
status      : Identifies status of response. 1-byte
segment     : Unused, 2-bytes
contents    : Packet dependent, variable length

Protocol Version 2 - ASCII

<packet type[1]><status[1]><sequence[2]><contents[variable]>
Fields:
packet type : Identifies response, 1-byte
status      : Identifies status of response. 1-byte
sequence    : Packet number - count of packets sent by the sender since restart, including the current. 2-bytes, binary
contents    : Packet dependent, variable length

Request, Notification, and Response Types

Packet TypeRequest (asset to Octave edge device)Response (Octave edge device to asset)Version
Create Resource (input)I (49h)i (69h)1
Create Resource (output)O (4Fh)o (6Fh)1
Delete ResourceD (44h)d (64h)1
Add Push HandlerH (48h)h (68h)1
Remove Push HandlerK (4Bh)k (6Bh)1
Push to ResourceP (50h)p (70h)1
Get from ResourceG (47h)g (67h)1
Create SensorS (53h)s (73h)1
Remove SensorR (52h)r (72h)1
Set JSON ExampleE (45h)e (65h)1
Push Handler Callc (63h)C (43h)1
Sensor Handler Callb (62h)B (42h)1
Syncy (79h)Y (59h)2
Unknown Request? (3Fh)1

Data Types

TypeValue
TriggerT (54h)
BooleanB (42h)
NumericN (4Eh)
StringS (53h)
JSONJ (4Ah)

📘

Note

When the data type field is ignored, any character may be used.

Version

The version byte is encoded in ASCII hex, beginning with '0'. The version number is calculated as follows:

version number = version byte + 0x01

For example, a version byte of 0x31 equates to version 2.

Sequence

The number of the current packet (i.e., count of the number of packets sent by the sender since restart, including the current one). This field is available in ORP versions 2.x and up.
The sequence number is Big Endian encoded (high byte transferred first).

Status

The status byte is encoded beginning with '@' (hex 40), which represents success. The status value can be calculated from this byte as:

status value = -1 * (<status byte> - 0x40)

where the status value is interpreted as:

CodeDescription
0OK
-1NOT FOUND
-3OUT OF RANGE
-4NO MEMORY
-5NOT PERMITTED
-6FAULT
-7COMM ERROR
-8TIMEOUT
-9OVERFLOW
-10UNDERFLOW
-11WOULD BLOCK
-12DEADLOCK
-13FORMAT ERROR
-14DUPLICATE
-15BAD PARAMETER
-16CLOSED
-17BUSY
-18UNSUPPORTED
-19IO ERROR
-20NOT IMPLEMENTED
-21UNAVAILABLE
-22TERMINATED

Timestamps

The timestamp is encoded as a decimal number, representing seconds since the UNIX epoch. Digits are encoded as ASCII decimal and are preceded by the character 'T'.

E.g: T1661434984.000000 = 8/25/2022, 3:43:04 PM

The maximum length of a timestamp is 11 digits + '.' + 6 digits = 18 characters.

Paths

The path is encoded as ASCII text with no null terminator. The path field is preceded by the character 'P'. (e.g., Pinput/button_01).

Allowable characters are: a-z A-Z 0-9 / _ -

ORP Resources

Paths may be relative or absolute. The ORP service treats paths with a leading '/' as follows:

'sub-path' is under 'asset' and is read-write:

/asset/<sub-path>
/orp/asset/<sub-path>
/app/orp/asset/<sub-path>

'sub-path' is internal to ORP (i.e., not under 'asset'), and is read-only:

/orp/<sub-path>
/app/orp/<sub-path>

📘

Note:

In order to access other ORP Resources, such as those under /orp/status, a path must be provided which includes a beginning ‘/’ character (e.g., /orp/status/UART1/value).

Relative paths are always assumed to be under the 'asset' path. For example, each of these forms is treated as '/app/orp/' by the ORP service:

<sub-path>
asset/<sub-path>

Non-ORP Resources

Resources outside of ORP in other applications are accessible using absolute paths. The remote asset can read from and write to these Resources (get, push) as well as register for notifications on them. It cannot create or delete resources under other applications. Access to these Resources requires the form:

/app/<appname>/<sub-path>

The maximum length of a path depends on the type of Resource being created or accessed. A Sensor Resource includes auto-generated sub-nodes which reduce the allowable path length during the create request.

FieldBytesComment
Path, Resource65Data Hub MAX_RESOURCE_PATH_LEN - "/app/orp/asset"
Path, Sensor57Resource path max len - "/trigger"

ORP Status Resource

Octave edge devices provide a Resource with sub Resources under the node: orp/status. This status Resource provides the connection state as well as statistics and error reporting.

Data

Data is prepended with the character 'D' and there is no encoding of the contents. The data field must occur last in a packet. The maximum data length (payload) is 50,000 bytes.

For example: D0123456789,abc*

For some data types, the ORP service will transform the data it receives into the correct internal type. A failure to convert the data will result in an error being returned.

Data TypeConversion
triggerNot applicable
booleanCase insensitive comparison with "false" -> false
Case insensitive comparison with "true" ‐> true
"0" -> false
"1" -> true
Otherwise an error is returned
numericInterpreted as double-precision real
stringNo conversion
JSONNo conversion

Packet Counts

Sync packets (version 2 and later) contain fields to report packets sent and received. These are whole numbers, encoded as ASCII decimal, and are preceded by an 'R' for received count and an 'S' for sent count (e.g., R251,S305).

Resource Operations

📘

Resources access

From firmware 3.2.0, ORP allows to access to other all resources.

Asset to Octave Edge Device

CreateResource

Request to create a Resource in the Data Hub. If a CreateResource request is received for a Resource which already exists, the request will succeed only if all requested parameters match those of the existing Resource. In this case, no changes are actually applied. If one or more parameters differs from the existing Resource, the request will fail.

Request:      <packet type[1]><data type[1]><sequence[2]><path>[,<units>]

packet type:  'I' || 'O'
data type:    'T' || 'B' || 'N' || 'S' || 'J'  (Trigger || Boolean || Numeric || String || Json)
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
units:        'U'<units> (optional)
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'i' || 'o'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

DeleteResource

Request to remove a Resource from the Data Hub. When a Resource is deleted, any associated handlers are also de-registered.

Request:      <packet type[1]><data type[1]><sequence[2]><path>

packet type:  'D'
data type:    ignored
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'd'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

AddPushHandler

Asset request to be notified when data is written to a path. Once an asset successfully registers a handler, notification packets will be sent by the ORP service whenever there is a change in the associated Resource (path).

Request:      <packet type[1]><data type[1]><sequence[2]><path>

packet type:  'H'
data type:    ignored
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'h'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

RemovePushHandler

Asset request to cease notifications for a particular path.

Request:      <packet type[1]><data type[1]><sequence[2]><path>

packet type:  'K'
data type:    ignored
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'k'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

Push

Asset request to push data to a Resource.

Request:      <packet type[1]><data type[1]><sequence[2]><path>[,<timestamp>][,<data>]

packet type:  'P'
data type:    'T' || 'B' || 'N' || 'S' || 'J'  (Trigger || Boolean || Numeric || String || Json)
sequence:      Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
timestamp:    'T'<time in seconds>  (optional - omit to use current data hub timestamp)
data:         'D'<data>  (optional)
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'p'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

Get

Asset request to read data from a Resource.

Request:      <packet type[1]><data type[1]><sequence[2]><path>

packet type:  'G'
data type:    ignored
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
Response:     <packet type[1]><status[1]><sequence[2]><timestamp>,<data>

packet type:  'g'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number
timestamp:    'T'<time in seconds>
data:         'D'<data>  (represented as ASCII, NOT null terminated)

CreateSensor

Asset request to create a sensor type in the Data Hub.

Note: A sensor is a Resource that represents a sensing device to gather data about some some physical phenomenon (e.g., light, temperature, etc.). See Sensor Resources for more information.

If a CreateSensor request is received for a sensor which already exists, the request will succeed only if all requested parameters match those of the existing Resource. In this case, no changes are actually applied. If one or more parameters differs from the existing Resource, the request fails.

Request:      <packet type[1]><data type[1]><sequence[2]><path>[,<units>]

packet type:  'S'
data type:    'B' || 'N' || 'S' || 'J'  (Boolean || Numeric || String || Json)
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
units:        'U'<units> (optional)
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  's'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

DestroySensor

Asset request to delete a sensor from the Data Hub.

Request:      <packet type[1]><data type[1]><sequence[2]><path>

packet type:  'R'
data type:    ignored
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the sensor>
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'r'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

SetJsonExample

Asset request to populate the JSON example node of a Resource.

Request:      <packet type[1]><data type[1]><sequence[2]><path>,<data>

packet type:  'E'
data type:    'J'  (Json)
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
data:         'D'<data>
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'e'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

Octave Edge Device to Asset

PushHandler

Notification that data has changed on a Resource.

Notification: <packet type[1]><unused[1]><sequence[2]><timestamp>,<path>[,<data>]
packet type:  'c'

unused:       not applicable - ignore
sequence:     Version 1: ignored.  Version 2: packet number
timestamp:    'T'<time in seconds>
path:         'P'<path of the Resource>
data:         'D'<data> (optional)
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'C'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

SensorCall

Notification that a sensor is requesting a push. A SensorCall notification is to inform the owner of a sensor (the asset) that the Data Hub is requesting that data be pushed to the sensor value node. The asset should follow this notification with a Push to the sensor value Resource.

Notification: <packet type[1]><unused[1]><sequence[2]><path>

packet type:  'b'
unused:       not applicable - ignore
sequence:     Version 1: ignored.  Version 2: packet number
path:         'P'<path of the Resource>
Response:     <packet type[1]><status[1]><sequence[2]>

packet type:  'B'
status:       see above
sequence:     Version 1: ignored.  Version 2: packet number

Sync (Version 2 and up)

An unsolicited notification sent from the ORP service to the asset to indicate that the service has restarted.

After a restart of the ORP service, the service will periodically send this message until either a direct response is received from the asset, or the asset sends any other valid packet. Once a response has been received, the ORP service will update its status to "connected".

The response packet must contain the protocol version which the remote device will use. The version byte is calculated as: version byte = version number - 0x01. If the remote device does not explicitly respond to the sync packet with a sync response but instead sends any other valid packet, the ORP service assumes that the remote is using protocol version 1.

📘

Note

The sequence numbers are not used in the sync and sync response packets. The sequence count must not be incremented when sending a sync or sync response.

Notification: <packet type[1]><version[1]><sequence[2]><timestamp>[,<sent>,<received>][,<MTU>]

packet type:  'Y'
version:      Maximum ORP version supported
sequence:     unused
timestamp:    'T'<time in seconds>
sent:         'S'<sent count>. Packets sent since restart, equal to zero (ASCII decimal, NOT null terminated)
received:     'R'<received count>. Packets received since restart, equal to zero (ASCII decimal, NOT null terminated)
MTU:          'M'<mtu size>. Requested MTU size, optional (ASCII decimal, NOT null terminated)
Response:     see below

Sync-Acknowledge (SYNACK): Response to a sync packet, used when the recipient of the sync wishes to negotiate part of the handshake. The recipient is acknowledging the sync packet but wishes to use some value other than the default or what was sent in the original sync packet.

Response:     <packet type[1]><version[1]><sequence[2]>[,<MTU>]
packet type:  'y'
version:      ORP version supported
sequence:     unused
MTU:          'M'<mtu size>. Requested MTU size, optional (ASCII decimal, NOT null terminated)

Acknowledge (ACK): Response to a sync packet or to a sync-acknowledge packet. Used to accept the last received sync or sync-acknowledge packet.

Response:     <packet type[1]><version[1]><sequence[2]>
packet type:  'z'
version:      unused
sequence:     unused

File Operations

The Octave file-sending functionality involves the use of ORP. For this functionality, ORP and the Remote Asset manage file transfers using two packets:

  1. File Transfer Notification: for control (notifications).
  2. File Transfer Data: for data.

Both packet types can be sent from either the ORP service or from the asset and both types must be acknowledged by the receiver before further processing of a file transfer can continue.

If a packet is not acknowledged by the asset, ORP will eventually report an error and the transfer will be aborted.

All transfers over ORP are initiated by the File Service. Even if a transfer is initiated by the Remote Asset, it must go through the File Service in order to start the transfer over ORP.

Note that if the ORP packet limitation is too large for file transfer to the Remote Asset, the maximum packet size of the ORP interface can be reduced through an optional field in the SYNC and SYNACK packets as we’ll describe in next section.

Change Maximum Packet Size

The default maximum size of an ORP packet is limited by the size of a string or JSON sample in the Datahub, which is 50000 bytes on the FX30. This may be too large for file transfer to some remote assets. To address this, the ORP interface supports setting the maximum packet size (MTU: Maximum Transfer Unit). This is an optional field in the SYNC and SYNACK packets. See the section on sync, above

The Remote Asset can change the MTU size as follows:

  1. By responding to the SYNC packet with a SYNACK packet with the optional MTU size included
  2. By initiating a sync operation by sending a SYNC packet with the optional MTU size included

The maximum packet size is applied only to the File Transfer packet.

435

File Notification (Control)

The File Notification packet is used to exchange control information between ORP and the asset in the form of events.

Features of the notification packets:

  • Can be sent by the Remote Asset or by ORP.
  • Byte 1 contains the event type.
  • An optional data field can be used to pass information between the File Service and the Remote Asset.
  • The response to the notification contains a status to accept or reject the event.
Notification: <packet type[1]><event[1]><sequence[2]>[,<data>]
packet type: 'L'
event:       INFO | READY | PENDING | START | SUSPEND | RESUME | ABORT
sequence:    packet number
data:        'D'<data> (optional)

Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'l'
status:      see status codes
sequence:    packet number

File Transfer (Data)

The File Transfer data packet is used to stream data between ORP and the Remote Asset. Each data packet must be acknowledged by the receiver before the sender can send another packet.

Request: <packet type[1]><unused[1]><sequence[2]>[,<data>]
packet type: 'T'
sequence:    packet number
data:        'D'<data>

Response: <packet type[1]><status[1]><sequence[2]>
packet type: 't'
status:      see status codes
sequence:    packet number

File Start-up Sequence

  1. The Remote Asset starts and synchronizes with the ORP service. See ORP Start-up Sequence.
  2. The Remote Asset registers a Handler on the /files/list/value Resource to receive notifications when a new file is available for transfer from the Octave Edge device.
  3. (Optional) The Remote Asset registers a Handler on the /files/download/value Resource to receive notifications on the progress of the cloud-to-device file-sending operation.

📘

Note:

  • When autostart is set to true, a handler may not be required on the /files/download/value Resource.
  • Watching the /files/download/value Resource (Step 4 above) is mandatory when file/autostart is set to false, as this is the only means for the Remote Asset to be notified when a file is pending for download on the Octave Cloud.
  1. The Remote Asset notifies the ORP service that it is ready for transfers by sending the File Notification packet with the READY event. This is required as not all remote assets will support the file transfer protocol.

The following diagram depicts this startup sequence:

573

File Transfer Sequence

The following is the sequence of calls to be made between the Remote Asset and the ORP service to handle the transfer of a file from the Octave Edge device to the asset:

  1. The Remote Asset is notified by the handler for the /files/list/value Resource that a new file is available on the Octave Edge device for transfer.

  2. The Remote Asset requests the ORP service to start the transfer by sending the START notification with the name of the file contained in the optional data portion of the packet.

  3. The ORP service reads the file contents from a stream and forwards it to the Remote Asset using File Transfer data packets.

    a. The ORP service sends as much data as is available or as permitted by the MTU to the Remote Asset in the data packet.
    b. The ORP service waits for a response from the Remote Asset.
    c. If the Remote Asset responds with OK, ORP continues sending. If the Remote Asset responds with not OK, ORP attempts to resend the packet.

  4. (Optional) The Remote Asset may request the ORP service to suspend the transfer at any time before the transfer is complete, by sending a File Transfer notification packet with the SUSPEND event. The ORP service will wait indefinitely until the Remote Asset sends another notification with the RESUME event.

  5. Once all bytes are transferred, the ORP service closes the file stream and stops sending data. The Remote Asset must keep track of the received bytes and compare this to the expected file size.

  6. The Remote Asset verifies the file size and hash are correct.

  7. (Optional) The Remote Asset requests that the file be deleted after transfer using the /files/control Resource.

📘

Note:

If the file is not deleted from the Octave Edge after a successful transfer to the remote asset, the Octave Edge storage capacity can be used up over time and future file-sending requests could be rejected.

The following diagram depicts this transfer sequence:

592

ORP Start-up Sequence

There are 2 possible sequences of calls that need to occur between the Remote Asset and the ORP service at startup: with or without MTU (Maximum Transfer Unit) negotiation.

Basic (no negotiation)

407

With MTU (Maximum Transfer Unit) negotiation

435