Бирючина

Privet — это API локального обнаружения облачных устройств, используемый облачными сервисами. Этот документ состоит из следующих разделов:

  1. Введение : знакомство с Privet
  2. Открытие : локальные механизмы открытия
  3. Объявления : объявления о местных открытиях
  4. API : Частные API для общих облачных устройств
  5. API принтера : закрытые API, используемые принтерами
  6. Приложение : дополнительные диаграммы

1. Введение

Устройства, подключенные к облаку, обладают множеством преимуществ. Они могут использовать онлайн-сервисы конвертации, размещать очереди заданий, даже когда устройство находится в автономном режиме, и быть доступными из любой точки мира. Однако, поскольку пользователю доступно множество облачных устройств, необходимо предоставить метод поиска ближайшего к нему устройства в зависимости от его местоположения. Цель протокола Privet — объединить гибкость облачных устройств с подходящим механизмом локального обнаружения, чтобы устройства можно было легко обнаружить в новых условиях.

Цели этого протокола:
  • сделать облачные устройства локально обнаруживаемыми
  • регистрировать облачные устройства в облачном сервисе
  • связать зарегистрированные устройства с их облачным представлением
  • включить автономную функциональность
  • упростить реализацию, чтобы ее могли использовать небольшие устройства

Протокол Privet состоит из двух основных частей: обнаружения и API. Обнаружение используется для поиска устройства в локальной сети, а API — для получения информации об устройстве и выполнения некоторых действий. В этом документе под устройством понимается устройство, подключенное к облаку и реализующее протокол Privet.

2. Открытие

Discovery — это протокол на основе ZeroConf (mDNS + DNS-SD). Устройство ДОЛЖНО поддерживать IPv4-адресацию Link-Local. Устройство ДОЛЖНО соответствовать спецификациям mDNS и DNS-SD.

Устройство ДОЛЖНО выполнять разрешение конфликтов имен в соответствии с вышеуказанными спецификациями.

2.1 Тип услуги

DNS Service Discovery использует следующий формат для типов сервисов: _applicationprotocol._transportprotocol . В случае протокола Privet тип сервиса для DNS-SD должен быть: _privet._tcp

Устройство может реализовывать и другие типы служб. Рекомендуется использовать одно и то же имя экземпляра службы для всех типов служб, реализуемых устройством. Например, принтер может реализовывать службы «Printer XYZ._privet._tcp» и «Printer XYZ._printer._tcp». Это упростит настройку для пользователя. Однако клиенты Privet будут искать только «_privet._tcp».

Помимо основного типа сервиса, устройство ДОЛЖНО анонсировать записи PTR для соответствующих подтипов (см. спецификацию DNS-SD: «7.1. Выборочное перечисление экземпляров (подтипы)»). Формат должен быть следующим: _<подтип>._sub._privet._tcp

В настоящее время поддерживается только один подтип устройства — «принтер» . Поэтому все принтеры ДОЛЖНЫ объявлять две записи PTR:

  • _privet._tcp.local.
  • _printer._sub._privet._tcp.local.

2.2. TXT-запись

Функция обнаружения служб DNS определяет поля для добавления дополнительной информации о службе в TXT-записи. TXT-запись состоит из пар «ключ/значение». Каждая пара «ключ/значение» начинается с байта длины, за которым следует текст длиной до 255 байт. Ключом является текст до первого символа «=», а значением — текст после первого символа «=» и до конца. Спецификация допускает отсутствие значений в записи. В этом случае символ «=» будет отсутствовать ИЛИ текст после символа «=». (См. спецификацию DNS-SD: «6.1. Общие правила форматирования TXT-записей DNS» для формата TXT-записи DNS и «6.2. Размер TXT-записи DNS-SD» для рекомендуемой длины).

Privet требует, чтобы устройство отправляло следующие пары «ключ/значение» в TXT-записи. Строки «ключ/значение» нечувствительны к регистру, например, «CS=online» и «cs=ONLINE» — это одно и то же. Информация в TXT-записи ДОЛЖНА совпадать с информацией, доступной через API /info (см. раздел 4.1. API).

Рекомендуется поддерживать размер TXT-записи менее 512 байт.

2.2.1. txtvers

Версия структуры TXT. txtvers ДОЛЖНА быть первой записью структуры TXT. В настоящее время поддерживается только версия 1.

txtvers=1

2.2.2. ти

Предоставляет понятное пользователю имя устройства. Например:

ty=Google Cloud Ready Printer Model XYZ

2.2.3. примечание (необязательно)

Предоставляет понятное пользователю имя устройства. Например:

note=1st floor lobby printer

Примечание: Это необязательный ключ, который можно пропустить. Однако, если он присутствует, пользователь ДОЛЖЕН иметь возможность изменить это значение. Такое же описание ДОЛЖНО использоваться при регистрации устройства.

2.2.4. URL-адрес

URL-адрес сервера, к которому подключено это устройство (включая протокол). Например:

url=https://www.google.com/cloudprint

2.2.5. тип

Список подтипов устройств, поддерживаемых данным устройством, разделённый запятыми. Формат: "type=_subtype1,_subtype2". В настоящее время поддерживается только один подтип устройства — принтер .

type=printer

Каждый перечисленный подтип должен быть объявлен с помощью соответствующей записи PTR. Для каждого поддерживаемого подтипа сервиса должен быть один соответствующий элемент. Имя подтипа сервиса (<subtype>._sub._privet._tcp) должно совпадать с типом устройства.

2.2.6. идентификатор

Идентификатор устройства. Если устройство ещё не зарегистрировано, этот ключ должен присутствовать, но значение должно быть пустым. Например:

  id=11111111-2222-3333-4444-555555555555
  id=

2.2.7.cs

Показывает текущее состояние подключения устройства. В данной спецификации определены четыре возможных значения.

  • «online» означает, что устройство в данный момент подключено к облаку.
  • «offline» означает, что устройство доступно в локальной сети, но не может связаться с сервером.
  • «connecting» означает, что устройство выполняет последовательность запуска и еще не полностью подключено к сети.
  • «not-configured» означает, что доступ устройства к Интернету ещё не настроен. Это значение в настоящее время не используется, но может быть полезно в будущих версиях спецификации.
Например:
  • cs=онлайн
  • cs=офлайн
  • cs=подключение

Если устройство зарегистрировано в облаке, при запуске оно должно проверить соединение с сервером для определения состояния соединения (например, вызвав облачный API для получения настроек устройства). Устройство может использовать состояние соединения по каналу уведомлений (например, XMPP) для передачи этого значения. Незарегистрированные устройства при запуске могут отправлять запросы на пинг домена для определения состояния соединения (например, ping www.google.com для устройств облачной печати).

3. Объявления

При запуске, выключении или изменении состояния устройство ОБЯЗАНО выполнить шаг оповещения, описанный в спецификации mDNS . Оно ДОЛЖНО отправить соответствующее оповещение как минимум дважды с интервалом не менее одной секунды между ними.

3.1. Запуск

При запуске устройство ОБЯЗАТЕЛЬНО должно выполнить шаги зондирования и анонсирования, описанные в спецификации mDNS. В этом случае следует отправлять записи SRV, PTR и TXT. Рекомендуется, если это возможно, сгруппировать все записи в один DNS-ответ. В противном случае рекомендуется следующий порядок: записи SRV, PTR, TXT.

3.2. Выключение

При выключении устройства оно ДОЛЖНО попытаться уведомить об этом все заинтересованные стороны, отправив «прощальный пакет» с TTL=0 (как описано в документации mDNS).

3.3. Обновление

Если какая-либо информация, указанная в TXT, изменилась, устройство ОБЯЗАТЕЛЬНО ДОЛЖНО отправить уведомление об обновлении. В этом случае достаточно отправить только новую запись TXT. Например, после регистрации устройства оно ДОЛЖНО отправить уведомление об обновлении, включающее новый идентификатор устройства.

