Sysclient protocol

The sysclient protocol is used for devices to register in the Devices App and to tunnel HTTP connections to access the device UI through the Devices App.
Binary websocket messages are used for the communication.

Table of contents

Devices App

The Devices App provides a URL to which so called "sysclients" can connect to. The URL e.g. looks like this: wss://app-platform-dns/domain.com/devices/sysclients
Any sysclient which connects to this URL will not be added to any domain inside the Devices App as long as it can't answer the challenge request successfully.

Binary protocol

The first byte of each message contains the sysclient message type.


// An sysclient message has the following format (depending on the value of the message type - SMT = sysclient message type):
//
// SMT | Byte offset
//     |  0      1      2      3      4      5      6      7      8      9     ...
//     +------+------+------+------+------+------+------+------+------+------+------+
//  1  | Msg- |   Adm-Msg   | Data.........
// --- | Type +------+------+------+------+------+------+------+------+------+------+
//  2  |      |        Session-ID         |         Event-Type        |  Data.....
//     +------+------+------+------+------+------+------+------+------+------+------+

Sysclient message header

1 byte: the sysclient message header is a byte value starting with 1

0x01: Admin message header
0x02: Tunnel message header

Admin message header

1 word: there are different administrative messages. The admin message type is written into a word.
The data following this admin message header is a non null terminated JSON string.

0x0000: Send identify
0x0001: Receive sysclient password
0x0002: Receive challenge
0x0003: Receive new administrative password
0x0004: Provision
0x0005: Provision result
0x0006: Configuration

Message flow of admin messages

0x0000: Send identify

The identify JSON is a JSON object. The sysclient sends this message after the connection establishment towards the Devices App:

Parameters

string id The unique hardware id.
string product The product name, e.g. IP222.
string version The complete version string, e.g. 13r2 dvl [13.4250/131286/1300].
object platform A JSON object which contains data about the platform.
string type The device type, possible values are VA|GW|PHONE|DECT|APP_PLATFORM.
boolean fxs (optional)Devices has FXS interfaces.
string name (optional)Name which is configured on the client itself (is superceded by the configured name in the Devices App).
string fwBuild (optional)The firmware build number, e.g. 13233.
string bcBuild (optional)The bootcode build number, e.g. 13233.
string major (optional)The major release, e.g. 13r1.
string fw (optional)The firmware filename, e.g. ip222.bin.
string bc (optional)The bootcode filename, e.g. boot222.bin.
string provisioningCode (optional)The provisioning code used to be added to a domain.
string digest (optional)The calculated digest after receiving a new challenge to authenticate in a domain.
boolean mini (optional)Minifirmware booted.
boolean pbxActive (optional)PBX active or not.
boolean other (optional)true means, that this is not an innovaphone device. The "Admin UI" tab in the Devices UI is not available in this case.
array ethIfs (optional)A JSON array containing JSON objects with the following parameters:
string if The ethernet interface name.
string ipv4 (optional)The IPv4 address.
string ipv6 (optional)The IPv6 address.

Example JSON object


{
  "id": "009033460af2",
  "product": "IP222",
  "version": "13r2 dvl [13.4250\/131286\/1300]",
  "fwBuild": "134250",
  "bcBuild": "131286",
  "major": "13r2",
  "fw": "ip222.bin",
  "bc": "boot222.bin",
  "mini": false,
  "platform": {
    "type": "PHONE"
  },
  "digest": "f3d37205d8eb93a4ccdd236b5a957c98d629d925aa58fe03b770035853c12984",
  "ethIfs": [
    {
      "if": "ETH0",
      "ipv4": "172.16.4.141",
      "ipv6": "2002:91fd:9d07:0:290:33ff:fe46:af2"
    }
  ]
}

0x0001: Receive sysclient password

The password JSON is a JSON object. The message is received when the device is added to a domain inside the Devices App.
The password must be stored on the client device to successfully answer a challenge request for future connections.

Parameters

string password The password for this sysclient.

0x0002: Receive challenge

The challenge JSON is a JSON object. The message is received when the device identified to the Devices App and is already inside a domain:

Parameters

string challenge A challenge to calculate a digest and send it with another identify message.

Digest calculation

Calculate the digest with the received challenge and the password from the password message.
The digest is an SHA256 hex string of:
HardwareId:product:version:challenge:password

A C++ implementation could look like this:
class hash hash;
byte digest_bin[HASH_SIZE_SHA256];
char digest[HASH_SIZE_SHA256 * 2 + 1];
hash.init(HASH_SHA256);
hash.update(id, strlen(id));
hash.update(":", 1);
hash.update(product, strlen(product));
hash.update(":", 1);
hash.update(version, strlen(version));
hash.update(":", 1);
hash.update(challenge, strlen(challenge));
hash.update(":", 1);
hash.update(password, strlen(password));
hash.final(digest_bin);
str::from_hexmem(digest_bin, HASH_SIZE_SHA256, digest);

0x0003: Receive new administrative password

The administrative password JSON is a JSON object. This message is always received after a successfull connection to a domain if the domain provides a password to all devices:

Parameters

string seed A seed for decrypting the password.
string pwd The encrypted password.

Password decryption

The password is RC4 encrypted with the sysclient password from the password message.

A c++ decryption could look like this:
size_t len = strlen(pwdEncrypted);
size_t outLen = len / 2 + 1;
char * k = (char *)alloca(strlen(seed) + strlen(sysclientPassword) + 2);
char * pwdDecrypted = (char *)alloca(outLen);
byte * i = (byte *)alloca(outLen);
len = str::to_hexmem(pwdEncrypted, i, outLen);
_sprintf(k, "%s:%s", seed, sysclientPassword);
Cipher c;
c.Init(CIPHER_RC4, (const byte *)k, strlen(k), false);
c.Crypt(i, (byte*)pwdDecrypted, len);
pwdDecrypted[len] = '\0';

0x0004: Provision

The provision JSON is a JSON object. The sysclient sends this message to provision a new FXS interface:

Parameters

string id The interface id, e.g. TEL1.
string code The provisioning code.

0x0005: Provision result

The provision result JSON is a JSON object. It is the answer to the provision message:

Parameters

string error (optional)If not empty, an error occurred.

0x0006: Configuration

The config JSON is a JSON object.

In a special scenario where the syscleint connection is maintained by a third-party provisioning app, a subscription to configuration updates for a specific device can be created by sending a Send identify message with the "other" property set to "true".

Multiple Configuration messages will be sent until all available configuration options for a particular device have been submitted. The last configuration message for a particular device contains the "last" property set to "true". This means that no further messages are expected and the complete configuration can be forwarded to the device.

If configuration changes are made to the Devices App that applies to the subscribed device, the Devices Service communicates the changes by sending an additional Configuration message that contains the changed configuration option.

For the description of the particular Configuration message fields please refer to the Devices Service API documentation.

Parameters

boolean last (optional)If last is set, the last config item from the intial config item messages is received.

Tunnel message header

The tunnel message header always contains a session id with corresponds to one HTTP request.
The session id is followed by the event type, which allows the handling of the HTTP data.

1 dword: session id
1 dword: event type

The following event types exist:

0x00000000: socket send
0x00000001: socket receive
0x00000002: socket receive result
0x00000003: socket send result
0x00000004: socket shutdown

Message flow of socket messages

If a new connection to a sysclient is established through the Devices App, the sysclient receives the tunnel message with a socket send event type and a new session id.
The sysclient itself is responsible to handle multiple sessions and the flow of the events.
In addition the sysclient must now forward the received data to the local webserver and afterwards send the answer transparently back.

0x00000000: socket send

After the tunnel message header, just HTTP data is received and must be forwarded to the local webserver.

0x00000001: socket receive

The tunnel message header is followed by a socket receive header:

1 dword: the length of data to receive

0x00000002: socket receive result

The tunnel message header is followed by the received data from the local webserver.

0x00000003: socket send result

No further data is sent.

0x00000004: socket shutdown

No further data is sent. A sysclient must also send this message as an answer to a socket shutdown message.