Skip to content
SBC-Standard The data standard for libraries

Message structure

Every message is a single line of text. It begins with a two-digit command code, followed first by the fixed-length fields – in exactly the order the command prescribes – and then by the variable-length fields, each preceded by a two-character field identifier. The line ends with a carriage return.

17 20260728    143012 AOBVS| AB1140360000123| XKBAR| AY3 AZF37B <CR>
│  │                  │                             │   │
│  │                  │                             │   └─ checksum
│  │                  │                             └───── sequence number
│  │                  └─────────────────────────────────── variable fields
│  └────────────────────────────────────────────────────── fixed fields
└───────────────────────────────────────────────────────── command code

The spaces in the diagram are for legibility only – in the message everything follows on without gaps.

Connection#

The connection is an ordinary TCP connection. The device opens it, the library system accepts it; both keep it open throughout operation. No fixed port is prescribed; it must be configured in both systems.

Several devices may be connected at the same time, each with its own connection. Everything that constitutes a session – sequence number, agreed character set, the last message held ready for a resend – applies per connection. A device therefore notices nothing of what happens at the one next to it.

If the connection drops, the device opens a new one and starts afresh: everything agreed is void.

Encryption#

The connection may run over TLS. This changes nothing about the protocol: messages, fields, sequence number and checksum stay as they are – TLS sits underneath, as it does for a web page.

Encrypted traffic uses a port of its own. The library system can serve both ports at the same time while a library converts its devices one by one; once it is done, it switches the clear-text port off.

Nothing is negotiated: both sides have it configured that they speak encrypted.

How the sides recognise each other#

The library system holds a key and a matching certificate. The certificate is the public part; it is copied to the device once, by hand – over a route the library trusts: a USB stick, a network drive, during on-site installation.

When the connection is opened, the device checks that the other side presents exactly this certificate. Host name, expiry date and issuer chain are not checked: the question of trust was already answered when the file was copied, and every further check is only one more place where operations may come to a halt one day.

Two rules follow from this:

  1. The private key never leaves the library system. Only the certificate is copied.
  2. A device meant to speak encrypted does so, or not at all. If the certificate does not match, or encryption is unavailable, it stops and says so in plain words – quietly falling back to an open connection is not permitted.

If the other side presents a certificate other than the one copied, that is no reason for an exception: either the library system has been reinstalled – in which case the certificate belongs copied again – or somebody else is answering there.

Character set#

Windows-1252 applies to the text content of the fields (see appendix). This covers every character occurring in everyday German library work.

Both sides may agree on UTF-8 instead; how that works is described under system status. Without an explicit agreement Windows-1252 always applies – a device and a library system that both know nothing of this option therefore understand each other unchanged.

Two things expressly do not change with UTF-8:

  • Fixed fields stay ASCII. Dates, Y/N and counters contain no umlauts. Only this keeps the field boundaries countable where they are found by position alone.
  • The checksum is formed over bytes, not over letters (see below). With Windows-1252 the two are the same; with UTF-8 an umlaut counts as two bytes.

Two characters must therefore never appear inside a field, because they carry the structure of the message itself:

Character Code Meaning
\| 7C separates variable fields
<CR> 0D ends the message

The null byte (00) must not occur either. If a title or a message text contains one of these characters, the sender replaces it with a space.

Fixed fields#

Fixed fields carry no identifier. They follow immediately after the command code, in fixed order and fixed length, and must not be omitted. A value shorter than its field is padded with spaces on the right.

Three formats recur throughout:

Timestamp – 18 characters, YYYYMMDDZZZZHHMMSS. The four positions ZZZZ hold the time zone; for local time they remain blank. Local time is the normal case.

20260728    143012      28 July 2026, 14:30:12 local time

Flag – 1 character, Y for yes, N for no. Where a system cannot answer the question, U stands for unknown, provided the command allows it.

Result flag – 1 character, 1 if the operation was carried out, 0 if not.

Variable fields#

A variable field consists of a two-character field identifier, the content and the delimiter |:

AB1140360000123|
││└─ content    └─ delimiter
└┴─ field identifier

Four rules apply:

  1. The order is free. A recipient must not rely on fields arriving in the order given in this specification.
  2. Fields the sender cannot fill are left out entirely. A field with empty content (AB|) is permitted but says something different: The sender knows the field and has nothing to enter.
  3. Unknown field identifiers are skipped, not treated as an error. Only this allows the interface to be extended without replacing every device at once.
  4. Some fields may occur more than once – AU for each charged item, for instance. Where this applies is noted with the command concerned.

The content is at most 255 bytes long – with UTF-8 therefore possibly fewer than 255 letters.

Sequence number and checksum#

Both appear at the end of every message, always in this order, and are the only fields without a trailing delimiter.

Sequence number AY – one digit from 0 to 9. The device increments it with every new request and starts again at 0 after 9. The library system copies the digit unchanged into its response. This lets the device tell whether a response belongs to the question just asked or is a late answer to an earlier request; the latter it discards.

Checksum AZ – four hexadecimal digits. It is formed over every byte of the message, from the first up to and including the identifier AZ: Add the byte values, take the lower 16 bits and form the two's complement.

Byte, not letter: With Windows-1252 the two coincide; with UTF-8 an umlaut enters the sum with each of its two bytes. The checksum secures the transmission – and what is transmitted are bytes.

Message up to "AZ":  1720260728    143012AOBVS|AB1140360000123|XKBAR|AY3AZ
Sum of bytes:        3205
Two's complement:    65536 − 3205 = 62331 = F37B
Complete:            1720260728    143012AOBVS|AB1140360000123|XKBAR|AY3AZF37B<CR>

To verify, the recipient adds all byte values including the four hexadecimal digits; the lower 16 bits of the sum must come to zero.

When something goes wrong#

If the checksum of a received message does not match, the recipient asks for a repeat: The device sends 97 for this, the library system 96. The other side then sends its last message again unchanged – with the same sequence number, so that no transaction is carried out twice. Neither command carries a sequence number itself.

If a response fails to arrive at all, the device repeats its request until the number of attempts given in the system status is exhausted. After that the connection counts as broken; the device opens a new one and logs in again.

A command code the library system does not know goes unanswered. Which commands it supports it states in field BX of the system status – a device should ask for that rather than find out by trial.

This page was translated automatically from the German original. If anything reads oddly or looks wrong, please let us know — the German edition prevails.