4. API

После обнаружения облачного устройства клиент взаимодействует с ним напрямую по локальной сети. Все API основаны на HTTP 1.1. Форматы данных — JSON. Запросы к API могут быть GET- или POST-запросами.

Каждый запрос ДОЛЖЕН содержать допустимый заголовок « X-Privet-Token ». ЕДИНСТВЕННЫЙ запрос, который может иметь пустой заголовок «X-Privet-Token», — это запрос /privet/info (обратите внимание, что заголовок ДОЛЖЕН присутствовать). Если заголовок «X-Privet-Token» отсутствует, устройство ДОЛЖНО ответить следующей ошибкой HTTP 400:

HTTP/1.1 400 Missing X-Privet-Token header.

Если заголовок «X-Privet-Token» пуст или недействителен, устройство ДОЛЖНО ответить ошибкой «invalid X-Privet-Token» (invalid_x_privet_token, подробности см. в разделе «Ошибки»). Единственным исключением является API /info. Подробнее о причинах этого и о том, как должны генерироваться токены, см. в Приложении A: Атаки XSSI и XSRF и меры их предотвращения.

Если запрошенный API не существует или не поддерживается, устройство ДОЛЖНО вернуть ошибку HTTP 404.

4.1. Доступность API

Перед предоставлением ЛЮБОГО API (включая API /info) устройство ОБЯЗАТЕЛЬНО должно связаться с сервером для проверки локальных настроек . Локальные настройки ОБЯЗАТЕЛЬНО должны сохраняться между перезапусками. Если сервер недоступен, следует использовать последние известные локальные настройки. Если устройство ещё не зарегистрировано, следует использовать настройки по умолчанию.

Устройства облачной печати ДОЛЖНЫ выполнить следующие шаги для регистрации, получения и обновления локальных настроек.

4.1.1. Регистрация

При регистрации устройства ОБЯЗАТЕЛЬНО необходимо указать параметр «local_settings» следующим образом:

{
       "current": {
                "local_discovery": true,
                "access_token_enabled": true,
                "printer/local_printing_enabled": true,
                "printer/conversion_printing_enabled": true,
                "xmpp_timeout_value": 300
        }
}
Можно установить следующие настройки:
Имя значения Тип значения Описание
local_discovery булев Указывает, разрешена ли функция локального обнаружения. Если значение "false", все локальные API (включая /info) и обнаружение DNS-SD должны быть отключены. По умолчанию вновь регистрируемые устройства должны передавать значение "true".
access_token_enabled логическое значение (необязательно) Указывает, должен ли API /accesstoken быть доступен в локальной сети. По умолчанию должно быть «true».
принтер/локальная_печать_включена логическое значение (необязательно) Указывает, должны ли функции локальной печати (/printer/createjob, /printer/submitdoc, /printer/jobstate) быть доступны в локальной сети. По умолчанию должно быть «true».
принтер/конверсионная_печать_включена логическое значение (необязательно) Указывает, может ли локальная печать отправлять задание на сервер для преобразования. Имеет смысл только при включенной локальной печати.
xmpp_timeout_value int (необязательно) Указывает количество секунд между пингами канала XMPP. По умолчанию ДОЛЖНО быть 300 (5 минут) или более.

Важно: отсутствие какого-либо необязательного значения указывает на то, что соответствующая функциональность полностью не поддерживается устройством.

4.1.2. Запуск

При запуске устройство должно обратиться к серверу, чтобы проверить, какие API доступны в локальной сети. Для принтеров, подключенных к Cloud Print, необходимо вызвать:

/cloudprint/printer?printerid=<printer_id>
или
/cloudprint/list

/cloudprint/printer предпочтительнее, чем /cloudprint/list, но оба варианта будут работать.

Этот API возвращает текущие параметры устройства, включая настройки локального API. Ответ сервера будет иметь следующий формат:

"local_settings": {
        "current": {
                "local_discovery": true,
                "access_token_enabled": true,
                "printer/local_printing_enabled": true,
                "printer/conversion_printing_enabled": true,
                "xmpp_timeout_value": 300
         },
         "pending": {
                "local_discovery": true,
                "access_token_enabled": true,
                "printer/local_printing_enabled": false,
                "printer/conversion_printing_enabled": false,
                "xmpp_timeout_value": 500
         }
}

Объект «current» указывает настройки, которые действуют в данный момент.

Объект «pending» указывает настройки, которые следует применить к устройству (этот объект может отсутствовать).

Как только устройство обнаружит «ожидающие» настройки, оно ДОЛЖНО обновить свое состояние (см. ниже).

4.1.3. Обновление

При необходимости обновления настроек на устройство будет отправлено XMPP-уведомление следующего формата:

<device_id>/update_settings

Получив такое уведомление, устройство ДОЛЖНО запросить у сервера последние настройки. Устройства Cloud Print ДОЛЖНЫ использовать:

/cloudprint/printer?printerid=<printer_id>

Как только устройство увидит раздел «ожидание» в результате работы API /cloudprint/printer (при запуске или в результате получения уведомления), оно ДОЛЖНО обновить своё внутреннее состояние, чтобы запомнить новые настройки. Оно ДОЛЖНО обратиться к API сервера для подтверждения новых настроек. Для облачных принтеров устройство ДОЛЖНО вызвать API /cloudprint/update и использовать параметр «local_settings», как при регистрации.

При повторном подключении к каналу XMPP устройство ДОЛЖНО вызвать API /cloudprint/printer, чтобы проверить, были ли изменены локальные настройки с момента последнего подключения.

4.1.3.1. Ожидание локальных настроек

Параметр «local_settings», который устройство использует для вызова API сервера, НИКОГДА не должен содержать раздел «pending».

4.1.3.2 Текущие локальные настройки

ТОЛЬКО устройство может изменить раздел «current» в разделе «local_settings». Все остальные будут изменять раздел «pending» и ждать, пока изменения не будут переданы устройством в раздел «current».

4.1.4. Оффлайн

Если во время запуска не удается связаться с сервером, после уведомления устройство ДОЛЖНО использовать последние известные локальные настройки.

4.1.5. Удаление устройства из сервиса

Если устройство было удалено из сервиса (например, GCP), на него будет отправлено XMPP-уведомление следующего формата:

<device_id>/delete

Получив такое уведомление, устройство ОБЯЗАТЕЛЬНО должно обратиться к серверу для проверки своего состояния. Устройства облачной печати ОБЯЗАТЕЛЬНО должны использовать:

/cloudprint/printer?printerid=<printer_id>

Устройство ДОЛЖНО получить успешный HTTP-ответ с параметром success=false и без описания устройства/принтера. Это означает, что устройство было удалено с сервера, и оно ДОЛЖНО удалить свои учётные данные и перейти в режим заводских настроек по умолчанию.

В ЛЮБОЙ раз, когда устройство получает ответ, указывающий на то, что оно было удалено в результате работы API /cloudprint/printer (запуск, уведомление об обновлении настроек, ежедневный пинг), оно ДОЛЖНО удалить свои учетные данные и перейти в режим по умолчанию.

4.2. /privet/info API

API info ОБЯЗАТЕЛЬНО должен быть реализован на каждом устройстве. Это HTTP-запрос GET к URL "/privet/info": GET /privet/info HTTP/1.1

API info возвращает базовую информацию об устройстве и поддерживаемых им функциях. Этот API НЕ ДОЛЖЕН изменять состояние устройства или выполнять какие-либо действия, поскольку он уязвим для атак XSRF. Это ЕДИНСТВЕННЫЙ API, которому разрешено иметь пустой заголовок "X-Privet-Token". Клиенты должны вызывать API /privet/info с заголовком "X-Privet-Token", установленным в значение X-Privet-Token: ""

Информационный API ДОЛЖЕН возвращать данные, соответствующие данным, доступным в записи TXT во время обнаружения.

