Overview
Cumulocity IoT offers a public API which enables device integrators to support the Cloud Remote Access feature on their devices.
For this functionality, the gateway needs to listen for an operation which establishes a new tunnel to a device endpoint. For this purpose, the gateway needs to create a WebSocket connection to the cloud and a TCP connection to the device. Using these connections, simple tunneling of protocol data is done on a binary level.
Implementation
This section describes how to implement a device agent at a gateway.
The device agent is responsible for creating the device part of the tunnel between an unencrypted TCP/IP connection at private network and the secure device WebSocket endpoint.
Supported operation
To indicate that your device is capable of handling Cloud Remote Access, it should report c8y_RemoteAccessConnect
as supported operation in its managed object:
"c8y_SupportedOperations": [
...
"c8y_RemoteAccessConnect",
...
]
Connect operation
This operation is created when the application generates a connect request. The operation is then sent to the device agent to establish the connection between the WebSocket endpoint at the server and the local network endpoint.
Example of an c8y_RemoteAccessConnect
operation:
{
"deviceId" : "10200",
"c8y_RemoteAccessConnect": {
"hostname": "10.0.0.67",
"port": 5900,
"connectionKey": "eb5e9d13-1caa-486b-bdda-130ca0d87df8"
},
"description": "Connect to remote access server"
}
Field | Data type | Details |
---|---|---|
connectionKey | String | Shared secret to authenticate the connection request from device side. |
hostname | Number | Endpoint on the local network to connect to. |
port | String | Port to be used on local network endpoint. |
Connecting to a new endpoint
For each c8y_RemoteAccessConnect
operation received the device agent connects to the provided hostname and port using TCP. Using the provided ConnectionKey the agent also securely connects to the WebSocket endpoint on server side. If all these operations succeeded the device reports the operation as SUCCESSFUL and starts forwarding binary packets between the TCP connection and the WebSocket in both directions.
The following events are triggered when the device agent receives a c8y_RemoteAccessConnect
operation.
- The operation status is set to EXECUTING.
- The connectionKey is used to connect to the Cumulocity IoT Cloud Remote Access WebSocket. All data received from the WebSocket should be forwarded to the TCP connection (if already established): wss://
/service/remoteaccess/device/ - The hostname and port is used to connect TCP in a local area network. Hostname and port are configured on server side and are used to connect to the endpoint of the device. Depending on the protocol (VNC, Telnet, SSH) the device will initiate a protocol-specific handshake. All data should be forwarded directly to the WebSocket endpoint (if already established).
- The operation status is set to SUCCESSFUL or FAILED based on the status of the previous steps.
Operating a connected endpoint
When both connections are established and fully functional the agent simply needs to forward all binary packets between the TCP connection and the WebSocket in both directions.
Disconnecting an endpoint
Whenever one of the connections is terminated (WebSocket or TCP) the device agent should consider the session as ended and should also terminate both connections associated with the tunnel.
Recommendations
It is highly recommended to implement a small buffer especially for bootstrapping when one connection is already functional while the other is not setup yet.
Reference implementation
Cumulocity IoT provides a C++ reference agent which includes a plugin for Cloud Remote Access.
Find the source code at our public GitHub repositories:
https://github.com/SoftwareAG/cumulocity-agents-linux
(note that for historical reasons the module is called vnc here)