Privet es una API de Cloud Device Local Discovery que usan los servicios en la nube. Este documento se organiza en las siguientes secciones:
- Introducción: Introducción a Privet
- Descubrimiento: Mecanismos de descubrimiento local
- Anuncios: Anuncios de descubrimiento local
- API: APIs de Privet para dispositivos en la nube generales
- API de Printer: APIs de Privet que usan las impresoras
- Apéndice: Diagramas complementarios
1. Introducción
Los dispositivos conectados a la nube tienen muchos beneficios. Pueden usar servicios de conversión en línea, alojar colas de trabajos mientras el dispositivo está sin conexión y ser accesibles desde cualquier parte del mundo. Sin embargo, con la gran cantidad de dispositivos en la nube a los que puede acceder un usuario determinado, necesitamos proporcionar un método para encontrar el dispositivo más cercano según la ubicación. El propósito del protocolo Privet es vincular la flexibilidad de los dispositivos en la nube con un mecanismo de detección local adecuado para que los dispositivos se detecten fácilmente en entornos nuevos.
Los objetivos de este protocolo son los siguientes:- Hacer que los dispositivos en la nube sean detectables de forma local
- registrar dispositivos en la nube con un servicio en la nube
- Asocia los dispositivos registrados con su representación en la nube
- garantizar funcionalidad sin conexión
- Simplificar la implementación para que los dispositivos pequeños puedan utilizarla
El protocolo Privet consta de 2 partes principales: el descubrimiento y la API. El descubrimiento se usa para encontrar el dispositivo en la red local, y la API se usa para obtener información sobre el dispositivo y realizar algunas acciones. En este documento, el dispositivo se refiere a un dispositivo conectado a la nube que implementa el protocolo Privet.
2. Discovery
Discovery es un protocolo basado en Zeroconf (mDNS + DNS-SD). El dispositivo DEBE implementar el direccionamiento de vínculo local IPv4. El dispositivo DEBE cumplir con las especificaciones de mDNS y DNS-SD.
- http://www.rfc-editor.org/rfc/rfc3927.txt (IPv4 Link-local)
- http://www.rfc-editor.org/rfc/rfc4862.txt (IPv6 Link-local)
- http://www.rfc-editor.org/rfc/rfc6762.txt (mDNS)
- http://www.rfc-editor.org/rfc/rfc6763.txt (DNS-SD)
El dispositivo DEBE realizar la resolución de conflictos de nombres según las especificaciones anteriores.
2.1. Tipo de servicio
El descubrimiento de servicios de DNS usa el siguiente formato para los tipos de servicios: _applicationprotocol._transportprotocol. En el caso del protocolo Privet, el tipo de servicio para DNS-SD debe ser: _privet._tcp
El dispositivo también puede implementar otros tipos de servicios. Se recomienda usar el mismo nombre de instancia de servicio para todos los tipos de servicios que implementa el dispositivo. Por ejemplo, una impresora puede implementar los servicios "Printer XYZ._privet._tcp" y "Printer XYZ._printer._tcp". Simplificará la configuración para el usuario. Sin embargo, los clientes de Privet solo buscarán "_privet._tcp".
Además del tipo de servicio principal, el dispositivo DEBE anunciar los registros PTR de sus subtipos correspondientes (consulta la especificación de DNS-SD: "7.1. Selective Instance Enumeration (Subtypes)"). El formato debe ser el siguiente: _<subtype>._sub._privet._tcp
Actualmente, el único subtipo de dispositivo admitido es printer. Por lo tanto, todas las impresoras DEBEN anunciar dos registros PTR:
- _privet._tcp.local.
- _printer._sub._privet._tcp.local.
2.2. Registro TXT
La detección de servicios DNS define campos para agregar información opcional sobre un servicio en los registros TXT. Un registro TXT consta de pares clave/valor. Cada par clave/valor comienza con el byte de longitud seguido de hasta 255 bytes de texto. La clave es el texto que aparece antes del primer carácter “=” y el valor es el texto que aparece después del primer carácter “=” hasta el final. La especificación no permite ningún valor en el registro, en cuyo caso no habrá ningún carácter “=” NI ningún texto después del carácter “=”. (Consulta la especificación de DNS-SD: "6.1. Reglas generales de formato para registros TXT de DNS" para el formato de registro TXT de DNS y "6.2. Tamaño del registro TXT de DNS-SD" (DNS-SD TXT Record Size) para la longitud recomendada).
Privet requiere que el dispositivo envíe los siguientes pares clave-valor en el registro TXT. Las cadenas de clave/valor no distinguen mayúsculas de minúsculas. Por ejemplo, "CS=online" y "cs=ONLINE" son iguales. La información del registro TXT DEBE ser la misma a la que se puede acceder a través de la API de /info (consulta el punto 4.1). sección de la API).
Se recomienda que el tamaño del registro TXT sea inferior a 512 bytes.
2.2.1, txtvers
Versión de la estructura TXT. txtvers DEBE ser el primer registro de la estructura TXT. Actualmente, la única versión admitida es la 1.
txtvers=1
2.2.2, ty
Proporciona un nombre del dispositivo legible para el usuario. Por ejemplo:
ty=Google Cloud Ready Printer Model XYZ
2.2.3. Nota (opcional)
Proporciona un nombre del dispositivo legible para el usuario. Por ejemplo:
note=1st floor lobby printer
Nota: Esta es una clave opcional y se puede omitir. Sin embargo, si está presente, el usuario DEBE poder modificar este valor. Se DEBE usar la misma descripción cuando se registre el dispositivo.
2.2.4, url
Es la URL del servidor al que está conectado este dispositivo (incluido el protocolo). Por ejemplo:
url=https://www.google.com/cloudprint
2.2.5, type
Lista separada por comas de los subtipos de dispositivos compatibles con este dispositivo. El formato es "type=_subtype1,_subtype2". Actualmente, el único subtipo de dispositivo admitido es printer.
type=printer
Cada subtipo que se enumere debe anunciarse con un registro PTR correspondiente. Para cada subtipo de servicio admitido, debe haber un elemento correspondiente. El nombre del subtipo de servicio (<subtype>._sub._privet._tcp) debe ser igual al tipo de dispositivo aquí.
2.2.6. id
ID de dispositivo. Si el dispositivo aún no se registró, esta clave debe estar presente, pero el valor debe estar vacío. Por ejemplo:
id=11111111-2222-3333-4444-555555555555 id=
2.2.7, cs
Indica el estado de conexión actual del dispositivo. En esta especificación, se definen cuatro valores posibles.
- "En línea" indica que el dispositivo está conectado a la nube.
- "Sin conexión" indica que el dispositivo está disponible en la red local, pero no puede comunicarse con el servidor.
- "connecting" indica que el dispositivo está realizando su secuencia de inicio y aún no está completamente en línea.
- "not-configured" indica que aún no se configuró el acceso a Internet del dispositivo. Actualmente, no se usa este valor, pero podría ser útil en versiones futuras de la especificación.
- cs=online
- cs=offline
- cs=connecting
Si el dispositivo se registró en una nube, al iniciarse, debe verificar la conectividad con un servidor para detectar su estado de conexión (por ejemplo, llamar a la API de la nube para obtener la configuración del dispositivo). El dispositivo puede usar el estado de conexión de su canal de notificaciones (p.ej., XMPP) para informar este valor. Los dispositivos no registrados al inicio pueden hacer ping a un dominio para detectar su estado de conexión (por ejemplo, hacer ping a www.google.com para dispositivos de impresión en la nube).
3. Anuncios
Cuando el dispositivo se inicia, se apaga o cambia de estado, DEBE realizar el paso de anuncio como se describe en la especificación de mDNS. DEBE enviar el anuncio correspondiente al menos dos veces con un intervalo de al menos un segundo entre cada envío.
3.1. Inicio
Al iniciar el dispositivo, DEBE realizar los pasos de sondeo y anuncio como se describen en la especificación de mDNS. En este caso, se deben enviar los registros SRV, PTR y TXT. Se recomienda agrupar todos los registros en una respuesta de DNS si es posible. De lo contrario, se recomienda el siguiente orden: registros SRV, PTR y TXT.
3.2. Cierre
Cuando se apaga el dispositivo, DEBE intentar notificar a todas las partes interesadas enviando un "paquete de despedida" con TTL=0 (como se describe en la documentación de mDNS).
3.3. Actualizar
En caso de que haya cambiado la información descrita en TXT, el dispositivo DEBE enviar un anuncio de actualización. En este caso, es suficiente con enviar solo el nuevo registro TXT. Por ejemplo, después de que se registra un dispositivo, DEBE enviar un anuncio de actualización que incluya el nuevo ID del dispositivo.
4. API
Después de que se descubre un dispositivo en la nube, se habilita la comunicación del cliente con el dispositivo directamente a través de la red local. Todas las APIs se basan en HTTP 1.1. Los formatos de datos se basan en JSON. Las solicitudes de la API pueden ser solicitudes GET o POST.
Cada solicitud DEBE contener un encabezado "X-Privet-Token" válido. La ÚNICA solicitud que puede tener un encabezado "X-Privet-Token" vacío es la solicitud /privet/info (ten en cuenta que el encabezado DEBE estar presente). Si falta el encabezado "X-Privet-Token", el dispositivo DEBE responder con el siguiente error HTTP 400:
HTTP/1.1 400 Missing X-Privet-Token header.
Si el encabezado "X-Privet-Token" está vacío o no es válido, el dispositivo DEBE responder con el mensaje "invalid X-Privet-Token error" (invalid_x_privet_token; consulta la sección de errores para obtener más detalles). La única excepción es la API de /info. Para obtener más información sobre por qué se hace esto y cómo se deben generar los tokens, consulta el Apéndice A: Ataques y prevención de XSSI y XSRF.
Si una API solicitada no existe o no es compatible, el dispositivo DEBE devolver un error HTTP 404.
4.1. de disponibilidad de API
Antes de que se exponga CUALQUIER API (incluida la API de /info), el dispositivo DEBE comunicarse con el servidor para verificar la configuración local. La configuración local SE DEBE conservar entre reinicios. Si el servidor no está disponible, se deben usar los últimos parámetros de configuración locales conocidos. Si el dispositivo aún no se registró, debe seguir la configuración predeterminada.
Los dispositivos de Cloud Print DEBEN seguir los pasos que se indican a continuación para registrarse, recibir y actualizar la configuración local.
4.1.1. Registro
Cuando el dispositivo se registra, DEBE especificar el parámetro "local_settings", de la siguiente manera:
{ "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 } }
Nombre del valor | Tipo de valor | Descripción |
---|---|---|
local_discovery | booleano | Indica si se permite la funcionalidad de descubrimiento local. Si es "false", se deben inhabilitar todas las APIs locales (incluida /info) y la detección de DNS-SD. De forma predeterminada, los dispositivos que se registran recientemente deben pasar "true". |
access_token_enabled | booleano (opcional) | Indica si la API de /accesstoken se debe exponer en la red local. De forma predeterminada, debe ser "true". |
printer/local_printing_enabled | booleano (opcional) | Indica si la funcionalidad de impresión local (/printer/createjob, /printer/submitdoc, /printer/jobstate) debe exponerse en la red local. De forma predeterminada, debe ser "true". |
printer/conversion_printing_enabled | booleano (opcional) | Indica si la impresión local puede enviar el trabajo al servidor para su conversión. Solo tiene sentido cuando la impresión local está habilitada. |
xmpp_timeout_value | int (opcional) | Indica la cantidad de segundos entre los pings del canal XMPP. De forma predeterminada, DEBE ser de 300 (5 minutos) o más. |
Importante: La falta de cualquier valor opcional indica que el dispositivo no admite en absoluto la funcionalidad correspondiente.
4.1.2. Inicio
Al iniciar el dispositivo, debe comunicarse con el servidor para verificar qué APIs están disponibles para exponerse en la red local. En el caso de las impresoras conectadas a Cloud Print, se debe llamar a lo siguiente:
/cloudprint/printer?printerid=<printer_id>
/cloudprint/list
Se prefiere /cloudprint/printer en lugar de /cloudprint/list, pero ambos funcionarán.
Esta API devuelve los parámetros actuales del dispositivo, incluidos los parámetros de configuración de la API local. La respuesta del servidor tendrá el siguiente formato:
"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 } }
El objeto "current" indica la configuración que está vigente en el momento.
El objeto "pending" indica la configuración que se debe aplicar al dispositivo (es posible que falte este objeto).
Una vez que el dispositivo vea la configuración "pendiente", DEBE actualizar su estado (consulta a continuación).
4.1.3. Actualizar
Si se necesita actualizar la configuración, se enviará una notificación XMPP al dispositivo. La notificación tendrá el siguiente formato:
<device_id>/update_settings
Cuando el dispositivo recibe una notificación de este tipo, DEBE consultar al servidor para obtener la configuración más reciente. Los dispositivos de Cloud Print DEBEN usar lo siguiente:
/cloudprint/printer?printerid=<printer_id>
Una vez que el dispositivo vea la sección "pendiente" como resultado de la API de /cloudprint/printer (en el inicio o debido a la notificación), DEBE actualizar su estado interno para recordar la nueva configuración. DEBE llamar a la API del servidor para confirmar la nueva configuración. En el caso de las impresoras de Cloud, el dispositivo DEBE llamar a la API de /cloudprint/update y usar el parámetro "local_settings" como durante el registro.
Cuando se vuelve a conectar al canal XMPP, el dispositivo DEBE llamar a la API de /cloudprint/printer para verificar si se cambiaron los parámetros de configuración locales desde la última vez.
4.1.3.1. Configuración local pendiente
El parámetro "local_settings" que usa el dispositivo para llamar a la API del servidor NUNCA debe contener la sección "pending".
4.1.3.2. Configuración local actual
SOLO el dispositivo puede cambiar la sección "actual" de "local_settings". Todos los demás cambiarán la sección "pendiente" y esperarán hasta que el dispositivo propague los cambios a la sección "actual".
4.1.4. Sin conexión
Cuando no se pueda establecer contacto con el servidor durante el inicio, después de la notificación, el dispositivo DEBE usar la última configuración local conocida.
4.1.5. Cómo borrar un dispositivo del servicio
Si el dispositivo se borró del servicio (por ejemplo, GCP), se enviará una notificación XMPP al dispositivo. La notificación tendrá el siguiente formato:
<device_id>/delete
Cuando recibe una notificación de este tipo, el dispositivo DEBE conectarse al servidor para verificar su estado. Los dispositivos Cloud Print DEBEN usar lo siguiente:
/cloudprint/printer?printerid=<printer_id>
El dispositivo DEBE recibir una respuesta HTTP correcta con success=false y sin descripción del dispositivo o la impresora. Esto significa que se quitó el dispositivo del servidor y que el dispositivo DEBE borrar sus credenciales y pasar al modo de configuración predeterminada de fábrica.
CADA VEZ que el dispositivo recibe una respuesta que indica que se borró como resultado de la API de /cloudprint/printer (inicio, notificación de actualización de la configuración, ping diario), DEBE borrar sus credenciales y pasar al modo predeterminado.
4.2. API de /privet/info
La API de info es OBLIGATORIA y todos los dispositivos la deben implementar. Es una solicitud HTTP GET para la URL "/privet/info": GET /privet/info HTTP/1.1
La API de info devuelve información básica sobre un dispositivo y la funcionalidad que admite. Esta API NUNCA debe cambiar el estado del dispositivo ni realizar ninguna acción, ya que es vulnerable a ataques de XSRF. Esta es la ÚNICA API que puede tener un encabezado "X-Privet-Token" vacío. Los clientes deben llamar a la API de /privet/info con el encabezado "X-Privet-Token" establecido en X-Privet-Token: ""
La API de info DEBE devolver datos coherentes con los datos disponibles en el registro TXT durante el descubrimiento.
4.2.1. Entrada
La API de /privet/info no tiene parámetros de entrada.
4.2.2. Volver
La API de /privet/info devuelve información básica sobre el dispositivo y la funcionalidad compatible.
La columna TXT indica el campo correspondiente en el registro TXT de DNS-SD.
Nombre del valor | Tipo de valor | Descripción | TXT |
---|---|---|---|
version | string | Es la versión más alta (principal.secundaria) de la API admitida. Actualmente, es 1.0. | |
nombre | string | Nombre del dispositivo legible por humanos. | ty |
descripción | string | (Opcional) Descripción del dispositivo. El usuario DEBE poder modificarlo. | nota |
url | string | Es la URL del servidor con el que se comunica este dispositivo. La URL DEBE incluir la especificación del protocolo, por ejemplo, https://www.google.com/cloudprint. | url |
tipo | Lista de cadenas | Es la lista de tipos de dispositivos admitidos. | tipo |
id | string | Es el ID del dispositivo, que está vacío si el dispositivo aún no se registró. | id |
device_state | string | Estado del dispositivo. idle significa que el dispositivo está listo. processing significa que el dispositivo está ocupado y que la funcionalidad puede estar limitada durante un tiempo. stopped significa que el dispositivo no funciona y se requiere la intervención del usuario. | |
connection_state | string | Estado de la conexión con el servidor (base_url)
online: Conexión disponible offline: Sin conexión connecting: Se están realizando los pasos de inicio not-configured: La conexión aún no se configuró Un dispositivo registrado puede informar su estado de conexión según el estado del canal de notificaciones (p.ej., el estado de la conexión XMPP). | cs |
manufacturer | string | Nombre del fabricante del dispositivo | |
modelo | string | Modelo del dispositivo | |
serial_number | string | Es el identificador único del dispositivo. En esta especificación, DEBE ser un UUID. (Especificación de GCP 1.1)
(opcional) Recomendamos usar el mismo ID de número de serie en todas partes para que los diferentes clientes puedan identificar el mismo dispositivo. Por ejemplo, las impresoras que implementan IPP pueden usar este ID de número de serie en el campo "printer-device-id". | |
firmware | string | Versión del firmware del dispositivo | |
tiempo de actividad | int | Cantidad de segundos desde el inicio del dispositivo. | |
setup_url | string | (Opcional) URL (incluido el protocolo) de la página con instrucciones de configuración | |
support_url | string | (Opcional) URL (incluido el protocolo) de la página con información de asistencia y preguntas frecuentes | |
update_url | string | (Opcional) URL (incluido el protocolo) de la página con instrucciones para actualizar el firmware | |
x-privet-token | string | Valor del encabezado X-Privet-Token que se debe pasar a todas las APIs para evitar ataques de XSSI y XSRF. Consulta la sección 6.1 para obtener más información. | |
api | Descripción de las APIs | Lista de APIs compatibles (se describen a continuación) | |
semantic_state | JSON | (Opcional) Es el estado semántico del dispositivo en formato CloudDeviceState. |
api: Es una lista en formato JSON que contiene la lista de APIs disponibles a través de la red local. Ten en cuenta que es posible que no todas las APIs estén disponibles al mismo tiempo en la red local. Por ejemplo, un dispositivo recién conectado solo debería admitir la API de /register:
"api": [ "/privet/register", ]
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
Las siguientes APIs están disponibles en este momento:
- /privet/register: API para el registro de dispositivos en la red local. (consulta la API de /privet/register para obtener más detalles). Esta API DEBE ocultarse una vez que el dispositivo se registre correctamente en la nube.
- /privet/accesstoken: API para solicitar un token de acceso desde el dispositivo (consulta la API de /privet/accesstoken para obtener más detalles).
- /privet/capabilities: API para recuperar las capacidades del dispositivo (consulta la API de /privet/capabilities para obtener más detalles).
- /privet/printer/*: Es una API específica para el tipo de dispositivo "impresora". Consulta las APIs específicas de la impresora para obtener más detalles.
{ "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", ] }
{ "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. Errores
La API de /privet/info SOLO debe devolver un error si falta el encabezado X-Privet-Token. DEBE ser un error HTTP 400:
HTTP/1.1 400 Missing X-Privet-Token header.
4.3. API de /privet/register
La API de /privet/register es OPCIONAL. Es una solicitud HTTP POST. La API de /privet/register DEBE verificar si hay un encabezado X-Privet-Token válido. El dispositivo DEBE implementar esta API en la 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
El dispositivo debe exponer la API de /privet/register SOLO cuando permita el registro anónimo en ese momento. Por ejemplo:
- Cuando el dispositivo está encendido (o después de hacer clic en un botón especial del dispositivo) y aún no se registró, debe exponer la API de /privet/register para permitir que un usuario de la red local reclame la impresora.
- Una vez que se complete el registro, el dispositivo debería dejar de exponer la API de /privet/register para evitar que otro usuario de la red local reclame el dispositivo.
- Es posible que algunos dispositivos tengan diferentes formas de registrarse y no deberían exponer la API de /privet/register en absoluto (por ejemplo, el conector de Chrome Cloud Print).
El proceso de registro consta de 3 pasos (consulta el registro anónimo para Cloud Print).
- Inicia el proceso de registro anónimo.
- Un cliente inicia este proceso llamando a la API de /privet/register. En ese momento, es posible que el dispositivo espere la confirmación del usuario.
- Obtén el token de reclamo.
El cliente sondea para saber cuándo el dispositivo está listo para continuar. Una vez que el dispositivo está listo, envía una solicitud al servidor para recuperar el token y la URL de registro. El token y la URL recibidos SE DEBEN devolver al cliente. Durante este paso, si el dispositivo recibe otra llamada para inicializar el registro, debe hacer lo siguiente:
- Si se trata del mismo usuario que inició el registro, descarta todos los datos anteriores (si los hay) y comienza un nuevo proceso de registro.
- Si se trata de un usuario diferente, devuelve un error de dispositivo ocupado y un tiempo de espera de 30 segundos.
Completar el proceso de registro
Después de que el cliente haya reclamado el dispositivo, debe notificarle que complete el registro. Una vez que se complete el proceso de registro, el dispositivo debería enviar un anuncio de actualización, incluido el ID del dispositivo recién adquirido.
Nota: Cuando el dispositivo procesa una llamada a la API de /privet/register, no se pueden procesar otras llamadas a la API de /privet/register de forma simultánea. El dispositivo DEBE devolver el error device_busy y un tiempo de espera de 30 segundos.
Se RECOMIENDA ENCARECIDAMENTE que el usuario confirme el registro en el dispositivo. Si se implementa, el dispositivo DEBE esperar la confirmación del usuario DESPUÉS de recibir una llamada a la API de /privet/register?action=start. El cliente llamará a la API de /privet/register?action=getClaimToken para saber cuándo se completó la confirmación del usuario y el token de reclamo está disponible. Si el usuario cancela el registro en el dispositivo (p.ej., presiona el botón Cancelar), se DEBE devolver el error user_cancel. Si el usuario no confirmó el registro dentro de un período determinado, se DEBE devolver el error confirmation_timeout. Consulta la sección de valores predeterminados para obtener más detalles.
4.3.1. Entrada
La API de /privet/register tiene los siguientes parámetros de entrada:Nombre | Valor |
---|---|
acción | Puede ser uno de los siguientes:
start: Para iniciar el proceso de registro getClaimToken: Para recuperar el token de reclamo del dispositivo cancel: Para cancelar el proceso de registro complete: Para completar el proceso de registro |
usuario | Correo electrónico del usuario que reclamará este dispositivo. |
El dispositivo DEBE verificar que la dirección de correo electrónico de todas las acciones (start, getClaimToken, cancel, complete) coincida.
4.3.2. Volver
La API de /privet/register devuelve los siguientes datos:Nombre del valor | Tipo de valor | Descripción |
---|---|---|
acción | string | Es la misma acción que en el parámetro de entrada. |
usuario | cadena (opcional) | Es el mismo usuario que se indica en el parámetro de entrada (puede faltar si se omite en la entrada). |
token | cadena (opcional) | Token de registro (obligatorio para la respuesta de "getClaimToken", se omite para "start", "complete" y "cancel"). |
claim_url | cadena (opcional) | URL de registro (obligatoria para la respuesta de "getClaimToken", se omite para "start", "complete" y "cancel"). En el caso de las impresoras de Cloud, debe ser la "complete_invite_url" recibida del servidor. |
automated_claim_url | cadena (opcional) | URL de registro (obligatoria para la respuesta de "getClaimToken", se omite para "start", "complete" y "cancel"). En el caso de las impresoras de Cloud, debe ser la "automated_invite_url" que se recibió del servidor. |
device_id | cadena (opcional) | Es el ID del dispositivo nuevo (se omite en la respuesta "start" y es obligatorio en la respuesta "complete"). |
El dispositivo DEBE devolver su ID en la respuesta de la API de /privet/info SOLO después de que se complete el registro.
Ejemplo 1:
{ "action": "start", "user": "user@domain.com", }
Ejemplo 2:
{ "action": "getClaimToken", "user": "user@domain.com", "token": "AAA111222333444555666777", "claim_url": "https://domain.com/SoMeUrL", }
Ejemplo 3:
{ "action": "complete", "user": "user@domain.com", "device_id": "11111111-2222-3333-4444-555555555555", }
4.3.3. Errores
La API de /privet/register puede devolver los siguientes errores (consulta la sección Errores para obtener más detalles):Error | Descripción |
---|---|
device_busy | El dispositivo está ocupado y no puede realizar la acción solicitada. Vuelve a intentarlo después de que se agote el tiempo de espera. |
pending_user_action | En respuesta a "getClaimToken", este error indica que el dispositivo aún está pendiente de la confirmación del usuario y que se debe volver a intentar la solicitud de "getClaimToken" después del tiempo de espera. |
user_cancel | El usuario canceló explícitamente el proceso de registro desde el dispositivo. |
confirmation_timeout | Se agota el tiempo de espera de la confirmación del usuario. |
invalid_action | Se llama a una acción no válida. Por ejemplo, si el cliente llamó a action=complete antes de llamar a action=start y action=getClaimToken. |
invalid_params | Se especificaron parámetros no válidos en la solicitud. (Los parámetros desconocidos se deben ignorar de forma segura para la compatibilidad futura). Por ejemplo, devuelve esto si el cliente llamó a action=unknown o user=. |
device_config_error | La fecha y hora (o algún otro parámetro de configuración) son incorrectos en el dispositivo. El usuario debe ir (al sitio web interno del dispositivo) y configurar los parámetros del dispositivo. |
Sin conexión | Actualmente, el dispositivo no tiene conexión y no puede comunicarse con el servidor. |
server_error | Se produjo un error del servidor durante el proceso de registro. |
invalid_x_privet_token | X-Privet-Token no es válido o está vacío en la solicitud. |
El dispositivo DEBE dejar de exponer la API de /privet/register después de que se complete correctamente el registro. Si el dispositivo no expone la API de /privet/register, DEBE devolver un error HTTP 404. Por lo tanto, si un dispositivo ya está registrado, la llamada a esta API DEBE devolver el error 404. Si falta el encabezado X-Privet-Token, el dispositivo DEBE devolver un error HTTP 400.
4.4. API de /privet/accesstoken
La API de /privet/accesstoken es OPCIONAL. Es una solicitud HTTP GET. La API de /privet/accesstoken DEBE verificar si hay un encabezado "X-Privet-Token" válido. El dispositivo DEBE implementar esta API en la URL "/privet/accesstoken":GET /privet/accesstoken HTTP/1.1
Cuando el dispositivo recibe la llamada a la API de /accesstoken, debe llamar al servidor para recuperar el token de acceso del usuario determinado y devolver el token al cliente. Luego, el cliente usará el token de acceso para acceder a este dispositivo a través de la nube.
Los dispositivos de Cloud Print DEBEN llamar a la siguiente API:
/cloudprint/proximitytoken
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }
4.4.1. Entrada
La API de /privet/accesstoken tiene los siguientes parámetros de entrada:Nombre | Valor |
---|---|
usuario | Es el correo electrónico del usuario que intentó usar este token de acceso. Puede estar vacío en la solicitud. |
4.4.2. Volver
La API de /privet/accesstoken devuelve los siguientes datos:Nombre del valor | Tipo de valor | Descripción |
---|---|---|
token | string | Token de acceso que devuelve el servidor |
usuario | string | Es el mismo usuario que en el parámetro de entrada. |
expires_in | int | Cantidad de segundos hasta que vence este token. Se recibe del servidor y se pasa en esta respuesta. |
Ejemplo:
{ "token": "AAA111222333444555666777", "user": "user@domain.com", "expires_in": 600 }
4.4.3. Errores
La API de /privet/accesstoken puede devolver los siguientes errores (consulta la sección Errores para obtener más detalles):Error | Descripción |
---|---|
Sin conexión | El dispositivo no tiene conexión y no puede comunicarse con el servidor. |
access_denied | No tienes derechos suficientes. Acceso denegado El dispositivo debe devolver este error cuando el servidor rechaza explícitamente la solicitud. |
invalid_params | Se especificaron parámetros no válidos en la solicitud. (Los parámetros desconocidos se deben ignorar de forma segura para la compatibilidad futura). Por ejemplo, si el cliente llamó a /accesstoken?user= o /accesstoken. |
server_error | Error del servidor. |
invalid_x_privet_token | X-Privet-Token no es válido o está vacío en la solicitud. |
Si el dispositivo no expone la API de /privet/accesstoken, DEBE devolver un error HTTP 404. Si falta el encabezado X-Privet-Token, el dispositivo DEBE devolver un error HTTP 400.
4.5. API de /privet/capabilities
La API de /privet/capabilities es OPCIONAL. Es una solicitud HTTP GET. La API de /privet/capabilities DEBE verificar si hay un encabezado "X-Privet-Token" válido. El dispositivo DEBE implementar esta API en la URL "/privet/capabilities":GET /privet/capabilities HTTP/1.1
4.5.1. Entrada
La API de /privet/capabilities tiene los siguientes parámetros de entrada:Nombre | Valor |
---|---|
Sin conexión | (opcional) Solo puede ser "offline=1". En este caso, el dispositivo debería devolver las capacidades para el uso sin conexión (si son diferentes de las capacidades "en línea"). |
4.5.2. Volver
La API de /privet/capabilities devuelve las capacidades del dispositivo en formato JSON de Cloud Device Description (CDD) (consulta el documento de CDD para obtener más detalles). Las impresoras como mínimo DEBEN devolver una lista de los tipos admitidos aquí. Por ejemplo, una impresora compatible con Cloud que esté en línea en este momento puede devolver algo como lo siguiente (como mínimo):{ "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" } ] } }
Nota: Las impresoras expresan la prioridad de los tipos de contenido admitidos con el orden. Por ejemplo, en las muestras anteriores, la impresora especifica que prefiere los datos "application/pdf" a "image/pwg-raster" y "image/jpeg". Si es posible, los clientes deben respetar la priorización de la impresora (consulta el documento de CDD para obtener más detalles).
4.5.3. Errores
La API de /privet/capabilities puede devolver los siguientes errores (consulta la sección Errores para obtener más detalles):Error | Descripción |
---|---|
invalid_x_privet_token | X-Privet-Token no es válido o está vacío en la solicitud. |
Si el dispositivo no expone la API de /privet/capabilities, DEBE devolver un error HTTP 404. Si falta el encabezado X-Privet-Token, el dispositivo DEBE devolver un error HTTP 400.
4.6. Errores
Las APIs anteriores muestran los errores en el siguiente formato:Nombre del valor | Tipo de valor | Descripción |
---|---|---|
error | string | Tipo de error (definido por API) |
descripción | cadena (opcional) | Es una descripción del error legible por humanos. |
server_api | cadena (opcional) | En caso de error del servidor, este campo contiene la API del servidor que falló. |
server_code | int (opcional) | En caso de error del servidor, este campo contiene el código de error que devolvió el servidor. |
server_http_code | int (opcional) | En caso de error HTTP del servidor, este campo contiene el código de error HTTP que devolvió el servidor. |
tiempo de espera agotado | int (opcional) | Cantidad de segundos que el cliente debe esperar antes de reintentar (solo para errores recuperables). El cliente DEBE aleatorizar el tiempo de espera real a partir de este valor hasta un valor que sea un 20% mayor. |
Todas las APIs DEBEN devolver un error HTTP 400 si falta el encabezado X-Privet-Token.
HTTP/1.1 400 Falta el encabezado X-Privet-Token.
Ejemplo 1:
{ "error": "server_error", "description": "Service unavailable", "server_api": "/submit", "server_http_code": 503 }
Ejemplo 2:
{ "error": "printer_busy", "description": "Printer is currently printing other job", "timeout": 15 }
5. API de Printer
Uno de los tipos de dispositivos que admite este protocolo es el tipo de impresora. Los dispositivos que admiten este tipo PUEDEN implementar algunas funciones específicas para impresoras. Lo ideal es que la impresión en impresoras listas para imprimir en la nube se realice a través de un servidor de Cloud Print:

En algunos casos, es posible que un cliente necesite enviar un documento de forma local. Puede ser necesario cuando el cliente no tiene un ID de Google o no puede comunicarse con el servidor de Cloud Print. En ese caso, el trabajo de impresión se enviará de forma local a la impresora. A su vez, la impresora usará el servicio de Cloud Print para la conversión y la cola de trabajos. La impresora volverá a publicar el trabajo enviado de forma local en el servicio de Cloud Print y, luego, lo solicitará, ya que se envió a través de la nube. Este proceso proporcionará una experiencia del usuario flexible en términos de administración y seguimiento de trabajos de impresión (conversión) y de servicio.

Dado que el servicio de Cloud Print implementa la conversión, la impresora DEBE anunciar que admite todos los formatos de entrada ("*/*") entre la lista de los tipos de contenido admitidos:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
En algunos casos, se desea una solución completamente sin conexión. Dado que las impresoras admiten una cantidad limitada de formatos de entrada, un cliente deberá convertir los documentos a algunos formatos de impresora admitidos de forma nativa.

Esta especificación REQUIERE que todas las impresoras admitan al menos el formato PWG Raster (“image/pwg-raster”) para el caso de impresión sin conexión. Una impresora puede admitir otros formatos (por ejemplo, JPEG) y, si un cliente lo admite, puede enviar documentos en ese formato. La impresora DEBE exponer los tipos admitidos a través de la API de /capabilities, por ejemplo:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }
Impresión simple: El cliente envía el documento a través de la red local a la API de /submitdoc (sin especificar el parámetro job_id). El documento enviado se imprimirá con la configuración predeterminada del ticket de impresión y no se necesitarán estados del trabajo de impresión. Si la impresora SOLO admite este tipo de impresión, DEBE anunciar SOLO la API de /submitdoc en la respuesta de la API de /privet/info.
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
Impresión avanzada: El cliente primero debe crear un trabajo de impresión en la impresora llamando a la API de /privet/printer/createjob con un ticket de trabajo CJT válido en la solicitud. La impresora DEBE almacenar el ticket de impresión en la memoria y devolver un job_id al cliente. Luego, el cliente llamará a la API de /printer/submitdoc y especificará el job_id recibido anteriormente. En ese momento, la impresora comenzará a imprimir. El cliente sondeará la impresora para conocer el estado del trabajo de impresión llamando a la API de /privet/printer/jobstate.
En un entorno de varios clientes, no se garantiza cómo se llama a esta API. Es posible que un cliente llame a /createjob entre las llamadas /createjob->/submitdoc de otro cliente. Para eliminar posibles bloqueos y mejorar la usabilidad, recomendamos tener una pequeña cola de trabajos de impresión pendientes en la impresora (al menos de 3 a 5):
- /createjob toma el primer lugar disponible en la cola.
- El trabajo debe tener una vida útil (en la cola) de al menos 5 minutos.
- Si todos los lugares de la cola están ocupados, se quitará el trabajo más antiguo que no se haya impreso y se colocará uno nuevo en su lugar.
- Si hay un trabajo de impresión en curso en el dispositivo (impresión simple o avanzada), /submitdoc debe devolver el estado ocupado y proponer un tiempo de espera para volver a intentar este trabajo de impresión.
- Si /submitdoc hace referencia a un trabajo que se quitó de la cola (debido a un reemplazo o un tiempo de espera agotado), la impresora debe devolver un error invalid_print_job y el cliente volverá a intentar el proceso desde el paso /createjob. El cliente DEBE esperar un período de tiempo de espera aleatorio de hasta 5 segundos antes de volver a intentarlo.
Si las restricciones de memoria impiden almacenar varios trabajos pendientes en el dispositivo, es posible que haya una cola de 1 trabajo de impresión. Debe seguir el mismo protocolo que se indicó anteriormente. Después de que un trabajo se complete o falle con un error, la impresora debe almacenar información sobre el estado del trabajo durante al menos 5 minutos. El tamaño de la cola para almacenar los estados de los trabajos completados debe ser de al menos 10. Si hay más estados de trabajo que se deben almacenar, es posible que se quite el más antiguo de la cola antes de que se agote el tiempo de espera de 5 minutos.
Nota: Por el momento, los clientes sondearán el estado del trabajo. En el futuro, es posible que exijamos que la impresora envíe una notificación de DNS TXT cuando CAMBIE el estado de CUALQUIER trabajo de impresión.
5.1. API de /privet/printer/createjob
La API de /privet/printer/createjob es OPCIONAL (consulta la sección Impresión simple más arriba). Es una solicitud HTTP POST. La API de /privet/printer/createjob DEBE verificar si hay un encabezado "X-Privet-Token" válido. El dispositivo DEBE implementar esta API en la URL "/privet/printer/createjob":
POST /privet/printer/createjob HTTP/1.1
5.1.1. Entrada
La API de /privet/printer/createjob no tiene parámetros de entrada en la URL. El cuerpo de la solicitud debe contener los datos del ticket de trabajo de impresión en formato CJT.5.1.2. Volver
La API de /privet/printer/createjob devuelve los siguientes datos:Nombre del valor | Tipo de valor | Descripción |
---|---|---|
job_id | string | ID del trabajo de impresión recién creado. |
expires_in | int | Cantidad de segundos durante los que es válido este trabajo de impresión. |
Ejemplo:
{ "job_id": "123", "expires_in": 600 }
5.1.3. Errores
La API de /privet/printer/createjob puede devolver los siguientes errores (consulta la sección Errores para obtener más detalles):Error | Descripción |
---|---|
invalid_ticket | El boleto de impresión enviado no es válido. |
printer_busy | La impresora está ocupada y no puede procesar o crear el trabajo en este momento. Vuelve a intentarlo después de que se agote el tiempo de espera. |
printer_error | La impresora está en estado de error y requiere la interacción del usuario para solucionarlo. La descripción debe contener una explicación más detallada (p.ej., "Atasco de papel en la bandeja 1"). |
invalid_x_privet_token | X-Privet-Token no es válido o está vacío en la solicitud. |
Si el dispositivo no expone /privet/printer/createjob, DEBE devolver un error HTTP 404. Si falta el encabezado X-Privet-Token, el dispositivo DEBE devolver un error HTTP 400.
5.2. API de /privet/printer/submitdoc
La API de /privet/printer/submitdoc es OBLIGATORIA para implementar la impresión a través de una red local (sin conexión o volver a publicar en Cloud Print). Es una solicitud HTTP POST. La API de /privet/printer/submitdoc DEBE verificar si hay un encabezado "X-Privet-Token" válido. El dispositivo DEBE implementar esta API en la URL "/privet/printer/submitdoc":POST /privet/printer/submitdoc HTTP/1.1
Si la impresora no puede almacenar todos los datos en su búfer interno, DEBE usar mecanismos de TCP para ralentizar la transferencia de datos hasta que imprima una parte del documento, lo que hará que parte del búfer vuelva a estar disponible. (Por ejemplo, la impresora puede establecer windowsize=0 en las capas de TCP, lo que hará que el cliente espere).
Enviar un documento a la impresora puede tardar bastante tiempo. El cliente debe poder verificar el estado de la impresora y el trabajo (impresión avanzada) mientras la impresión está en curso. Para ello, la impresora DEBE permitir que el cliente llame a las APIs de /privet/info y /privet/printer/jobstate mientras procesa las llamadas a la API de /privet/printer/submitdoc. Se recomienda que todos los clientes inicien un nuevo subproceso para ejecutar la llamada a la API de /privet/printer/submitdoc, de modo que el subproceso principal pueda usar las APIs de /privet/info y /privet/printer/jobstate para verificar los estados de la impresora y del trabajo.
Nota: Una vez que se complete o se cancele el trabajo de impresión local, se recomienda (y será obligatorio en una versión futura de esta especificación) informar el estado final del trabajo a la interfaz /cloudprint/submit para fines de contabilidad y experiencia del usuario. Se requieren los parámetros "printerid", "title", "contentType" y "final_semantic_state" (en formato PrintJobState), y los parámetros "tag" (parámetro repetido) y "ticket" (el ticket del trabajo en formato CloudJobTicket). Ten en cuenta que el PrintJobState proporcionado debe ser final, es decir, su tipo debe ser DONE o ABORTED, y se debe proporcionar una causa en caso de que sea ABORTED (consulta JobState para obtener más detalles). También ten en cuenta que este uso de la interfaz /cloudprint/submit para informar trabajos de impresión locales no se menciona en su especificación porque esa sección tiene como objetivo describir el uso principal de la interfaz: enviar un trabajo de impresión con el documento que se imprimirá proporcionado en el parámetro "content".
5.2.1. Entrada
La API de /privet/printer/submitdoc tiene los siguientes parámetros de entrada:Nombre | Valor |
---|---|
job_id | ID de trabajo de impresión (opcional). Se puede omitir en el caso de impresión simple (consulta más arriba). Debe coincidir con el que devuelve la impresora. |
user_name | (opcional) Nombre de usuario legible. Esta no es definitiva y solo debe usarse para las anotaciones de trabajos de impresión. Si el trabajo se vuelve a publicar en el servicio de Cloud Print, esta cadena se debe adjuntar al trabajo de Cloud Print. |
client_name | (Opcional) Nombre de la aplicación cliente que realiza esta solicitud. Solo para fines de visualización. Si el trabajo se vuelve a publicar en el servicio de Cloud Print, esta cadena se debe adjuntar al trabajo de Cloud Print. |
job_name | (Opcional) Nombre del trabajo de impresión que se registrará. Si el trabajo se vuelve a publicar en el servicio de Cloud Print, esta cadena se debe adjuntar al trabajo de Cloud Print. |
Sin conexión | (Opcional) Solo puede ser "offline=1". En este caso, la impresora solo debe intentar imprimir sin conexión (no volver a publicar en el servidor de Cloud Print). |
El cuerpo de la solicitud debe contener un documento válido para imprimir. "Content-Length" debe incluir la longitud correcta de la solicitud. El encabezado "Content-Type" debe establecerse en el tipo de MIME del documento y coincidir con uno de los tipos del CDD (a menos que el CDD especifique "*/*").
Se RECOMIENDA ENORMEMENTE que los clientes proporcionen un nombre de usuario (o correo electrónico) válido, un nombre de cliente y un nombre de trabajo con esta solicitud. Esos campos solo se usan en las IU para mejorar la experiencia del usuario.
5.2.2. Volver
La API de /privet/printer/submitdoc devuelve los siguientes datos:Nombre del valor | Tipo de valor | Descripción |
---|---|---|
job_id | string | ID del trabajo de impresión recién creado (impresión simple) o job_id especificado en la solicitud (impresión avanzada). |
expires_in | int | Cantidad de segundos durante los que es válido este trabajo de impresión. |
job_type | string | Tipo de contenido del documento enviado. |
job_size | int de 64 bits | Tamaño de los datos de impresión en bytes. |
job_name | string | (opcional) Es el mismo nombre del trabajo que en la entrada (si hay alguno). |
Ejemplo:
{ "job_id": "123", "expires_in": 500, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
5.2.3. Errores
La API de /privet/printer/submitdoc puede devolver los siguientes errores (consulta la sección Errores para obtener más detalles):Error | Descripción |
---|---|
invalid_print_job | Se especificó un ID de trabajo no válido o vencido en la solicitud. Vuelve a intentarlo después del tiempo de espera. |
invalid_document_type | La impresora no admite el tipo de MIME del documento. |
invalid_document | El documento enviado no es válido. |
document_too_large | El documento supera el tamaño máximo permitido. |
printer_busy | La impresora está ocupada y no puede procesar el documento en este momento. Vuelve a intentarlo después de que se agote el tiempo de espera. |
printer_error | La impresora está en estado de error y requiere la interacción del usuario para solucionarlo. La descripción debe contener una explicación más detallada (p.ej., "Atasco de papel en la bandeja 1"). |
invalid_params | Se especificaron parámetros no válidos en la solicitud. (Los parámetros desconocidos se deben ignorar de forma segura para la compatibilidad futura). |
user_cancel | El usuario canceló explícitamente el proceso de impresión desde el dispositivo. |
server_error | No se pudo publicar el documento en Cloud Print. |
invalid_x_privet_token | X-Privet-Token no es válido o está vacío en la solicitud. |
Si el dispositivo no expone /privet/printer/submitdoc, DEBE devolver un error HTTP 404. Si falta el encabezado X-Privet-Token, el dispositivo DEBE devolver un error HTTP 400.
Nota: Es posible que la API de /privet/printer/submitdoc requiera un manejo especial del lado de la impresora (debido a la gran carga útil adjunta). En algunos casos (según la implementación y la plataforma del servidor HTTP de la impresora), es posible que la impresora cierre el socket ANTES de devolver el error HTTP. En otros casos, la impresora puede devolver un error 503 (en lugar de un error de Privet). Las impresoras DEBEN intentar devolver Privet tanto como sea posible. Sin embargo, todos los clientes que implementen la especificación de Privet DEBEN poder controlar el cierre de sockets (sin errores HTTP) y los casos de error HTTP 503 para la API de /privet/printer/submitdoc. En este caso, el cliente DEBE controlarlo como un error de Privet "printer_busy" con "timeout" establecido en 15 segundos. Para evitar reintentos infinitos, el cliente puede dejar de reintentar después de una cantidad razonable de intentos (por ejemplo, 3).
5.3. API de /privet/printer/jobstate
La API de /privet/printer/jobstate es OPCIONAL (consulta la sección Impresión simple más arriba). Es una solicitud HTTP GET. La API de /privet/printer/jobstate DEBE verificar si hay un encabezado "X-Privet-Token" válido. El dispositivo DEBE implementar esta API en la URL "/privet/printer/jobstate":GET /privet/printer/jobstate HTTP/1.1
5.3.1. Entrada
La API de /privet/printer/jobstate tiene los siguientes parámetros de entrada:Nombre | Valor |
---|---|
job_id | Es el ID del trabajo de impresión para el que se devolverá el estado. |
5.3.2. Volver
La API de /privet/printer/jobstate devuelve los siguientes datos:Nombre del valor | Tipo de valor | Descripción |
---|---|---|
job_id | string | Es el ID del trabajo de impresión para el que se proporciona información de estado. |
state | string | draft: Se creó el trabajo de impresión en el dispositivo (aún no se recibieron llamadas de /privet/printer/submitdoc).
queued: Se recibió y se puso en cola el trabajo de impresión, pero aún no comenzó la impresión. in_progress: El trabajo de impresión está en curso. stopped: El trabajo de impresión se pausó, pero se puede reiniciar de forma manual o automática. done: El trabajo de impresión finalizó. aborted: Falló el trabajo de impresión. |
descripción | string | (Opcional) Es una descripción legible del estado del trabajo de impresión. Debe incluir información adicional si state es stopped o aborted. Por lo general, el campo semantic_state proporciona una descripción mejor y más significativa para el cliente. |
expires_in | int | Cantidad de segundos durante los que es válido este trabajo de impresión. |
job_type | string | (Opcional) Tipo de contenido del documento enviado. |
job_size | int de 64 bits | Tamaño de los datos de impresión en bytes (opcional). |
job_name | string | (opcional) Es el mismo nombre del trabajo que en la entrada (si hay alguno). |
server_job_id | string | (Opcional) ID del trabajo que devolvió el servidor (si el trabajo se publicó en el servicio de Cloud Print). Se omite para la impresión sin conexión. |
semantic_state | JSON | (Opcional) Es el estado semántico del trabajo en formato PrintJobState. |
Ejemplo (impresión por informes a través de Cloud Print):
{ "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" }
Ejemplo (error de impresión sin conexión):
{ "job_id": "123", "state": "stopped", "description": "Out of paper", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
Ejemplo (el usuario anuló el trabajo de impresión):
{ "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 } }
Ejemplo (se detuvo el trabajo de impresión porque se acabó el papel). Observa la referencia al estado del dispositivo. El cliente deberá llamar a la API de /privet/info para obtener más detalles sobre el estado del dispositivo:
{ "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. Errores
La API de /privet/printer/jobstate puede devolver los siguientes errores (consulta la sección Errores para obtener más detalles):Error | Descripción |
---|---|
invalid_print_job | Se especificó un ID de trabajo no válido o vencido en la solicitud. |
server_error | No se pudo obtener el estado del trabajo de impresión (para los trabajos de impresión publicados en Cloud Print). |
invalid_x_privet_token | X-Privet-Token no es válido o está vacío en la solicitud. |
Si el dispositivo no expone /privet/printer/jobstate, DEBE devolver un error HTTP 404. Si falta el encabezado X-Privet-Token, el dispositivo DEBE devolver un error HTTP 400.
6. Apéndice
6.1. Comportamiento y configuración predeterminados
En esta sección, se explicará el comportamiento predeterminado que esperamos de TODOS los dispositivos compatibles con Privet.- Los dispositivos listos para usar solo deben admitir las APIs de /privet/info y /privet/register. Todas las demás APIs (p.ej., /privet/accesstoken, impresión local) deben inhabilitarse.
- El registro requiere interacción física con un dispositivo.
- El usuario DEBE realizar una acción física en el dispositivo (p.ej., presionar un botón) para confirmar su acceso al dispositivo.
- Después de que el usuario realice la acción mencionada anteriormente, la impresora debe enviar la solicitud /cloudprint/register. No debe enviar esta solicitud hasta después de que se realice la acción (consulta el diagrama de secuencia 1).
- Si el dispositivo está procesando una solicitud de /privet/register (por ejemplo, si está esperando la acción anterior), debe rechazar todas las demás solicitudes de /privet/register. En este caso, el dispositivo DEBE devolver el error device_busy.
- El dispositivo debe agotar el tiempo de espera de cualquier solicitud /register que no reciba la acción física mencionada anteriormente en un plazo de 60 segundos. En este caso, el dispositivo DEBE devolver el error confirmation_timeout.
- Opcional: Las siguientes opciones son recomendadas, pero no obligatorias, y pueden mejorar la experiencia del usuario:
- Es posible que la impresora parpadee o que su pantalla indique que el usuario debe realizar una acción para confirmar el registro.
- Es posible que la impresora muestre en su pantalla el mensaje "Se está registrando en Google Cloud Print para el usuario "abc@def.com" - presione Aceptar para continuar", en el que abc@def.com es el parámetro del usuario de la llamada a la API de /register. Esto le dejaría más claro al usuario que:
- es su solicitud de registro la que está confirmando
- qué sucede si no activó la solicitud.
- Además de una acción física para confirmar desde la impresora (p.ej., “Presiona el botón Aceptar”), una impresora también puede ofrecerle al usuario un botón para cancelar la solicitud (p.ej., Presiona Cancelar para rechazarla"). Esto permitiría que los usuarios que no activaron la solicitud de registro la cancelen antes del tiempo de espera de 60 segundos. En este caso, el dispositivo DEBE devolver el error user_cancel.
- Transferencias de propiedad:
- Es posible que el dispositivo se haya borrado explícitamente del servicio de Cloud.
- Si el dispositivo recibe una respuesta correcta, pero no una descripción del dispositivo como resultado de la llamada a /cloudprint/printer (para GCP), DEBE volver al modo predeterminado (listo para usar).
- Si las credenciales del dispositivo ya no funcionan (explícitamente debido a la respuesta "credenciales no válidas" del servidor), DEBE volver al modo predeterminado (listo para usar).
- El restablecimiento de la configuración de fábrica LOCAL DEBE borrar las credenciales del dispositivo y establecerlo en el estado predeterminado.
- Opcional: Es posible que el dispositivo proporcione un elemento de menú para borrar las credenciales y ponerlo en modo predeterminado.
- Los dispositivos que admiten notificaciones XMPP DEBEN incluir la capacidad de hacer ping al servidor. El tiempo de espera de ping DEBE poder controlarse desde el servidor a través de "local_settings".
- El dispositivo puede hacer ping explícitamente al servidor (/cloudprint/printer API para GCP, además de los pings de XMPP) no más de una vez al día (24 horas) para asegurarse de que estén sincronizados. Se recomienda aleatorizar la ventana de verificación dentro de un período de 24 a 32 horas.
- Opcional: En el caso de los dispositivos de Cloud Print, se recomienda, pero no es obligatorio, tener una forma manual (botón) para permitir que el usuario inicie una verificación de nuevos trabajos de impresión desde el dispositivo. Algunas impresoras ya tienen esta función.
- Opcional. Es posible que las impresoras empresariales tengan una opción para inhabilitar por completo la detección local. En ese caso, el dispositivo DEBE actualizar estos parámetros de configuración locales en el servidor. Los nuevos parámetros de configuración locales DEBEN estar vacíos (establecer "local_discovery" en "false" significa que se pueden volver a habilitar desde el servicio de GCP).
6.1.2 Diagrama de registro predeterminado

6.2. Ataques de XSSI y XSRF, y su prevención
En esta sección, se explicará la posibilidad de ataques de XSSI y XSRF en el dispositivo, y cómo protegerse de ellos (incluidas las técnicas de generación de tokens).Aquí encontrarás más detalles: http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
Normalmente, los ataques de XSSI y XSRF son posibles cuando un sitio usa mecanismos de autenticación de cookies. Si bien Google no usa cookies con su servicio Cloud Print, estos ataques siguen siendo posibles. Por diseño, el acceso a la red local confía implícitamente en las solicitudes.
6.2.1. XSSI
Es posible que un sitio web malicioso adivine la dirección IP y el número de puerto de un dispositivo compatible con Privet y que intente llamar a la API de Privet con "src=<nombre de la API>" dentro de una etiqueta <script>:<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>
Para evitar este tipo de ataque, TODAS las llamadas a la API de Privet DEBEN requerir el encabezado "X-Privet-Token" en la solicitud. Las etiquetas de secuencia de comandos "src=<api>" no pueden agregar encabezados, lo que protege de manera eficaz contra este tipo de ataque.
6.2.2. XSRF
http://en.wikipedia.org/wiki/Cross-site_request_forgeryEs posible que un sitio web malicioso adivine la dirección IP y el número de puerto de un dispositivo compatible con Privet y trate de llamar a la API de Privet con un <iframe>, formularios o algún otro mecanismo de carga entre sitios web. Los atacantes no podrían acceder a los resultados de la solicitud, pero, si la solicitud realizara una acción (p.ej., imprimir), podrían activarla.
Para evitar este ataque, necesitamos la siguiente protección:
- Dejar la API de /privet/info abierta a XSRF
- La API de /privet/info NO DEBE realizar ninguna acción en el dispositivo.
- Usa la API de /privet/info para recibir x-privet-token
- Todas las demás APIs DEBEN verificar si hay un x-privet-token válido en el encabezado "X-Privet-Token".
- x-privet-token DEBE ser válido solo durante 24 horas.
Incluso si un atacante puede ejecutar la API de /privet/info, no podrá leer x-privet-token de la respuesta y, por lo tanto, no podrá llamar a ninguna otra API.
Se recomienda generar el token de XSRF con el siguiente algoritmo:
XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )
Elementos de generación de tokens de XSRF:
- DELIMITER es un carácter especial, por lo general, “:”.
- issue_timecounter es una cantidad de segundos desde algún evento (época para la marca de tiempo) o la hora de inicio del dispositivo (para los contadores de CPU). issue_timecounter aumenta constantemente cuando el dispositivo está en funcionamiento (consulta la verificación de tokens a continuación).
- SHA1: Función hash que usa el algoritmo SHA1
- base64: Codificación en base64
- device_secret: Es un secreto específico del dispositivo. El secreto del dispositivo SE DEBE actualizar en cada reinicio.
Estas son las formas recomendadas de generar el secreto del dispositivo:
- Genera un UUID nuevo cada vez que se reinicia
- Genera un número aleatorio de 64 bits en cada reinicio
No es necesario que el dispositivo almacene todos los tokens de XSRF que emitió. Cuando el dispositivo necesita verificar la validez de un token de XSRF, debe decodificarlo en base64. Obtén el issue_timecounter de la segunda mitad (texto sin formato) y trata de generar el hash SHA1 de device_secret + DELIMITER + issue_timecounter, donde issue_timecounter proviene del token. Si el SHA1 recién generado coincide con el del token, el dispositivo debe verificar si el issue_timecounter se encuentra dentro del período de validez (24 horas) del contador de tiempo actual. Para ello, el dispositivo toma el contador de tiempo actual (por ejemplo, el contador de la CPU) y le resta issue_timecounter. El resultado DEBE ser la cantidad de segundos transcurridos desde la emisión del token.
Importante: Esta es la forma recomendada de implementar la protección contra XSRF. Los clientes de la especificación de Privet no deben intentar comprender el token de XSRF, sino que deben tratarlo como una caja negra. En la figura 6.2.3, se ilustra una forma recomendada de implementar el token X-Privet y la verificación de una solicitud típica.
6.2.3 Diagrama de secuencia de generación y verificación de tokens X-Privet

6.3. Diagramas de flujo de trabajo
En esta sección, se ilustrará un flujo de trabajo en diferentes casos.6.3.1. Flujo de trabajo de la impresora lista para usar

6.3.2. Inicio de la impresora registrada

6.3.3 Flujo de trabajo de administración de notificaciones XMPP

6.3.4. Flujo de trabajo para verificar la configuración de la impresora