4.2.1 Ввод

API /privet/info не имеет входных параметров.

4.2.2 Возврат

API /privet/info возвращает основную информацию об устройстве и поддерживаемых функциях.

Столбец TXT указывает соответствующее поле в записи DNS-SD TXT.

Имя значения Тип значения Описание ТЕКСТ
версия нить Самая высокая поддерживаемая версия API (major.minor), в настоящее время 1.0
имя нить Удобочитаемое название устройства. ти
описание нить (необязательно) Описание устройства. ДОЛЖНО быть доступным для изменения пользователем. примечание
URL-адрес нить URL-адрес сервера, с которым взаимодействует это устройство. URL-адрес ДОЛЖЕН включать спецификацию протокола, например: https://www.google.com/cloudprint. URL-адрес
тип список строк Список поддерживаемых типов устройств. тип
идентификатор нить Идентификатор устройства, пустой, если устройство еще не зарегистрировано. идентификатор
состояние_устройства нить Состояние устройства.
режим ожидания означает, что устройство готово
обработка означает, что устройство занято, и функциональность может быть ограничена в течение некоторого времени
остановлено означает, что устройство не работает и требуется вмешательство пользователя
состояние_подключения нить Состояние соединения с сервером (base_url)
онлайн - подключение доступно
офлайн - нет соединения
подключение - выполнение шагов запуска
не настроено — соединение еще не настроено
Зарегистрированное устройство может сообщать о состоянии своего подключения на основе состояния канала уведомлений (например, состояния подключения XMPP).
cs
производитель нить Название производителя устройства
модель нить Модель устройства
серийный номер нить Уникальный идентификатор устройства. В данной спецификации это ДОЛЖЕН быть UUID. (Спецификация GCP 1.1)
(необязательно) Мы настоятельно рекомендуем использовать один и тот же серийный номер везде, чтобы разные клиенты могли идентифицировать одно и то же устройство. Например, принтеры с поддержкой IPP могут использовать этот серийный номер в поле «printer-device-id».
прошивка нить Версия прошивки устройства
время безотказной работы инт Количество секунд с момента загрузки устройства.
setup_url нить (необязательно) URL (включая протокол) страницы с инструкциями по настройке
support_url нить (необязательно) URL (включая протокол) страницы с поддержкой, часто задаваемыми вопросами
update_url нить (необязательно) URL (включая протокол) страницы с инструкциями по обновлению прошивки
x-privet-token нить Значение заголовка X-Privet-Token , которое необходимо передавать всем API для предотвращения атак XSSI и XSRF. Подробности см. в разделе 6.1.
API описание API Список поддерживаемых API (описан ниже)
семантическое_состояние JSON (необязательно) Семантическое состояние устройства в формате CloudDeviceState .

api — это список JSON, содержащий список API, доступных в локальной сети. Обратите внимание, что не все API могут быть доступны в локальной сети одновременно. Например, новое подключенное устройство должно поддерживать только API /register:

"api": [
        "/privet/register",
]
После завершения регистрации устройство ДОЛЖНО прекратить поддержку API /register. Устройство также должно обратиться к сервису, чтобы узнать, какие API доступны через локальную сеть. Например:
"api": [
        "/privet/accesstoken",
        "/privet/capabilities",
        "/privet/printer/submitdoc",
]

