current version: 1.6 (Sept 2025)
Tag Socket Exchange Protocol provides a standardized communication interface for exchange of process control data, often called "Tags", such as analog and digital inputs and outputs between a Tag Socket Server (TSS) and a Tag Socket Client (TSC).
The TSS collects data from attached control devices such as PLC, networked measurement devices like temperature or pressure transducers, flow meters, scales, energy meters or entire data collection appliances such as data concentrators or can serve as a data concentrator by itself.
It organizes and stores the data in memory, in log files or databases and specifically converts the process control data into the standardized format described herein.
The protocol is suitable for LAN and/or WAN exchange of process control ("Tag") information. It uses TCP/IP as transport layer and the specific Tag Socket Exchange Protocol (TSXP) protocol which aims to be open, simple, human readable, standardized yet flexible and extensible. The language which offers itself for such requirements is XML. In order to meet the requirement of simplicity we use a restricted subset which is easy to parse but retains the required flexibility.
Tag Socket Protocol uses a largely simplified subset of XML which makes parsing easy and fast.
Data are transmitted as human readable text in the XML 1.0 format with UTF-8 encoding.
Each and every message contains one and only one <TSXP>...</TSXP> element.
The <TSXP> element can contain either <REQ> elements, if they come from a client, or <REP> elements, if they come from a server.
Multiple <REQ/> and <REP/> elements can be contained within one <TSXP> element.
<REQ/> and <REP/> elements contain attributes but no text in between opening and closing brackets.
<REQ>text</REQ> is not used, instead <REQ attribute-1="text1" attribute-2="text2" attribute-3="text3"/> is used.
Each data exchange between the TSS and the TSC conforms to the following request and reply structure:
TSC sends a request <REQ/> to the TSS. The full message looks as follows:
<?xml version="1.0" encoding="utf-8"?><TSXP><REQ attribute-1="text1" attribute-2="text2" attribute-3="text3" /></TSXP>"\r\n" (carriage return + line feed)
TSS checks the request and, if justified by the user rights of the requester, sends a reply <REP/>. The full message looks as follows:
<?xml version="1.0" encoding="utf-8"?><TSXP><REP attribute-1="text1" attribute-2="text2" attribute-3="text3" /></TSXP>"\r\n" (carriage return + line feed)
The request and reply elements are further structured with the following mandatory and optional XML attributes:
version="" mandatory for login.
subject="" mandatory for request and reply
token="" mandatory for request only
state="" mandatory for reply only
tstmp="" mandatory for reply only
name="" mandatory for tag value requests, identifies a tag by its unique ID (name)
content="" mandatory for reply in general only if state is "OK" otherwise may contain error codes
user="" mandatory only for login and logout process
pass="" mandatory only for login process
Other than in general XML specification, in this protocol the length of an <REQ/> or <REP/> datagram is limited to 2048 chars, the length of an attribute to 255 chars.
In practice however datagrams are much shorter, more like 512 char in total since except the name="" and the content="" attribute all other are of fixed and short length.
Letter case is not significant. <req/> is not different from <REQ/>. However in the XML specification it is recommended to use lower case. Here we stay with upper case in order to improve readability.
The total size within the <TSXP></TSXP> element should not exceed 64kB which means that not more than approx. 125 tags of max 512 bytes length should be transmitted in one message.
For this reason tag lists can be subdivided and split in logical groups if needed.
The version attribute is the only attribute of the <TSXP> element and contains the version number in decimal notation, such as <tsxp version="1.6"> If no version number is given the server assumes the latest version it supports, which is version 1.6 (this)
The subject attribute contains the type of information requested and is repeated in the reply. Since subjects are theoretically unlimited (just an identifier string), it opens up the protocol for further extensions.
In the current version the following subjects can be sent by the TSC which must be recognized and replied by the TSS:
The token, which is a hexadecimal 32 bit value (integer) identifies the client after successful login procedure to the server with each following request.
The lifetime of a token can be set in the server configuration. After expiry a new login procedure is required by the server.
It should be well noted that this kind of software token security has considerable security vulnerabilities (such as man in the middle attack). However it provides a basic level of trustability between client and server and can be applied for each single datagram. Furter considerations at the bottom of this document.
With every login/logout a new unique token must be provided by the server.
Provides the ID (name) of a registered user only within the login process. The TSS maintains a list of registered users, user roles and passwords. User roles can be defined such that only certain user roles (e.g. Admins) are allowed to set Tag values or request Tag, Alarm or Message lists.
The password should follow minimum safety rules, such as having minimum 8 letters (lower and upper case) + 1 special char + 2 numbers. It is transmitted once per login. After 3 non-successful login attempts the server should block further login attempts from the same user for minimum 20 min.
Each server reply must contain a state attribute. It should take one of the following states: "OK", "BUSY" or "ERROR". Further error information should be provided in the content="" attribute either as text or error number.
The client can check the validity of the server reply according to the state attribute and provide the user with error messages by using either directly the "ERROR" + content="XXX" for the type of error or translate the error number content to a language specific phrase locally.
The timestamp attribute consists of a long integer (64 bit) in decimal form that encodes date and time (as defined by the Java specification for java.util.Date) of acquisition of the requested data element at the server side. In telemetry applications it could occur that the value is already hours or days old, in process control applications it should would be seconds or minutes.
The timestamp information gives the client the possibility to validate the age and credibility of the tag value it recieved.
The core information of the server reply is mainly contained in this attribute. It contains the result of the request encoded as the string representation of the original data format that represents the underlying Tag item.
Decimal comma is always a dot ('.')
Note: in some languages, such as German, the comma is a ',' which often causes error.
Here are the supported data formats:
real (float): content="-123.45" or "1.234E-02" in decimal or scientific notation.
boolean: content="true/false" or content="on/off"
integer: content="-876543" (32 bit signed integer)
text: "Lorem ipsum dolor sit amat." (chars as far as allowed by XML specification for the content of attributes, max. 255 chars. Special char must be escaped. No line breaks allowed!)
Here is a description of the client login process. A successful login results in the server sending a token that is used as authentification of a specific user session for further requests.
Server: (listening on port XXXX for communication attempt)
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="HELLO"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP version="1.6"><REP subject="HELLO" state="OK" content="READY"/></TSXP>
in case of error: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="HELLO" state="ERROR" content="101"/></TSXP>
in case of busy: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="HELLO" state="BUSY" content=""/></TSXP>
As soon as the server signals readyness, client tries a login:
Client: <?xml version="1.0" encoding="utf-8"?><TSXP version="1.6" ><REQ subject="LOGIN" user="someuser" pass="mypass"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="LOGIN" state="OK" user="someuser" token="0AC99FF1" content="ACCEPTED"/></TSXP>
in case of error: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="LOGIN" state="ERROR" user="someuser" content="DENIED"/></TSXP>
Now when the user is successfully logged in and has obtained a valid token it can use the token to request further data from the server.
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="GROUPS" token="0AC99FF1"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="GROUPS" state="OK" content="opc"/><REP subject="GROUPS" state="OK" content="other"/></TSXP>
(This shows how <REP/> elements are concatenated within an <TSXP></TSXP> element. The 2 tag groups "opc" and "other" are available on the server and could be requested separately.
Now the client can download from the server a list of available tags for later reference either en bloc or group wise. The server should ensure that a group is not longer than 125 tags.
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="LIST-TAGS" content="*" token="0AC99FF1"/></TSXP> (The wildcard '*' means all groups)
other version:
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="LIST-TAGS" content="opc" token="0AC99FF1"/></TSXP> (only the tag group named "opc" should be sent)
The server sends for each tag that matches the request a <REP/> element.
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="LIST-TAGS" state="OK" name="tag_01" group="opc" type="bool"/><REP subject="TAG" state="OK" name="tag_02" group="opc" type="int"/><REP subject="TAG" state="OK" name="tag_03" group="opc" type="float"/><REP subject="TAG" state="OK" name="tag_04" group="opc" type="float"/><REP subject="TAG" state="OK" name="tag_05" group="opc" type="text"/></TSXP>
The following attributes should be sent by the server (some omitted above for the ease of reading):
With this information the client can build up its own copy of the server's Tag list and further on ask only for Tag value changes with respect to the Tag ID.
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="ALARMS" token="0AC99FF1"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="ALARMS" state="OK" content="tag_01 above 1000 kg" tstmp="23568742"/></TSXP>
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="MESSAGES" token="0AC99FF1"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="MESSAGES" state="OK" content="Please change battery." tstmp="23568746"/><REP subject="MESSAGE" state="OK" content="Mary had a little lamb." tstmp="23568746"/></TSXP>
The server should keep a record of which alarms resp. messages have been already consumed by each client (user) and delete them from the list so that the list does not accumulate infinitely.
The client can subscribe to Tags which means it will get with each request only those Tags which have changed in value since the last request.
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="SUBSCRIBE" token="0AC99FF1"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="SUBSCRIBE" name="tag_01" state="OK" content="on" tstmp="23568756"/><REP subject="tag_02" state="OK" content="55" tstmp="23568768"/><REP subject="tag_03" state="OK" content="123.45" tstmp="2356800"/></TSXP>
NOTE: in the server reply the namet="" attribute is used to identify the Tag and the content="" attribute is used for the Tag value.
Each time the client repeats the subscribe request, the server will send only the changed values back.
The client can request and set single Tags according to their known ID.
The format of the tag value must match the tag type expressed as string.
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="SET-TAG" name="tag_01" content="off" token="0AC99FF1"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="SET-TAG" state="OK" name="tag_01" content="off" tstmp="23568756"/></TSXP>
Safety considerations:
Setting critical tag values over the internet in non-encrypted form, protected by a software token only can have serious consequences if misused.
Security considerations must start at the PLC or control software design side. Critical setpoints should be protected on site by local manual reconfirmation or prevented entirely.
Example1: A motor could be started and stopped over the internet every second, causing overheating of circuitry and subsequently leading to motor damage, even a fire or explosion. Such unallowed command behaviour must be prevented during construction and by design.
Example2: A heater setpoint could be set to arbitrary high value causing severe damage such as fire or even explosion. Such setpoints that can be changed over the internet must be limited to safe values by design and probably a second safety circuit that is hardwired.
Client: <?xml version="1.0" encoding="utf-8"?><TSXP><REQ subject="GET-TAG" name="tag_01" token="0AC99FF1"/></TSXP>
Server: <?xml version="1.0" encoding="utf-8"?><TSXP><REP subject="GET-TAG" name="tag_01" state="OK" content="off" tstmp="23568756"/></TSXP>
Safety considerations:
It is possible to obtain lots of information by systematically collecting data of a control system. E.g. it can be deducted when a site starts and stops operation, when critical values occur, when and which alarm messages arrive, what other messages the system creates. These data can be misused in many ways e.g. in order to gain unsolicited access by pretending an emergency situation etc.
Control systems process always the same, limited information content in always the same standardized patterns. Therefor even if encrypted, due to the mentioned repetetive nature of the data it would not be impossibly hard to decrypt by brute force. Weak encryption would give a false impression of data security.