This is an old revision of the document!


JRBusTCP is a proprietary binary communication protocol designed for efficient, deterministic data exchange between JRobo / JRoboPLC instances and client applications. The protocol operates over TCP/IP and is optimized for:

* High-frequency data exchange * Minimal bandwidth usage * Deterministic behavior suitable for automation and PLC-like systems * Explicit control over data serialization and transport

The protocol follows a request/response model with client-initiated communication. All messages are framed, version-agnostic at transport level, and protected by CRC32 checksums.

Maximum supported message size is 16384 bytes.

* Transport protocol: TCP * Connection model: persistent TCP connection * Byte order: Big Endian (network byte order) * Encoding for strings: UTF-8

JRBusTCP does not define connection establishment beyond TCP. Session state (authentication, tag list, update state) is maintained per TCP connection.

+--------+--------+----------------------------+--------+
| size   | header | payload                    | crc    |
| 2 B    | 2 B    | (size - 4 - 4 bytes)       | 4 B    |
+--------+--------+----------------------------+--------+

Where payload has the following structure:

+---------+------+---------------------------+
| reqId   | cmd  | body                      |
| 4 B     | 1 B  | variable length           |
+---------+------+---------------------------+

* size (2 bytes): Total message size in bytes, from `header` through `crc` inclusive * header (2 bytes): Constant magic value `0xABCD` * reqId (4 bytes): Request identifier (int32, signed). Generated by client * cmd (1 byte): Command code * body (variable): Command-specific payload * crc (4 bytes): CRC32 calculated over `[reqId..body]`

* Generated by the client * Initial value SHOULD be random * Incremented by 1 for each subsequent request * Server MUST return the same `reqId` value unchanged * Client MUST verify response `reqId` matches request

Server does not validate or interpret `reqId`.

Code Name
0x01 INIT
0x02 LIST
0x03 UPDATE
0x04 READ
0x05 WRITE
0x06 CRC
0x07 AUTH_INIT
0x08 AUTH_SUBMIT
0xFE UNAUTHENTICATED
0xFF UNKNOWN

Response commands are formed by setting the highest bit (`cmd | 0x80`).

Initializes tag list and session parameters.

==== Request ====

cmd        : 0x01
flen       : 1 byte
filter     : flen bytes (UTF-8 regex)
clen       : 1 byte
client     : clen bytes (UTF-8)
flags      : 2 bytes 

* b0: Client supports tag descriptions * b1: Client supports tag status in READ * b2: Exclude tags with `external` flag * b3: Include tags with `hidden` flag

==== Response ====

cmd        : 0x81
listsize   : 3 bytes (uint24) 

`listsize` indicates total number of tags selected.

Retrieves tag metadata in chunks.

==== Request ====

cmd   : 0x02
index : 3 bytes (uint24) 

==== Response ====

cmd      : 0x82
index    : 3 bytes
quantity : 3 bytes
next     : 3 bytes
[tag entries] 

==== Tag Entry Format ====

type    : 1 byte
nlen    : 1 byte
tagname : nlen bytes (UTF-8)
dlen    : 1 byte
descr   : dlen bytes (UTF-8) 
Code Type
1 BOOL
2 INT32
3 INT64
4 DOUBLE
5 STRING

Checks for tag value changes.

==== Request ====

cmd : 0x03 

==== Response ====

cmd        : 0x83
quantity   : 3 bytes
next       : 3 bytes
liststate  : 1 byte 

* 0x00: tag list unchanged * 0xFF: tag list changed; client MUST re-run INIT + LIST

Reads tag values.

==== Request ====

cmd   : 0x04
index : 3 bytes 

==== Response ====

cmd      : 0x84
index    : 3 bytes
quantity : 3 bytes
next     : 3 bytes
[data blocks] 

* 0xFE: Next tag index, uint16 * 0xFF: Next tag index, uint24

* 0xF0: false / zero * 0xF1: true / one * 0xF2: 1-byte integer * 0xF3: 2-byte integer

* 0xF8: int32 (4 bytes) * 0xF9: int64 (8 bytes) * 0xFA: double (8 bytes) * 0xFB: string (2-byte length + UTF-8 bytes)

Status bit: b4 of first value byte (if INIT.flags.b1 = 1)