В настоящее время доступны следующие API:

  • /privet/register — API для регистрации устройств по локальной сети. (Подробнее см. в разделе API /privet/register). Этот API ДОЛЖЕН быть скрыт после успешной регистрации устройства в облаке.
  • /privet/accesstoken — API для запроса токена доступа с устройства (подробности см. в API /privet/accesstoken).
  • /privet/capabilities — API для получения информации о возможностях устройства (подробности см. в API /privet/capabilities).
  • /privet/printer/* — API, специфичный для типа устройства «принтер», подробности см. в разделе API, специфичных для принтеров.
Вот пример ответа /privet/info. (Обратите внимание на отсутствие API /privet/register, поскольку это уже зарегистрированное устройство):
{
        "version": "1.0",
        "name": "Gene’s printer",
        "description": "Printer connected through Chrome connector",
        "url": "https://www.google.com/cloudprint",
        "type": [
                "printer"
        ],
        "id": "11111111-2222-3333-4444-555555555555",
        "device_state": "idle",
        "connection_state": "online",
        "manufacturer": "Google",
        "model": "Google Chrome",
        "serial_number": "1111-22222-33333-4444",
        "firmware": "24.0.1312.52",
        "uptime": 600,
        "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en",
        "support_url": "http://support.google.com/cloudprint/?hl=en",
        "update_url": "http://support.google.com/cloudprint/?hl=en",
        "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659",
        "api": [
                "/privet/accesstoken",
                "/privet/capabilities",
                "/privet/printer/submitdoc",
        ]
}
Вот пример ответа /privet/info для принтера, у которого закончились чернила (обратите внимание на поле semantic_state):
{
        "version": "1.0",
        "name": "Gene’s printer",
        "description": "Printer connected through Chrome connector",
        "url": "https://www.google.com/cloudprint",
        "type": [
                "printer"
        ],
        "id": "11111111-2222-3333-4444-555555555555",
        "device_state": "stopped",
        "connection_state": "online",
        "manufacturer": "Google",
        "model": "Google Chrome",
        "serial_number": "1111-22222-33333-4444",
        "firmware": "24.0.1312.52",
        "uptime": 600,
        "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en",
        "support_url": "http://support.google.com/cloudprint/?hl=en",
        "update_url": "http://support.google.com/cloudprint/?hl=en",
        "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659",
        "api": [
                "/privet/accesstoken",
                "/privet/capabilities",
                "/privet/printer/submitdoc",
        ],
        "semantic_state": {
                "version": "1.0",
                "printer": {
                        "state": "STOPPED",
                        "marker_state": {
                                "item": [
                                        {
                                                "vendor_id": "ink",
                                                "state": "EXHAUSTED",
                                                "level_percent": 0
                                        }
                                ]
                        }
                }
        }
}

4.2.3 Ошибки

API /privet/info должно возвращать ошибку ТОЛЬКО при отсутствии заголовка X-Privet-Token . Это ДОЛЖНА быть ошибка HTTP 400:

HTTP/1.1 400 Missing X-Privet-Token header.

4.3. API /privet/register

API /privet/register НЕОБЯЗАТЕЛЬНО. Это HTTP-запрос POST. API /privet/register ОБЯЗАТЕЛЬНО проверяет наличие корректного заголовка X-Privet-Token . Устройство ДОЛЖНО реализовать этот API по URL-адресу "/privet/register":

POST /privet/register?action=start&user=user@domain.com HTTP/1.1
POST /privet/register?action=complete&user=user@domain.com HTTP/1.1

Устройство должно предоставлять API /privet/register ТОЛЬКО в том случае, если оно в данный момент допускает анонимную регистрацию. Например:

  • Если устройство включено (или после нажатия специальной кнопки на устройстве) и еще не зарегистрировано, оно должно предоставить API /privet/register, чтобы пользователь из локальной сети мог затребовать принтер.
  • После завершения регистрации устройство должно прекратить предоставление API /privet/register, чтобы предотвратить возможность получения устройства другим пользователем в локальной сети.
  • Некоторые устройства могут иметь разные способы регистрации устройств и вообще не должны предоставлять API /privet/register (например, коннектор Chrome Cloud Print).

Процесс регистрации состоит из 3 этапов (см. анонимную регистрацию для Cloud Print).

  1. Инициировать процесс анонимной регистрации.
  2. Клиент инициирует этот процесс, вызывая API /privet/register. В это время устройство может ожидать подтверждения пользователя.
  3. Получите токен заявки.

Клиент опрашивает устройство, чтобы определить, готово ли оно к продолжению работы. После этого устройство отправляет запрос на сервер для получения регистрационного токена и URL-адреса. Полученные токен и URL-адрес ДОЛЖНЫ быть возвращены клиенту. На этом этапе, если устройство получает ещё один вызов для инициализации регистрации, оно должно:

  • Если это тот же пользователь, который начал регистрацию — удалите все предыдущие данные (если таковые имеются) и начните новый процесс регистрации.
  • Если это другой пользователь - верните ошибку device_busy и тайм-аут в 30 секунд.

Завершите процесс регистрации.

После того, как клиент зарегистрировал устройство, он должен уведомить устройство о завершении регистрации. После завершения процесса регистрации устройство должно отправить уведомление об обновлении, включающее полученный идентификатор устройства.

Примечание: Когда устройство обрабатывает вызов API /privet/register, одновременно с ним не могут обрабатываться другие вызовы API /privet/register. Устройство ДОЛЖНО вернуть ошибку device_busy и тайм-аут 30 секунд.

НАСТОЯТЕЛЬНО рекомендуется подтверждение регистрации пользователем на устройстве. Если это реализовано, устройство ДОЛЖНО ожидать подтверждения пользователя ПОСЛЕ получения вызова API /privet/register?action=start. Клиент будет вызывать API /privet/register?action=getClaimToken, чтобы узнать, когда подтверждение пользователя будет завершено и токен Claim будет доступен. Если пользователь отменяет регистрацию на устройстве (например, нажимает кнопку «Отмена»), ДОЛЖНА быть возвращена ошибка user_cancel. Если пользователь не подтвердил регистрацию в течение определённого времени, ДОЛЖНА быть возвращена ошибка confirm_timeout. Подробнее см. в разделе «Значения по умолчанию».

4.3.1 Ввод

API /privet/register имеет следующие входные параметры:
Имя Ценить
действие Может быть одним из следующих:
начать - начать процесс регистрации
getClaimToken — получить токен заявки для устройства
отменить - отменить процесс регистрации
завершить - завершить процесс регистрации
пользователь Адрес электронной почты пользователя, который получит это устройство.

Устройство ДОЛЖНО проверить, что адрес электронной почты из всех действий (запуск, getClaimToken, отмена, завершение) совпадает.

4.3.2 Возврат

API /privet/register возвращает следующие данные:
Имя значения Тип значения Описание
действие нить То же действие, что и во входном параметре.
пользователь строка (необязательно) Тот же пользователь, что и во входном параметре (может отсутствовать, если пропущен во входных данных).
токен строка (необязательно) Регистрационный токен (обязателен для ответа «getClaimToken», опускается для «start», «complete», «cancel»).
claim_url строка (необязательно) URL-адрес регистрации (обязателен для ответа "getClaimToken", опускается для ответов "start", "complete", "cancel"). Для облачных принтеров это должен быть "complete_invite_url", полученный с сервера.
автоматизированный_заявитель_url строка (необязательно) URL-адрес регистрации (обязателен для ответа "getClaimToken", опускается для ответов "start", "complete", "cancel"). Для облачных принтеров это должен быть "automated_invite_url", полученный с сервера.
идентификатор_устройства строка (необязательно) Новый идентификатор устройства (пропущен для ответа «start», обязателен для ответа «complete»).

Устройство ДОЛЖНО вернуть свой идентификатор устройства в ответе API /privet/info ТОЛЬКО после завершения регистрации.

Пример 1:

{
        "action": "start",
        "user": "user@domain.com",
}

Пример 2:

{
        "action": "getClaimToken",
        "user": "user@domain.com",
        "token": "AAA111222333444555666777",
        "claim_url": "https://domain.com/SoMeUrL",
}

Пример 3:

{
        "action": "complete",
        "user": "user@domain.com",
        "device_id": "11111111-2222-3333-4444-555555555555",
}

4.3.3 Ошибки

API /privet/register может возвращать следующие ошибки (подробности см. в разделе «Ошибки»):
Ошибка Описание
устройство_занято Устройство занято и не может выполнить запрошенное действие. Повторите попытку после истечения времени ожидания.
pending_user_action В ответ на «getClaimToken» эта ошибка означает, что устройство все еще ожидает подтверждения пользователя, и запрос «getClaimToken» следует повторить по истечении времени ожидания.
пользователь_отмена Пользователь явно отменил процесс регистрации с устройства.
время_подтверждения Срок действия подтверждения пользователя истек.
недействительное_действие Вызвано недопустимое действие. Например, если клиент вызвал action=complete до вызова action=start и action=getClaimToken.
недействительные_параметры В запросе указаны недопустимые параметры. (Неизвестные параметры следует игнорировать для обеспечения совместимости в будущем.) Например, верните это, если клиент вызвал action=unknown или user=.
ошибка_конфигурации_устройства Дата/время (или другие настройки) на устройстве неверны. Пользователю необходимо перейти на внутренний сайт устройства и настроить его.
офлайн Устройство в данный момент находится в автономном режиме и не может связаться с сервером.
ошибка_сервера Ошибка сервера во время процесса регистрации.
invalid_x_privet_token X-Privet-Token в запросе недействителен или пуст.

Устройство ДОЛЖНО прекратить предоставление API /privet/register после успешного завершения регистрации. Если устройство не предоставляет API /privet/register, оно ДОЛЖНО вернуть ошибку HTTP 404. Следовательно, если устройство уже зарегистрировано, вызов этого API ДОЛЖЕН вернуть ошибку 404. Если заголовок X-Privet-Token отсутствует, устройство ДОЛЖНО вернуть ошибку HTTP 400.

4.4. API /privet/accesstoken

API /privet/accesstoken НЕОБЯЗАТЕЛЬНО. Это HTTP-запрос GET. API /privet/accesstoken ОБЯЗАТЕЛЬНО должен проверять наличие допустимого заголовка "X-Privet-Token". Устройство ОБЯЗАТЕЛЬНО должно реализовать этот API в URL-адресе "/privet/accesstoken":
GET /privet/accesstoken HTTP/1.1

Когда устройство получает API-вызов /accesstoken, оно должно обратиться к серверу, чтобы получить токен доступа для указанного пользователя и вернуть его клиенту. Клиент затем будет использовать этот токен доступа для доступа к устройству через облако.

Устройства облачной печати ДОЛЖНЫ вызывать следующий API:

/cloudprint/proximitytoken
и передайте параметры "printerid=<printer_id>" и "user" из локального API. В случае успеха ответ сервера будет содержать следующий объект:
"proximity_token": {
        "user": "user@domain.com",
        "token": "AAA111222333444555666777",
        "expires_in": 600
}
Устройства облачной печати ОБЯЗАНЫ передавать значение объекта "proximity_token" в ответ на локальные вызовы API /privet/accesstoken. Будет выгоднее (с учётом будущих потребностей), если устройство сможет передавать ВСЕ параметры (включая те, которые не описаны в данной спецификации).

4.4.1. Ввод

API /privet/accesstoken имеет следующие входные параметры:
Имя Ценить
пользователь Адрес электронной почты пользователя, который намеревался использовать этот токен доступа. Может быть пустым в запросе.

4.4.2 Возврат

API /privet/accesstoken возвращает следующие данные:
Имя значения Тип значения Описание
токен нить Токен доступа, возвращенный сервером
пользователь нить Тот же пользователь, что и во входном параметре.
expires_in инт Количество секунд до истечения срока действия токена. Получено с сервера и передано в этом ответе.

Пример:

{
        "token": "AAA111222333444555666777",
        "user": "user@domain.com",
        "expires_in": 600
}

4.4.3 Ошибки

API /privet/accesstoken может возвращать следующие ошибки (подробности см. в разделе «Ошибки»):
Ошибка Описание
офлайн Устройство в данный момент находится в автономном режиме и не может связаться с сервером.
доступ запрещен Недостаточно прав. Доступ запрещён. Устройство должно возвращать эту ошибку, если запрос был явно отклонён сервером.
недействительные_параметры В запросе указаны недопустимые параметры. (Неизвестные параметры следует игнорировать для обеспечения совместимости в будущем.) Например, если клиент вызвал /accesstoken?user= или /accesstoken.
ошибка_сервера Ошибка сервера.
invalid_x_privet_token X-Privet-Token недействителен или пуст в запросе.

Если устройство не предоставляет API /privet/accesstoken, оно ДОЛЖНО вернуть ошибку HTTP 404. Если заголовок X-Privet-Token отсутствует, устройство ДОЛЖНО вернуть ошибку HTTP 400.

4.5. /privet/capabilities API

API /privet/capabilities НЕОБЯЗАТЕЛЬНО. Это HTTP-запрос GET. API /privet/capabilities ОБЯЗАТЕЛЬНО должен проверять наличие допустимого заголовка "X-Privet-Token". Устройство ОБЯЗАТЕЛЬНО должно реализовать этот API по URL-адресу "/privet/capabilities":
GET /privet/capabilities HTTP/1.1
Когда устройство получает вызов API /capabilities, если оно имеет такую возможность, оно ДОЛЖНО связаться с сервером для получения обновленных возможностей. Например, если принтер поддерживает отправку задания печати (полученного локально) самому себе через службу облачной печати, он должен вернуть возможности, которые вернула бы служба облачной печати. В этом случае облачная печать может изменить исходные возможности принтера, добавив новые функции, которые он может выполнить перед отправкой задания. Наиболее распространенным случаем является список поддерживаемых типов документов. Если принтер находится в автономном режиме, он должен вернуть поддерживаемые им типы документов. Однако, если принтер находится в сети и зарегистрирован в облачной печати, он ДОЛЖЕН вернуть "*/*" как один из поддерживаемых типов. В этом случае служба облачной печати выполнит необходимое преобразование. Для автономной печати принтер ДОЛЖЕН поддерживать как минимум формат "image/pwg-raster".

