Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ===== JRBusTCP Protocol v1 Specification ===== ===== 1. Overview ===== 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**. --- ===== 2. Transport Layer ===== * 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. --- ===== 3. Message Framing ===== ==== 3.1 General Message Format ==== <code> +--------+--------+----------------------------+--------+ | size | header | payload | crc | | 2 B | 2 B | (size - 4 - 4 bytes) | 4 B | +--------+--------+----------------------------+--------+ </code> Where payload has the following structure: <code> +---------+------+---------------------------+ | reqId | cmd | body | | 4 B | 1 B | variable length | +---------+------+---------------------------+ </code> ==== 3.2 Field Description ==== * **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]` ==== 3.3 Request Identifier (reqId) ==== * 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`. --- ===== 4. Command Set ===== ==== 4.1 Command Code Summary ==== ^ 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`). --- ===== 5. INIT (0x01) ===== Initializes tag list and session parameters. ==== Request ==== <code> cmd : 0x01 flen : 1 byte filter : flen bytes (UTF-8 regex) clen : 1 byte client : clen bytes (UTF-8) flags : 2 bytes </code> ==== Flags Bitmask ==== * 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 ==== <code> cmd : 0x81 listsize : 3 bytes (uint24) </code> `listsize` indicates total number of tags selected. --- ===== 6. LIST (0x02) ===== Retrieves tag metadata in chunks. ==== Request ==== <code> cmd : 0x02 index : 3 bytes (uint24) </code> ==== Response ==== <code> cmd : 0x82 index : 3 bytes quantity : 3 bytes next : 3 bytes [tag entries] </code> ==== Tag Entry Format ==== <code> type : 1 byte nlen : 1 byte tagname : nlen bytes (UTF-8) dlen : 1 byte descr : dlen bytes (UTF-8) </code> ==== Data Types ==== ^ Code ^ Type ^ | 1 | BOOL | | 2 | INT32 | | 3 | INT64 | | 4 | DOUBLE | | 5 | STRING | --- ===== 7. UPDATE (0x03) ===== Checks for tag value changes. ==== Request ==== <code> cmd : 0x03 </code> ==== Response ==== <code> cmd : 0x83 quantity : 3 bytes next : 3 bytes liststate : 1 byte </code> * 0x00: tag list unchanged * 0xFF: tag list changed; client MUST re-run INIT + LIST --- ===== 8. READ (0x04) ===== Reads tag values. ==== Request ==== <code> cmd : 0x04 index : 3 bytes </code> ==== Response ==== <code> cmd : 0x84 index : 3 bytes quantity : 3 bytes next : 3 bytes [data blocks] </code> ==== Index Blocks ==== * 0xFE: Next tag index, uint16 * 0xFF: Next tag index, uint24 ==== Value Encodings (Compact) ==== * 0xF0: false / zero * 0xF1: true / one * 0xF2: 1-byte integer * 0xF3: 2-byte integer ==== Value Encodings (Full) ==== * 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 --- ===== 9. WRITE (0x05) ===== Writes tag values. ==== Request ==== <code> cmd : 0x05 index : 3 bytes quantity : 3 bytes [data blocks] </code> ==== Response ==== <code> cmd : 0x85 </code> --- ===== 10. CRC (0x06) ===== Returns CRC32 checksum of all tag values after last UPDATE. ==== Request ==== <code> cmd : 0x06 </code> ==== Response ==== <code> cmd : 0x86 crc : 4 bytes </code> --- ===== 11. Authentication ===== ==== AUTH_INIT (0x07) ==== <code> request: cmd : 0x07 klen : 2 bytes keyname : klen bytes response: cmd : 0x87 status : 1 byte nlen : 2 bytes nonce : nlen bytes </code> Status: * 0x00 OK * 0x01 FAILED * 0x02 DISABLED ==== AUTH_SUBMIT (0x08) ==== <code> request: cmd : 0x08 nlen : 2 bytes nonce : nlen bytes response: cmd : 0x88 status : 1 byte </code> Status: * 0x00 ACCEPTED * 0xFF DENIED --- ===== 12. Error Responses ===== * 0xFE: UNAUTHENTICATED * 0xFF: UNKNOWN --- ===== 13. Session Lifecycle ===== 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 --- ===== 14. Design Notes ===== * Protocol favors deterministic binary layout * Compact encodings reduce bandwidth * Explicit pagination avoids oversized frames * reqId enables async request matching --- ===== 15. Versioning ===== This document defines **JRBusTCP Protocol v1**. Any incompatible changes MUST increment protocol version and be negotiated out-of-band. --- ===== 16. Diagrams ===== ==== 16.1 Typical Session Sequence ==== <code> 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) --------| | | </code> ==== 16.2 Binary Layout: READ Response ==== <code> +---------+------+---------+-----------+-----------+----------------+ | reqId | cmd | index | quantity | next | data blocks | | 4 B | 1 B | 3 B | 3 B | 3 B | variable | +---------+------+---------+-----------+-----------+----------------+ </code> ==== 16.3 Binary Layout: WRITE Request ==== <code> +---------+------+---------+-----------+----------------+ | reqId | cmd | index | quantity | data blocks | | 4 B | 1 B | 3 B | 3 B | variable | +---------+------+---------+-----------+----------------+ </code> --- ===== 17. Rationale ===== ==== 17.1 Why Not JSON / Protobuf ==== * 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 ==== 17.2 Why TCP and Not UDP ==== * Guaranteed delivery and ordering * Built-in congestion control * Simplified client/server implementations * NAT/firewall friendly --- ===== Appendix A: Examples ===== ==== A.1 INIT Request (hex dump) ==== <code> 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 </code> ==== A.2 READ Response (single INT32 value) ==== <code> 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 </code> --- ===== Appendix B: Performance Considerations ===== ==== B.1 Latency ==== * Typical RTT dominated by TCP latency * Binary parsing cost negligible * Suitable for polling rates up to several kHz on LAN ==== B.2 Batching ==== * READ/WRITE support bulk operations * Clients SHOULD batch contiguous tag indices * Server SHOULD maximize quantity per response until size limit reached ==== B.3 UPDATE Polling Strategy ==== * 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.txt Last modified: 2026/01/21 20:06by denis