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 Versions: provides information about specific changes in different versions of ORP
- Packet Structure: describes ORP's packet structure.
- Operations: describes ORP's available commands.
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
- All ORP Resources are under a node named
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 Type | Request (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 Resource | D (44h) | d (64h) | 1 |
Add Push Handler | H (48h) | h (68h) | 1 |
Remove Push Handler | K (4Bh) | k (6Bh) | 1 |
Push to Resource | P (50h) | p (70h) | 1 |
Get from Resource | G (47h) | g (67h) | 1 |
Create Sensor | S (53h) | s (73h) | 1 |
Remove Sensor | R (52h) | r (72h) | 1 |
Set JSON Example | E (45h) | e (65h) | 1 |
Push Handler Call | c (63h) | C (43h) | 1 |
Sensor Handler Call | b (62h) | B (42h) | 1 |
Sync | y (79h) | Y (59h) | 2 |
Unknown Request | ? (3Fh) | 1 |
Data Types
Type | Value |
---|---|
Trigger | T (54h) |
Boolean | B (42h) |
Numeric | N (4Eh) |
String | S (53h) |
JSON | J (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:
Code | Description |
---|---|
0 | OK |
-1 | NOT FOUND |
-3 | OUT OF RANGE |
-4 | NO MEMORY |
-5 | NOT PERMITTED |
-6 | FAULT |
-7 | COMM ERROR |
-8 | TIMEOUT |
-9 | OVERFLOW |
-10 | UNDERFLOW |
-11 | WOULD BLOCK |
-12 | DEADLOCK |
-13 | FORMAT ERROR |
-14 | DUPLICATE |
-15 | BAD PARAMETER |
-16 | CLOSED |
-17 | BUSY |
-18 | UNSUPPORTED |
-19 | IO ERROR |
-20 | NOT IMPLEMENTED |
-21 | UNAVAILABLE |
-22 | TERMINATED |
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.
Field | Bytes | Comment |
---|---|---|
Path, Resource | 65 | Data Hub MAX_RESOURCE_PATH_LEN - "/app/orp/asset" |
Path, Sensor | 57 | Resource 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 Type | Conversion |
---|---|
trigger | Not applicable |
boolean | Case insensitive comparison with "false" -> false Case insensitive comparison with "true" ‐> true "0" -> false "1" -> true Otherwise an error is returned |
numeric | Interpreted as double-precision real |
string | No conversion |
JSON | No 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:
- File Transfer Notification: for control (notifications).
- 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:
- By responding to the SYNC packet with a SYNACK packet with the optional MTU size included
- 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.
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
- The Remote Asset starts and synchronizes with the ORP service. See ORP Start-up Sequence.
- 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.
- (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.
- 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:
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:
-
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.
-
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.
-
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. -
(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.
-
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.
-
The Remote Asset verifies the file size and hash are correct.
-
(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:
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)
With MTU (Maximum Transfer Unit) negotiation
Updated about 2 years ago