4.5.1 Ввод

API /privet/capabilities имеет следующие входные параметры:
Имя Ценить
офлайн (необязательно) Может быть только «offline=1». В этом случае устройство должно вернуть возможности для использования в автономном режиме (если они отличаются от возможностей в режиме «онлайн»).

4.5.2 Возврат

API /privet/capabilities возвращает характеристики устройства в формате JSON Cloud Device Description (CDD) (подробности см. в документе CDD). Как минимум, принтеры ДОЛЖНЫ возвращать список поддерживаемых типов. Например, принтер Cloud Ready, который в данный момент подключен к сети, может возвращать что-то вроде этого (как минимум):
{
        "version": "1.0",
        "printer": {
                "supported_content_type": [
                        {
                                "content_type": "application/pdf",
                                "min_version": "1.4"
                        },
                        { "content_type": "image/pwg-raster" },
                        { "content_type": "image/jpeg" },
                        { "content_type": "*/*" }
                ]
        }
}
и когда он отключен от сервера, он может вернуться:
{
        "version": "1.0",
        "printer": {
                "supported_content_type": [
                        {
                                "content_type": "application/pdf",
                                "min_version": "1.4"
                        },
                        { "content_type": "image/pwg-raster" },
                        { "content_type": "image/jpeg" }
                ]
        }
}

Примечание : Принтеры указывают приоритет поддерживаемых типов контента с помощью порядка. Например, в приведенных выше примерах принтер указывает, что предпочитает данные «application/pdf» данным «image/pwg-raster» и «image/jpeg». Клиентам следует по возможности учитывать приоритет принтеров (подробности см. в документе CDD).

4.5.3 Ошибки

API /privet/capabilities может возвращать следующие ошибки (подробности см. в разделе «Ошибки»):
Ошибка Описание
invalid_x_privet_token X-Privet-Token в запросе недействителен или пуст.

Если устройство не предоставляет API /privet/capabilities, оно ДОЛЖНО вернуть ошибку HTTP 404. Если заголовок X-Privet-Token отсутствует, устройство ДОЛЖНО вернуть ошибку HTTP 400.

4.6 Ошибки

Ошибки возвращаются вышеуказанными API в следующем формате:
Имя значения Тип значения Описание
ошибка нить Тип ошибки (определяется API)
описание строка (необязательно) Понятное для человека описание ошибки.
сервер_api строка (необязательно) В случае ошибки сервера это поле содержит API сервера, в котором произошел сбой.
код_сервера int (необязательно) В случае ошибки сервера это поле содержит тот код ошибки, который вернул сервер.
сервер_http_код int (необязательно) В случае ошибки HTTP сервера это поле содержит код ошибки HTTP, возвращенный сервером.
тайм-аут int (необязательно) Количество секунд ожидания клиента перед повторной попыткой (только для устранимых ошибок). Клиент ДОЛЖЕН рандомизировать фактическое время ожидания от этого значения до значения, которое составляет +20%.

Все API ДОЛЖНЫ возвращать ошибку HTTP 400, если заголовок X-Privet-Token отсутствует.

HTTP/1.1 400 Отсутствует заголовок X-Privet-Token.

Пример 1:

{
        "error": "server_error",
        "description": "Service unavailable",
        "server_api": "/submit",
        "server_http_code": 503
}

Пример 2:

{
        "error": "printer_busy",
        "description": "Printer is currently printing other job",
        "timeout": 15
}

5. API принтера

Одним из типов устройств, поддерживаемых этим протоколом, является принтер. Устройства, поддерживающие этот тип, МОГУТ реализовывать некоторые функции, характерные для принтеров. В идеале печать на принтерах с поддержкой облачных технологий должна осуществляться через сервер облачной печати:

В некоторых случаях клиенту может потребоваться отправить документ локально. Это может потребоваться, если у клиента нет идентификатора Google ID или он не может подключиться к серверу облачной печати. В таком случае задание на печать будет отправлено на принтер локально. Принтер, в свою очередь, будет использовать службу облачной печати для постановки заданий в очередь и конвертации. Принтер повторно опубликует отправленное локально задание в службе облачной печати и затем запросит его, поскольку оно было отправлено через облако. Этот процесс обеспечивает гибкий пользовательский интерфейс с точки зрения обслуживания (конвертации) и управления/отслеживания заданий печати.

Поскольку служба облачной печати реализует преобразование, принтер ДОЛЖЕН объявить о поддержке всех входных форматов ("*/*") в списке поддерживаемых типов содержимого:

{
        "version": "1.0",
        "printer": {
                "supported_content_type": [
                        { "content_type": "image/pwg-raster" },
                        { "content_type": "*/*" }
                ]
        }
}

В некоторых случаях требуется полностью автономное решение. Поскольку принтеры поддерживают ограниченное количество форматов ввода, клиенту потребуется преобразовать документы в несколько изначально поддерживаемых принтером форматов.

Данная спецификация ТРЕБУЕТ, чтобы все принтеры поддерживали как минимум формат PWG Raster («image/pwg-raster») для офлайн-печати. Принтер может поддерживать другие форматы (например, JPEG), и если клиент их поддерживает, он может отправлять документы в этом формате. Принтер ДОЛЖЕН предоставлять поддерживаемые типы через API /capabilities, например:

{
        "version": "1.0",
        "printer": {
                "supported_content_type": [
                        { "content_type": "image/pwg-raster" },
                        { "content_type": "image/jpeg" }
                ]
        }
}
Клиент может инициировать печать по локальной сети двумя способами.

Простая печать — клиент отправляет документ по локальной сети в API /submitdoc (без указания параметра job_id). Отправленный документ будет напечатан с настройками тикета печати по умолчанию, и статусы заданий печати не требуются. Если принтер поддерживает ТОЛЬКО этот тип печати, он ДОЛЖЕН указать ТОЛЬКО API /submitdoc в ответе API /privet/info.

