Содержание
Коммуникационный протокол JRBusTcp
Формат сообщения
Максимально допустимый размер сообщения составляет 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.
01 - INIT
Инициализация списка тегов.
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.
02 - LIST
Запрос списка тегов.
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
03 - UPDATE
Запрос произошедших изменений.
request: 0x03 answer: 0x83 quantity#3 next#3 liststate#1
quantity - количество тегов, значение которых изменилось и их можно считать командой READ.
next - индекс первого тега, значение которого изменилось.
liststate - 00 - список тегов не изменился, FF - список тегов изменился, клиенту следует выполнить команды INIT и LIST.
04 - READ
Чтение значений.
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, значение тега не актуально
Статус тега передается только от сервера к клиенту.
05 - WRITE
Запись значений.
request: 0x05 index#3 quantity#3 [data] [...] answer: 0x85
index - индекс тега для первого значения
quantity - количество переданных тегов
data - аналогично READ.
06 - CRC
Чтение CRC32 по всем текущим значениям тегов, зафиксированным командой UPDATE.
request: 0x06 answer: 0x86 crc#4
crc - контрольная сумма CRC32 всех значений тегов
Подсчет CRC выполняется последовательно по списку тегов, сформированному командой INIT. Значение каждого тега представляется в виде байтового массива, длина которого зависит от типа тега:
- BOOL - 1 байт
- INT - 4 байт
- LONG - 8 байт
- DOUBLE - 8 байт
- STRING - 4 байт
Старший байт значения суммируется первым.
Для тегов типа 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.
07 - AUTH_INIT
Инициализация процесса аутентификации.
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.
08 - AUTH_SUBMIT
Завершение процесса аутентификации.
request: 0x08 nlen#2 nonce#nlen answer: 0x88 status#1
nlen - длина строки nonce в байтах.
nonce - расшифрованная приватным ключем значение nonce, полученное от сервера командой AUTH_INIT
status - результат аутентификации:
0 - ACCEPTED - успешно 0xFF - DENIED - отказано
FE - UNAUTHENTICATED
Ответ на любую команду, если сервер требует аутентификации, и она не выполнена. Не распространяется на команды AUTH_*.
answer: 0xFE
FF - UNKNOWN
Ответ на неизвестную серверу команду.
answer: 0xFF