Максимально допустимый размер сообщения составляет 16384 байт.
Общий формат сообщений:
size#2 header#2 [reqId#4 cmd#1 body#size-11] crc#4
#
- размер параметра в байтах.
size
- количество байт в сообщении с header
по crc
включительно.
header
- всегда равно 0xABCD.
reqId
- идентификатор запроса. Любое значение из диапазона int32, в т.ч. отрицательного. Предназначено для проверки клиентом соответствия ответа запросу. Начальное значение клиент формирует генератором случайных чисел при подключении. В дальнейшем при каждом запросе значение увеличивается на 1. Сервер полученное значение reqId
никак не проверяет и отсылает его без изменений. Клиент обязан убедиться, что принятое с ответом значение reqId
равно тому, что было отослано с запросом.
cmd
- код команды.
body
- тело запроса произвольной длины, включая нулевую.
crc
- контрольная сумма CRC32, расчитанная по блоку в квадратных скобках (от reqId
до body
включительно).
Далее в описании команд для краткости изложения не указываются size
, header
, reqId
и footer
. Направление сообщения обозначается следующим образом:
request
- запрос от клиента к серверу
answer
- ответ от сервера клиенту.
Все строковые значения используют кодировку UTF-8.
Инициализация списка тегов.
request: 0x01 flen#1 filter#flen clen#1 client#clen flags#2 answer: 0x81 listsize#3
flen
- длина строки filter в байтах.
filter
- regex-фильтр для формирования списка тегов. Если пустая строка, то выбрать все теги.
clen
- длина строки описания клиента в байтах.
client
- любое текстовое описание клиента (не обязательное).
listsize
- количество выбранных тегов от 0 до 0xFFFFFF (16777215).
flags
- битовые параметры:
b0
- клиент поддерживает передачу описания тегов. Если b0 не установлен, то описания тегов в ответе команды LIST
будут пустыми строками.b1
- клиент поддерживает передачу статусов тегов в ответе команды READ
.b2
- клиент требует не включать в список теги с флагом external
.b3
- клиент требует включить в список теги с флагом hidden
.Запрос списка тегов.
request: 0x02 index#3 answer: 0x82 index#3 quantity#3 next#3 [type#1 nlen#1 tagname#nlen dlen#1 descr#dlen] [...]
index
- стартовый индекс запроса списка
quantity
- количество переданных тегов
next
- индекс для следующего запроса, если не все данные были переданы в текущем сообщении. Если равно нулю, то дальнейшие запросы не требуются.
nlen
- длина строки имени тега в байтах
tagname
- имя тега.
dlen
- длина строки описания тега в байтах.
descr
- описание тега.
type
- тип данных:
1 - bool 2 - int32 3 - int64 4 - double 5 - string
Запрос произошедших изменений.
request: 0x03 answer: 0x83 quantity#3 next#3 liststate#1
quantity
- количество тегов, значение которых изменилось и их можно считать командой READ.
next
- индекс первого тега, значение которого изменилось.
liststate
- 00
- список тегов не изменился, FF
- список тегов изменился, клиенту следует выполнить команды INIT и LIST.
Чтение значений.
request: 0x04 index#3 answer: 0x84 index#3 quantity#3 next#3 [data] [...]
index
- индекс тега для первого значения
quantity
- количество переданных тегов
next
- индекс для следующего запроса, если не все данные были переданы в текущем сообщении. Если равно нулю, то дальнейшие запросы не требуются.
data
- блок данных, содержащий один из вариантов:
Индекс:
0xFE index#2 - индекс тега следующего значения (только для тегов с индексами < 65536) 0xFF index#3 - индекс тега следующего значения
Значения краткие:
0xF0 - bool false, int32/64 0 0xF1 - bool true, int32/64 1 0xF2 byte#1 - int32/64 byte, 0..0xFF 0xF3 word#2 - int32/64 word, 0..0xFFFF
Значения полные:
0xF8 int32#4 - integer 0xF9 int64#8 - long 0xFA double#8 - double 0xFB len#2 string#len - строка, где len - длина строки в байтах
Краткие значения помогают существенно сократить трафик, поэтому отправителю сообщения следует по возможности использовать краткую нотацию.
Статус тега
Совместно со значением тега сервер может отдавать клиенту информацию о статусе (актуальности значения) тега. Для этого при инициализации командой INIT
клиент должен передать параметр flags.b1 = 1
. Информация о статусе тега содержится в b4
первого байта блока данных:
b4 = 1 - Good, значение тега актуально b4 = 0 - Bad, значение тега не актуально
Статус тега передается только от сервера к клиенту.
Запись значений.
request: 0x05 index#3 quantity#3 [data] [...] answer: 0x85
index
- индекс тега для первого значения
quantity
- количество переданных тегов
data
- аналогично READ.
Чтение CRC32 по всем текущим значениям тегов, зафиксированным командой UPDATE.
request: 0x06 answer: 0x86 crc#4
crc
- контрольная сумма CRC32 всех значений тегов
Подсчет CRC выполняется последовательно по списку тегов, сформированному командой INIT. Значение каждого тега представляется в виде байтового массива, длина которого зависит от типа тега:
Старший байт значения суммируется первым.
Для тегов типа STRING используется значение хэш-кода, расчитываемого следующим образом (java):
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
При расчете хэш-кода используются значения символов строки в кодировке UNICODE.
Инициализация процесса аутентификации.
request: 0x07 klen#2 keyname#klen answer: 0x87 status#1 nlen#2 nonce#nlen
klen
- длина строки keyname в байтах.
nlen
- длина строки nonce в байтах.
keyname
- имя файла приватного ключа, который будет использоваться на стороне клиента.
status
- статус выполнения инициализации аутентификационного процесса на сервере:
0 - OK - процесс начат нормально, сформировано и зашифровано nonce (random-строка) 1 - FAILED - процесс не начат, в nonce находится описание проблемы 2 - DISABLED - аутентификация на сервере отключена, вход свободный
nonce
- зашифрованное публичным ключем сгенерированное значение (строка случайных символов)
Сервер должен иметь у себя соответствующий публичный ключ с именем файла keyname.pub
. После того, как клиент получил зашифрованный nonce, он должен расшифровать его своим приватным ключем keyname
и отправить на сервер последующей командой AUTH_SUBMIT.
Завершение процесса аутентификации.
request: 0x08 nlen#2 nonce#nlen answer: 0x88 status#1
nlen
- длина строки nonce в байтах.
nonce
- расшифрованная приватным ключем значение nonce, полученное от сервера командой AUTH_INIT
status
- результат аутентификации:
0 - ACCEPTED - успешно 0xFF - DENIED - отказано
Ответ на любую команду, если сервер требует аутентификации, и она не выполнена. Не распространяется на команды AUTH_*.
answer: 0xFE
Ответ на неизвестную серверу команду.
answer: 0xFF