"api": [
        "/privet/accesstoken",
        "/privet/capabilities",
        "/privet/printer/submitdoc",
]

Расширенная печать : клиент должен сначала создать задание печати на принтере, вызвав API /privet/printer/createjob с действительным тикетом задания CJT в запросе. Принтер ДОЛЖЕН сохранить тикет печати в памяти и вернуть клиенту идентификатор задания job_id. Затем клиент вызывает API /printer/submitdoc и указывает ранее полученный идентификатор задания job_id . В этот момент принтер начинает печать. Клиент опрашивает принтер о состоянии задания печати, вызывая API /privet/printer/jobstate .

В многоклиентской среде нет гарантий, как будет вызываться этот API. Один клиент может вызвать /createjob между вызовами /createjob->/submitdoc другого клиента. Чтобы исключить возможные взаимоблокировки и повысить удобство использования, мы рекомендуем создать небольшую очередь ожидающих заданий печати на принтере (не менее 3-5):

  • /createjob занимает первое доступное место в очереди.
  • Время нахождения задания (в очереди) — не менее 5 минут.
  • Если все места в очереди заняты, то самое старое, непечатаемое задание будет удалено, а на его место будет помещено новое.
  • Если в данный момент на устройстве выполняется задание печати (простая или расширенная печать), /submitdoc должен вернуть статус «занято» и предложить тайм-аут для повторной попытки выполнения этого задания печати.
  • Если /submitdoc ссылается на задание, удаленное из очереди (из-за замены или истечения времени ожидания), принтер должен вернуть ошибку invalid_print_job , и клиент повторит процесс с шага /createjob . Клиент ДОЛЖЕН подождать до 5 секунд, прежде чем повторить попытку.

Если ограничения памяти предотвращают хранение нескольких ожидающих заданий на устройстве, можно долго иметь очередь из 1 задания по печати. Он все еще должен следовать тому же протоколу, что и выше. После того, как задание завершилось или не удалось с ошибкой, принтер должен хранить информацию о статусе задания не менее 5 минут. Размер очереди для хранения завершенных статусов работы должен составлять не менее 10. Если есть больше статусов работы, которые необходимо хранить, самый старый может быть удален из очереди перед 5 -минутным тайм -аутом.

Примечание. На данный момент клиенты проведут опрос на статус работы. В будущем мы можем потребовать, чтобы принтер отправил уведомление TXT DNS при изменении какого -либо состояния задания печати.

5.1. /privet/printer/createjob api

/privet/printer/createJob API является необязательным (см. Простую печать выше). Это http -запрос. /Privet/Printer/CreateJob API должен проверить действительный заголовок «X-Privet-Token». Устройство должно реализовать этот API на «/privet/printer/createJob» URL:

POST /privet/printer/createjob HTTP/1.1
При получении/Privet/Printer/CreateJob API вызов API принтер должен создать новый идентификатор задания печати, хранить полученный билет печати в формате CJT и вернуть идентификатор задания печати обратно в клиент.

5.1.1. Вход

/privet/printer/createJob API не имеет входных параметров в URL. Организация запроса должно содержать данные о печатном билете в формате CJT.

5.1.2. Возвращение

/privet/printer/createjob api возвращает следующие данные:
Значение значения Тип значения Описание
job_id нить Удостоверение личности недавно созданной работы печати.
истекает_ин инт Количество секунд это задание печати действительна.

Пример:

{
        "job_id": "123",
        "expires_in": 600
}

5.1.3. Ошибки

/privet/printer/createJob API может вернуть следующие ошибки (для получения подробной информации см. В разделе ошибок):
Ошибка Описание
Invalid_ticket Отправленный печатный билет недействителен.
printer_busy Принтер занят и не может в настоящее время обработать /createjob. Повторите после тайм -аута.
printer_error Принтер находится в состоянии ошибки и требует взаимодействия пользователя, чтобы исправить его. Описание должно содержать более подробное объяснение (например, «бумажный варенье в подносе 1»).
Invalid_x_privet_token X-Privet-Token недействителен или пуст в запросе.

Если устройство не разоблачает/privet/printer/createJob, оно должно вернуть ошибку HTTP 404. Если заголовок X-Privet-Token отсутствует, устройство должно вернуть ошибку HTTP 400.

5.2. /privet/printer/отправить API

/Privet/Printer/OpendDOC API необходим для реализации печати через локальную сеть (офлайн или репост на облачную печать). Это http -запрос. /private/printer/opperdoc API должен проверить действительный заголовок «X-Privet-Token». Устройство должно реализовать этот API на «/private/printer/posticdoc» URL:
POST /privet/printer/submitdoc HTTP/1.1
При получении звонка/privet/printer/propectdoc API принтер должен начать печать. Если он не может начать печать, он должен вернуть ошибку Printer_busy и рекомендуемый период времени ожидания, чтобы клиент мог ждать, прежде чем попробовать снова.

Если принтер не может содержать все данные во внутреннем буфере, он должен использовать механизмы TCP для замедления передачи данных, пока он не печатает часть документа, что снова предоставит часть буфера. (Например, принтер может установить Windowsize = 0 на слоях TCP, что заставит клиента ждать.)

Отправка документа на принтер может занять значительное количество времени. Клиент должен иметь возможность проверить состояние принтера и работы (расширенная печать) во время печати. Чтобы сделать это, принтер должен позволить клиенту звонить в/privet/info и/privet/printer/jobstate API при обработке/Private/Printer/Opperdoc API вызовы. Для всех клиентов рекомендуется запустить новый поток, чтобы выполнить звонок/privet/printer/spectDoc, чтобы в основном поток использовался API/privet/info и/privet/printer/jobstate для проверки принтера и состояний задания.

ПРИМЕЧАНИЕ . По завершении или аборте локальной печатной работы настоятельно рекомендуется (и потребуется в будущей версии этой спецификации), чтобы сообщить о окончательном состоянии работы в интерфейс /cloudprint /отправить для целей учета и пользовательского опыта. Параметры «printerid», «title», «contentType» и «final_semantic_state» (в формате printjobstate ) и параметры «тег» (повторный параметр) и «билет» (билет работы в формате CloudJobticket ). Обратите внимание, что предоставленный PrintJobstate должен быть окончательным, т.е. его тип должен быть сделан или прерван, и причина должна быть указана в случае, когда он прерван (см. Подробнее, см. Jobstate ). Также обратите внимание, что это использование интерфейса /cloudprint /отправить для сообщений о местных заданиях печати не упоминается в ее спецификации, поскольку этот раздел предназначен для описания первичного использования интерфейса: отправка задания печати с документом для печати, указанного в параметре «Контент».

5.2.1. Вход

/Privet/Printer/Opperdoc API имеет следующие входные параметры:
Имя Ценить
job_id (необязательно) Печать идентификатор задания. Может быть опущен для простого чехла печати (см. Выше). Должен соответствовать тому, что возвращается принтером.
имя пользователя (Необязательно) Человеческое читаемое имя пользователя. Это не является окончательным, и должно использоваться только для аннотаций печатной работы. Если задание будет перепродано в службу облачной печати, эта строка должна быть прикреплена к заданию облачной печати.
имя_клиента (Необязательно) Имя клиентского приложения, выполняющее этот запрос. Только для целей отображения. Если задание будет перепродано в службу облачной печати, эта строка должна быть прикреплена к заданию облачной печати.
job_name (Необязательно) Название задания печати, которая будет записана. Если задание будет перепродано в службу облачной печати, эта строка должна быть прикреплена к заданию облачной печати.
офлайн (необязательно) может быть только «офлайн = 1». В этом случае принтер должен только попытаться печатать офлайн (без переосмысления на сервер облачной печати).

Запрос корпус должен содержать действительный документ для печати. «Длина контента» должна включать правильную длину запроса. Заголовок «Контент-тип» должен быть установлен для документирования типа MIME и сопоставления одного из типов в CDD (если CDD не указан "*/*").

