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:
- The private key never leaves the library system. Only the certificate is copied.
- 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/Nand 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:
- The order is free. A recipient must not rely on fields arriving in the order given in this specification.
- 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. - Unknown field identifiers are skipped, not treated as an error. Only this allows the interface to be extended without replacing every device at once.
- Some fields may occur more than once –
AUfor 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.