* 1 = Good * 0 = Bad

Writes tag values.

==== Request ====

cmd      : 0x05
index    : 3 bytes
quantity : 3 bytes
[data blocks] 

==== Response ====

cmd : 0x85 

Returns CRC32 checksum of all tag values after last UPDATE.

==== Request ====

cmd : 0x06 

==== Response ====

cmd : 0x86
crc : 4 bytes 

==== AUTH_INIT (0x07) ====

request:
cmd      : 0x07
klen     : 2 bytes
keyname  : klen bytes

response:
cmd      : 0x87
status   : 1 byte
nlen     : 2 bytes
nonce    : nlen bytes 

Status:

* 0x00 OK * 0x01 FAILED * 0x02 DISABLED

==== AUTH_SUBMIT (0x08) ====

request:
cmd      : 0x08
nlen     : 2 bytes
nonce    : nlen bytes

response:
cmd      : 0x88
status   : 1 byte 

Status:

* 0x00 ACCEPTED * 0xFF DENIED

* 0xFE: UNAUTHENTICATED * 0xFF: UNKNOWN

1. TCP connect 2. AUTH_INIT / AUTH_SUBMIT (optional) 3. INIT 4. LIST (paged) 5. UPDATE 6. READ / WRITE 7. CRC (optional) 8. TCP disconnect

* Protocol favors deterministic binary layout * Compact encodings reduce bandwidth * Explicit pagination avoids oversized frames * reqId enables async request matching

This document defines JRBusTCP Protocol v1. Any incompatible changes MUST increment protocol version and be negotiated out-of-band.

==== 16.1 Typical Session Sequence ====

Client                          Server
|                                 |
|--- TCP CONNECT ---------------->|
|                                 |
|--- INIT ----------------------->|
|<-- INIT RESPONSE (listsize) ----|
|                                 |
|--- LIST (index=0) ------------->|
|<-- LIST (chunk 1) --------------|
|--- LIST (next) ---------------->|
|<-- LIST (last chunk) -----------|
|                                 |
|--- UPDATE --------------------->|
|<-- UPDATE (quantity,next) ------|
|                                 |
|--- READ (index=first changed) ->|
|<-- READ (values) ---------------|
|                                 |
|--- UPDATE / READ (loop) --------|
|                                 | 

==== 16.2 Binary Layout: READ Response ====

+---------+------+---------+-----------+-----------+----------------+
| reqId   | cmd  | index   | quantity  | next      | data blocks    |
| 4 B     | 1 B  | 3 B     | 3 B       | 3 B       | variable       |
+---------+------+---------+-----------+-----------+----------------+ 

==== 16.3 Binary Layout: WRITE Request ====

+---------+------+---------+-----------+----------------+
| reqId   | cmd  | index   | quantity  | data blocks    |
| 4 B     | 1 B  | 3 B     | 3 B       | variable       |
+---------+------+---------+-----------+----------------+ 

* Determinism: binary layouts provide predictable parsing cost * Zero allocations: no intermediate object trees required * Bandwidth efficiency: compact numeric encodings outperform JSON * Schema stability: no dependency on external IDL or runtime reflection

* Guaranteed delivery and ordering * Built-in congestion control * Simplified client/server implementations * NAT/firewall friendly

==== A.1 INIT Request (hex dump) ====

00 1A AB CD 00 00 00 01 01
05 2E 2A 00 06 4A 52 6F 62 6F
00 03
A1 B2 C3 D4 

==== A.2 READ Response (single INT32 value) ====

00 14 AB CD 00 00 00 05 84
00 00 01 00 00 01 00 00 00
F8 00 00 00 2A
DE AD BE EF 

* Typical RTT dominated by TCP latency * Binary parsing cost negligible * Suitable for polling rates up to several kHz on LAN

* READ/WRITE support bulk operations * Clients SHOULD batch contiguous tag indices * Server SHOULD maximize quantity per response until size limit reached

* Poll UPDATE at fixed interval (e.g., 10–100 ms) * Issue READ only when quantity > 0 * Use CRC command to validate full state synchronization when needed

  • doc/jroboplc/modules/jrbustcp-eng.1769014802.txt.gz
  • Last modified: 2026/01/21 20:00
  • by denis