Клиентам настоятельно рекомендуется предоставить действительное имя пользователя (или электронную почту), имя клиента и имя задания с этим запросом. Эти поля используются только в пользовательских интерфейсах для улучшения пользовательского опыта.

5.2.2. Возвращение

/private/printer/opperdoc api возвращает следующие данные:
Значение значения Тип значения Описание
job_id нить Идентификатор недавно созданного задания печати (простая печать) или job_id, указанный в запросе (Advanced Printing).
истекает_ин инт Количество секунд это задание печати действительна.
job_type нить Тип контента отправленного документа.
job_size int 64 бит Размер данных печати в байтах.
job_name нить (Необязательно) То же имя задания, что и во входе (если есть).

Пример:

{
        "job_id": "123",
        "expires_in": 500,
        "job_type": "application/pdf",
        "job_size": 123456,
        "job_name": "My PDF document"
}

5.2.3. Ошибки

/private/printer/opperdoc API может вернуть следующие ошибки (подробности см. В разделе ошибок):
Ошибка Описание
Invalid_print_job Недейтельный/истекший идентификатор задания указан в запросе. Повторите после тайм -аута.
Invalid_document_type Документ MIME-тип не поддерживается принтером.
Invalid_document Отправленный документ недействителен.
document_too_large Документ превышает максимальный размер разрешенного.
printer_busy Принтер занят и не может в настоящее время обрабатывать документ. Повторите после тайм -аута.
printer_error Принтер находится в состоянии ошибки и требует взаимодействия пользователя, чтобы исправить его. Описание должно содержать более подробное объяснение (например, «бумажный варенье в подносе 1»).
Invalid_params Неверные параметры, указанные в запросе. (Неизвестные параметры должны быть безопасно игнорироваться для будущей совместимости)
user_cancel Пользователь явно отменен процесс печати с устройства.
Server_error Размещение документа в Cloud Print не удалась.
Invalid_x_privet_token X-Privet-Token недействителен или пуст в запросе.

Если устройство не разоблачает/privet/printer/spectdoc, оно должно вернуть ошибку HTTP 404. Если заголовок X-Privet-Token отсутствует, устройство должно вернуть ошибку HTTP 400.

ПРИМЕЧАНИЕ :/Privet/Printer/Opperdoc API может потребовать специальной обработки на стороне принтера (из -за большой полезной нагрузки). В некоторых случаях (в зависимости от реализации и платформы HTTP -сервера принтера) принтер может закрыть сокет перед возвратом ошибки HTTP. С другой стороны, принтер может вернуть ошибку 503 (вместо приватной ошибки). Принтеры должны попробовать как можно больше, чтобы вернуть Privet. Тем не менее, каждый клиент, реализующий приватную спецификацию, должна иметь возможность обрабатывать Socket Close (без ошибок HTTP) и 503 случая ошибок HTTP для/private/printer/отправить API. В этом случае клиент должен обрабатывать его как приватную ошибку "printer_busy" с «тайм -аутом», установленной на 15 секунд. Чтобы избежать бесконечных повторений, клиент может прекратить повторение после разумного количества попыток (например, 3).

5.3. /Privet/Printer/JobState API

/Privet/Printer/Jobstate API является необязательным (см. Простую печать выше). Это запрос на http get. /Privet/Printer/JobState API должен проверить действительный заголовок «X-Privet-Token». Устройство должно реализовать этот API на «/privet/printer/jobstate».
GET /privet/printer/jobstate HTTP/1.1
При получении API API A/Privet/Printer/JobState принтер должен вернуть статус запрошенной задания печати или ошибки vangyd_print_job.

5.3.1. Вход

/Privet/Printer/Jobstate API имеет следующие параметры ввода:
Имя Ценить
job_id Печать идентификатор задания для возврата статуса для.

5.3.2. Возвращение

/Privet/Printer/JobState API возвращает следующие данные:
Значение значения Тип значения Описание
job_id нить Печать идентификатор задания там информация о состоянии.
состояние нить Проект - задание печати была создана на устройстве (NO/PRIVET/PRINTER/PURTED TOC CALLS еще не получено).
В очереди - печатная работа была получена и в очереди, но печать еще не началась.
in_progress - задание печати находится в ходе печати.
Остановлено - печатная работа была приостановлена, но ее можно возобновить вручную или автоматически.
Готово - Печатная задача выполнена.
Прерванное - печатная работа не удалась.
описание нить (Необязательно) Человеческое читаемое описание статуса задания печати. Следует включать дополнительную информацию, если состояние < остановлено или прервано . Поле Semantic_state обычно предоставляет клиенту лучшее и значимое описание.
истекает_ин инт Количество секунд это задание печати действительна.
job_type нить (Необязательно) Тип контента отправленного документа.
job_size int 64 бит (Необязательно) Размер данных печати в байтах.
job_name нить (Необязательно) То же имя задания, что и во входе (если есть).
server_job_id нить (Необязательно) Идентификатор задания, возвращаемого с сервера (если задание было размещено в службе облачной печати). Опущен для автономной печати.
Semantic_state JSON (Необязательно) Семантическое состояние работы в формате PrintJobstate .

Пример (печать путем отчетности через облачную печать):

{
        "job_id": "123",
        "state": "in_progress",
        "expires_in": 100,
        "job_type": "application/pdf",
        "job_size": 123456,
        "job_name": "My PDF document",
        "server_job_id": "1111-2222-3333-4444"
}

Пример (ошибка в автономной печати):

{
        "job_id": "123",
        "state": "stopped",
        "description": "Out of paper",
        "expires_in": 100,
        "job_type": "application/pdf",
        "job_size": 123456,
        "job_name": "My PDF document"
}

Пример (печатная задания прервана пользователем):

{
        "job_id": "123",
        "state": "aborted",
        "description": "User action",
        "expires_in": 100,
        "job_type": "application/pdf",
        "job_size": 123456,
        "job_name": "My PDF document",
        "semantic_state": {
                "version": "1.0",
                "state": {
                        "type": "ABORTED",
                        "user_action_cause": {"action_code": "CANCELLED"}
                },
                "pages_printed": 7
        }
}

Пример (печатная работа остановлена из -за бумаги). Обратите внимание на ссылку на состояние устройства. Клиент должен будет позвонить в API /privet /info, чтобы получить более подробную информацию о состоянии устройства:

{
        "job_id": "123",
        "state": "stopped",
        "description": "Out of paper",
        "expires_in": 100,
        "job_type": "application/pdf",
        "job_size": "123456",
        "job_name": "My PDF document",
        "semantic_state": {
                "version": "1.0",
                "state": {
                        "type": "STOPPED",
                        "device_state_cause": {"error_code": "INPUT_TRAY"}
                },
                "pages_printed": 7
        }
}

5.3.3. Ошибки

/privet/printer/api jobstate может вернуть следующие ошибки (подробности см. В разделе ошибок):
Ошибка Описание
Invalid_print_job Недейтельный/истекший идентификатор задания указан в запросе.
Server_error Получение статуса работы печатной работы (для печатных заданий, размещенных в облачной печати) не удалось.
Invalid_x_privet_token X-Privet-Token недействителен или пуст в запросе.

Если устройство не разоблачает/Privet/Printer/JobState, оно должно вернуть ошибку HTTP 404. Если заголовок X-Privet-Token отсутствует, устройство должно вернуть ошибку HTTP 400.

6. Приложение

6.1. Поведение и настройки по умолчанию

В этом разделе будет объяснено поведение по умолчанию, которое мы ожидаем от всех приватных совместимых устройств.
  • Устройства вне коробки должны поддерживать только /private /info и /privet /apis /register . Все другие API (например, Privet /AccessToken, локальная печать) должны быть отключены.
  • Регистрация требует физического взаимодействия с устройством.
    • Пользователь должен принять физическое действие на устройстве (например, нажатие кнопки), чтобы подтвердить их доступ к устройству.
    • После того, как пользователь принимает действие, отмеченное выше, принтер должен отправить запрос /cloudprint /regire. Он не должен отправлять этот запрос до тех пор, пока не будет принят действие (см. Диаграмму последовательности 1).
    • Если устройство обрабатывает A /Privet /Register запрос (например, ожидание приведенного выше действия), оно должно отклонить все остальные /Privet /Register -запросы. Устройство должно вернуть ошибку device_busy в этом случае.
    • Устройство должно тайметь любой запрос /регистрации, который не получает физическое действие, упомянутое выше в течение 60 секунд. Устройство должно вернуть ошибку подтверждения_ времен в этом случае.
    • Необязательно: рекомендуется, но не требуется, следующее может улучшить пользовательский опыт:
      • Принтер может пропустить свет или экран, чтобы указать, что пользователю необходимо предпринять действие для подтверждения регистрации.
      • Принтер может указать на своем экране, что «он зарегистрирован в Google Cloud Print для пользователя« abc@def.com » - нажмите OK, чтобы продолжить», где abc@def.com - это пользовательский параметр из вызова API /регистр. Это прояснит пользователю, что:
        • это их запрос на регистрацию, чтобы они подтвердили
        • Что происходит, если он/он не вызвал запрос.
      • В дополнение к физическому действию для подтверждения принтера (например, «нажмите кнопку OK»), принтер также может предложить пользователю кнопку для отмены запроса (например, «Нажмите отмена, чтобы отказаться»). Это позволило бы пользователям, которые не запустили запрос на регистрацию, отменить его до 60 второго тайм -аута. Устройство должно вернуть ошибку user_cancel в этом случае.
  • Перевод права собственности:
    • Устройство может быть явно удалено из облачной службы.
      • Если устройство получает успех, но никакого описания устройства в результате вызова /cloudprint /printer (для GCP) оно должно вернуться к режиму по умолчанию (вне коробки).
      • Если учетные данные устройства больше не работают (явно из-за ответа «недопустимых учетных данных» с сервера), оно должно вернуться в режим по умолчанию (вне коробки).
    • Локальный сброс заводов должен очистить учетные данные устройства и установить его в состояние по умолчанию.
    • Необязательно: устройство может предоставить пункт меню для очистки учетных данных и поместить его в режим по умолчанию.
  • Устройства, поддерживающие уведомления XMPP, должны включать в себя возможность пинга. Тайм -аут Ping должен управлять с сервера через "local_settings".
  • Устройство может явно пинговать сервер (/CloudPrint/Printer API для GCP, в дополнение к писанию XMPP) не чаще, чем раз в день (24 часа), чтобы убедиться, что они синхронизированы. Рекомендуется рандомизировать контрольное окно в течение 24-32 часов.
  • Необязательно: для устройств облачной печати рекомендуется, но не обязательно иметь ручной способ (кнопка), чтобы позволить пользователю инициировать проверку на новые задания печати с устройства. У некоторых принтеров это уже есть.
  • Необязательный. ПРИНТЕРЫ ПРЕДСТАВЛЕНИЯ могут иметь возможность полностью отключить локальное обнаружение. В таком случае устройство должно обновить эти локальные настройки на сервере. Новые локальные настройки должны быть пустыми (настройка «local_discovery» на «false» означает, что его можно повторно включить в службу GCP).

6.1.2 Диаграмма регистрации по умолчанию

6.2. Атаки и профилактика XSSI и XSRF

В этом разделе будет объяснена возможность атак XSSI и XSRF на устройство и как защитить от них (включая методы генерации токенов).
Более подробная информация здесь: http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
Обычно атаки XSSI и XSRF возможны, когда сайт использует механизмы аутентификации cookie. В то время как Google не использует файлы cookie с их службой облачной печати, такие атаки все еще возможны. Доступ к локальной сети, по проектированию, неявно доверяет запросам.

6.2.1. XSSI

Злоусованный веб-сайт возможно угадать IP-адрес и номер порта приватного совместимого устройства и попытаться вызвать Privet API с использованием «src = <имя API>» внутри <script> тега:
<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>
Без защиты вредоносные веб -сайты смогут выполнять вызовы API и доступа к результатам.
Чтобы предотвратить этот тип атаки, все приватные вызовы API должны потребовать заголовка «X-Privet-Token» в запросе. «src = <pi>» Теги скрипта не могут добавлять заголовки, эффективно защищая от этого типа атаки.

6.2.2. Xsrf

http://en.wikipedia.org/wiki/cross-site_request_forgery
Злоусовный веб-сайт возможно угадать IP-адрес и номер порта приватного совместимого устройства и попытаться вызвать Privet API, используя <iframe>, формы или какой-то другой механизм загрузки межветального веки. Злоумышленники не смогут получить доступ к результатам запроса, но если запрос выполнит действие (например, печать), они могли бы вызвать его.

Чтобы предотвратить эту атаку, нам нужна следующая защита:

  • Оставьте /Privet /Info API открыт для xsrf
  • /Privet/Info API не должен выполнять никаких действий на устройстве
  • Использовать /Privet /Info API для получения X-Privet-Token
  • Все остальные API должны проверить действительный X-Privet-Token в заголовке «X-Privet-Token».
  • X-Privet-Token должен быть действительным всего в течение 24 часов.

Даже если злоумышленник сможет выполнить API /privet /info , он не сможет прочитать X-Privet-Token из ответа и, следовательно, не смогут вызвать какой-либо другой API.

Настоятельно рекомендуется генерировать токен XSRF, используя следующий алгоритм:

XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )

Xsrf Элементы генерации токенов:

  • Разделитель - это особый персонаж, обычно »:«
  • Mage_timeCounter - это несколько секунд с момента некоторого события (эпоха для временной метки) или времени загрузки устройства (для счетчиков процессора). Issuge_timeCounter постоянно увеличивается, когда устройство работает и работает (см. Проверку токена ниже).
  • Функция SHA1 - HASH с использованием алгоритма SHA1
  • BASE64 - Кодирование BASE64
  • device_secret - секрет, специфичный для устройства. Секрет устройства должен быть обновлен на каждом перезапуске.

Рекомендуемые способы создания секрета устройства:

  • Создайте новый UUID на каждом перезапуске
  • Генерировать 64 -битное случайное число при каждом перезапуске

Устройство не требуется для хранения всех выданных токенов XSRF. Когда устройство необходимо проверить токен XSRF для обоснованности, оно должно основывать токен. Получите проблему с Assue_timeCounter во второй половине (ClearText) и попытайтесь создать хэш SHA1 Device_Secret + DeLimiter + Vicele_timeCounter , где Vises_timeCounter находится из токена. Если недавно сгенерированный SHA1 соответствует тому, что в токене, устройство должно теперь проверить, находится ли alsage_timeCounter в течение периода достоверности от (24 часа) текущего счетчика времени. Для этого устройство берет текущий счетчик времени (например, счетчик процессора) и вычитает из него assuest_timecounter . Результат должен быть количество секунд с момента проблемы токена.

Важно: это рекомендуемый способ реализации защиты XSRF. Клиенты приватной спецификации не должны пытаться понять токен XSRF, вместо этого они должны рассматривать, как Blackbox. Рисунок 6.2.3 иллюстрирует рекомендуемый способ реализации X-Privet-Token и проверки типичного запроса.

6.2.3 Диаграмма последовательности Generation и проверки токенов x Privet

6.3. Рабочие диаграммы

Этот раздел проиллюстрирует рабочий процесс в разных случаях.

6.3.1. Принтер из коробки

6.3.2. Запуск зарегистрированного принтера

6.3.3 xmpp уведомлений обрабатывает рабочий процесс

6.3.4. Проверьте настройки принтера Рабочий процесс