Privet é uma API de descoberta local de dispositivos na nuvem usada por serviços de nuvem. Este documento é organizado nas seguintes seções:
- Introdução: introdução ao Privet
- Discovery: mecanismos de descoberta local
- Avisos: avisos de descoberta local
- API: APIs Privet para dispositivos gerais na nuvem
- API Printer: APIs Privet usadas por impressoras.
- Apêndice: diagramas complementares
1. Introdução
Os dispositivos conectados à nuvem têm muitos benefícios. Eles podem usar serviços de conversão on-line, hospedar filas de trabalhos enquanto o dispositivo está off-line e ser acessados de qualquer lugar do mundo. No entanto, com muitos dispositivos de nuvem acessíveis por um determinado usuário, precisamos fornecer um método para encontrar o dispositivo mais próximo com base na localização. O objetivo do protocolo Privet é unir a flexibilidade dos dispositivos de nuvem com um mecanismo de descoberta local adequado para que os dispositivos sejam facilmente descobertos em novos ambientes.
As metas deste protocolo são:- tornar os dispositivos na nuvem detectáveis localmente
- registrar dispositivos na nuvem com um serviço na nuvem
- associar dispositivos registrados à representação deles na nuvem;
- ativar a funcionalidade off-line.
- simplificar a implementação para que dispositivos pequenos possam usá-lo
O protocolo Privet consiste em duas partes principais: descoberta e API. A descoberta é usada para encontrar o dispositivo na rede local, e a API é usada para receber informações sobre o dispositivo e realizar algumas ações. Neste documento, o dispositivo se refere a um dispositivo conectado à nuvem que implementa o protocolo Privet.
2. Discovery
A descoberta é um protocolo baseado em zeroconf (mDNS + DNS-SD). O dispositivo PRECISA implementar o endereçamento link-local IPv4. O dispositivo PRECISA estar em conformidade com as especificações mDNS e 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)
O dispositivo PRECISA realizar a resolução de conflitos de nomes de acordo com as especificações acima.
2.1. Tipo de serviço
A descoberta de serviços DNS usa o seguinte formato para tipos de serviço: _applicationprotocol._transportprotocol. No caso do protocolo Privet, o tipo de serviço para DNS-SD deve ser: _privet._tcp
O dispositivo também pode implementar outros tipos de serviço. Recomendamos usar o mesmo nome de instância de serviço para todos os tipos de serviço implementados pelo dispositivo. Por exemplo, uma impressora pode implementar os serviços "Printer XYZ._privet._tcp" e "Printer XYZ._printer._tcp". Isso vai simplificar a configuração para o usuário. No entanto, os clientes Privet procuram apenas por "_privet._tcp".
Além do tipo de serviço principal, o dispositivo PRECISA anunciar os registros PTR para os subtipos correspondentes (consulte a especificação DNS-SD: "7.1. Enumeração seletiva de instâncias (subtipos)"). O formato precisa ser: _<subtype>._sub._privet._tcp
No momento, o único subtipo de dispositivo compatível é printer. Portanto, todas as impressoras PRECISAM anunciar dois registros PTR:
- _privet._tcp.local.
- _printer._sub._privet._tcp.local.
2.2. Registro TXT
A descoberta de serviços DNS define campos para adicionar informações opcionais sobre um serviço nos registros TXT. Um registro TXT consiste em pares de chave/valor. Cada par chave/valor começa com o byte de comprimento, seguido por até 255 bytes de texto. A chave é o texto antes do primeiro caractere "=", e o valor é o texto após o primeiro caractere "=" até o final. A especificação permite que não haja valor no registro. Nesse caso, não haverá o caractere "=" OU não haverá texto após o caractere "=". Consulte a especificação DNS-SD: "6.1. Regras gerais de formato para registros TXT do DNS" para o formato de registro TXT do DNS e "6.2. Tamanho do registro TXT DNS-SD" para o comprimento recomendado).
O Privet exige que o dispositivo envie os seguintes pares de chave-valor no registro TXT. As strings de chave/valor não diferenciam maiúsculas de minúsculas. Por exemplo, "CS=online" e "cs=ONLINE" são iguais. As informações no registro TXT precisam ser as mesmas acessíveis pela API /info (consulte 4.1. seção "API").
Recomendamos manter o tamanho do registro TXT abaixo de 512 bytes.
2.2.1. txtvers
Versão da estrutura TXT. txtvers PRECISA ser o primeiro registro da estrutura TXT. No momento, a única versão compatível é a 1.
txtvers=1
2.2.2. ty
Fornece um nome legível para o usuário do dispositivo. Exemplo:
ty=Google Cloud Ready Printer Model XYZ
2.2.3. note (opcional)
Fornece um nome legível para o usuário do dispositivo. Exemplo:
note=1st floor lobby printer
Observação:essa é uma chave opcional e pode ser ignorada. No entanto, se presente, o usuário DEVE poder modificar esse valor. A mesma descrição PRECISA ser usada ao registrar o dispositivo.
2.2.4. url
URL do servidor a que este dispositivo está conectado (incluindo o protocolo). Exemplo:
url=https://www.google.com/cloudprint
2.2.5. type
Lista separada por vírgulas de subtipos de dispositivos compatíveis com este dispositivo. O formato é: "type=_subtype1,_subtype2". No momento, o único subtipo de dispositivo compatível é printer.
type=printer
Cada subtipo listado precisa ser anunciado usando um registro PTR correspondente. Para cada subtipo de serviço compatível, deve haver um item correspondente. O nome do subtipo de serviço (<subtype>._sub._privet._tcp) precisa ser igual ao tipo de dispositivo aqui.
2.2.6. id
ID do dispositivo. Se o dispositivo ainda não tiver sido registrado, essa chave vai estar presente, mas o valor vai estar vazio. Exemplo:
id=11111111-2222-3333-4444-555555555555 id=
2.2.7. cs
Indica o estado atual da conexão do dispositivo. Quatro valores possíveis são definidos nesta especificação.
- "online" indica que o dispositivo está conectado à nuvem.
- "offline" indica que o dispositivo está disponível na rede local, mas não consegue se comunicar com o servidor.
- "conectando" indica que o dispositivo está executando a sequência de inicialização e ainda não está totalmente on-line.
- "not-configured" indica que o acesso à Internet do dispositivo ainda não foi configurado. Esse valor não é usado no momento, mas pode ser útil em versões futuras da especificação.
- cs=online
- cs=offline
- cs=connecting
Se o dispositivo tiver sido registrado em uma nuvem, na inicialização, ele vai verificar a conectividade com um servidor para detectar o estado da conexão (por exemplo, chamando a API de nuvem para receber as configurações do dispositivo). O dispositivo pode usar o estado da conexão do canal de notificações (por exemplo, XMPP) para informar esse valor. Dispositivos não registrados na inicialização podem fazer ping em um domínio para detectar o estado da conexão. Por exemplo, faça ping em www.google.com para dispositivos de impressão na nuvem.
3. Anúncios
Na inicialização, no desligamento ou na mudança de estado do dispositivo, ele PRECISA executar a etapa de anúncio, conforme descrito na especificação mDNS. Ele DEVE enviar o anúncio correspondente pelo menos duas vezes com um intervalo de pelo menos um segundo entre eles.
3.1. Inicialização
Na inicialização do dispositivo, ele PRECISA realizar as etapas de sondagem e anúncio, conforme descrito na especificação mDNS. Nesse caso, os registros SRV, PTR e TXT precisam ser enviados. Recomendamos agrupar todos os registros em uma resposta de DNS, se possível. Caso contrário, a ordem recomendada é: SRV, PTR e TXT.
3.2. Encerrar
Ao desligar o dispositivo, ele DEVE tentar notificar todas as partes interessadas enviando um "pacote de despedida" com TTL=0 (conforme descrito na documentação do mDNS).
3.3. Atualizar
Se alguma informação descrita no TXT mudar, o dispositivo PRECISA enviar um anúncio de atualização. Basta enviar apenas o novo registro TXT nesse caso. Por exemplo, depois que um dispositivo é registrado, ele PRECISA enviar um anúncio de atualização incluindo o novo ID do dispositivo.
4. API
Depois que um dispositivo de nuvem é descoberto, a comunicação do cliente é ativada diretamente com ele pela rede local. Todas as APIs são baseadas em HTTP 1.1. Os formatos de dados são baseados em JSON. As solicitações de API podem ser GET ou POST.
Cada solicitação PRECISA conter um cabeçalho "X-Privet-Token" válido. A ÚNICA solicitação permitida a ter um cabeçalho "X-Privet-Token" vazio é a solicitação /privet/info. Observe que o cabeçalho AINDA precisa estar presente. Se o cabeçalho "X-Privet-Token" estiver faltando, o dispositivo PRECISA responder com o seguinte erro HTTP 400:
HTTP/1.1 400 Missing X-Privet-Token header.
Se o cabeçalho "X-Privet-Token" estiver vazio ou inválido, o dispositivo PRECISA responder com "invalid X-Privet-Token error" (invalid_x_privet_token, consulte a seção "Erros" para detalhes). A única exceção é a API /info. Para mais informações sobre por que isso é feito e como os tokens devem ser gerados, consulte o Apêndice A: ataques e prevenção de XSSI e XSRF.
Se uma API solicitada não existir ou não for compatível, o dispositivo precisará retornar um erro HTTP 404.
4.1. de disponibilidade da API
Antes de qualquer API ser exposta (incluindo a API /info), o dispositivo PRECISA entrar em contato com o servidor para verificar as configurações locais. As configurações locais PRECISAM ser preservadas entre reinicializações. Se o servidor não estiver disponível, as últimas configurações locais conhecidas deverão ser usadas. Se o dispositivo ainda não tiver sido registrado, ele vai seguir as configurações padrão.
Os dispositivos do Cloud Print PRECISAM seguir as etapas abaixo para registrar, receber e atualizar as configurações locais.
4.1.1. Registro
Quando o dispositivo se registra, ele PRECISA especificar o parâmetro "local_settings", da seguinte forma:
{ "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 } }
Nome do valor | Tipo de valor | Descrição |
---|---|---|
local_discovery | booleano | Indica se a funcionalidade de descoberta local é permitida. Se for "false", todas as APIs locais (incluindo /info) e a descoberta DNS-SD precisam ser desativadas. Por padrão, os dispositivos recém-registrados transmitem "true". |
access_token_enabled | booleano (opcional) | Indica se a API /accesstoken deve ser exposta na rede local. O padrão é "true". |
printer/local_printing_enabled | booleano (opcional) | Indica se a funcionalidade de impressão local (/printer/createjob, /printer/submitdoc, /printer/jobstate) deve ser exposta na rede local. O padrão é "true". |
printer/conversion_printing_enabled | booleano (opcional) | Indica se a impressão local pode enviar o job para o servidor para conversão. Só faz sentido quando a impressão local está ativada. |
xmpp_timeout_value | int (opcional) | Indica o número de segundos entre os pings do canal XMPP. Por padrão, precisa ser de 300 (5 minutos) ou mais. |
Importante:a falta de um valor opcional indica que a funcionalidade correspondente não é compatível com o dispositivo.
4.1.2. Inicialização
Na inicialização do dispositivo, ele precisa entrar em contato com o servidor para verificar quais APIs estão disponíveis para serem expostas na rede local. Para impressoras conectadas ao Cloud Print, chame:
/cloudprint/printer?printerid=<printer_id>
/cloudprint/list
/cloudprint/printer é preferível a /cloudprint/list, mas ambos funcionam.
Essa API retorna os parâmetros atuais do dispositivo, incluindo configurações para a API local. A resposta do servidor terá o seguinte 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 } }
O objeto "current" indica as configurações em vigor no momento.
O objeto "pending" indica as configurações que precisam ser aplicadas ao dispositivo. Esse objeto pode estar ausente.
Quando o dispositivo encontrar configurações "pendentes", ele DEVE atualizar o estado (veja abaixo).
4.1.3. Atualizar
Se for necessário atualizar as configurações, uma notificação XMPP será enviada ao dispositivo. A notificação vai estar no seguinte formato:
<device_id>/update_settings
Ao receber essa notificação, o dispositivo PRECISA consultar o servidor para receber as configurações mais recentes. Os dispositivos do Cloud Print PRECISAM usar:
/cloudprint/printer?printerid=<printer_id>
Quando o dispositivo vê a seção "pendente" como resultado da API /cloudprint/printer (na inicialização ou devido à notificação), ele PRECISA atualizar o estado interno para lembrar as novas configurações. Ele PRECISA chamar a API do servidor para confirmar as novas configurações. Para impressoras na nuvem, o dispositivo PRECISA chamar a API /cloudprint/update e usar o parâmetro "local_settings" como durante o registro.
Ao se reconectar ao canal XMPP, o dispositivo PRECISA chamar a API /cloudprint/printer para verificar se as configurações locais foram alteradas desde a última vez.
4.1.3.1. Configurações locais pendentes
O parâmetro "local_settings" que o dispositivo usa para chamar a API do servidor NUNCA pode conter a seção "pending".
4.1.3.2. Local Settings Current
SOMENTE o dispositivo pode mudar a seção "atual" de "local_settings". Todos os outros vão mudar a seção "pendente" e aguardar até que as mudanças sejam propagadas para a seção "atual" pelo dispositivo.
4.1.4. Off-line
Quando não for possível entrar em contato com o servidor durante a inicialização, após a notificação, o dispositivo DEVE usar as últimas configurações locais conhecidas.
4.1.5. Excluir o dispositivo do serviço
Se o dispositivo tiver sido excluído do serviço (GCP, por exemplo), uma notificação XMPP será enviada para ele. A notificação vai estar no seguinte formato:
<device_id>/delete
Ao receber essa notificação, o dispositivo PRECISA acessar o servidor para verificar o estado. Os dispositivos do Cloud Print precisam usar:
/cloudprint/printer?printerid=<printer_id>
O dispositivo PRECISA receber uma resposta HTTP bem-sucedida com success=false e sem descrição do dispositivo/impressora. Isso significa que o dispositivo foi removido do servidor e PRECISA apagar as credenciais e entrar no modo de configurações padrão de fábrica.
SEMPRE que o dispositivo receber uma resposta indicando que ele foi excluído como resultado da API /cloudprint/printer (inicialização, notificação de atualização de configurações, ping diário), ele DEVERÁ excluir as credenciais e entrar no modo padrão.
4.2. API /privet/info
A API de informações é OBRIGATÓRIA e precisa ser implementada por todos os dispositivos. É uma solicitação HTTP GET para o URL "/privet/info": GET /privet/info HTTP/1.1
A API de informações retorna informações básicas sobre um dispositivo e a funcionalidade que ele oferece suporte. Essa API NÃO PODE mudar o status do dispositivo nem realizar nenhuma ação, já que é vulnerável a ataques XSRF. Essa é a ÚNICA API que pode ter um cabeçalho "X-Privet-Token" vazio. Os clientes precisam chamar a API /privet/info com o cabeçalho "X-Privet-Token" definido como X-Privet-Token: ""
A API de informações PRECISA retornar dados consistentes com os disponíveis no registro TXT durante a descoberta.
4.2.1. Entrada
A API /privet/info não tem parâmetros de entrada.
4.2.2. Retornar
A API /privet/info retorna informações básicas sobre o dispositivo e a funcionalidade compatível.
A coluna TXT indica o campo correspondente no registro TXT do DNS-SD.
Nome do valor | Tipo de valor | Descrição | TXT |
---|---|---|---|
version | string | Versão mais recente (principal.secundária) da API compatível, atualmente 1.0 | |
nome | string | Nome legível do dispositivo. | ty |
descrição | string | (opcional) Descrição do dispositivo. PRECISA ser modificável pelo usuário. | nota |
url | string | URL do servidor com que este dispositivo está se comunicando. O URL PRECISA incluir a especificação do protocolo, por exemplo: https://www.google.com/cloudprint. | url |
tipo | lista de strings | Lista de tipos de dispositivos compatíveis. | tipo |
id | string | ID do dispositivo, vazio se o dispositivo ainda não tiver sido registrado. | id |
device_state | string | Estado do dispositivo. idle significa que o dispositivo está pronto processing significa que o dispositivo está ocupado e a funcionalidade pode ser limitada por algum tempo stopped significa que o dispositivo não está funcionando e é necessária a intervenção do usuário | |
connection_state | string | Estado da conexão com o servidor (base_url)
online: conexão disponível offline: sem conexão connecting: realizando etapas de inicialização not-configured: a conexão ainda não foi configurada Um dispositivo registrado pode informar o estado da conexão com base no estado do canal de notificação (por exemplo, estado da conexão XMPP). | cs |
fabricante | string | Nome do fabricante do dispositivo | |
modelo | string | Modelo do dispositivo | |
serial_number | string | Identificador exclusivo do dispositivo. Nesta especificação, ele PRECISA ser
um UUID. (Especificação do GCP 1.1)
(opcional) Recomendamos usar o mesmo ID de número de série em todos os lugares para que diferentes clientes possam identificar o mesmo dispositivo. Por exemplo, impressoras que implementam IPP podem usar esse ID de número de série no campo "printer-device-id". | |
firmware | string | Versão do firmware do dispositivo | |
tempo de atividade | int | Número de segundos desde a inicialização do dispositivo. | |
setup_url | string | (opcional) URL (incluindo o protocolo) da página com instruções de configuração | |
support_url | string | (opcional) URL (incluindo protocolo) da página com suporte, informações de perguntas frequentes | |
update_url | string | (opcional) URL (incluindo o protocolo) da página com instruções de atualização do firmware | |
x-privet-token | string | Valor do cabeçalho X-Privet-Token que precisa ser transmitido a todas as APIs para evitar ataques XSSI e XSRF. Consulte 6.1 para mais detalhes. | |
api | descrição das APIs | Lista de APIs compatíveis (descritas abaixo) | |
semantic_state | JSON | (Opcional) Estado semântico do dispositivo no formato CloudDeviceState. |
api: é uma lista JSON que contém as APIs disponíveis na rede local. Nem todas as APIs podem estar disponíveis ao mesmo tempo na rede local. Por exemplo, um dispositivo conectado recentemente só pode oferecer suporte à API /register:
"api": [ "/privet/register", ]
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
As seguintes APIs estão disponíveis no momento:
- /privet/register: API para registro de dispositivos na rede local. Consulte a API /privet/register para mais detalhes. Essa API PRECISA ser ocultada quando o dispositivo for registrado com êxito na nuvem.
- /privet/accesstoken: API para solicitar um token de acesso do dispositivo. Consulte a API /privet/accesstoken para mais detalhes.
- /privet/capabilities: API para recuperar recursos do dispositivo. Consulte a API /privet/capabilities para mais detalhes.
- /privet/printer/*: API específica para o tipo de dispositivo "impressora". Consulte as APIs específicas da impressora para mais detalhes.
{ "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. Erros
A API /privet/info SÓ vai retornar um erro se o cabeçalho X-Privet-Token estiver faltando. Ele PRECISA ser um erro HTTP 400:
HTTP/1.1 400 Missing X-Privet-Token header.
4.3. API /privet/register
A API /privet/register é OPCIONAL. É uma solicitação HTTP POST. A API /privet/register PRECISA verificar um cabeçalho X-Privet-Token válido. O dispositivo PRECISA implementar essa API no 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
O dispositivo só deve expor a API /privet/register quando permitir o registro anônimo no momento. Exemplo:
- Quando o dispositivo é ligado (ou depois de clicar em um botão especial nele) e ainda não foi registrado, ele expõe a API /privet/register para permitir que um usuário da rede local reivindique a impressora.
- Depois que o registro for concluído, o dispositivo vai parar de expor a API /privet/register para evitar que outro usuário na rede local reivindique o dispositivo.
- Alguns dispositivos podem ter maneiras diferentes de registrar dispositivos e não devem expor a API /privet/register (por exemplo, o conector do Chrome Cloud Print).
O processo de registro consiste em três etapas (consulte o registro anônimo do Cloud Print).
- Inicie o processo de registro anônimo.
- Um cliente inicia esse processo chamando a API /privet/register. O dispositivo pode aguardar a confirmação do usuário nesse momento.
- Recebe um token de reivindicação.
O cliente faz uma pesquisa para descobrir quando o dispositivo está pronto para continuar. Quando o dispositivo está pronto, ele envia uma solicitação ao servidor para recuperar o token e o URL de registro. O token e o URL recebidos DEVEM ser retornados ao cliente. Durante essa etapa, se o dispositivo receber outra chamada para inicializar o registro, ele deverá:
- Se for o mesmo usuário que iniciou o registro, descarte todos os dados anteriores (se houver) e inicie um novo processo de registro.
- Se for um usuário diferente, retorne o erro device_busy e um tempo limite de 30 segundos.
Conclua o processo de registro.
Depois que o cliente reivindicar o dispositivo, ele precisará notificar o dispositivo para concluir o registro. Depois que o processo de registro for concluído, o dispositivo vai enviar um anúncio de atualização, incluindo o ID recém-adquirido.
Observação: quando o dispositivo está processando uma chamada de API /privet/register, nenhuma outra chamada de API /privet/register pode ser processada simultaneamente. O dispositivo PRECISA retornar o erro device_busy e um tempo limite de 30 segundos.
É MUITO recomendável que o usuário confirme o registro no dispositivo. Se implementado, o dispositivo PRECISA aguardar a confirmação do usuário APÓS receber uma chamada de API /privet/register?action=start. O cliente vai chamar a API /privet/register?action=getClaimToken para saber quando a confirmação do usuário for concluída e o token de reivindicação estiver disponível. Se o usuário cancelar o registro no dispositivo (por exemplo, pressionar o botão "Cancelar"), o erro user_cancel precisará ser retornado. Se o usuário não confirmar o registro em um determinado período, o erro confirmation_timeout DEVERÁ ser retornado. Consulte a seção de padrões para mais detalhes.
4.3.1. Entrada
A API /privet/register tem os seguintes parâmetros de entrada:Nome | Valor |
---|---|
ação | Pode ser um dos seguintes:
start: para iniciar o processo de registro getClaimToken: para recuperar o token de reivindicação do dispositivo cancel: para cancelar o processo de registro complete: para concluir o processo de registro |
usuário | E-mail do usuário que vai reivindicar o dispositivo. |
O dispositivo PRECISA verificar se o endereço de e-mail de todas as ações (start, getClaimToken, cancel, complete) corresponde.
4.3.2. Retornar
A API /privet/register retorna os seguintes dados:Nome do valor | Tipo de valor | Descrição |
---|---|---|
ação | string | Mesma ação do parâmetro de entrada. |
usuário | string (opcional) | O mesmo usuário do parâmetro de entrada (pode estar ausente se omitido na entrada). |
token | string (opcional) | Token de registro (obrigatório para a resposta "getClaimToken", omitido para "start", "complete", "cancel"). |
claim_url | string (opcional) | URL de registro (obrigatório para a resposta "getClaimToken", omitido para "start", "complete", "cancel"). Para impressoras na nuvem, ele precisa ser o "complete_invite_url" recebido do servidor. |
automated_claim_url | string (opcional) | URL de registro (obrigatório para a resposta "getClaimToken", omitido para "start", "complete", "cancel"). Para impressoras na nuvem, ele precisa ser o "automated_invite_url" recebido do servidor. |
device_id | string (opcional) | Novo ID do dispositivo (omitido para a resposta "start", obrigatório para "complete"). |
O dispositivo PRECISA retornar o ID na resposta da API /privet/info SOMENTE depois que o registro for concluído.
Exemplo 1:
{ "action": "start", "user": "user@domain.com", }
Exemplo 2:
{ "action": "getClaimToken", "user": "user@domain.com", "token": "AAA111222333444555666777", "claim_url": "https://domain.com/SoMeUrL", }
Exemplo 3:
{ "action": "complete", "user": "user@domain.com", "device_id": "11111111-2222-3333-4444-555555555555", }
4.3.3. Erros
A API /privet/register pode retornar os seguintes erros (consulte a seção "Erros" para mais detalhes):Erro | Descrição |
---|---|
device_busy | O dispositivo está ocupado e não pode realizar a ação solicitada. Tente de novo após o tempo limite. |
pending_user_action | Em resposta a "getClaimToken", esse erro indica que o dispositivo ainda está aguardando a confirmação do usuário, e a solicitação "getClaimToken" precisa ser repetida após o tempo limite. |
user_cancel | O usuário cancelou explicitamente o processo de registro no dispositivo. |
confirmation_timeout | O tempo limite da confirmação do usuário expira. |
invalid_action | Uma ação inválida é chamada. Por exemplo, se o cliente chamou action=complete antes de chamar action=start e action=getClaimToken. |
invalid_params | Parâmetros inválidos especificados na solicitação. (Parâmetros desconhecidos podem ser ignorados com segurança para compatibilidade futura). Por exemplo, retorne isso se o cliente chamou action=unknown ou user=. |
device_config_error | A data/hora (ou outras configurações) está incorreta no dispositivo. O usuário precisa acessar o site interno do dispositivo e configurar as opções. |
off-line | O dispositivo está off-line e não pode se comunicar com o servidor. |
server_error | Ocorreu um erro no servidor durante o processo de registro. |
invalid_x_privet_token | O X-Privet-Token é inválido ou está vazio na solicitação. |
O dispositivo NÃO PODE expor a API /privet/register depois que o registro for concluído. Se o dispositivo não estiver expondo a API /privet/register, ele PRECISA retornar o erro HTTP 404. Portanto, se um dispositivo já estiver registrado, a chamada dessa API vai retornar 404. Se o cabeçalho X-Privet-Token estiver faltando, o dispositivo vai retornar um erro HTTP 400.
4.4. API /privet/accesstoken
A API /privet/accesstoken é OPCIONAL. É uma solicitação HTTP GET. A API /privet/accesstoken PRECISA verificar um cabeçalho "X-Privet-Token" válido. O dispositivo PRECISA implementar essa API no URL "/privet/accesstoken":GET /privet/accesstoken HTTP/1.1
Quando o dispositivo receber a chamada de API /accesstoken, ele precisará chamar o servidor para recuperar o token de acesso do usuário especificado e retornar o token ao cliente. Em seguida, o cliente vai usar o token de acesso para acessar esse dispositivo pela nuvem.
Os dispositivos do Cloud Print PRECISAM chamar a seguinte API:
/cloudprint/proximitytoken
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }
4.4.1. Entrada
A API /privet/accesstoken tem os seguintes parâmetros de entrada:Nome | Valor |
---|---|
usuário | E-mail do usuário que pretendia usar este token de acesso. Pode estar vazio na solicitação. |
4.4.2. Retornar
A API /privet/accesstoken retorna os seguintes dados:Nome do valor | Tipo de valor | Descrição |
---|---|---|
token | string | Token de acesso retornado pelo servidor. |
usuário | string | O mesmo usuário do parâmetro de entrada. |
expires_in | int | Número de segundos até a expiração deste token. Recebido do servidor e transmitido nesta resposta. |
Exemplo:
{ "token": "AAA111222333444555666777", "user": "user@domain.com", "expires_in": 600 }
4.4.3. Erros
A API /privet/accesstoken pode retornar os seguintes erros (consulte a seção "Erros" para mais detalhes):Erro | Descrição |
---|---|
off-line | O dispositivo está off-line e não pode se comunicar com o servidor. |
access_denied | Direitos insuficientes. Acesso negado. O dispositivo precisa retornar esse erro quando a solicitação for explicitamente negada pelo servidor. |
invalid_params | Parâmetros inválidos especificados na solicitação. (Parâmetros desconhecidos podem ser ignorados com segurança para compatibilidade futura). Por exemplo, se o cliente chamou /accesstoken?user= ou /accesstoken. |
server_error | Erro do servidor. |
invalid_x_privet_token | O X-Privet-Token está inválido ou vazio na solicitação. |
Se o dispositivo não estiver expondo a API /privet/accesstoken, ele precisará retornar o erro HTTP 404. Se o cabeçalho X-Privet-Token estiver faltando, o dispositivo vai retornar um erro HTTP 400.
4.5. API /privet/capabilities
A API /privet/capabilities é OPCIONAL. É uma solicitação HTTP GET. A API /privet/capabilities PRECISA verificar um cabeçalho "X-Privet-Token" válido. O dispositivo PRECISA implementar essa API no URL "/privet/capabilities":GET /privet/capabilities HTTP/1.1
4.5.1. Entrada
A API /privet/capabilities tem os seguintes parâmetros de entrada:Nome | Valor |
---|---|
off-line | (opcional) Só pode ser "offline=1". Nesse caso, o dispositivo precisa retornar recursos para uso off-line (se forem diferentes dos recursos "on-line"). |
4.5.2. Retornar
A API /privet/capabilities retorna recursos do dispositivo no formato JSON da descrição do dispositivo na nuvem (CDD). Consulte o documento do CDD para mais detalhes. As impressoras precisam retornar uma lista de tipos compatíveis aqui. Por exemplo, uma impressora pronta para a nuvem que está on-line pode retornar algo assim (no 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" } ] } }
Observação: as impressoras expressam a prioridade do tipo de conteúdo compatível usando a ordem. Por exemplo, nas amostras acima, a impressora especifica que prefere dados "application/pdf" em vez de "image/pwg-raster" e "image/jpeg". Os clientes precisam respeitar a priorização da impressora, se possível. Consulte o documento CDD para mais detalhes.
4.5.3. Erros
A API /privet/capabilities pode retornar os seguintes erros (consulte a seção "Erros" para mais detalhes):Erro | Descrição |
---|---|
invalid_x_privet_token | O X-Privet-Token é inválido ou está vazio na solicitação. |
Se o dispositivo não estiver expondo a API /privet/capabilities, ele precisará retornar o erro HTTP 404. Se o cabeçalho X-Privet-Token estiver faltando, o dispositivo vai retornar um erro HTTP 400.
4.6. Erros
Os erros são retornados das APIs acima no seguinte formato:Nome do valor | Tipo de valor | Descrição |
---|---|---|
erro | string | Tipo de erro (definido por API) |
descrição | string (opcional) | Descrição legível do erro. |
server_api | string (opcional) | Em caso de erro do servidor, esse campo contém a API do servidor que falhou. |
server_code | int (opcional) | Em caso de erro do servidor, este campo contém o código de erro retornado pelo servidor. |
server_http_code | int (opcional) | Em caso de erro HTTP do servidor, este campo contém o código de erro HTTP retornado pelo servidor. |
timeout | int (opcional) | Número de segundos que o cliente deve esperar antes de tentar novamente (somente para erros recuperáveis). O cliente PRECISA randomizar o tempo limite real desse valor para um valor que seja + 20%. |
Todas as APIs precisam retornar o erro HTTP 400 se o cabeçalho X-Privet-Token estiver ausente.
HTTP/1.1 400 Missing X-Privet-Token header.
Exemplo 1:
{ "error": "server_error", "description": "Service unavailable", "server_api": "/submit", "server_http_code": 503 }
Exemplo 2:
{ "error": "printer_busy", "description": "Printer is currently printing other job", "timeout": 15 }
5. API Printer
Um dos tipos de dispositivo compatíveis com esse protocolo é o tipo impressora. Os dispositivos compatíveis com esse tipo PODEM implementar algumas funcionalidades específicas para impressoras. O ideal é que a impressão em impressoras prontas para a nuvem passe por um servidor do Cloud Print:

Em alguns casos, um cliente pode precisar enviar um documento localmente. Isso pode ser necessário quando o cliente não tem um ID do Google ou não consegue se comunicar com o servidor do Cloud Print. Nesse caso, o trabalho de impressão será enviado localmente para a impressora. A impressora, por sua vez, usará o serviço Cloud Print para conversão e enfileiramento de trabalhos. A impressora vai postar novamente o trabalho enviado localmente para o serviço Cloud Print e, em seguida, vai solicitá-lo, já que foi enviado pela nuvem. Esse processo vai oferecer uma experiência do usuário flexível em termos de serviço (conversão) e gerenciamento/rastreamento de trabalhos de impressão.

Como o serviço Cloud Print implementa a conversão, a impressora DEVE anunciar o suporte a todos os formatos de entrada ("*/*") na lista de tipos de conteúdo compatíveis:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
Em alguns casos, uma solução completamente off-line é desejada. Como as impressoras aceitam um número limitado de formatos de entrada, um cliente precisa converter documentos para alguns formatos de impressora compatíveis nativamente.

Essa especificação EXIGE que todas as impressoras ofereçam suporte a pelo menos o formato PWG Raster ("image/pwg-raster") para impressão off-line. Uma impressora pode ser compatível com outros formatos (por exemplo, JPEG) e, se um cliente for compatível, poderá enviar documentos nesse formato. A impressora PRECISA expor os tipos compatíveis pela API /capabilities, por exemplo:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }
Impressão simples: o cliente envia o documento pela rede local para a API /submitdoc (sem especificar o parâmetro job_id). O documento enviado será impresso usando as configurações padrão de tíquete de impressão, e não será necessário verificar o status do trabalho de impressão. Se a impressora for compatível APENAS com esse tipo de impressão, ela precisará anunciar APENAS a API /submitdoc na resposta da API /privet/info.
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
Impressão avançada: primeiro, o cliente precisa criar um trabalho de impressão na impressora chamando a API /privet/printer/createjob com um tíquete de trabalho CJT válido na solicitação. A impressora PRECISA armazenar o tíquete de impressão na memória e retornar um job_id ao cliente. Em seguida, o cliente vai chamar a API /printer/submitdoc e especificar o job_id recebido anteriormente. Nesse momento, a impressora vai começar a imprimir. O cliente vai consultar o status do trabalho de impressão na impressora chamando a API /privet/printer/jobstate.
Em um ambiente de vários clientes, não há garantia de como essa API é chamada. É possível que um cliente chame /createjob entre as chamadas /createjob->/submitdoc de outro cliente. Para eliminar possíveis impasses e melhorar a usabilidade, recomendamos ter uma pequena fila de trabalhos de impressão pendentes na impressora (pelo menos de 3 a 5):
- /createjob pega o primeiro lugar disponível na fila.
- A vida útil do job (na fila) é de pelo menos 5 minutos.
- Se todos os espaços da fila estiverem ocupados, o job mais antigo que não estiver sendo impresso será removido e um novo será colocado no lugar.
- Se houver um trabalho de impressão em andamento no dispositivo (impressão simples ou avançada), /submitdoc vai retornar o status "ocupado" e propor um tempo limite para tentar novamente.
- Se /submitdoc se referir a um job que foi removido da fila (devido a substituição ou tempo limite), a impressora vai retornar um erro invalid_print_job e o cliente vai tentar novamente o processo na etapa /createjob. O cliente PRECISA aguardar um período de tempo limite aleatório de até 5 segundos antes de tentar novamente.
Se as restrições de memória impedirem o armazenamento de vários jobs pendentes no dispositivo, será possível ter uma fila de um job de impressão. Ele ainda vai seguir o mesmo protocolo acima. Depois que um job for concluído ou falhar com um erro, a impressora vai armazenar informações sobre o status dele por pelo menos cinco minutos. O tamanho da fila para armazenar status de jobs concluídos precisa ser de pelo menos 10. Se houver mais status de job que precisam ser armazenados, o mais antigo poderá ser removido da fila antes do tempo limite de 5 minutos.
Observação:por enquanto, os clientes vão pesquisar o status do job. No futuro, talvez seja necessário que a impressora envie uma notificação TXT DNS quando o status de QUALQUER trabalho de impressão mudar.
5.1. API /privet/printer/createjob
A API /privet/printer/createjob é OPCIONAL (consulte "Impressão simples" acima). É uma solicitação HTTP POST. A API /privet/printer/createjob precisa verificar se há um cabeçalho "X-Privet-Token" válido. O dispositivo PRECISA implementar essa API no URL "/privet/printer/createjob":
POST /privet/printer/createjob HTTP/1.1
5.1.1. Entrada
A API /privet/printer/createjob não tem parâmetros de entrada no URL. O corpo da solicitação precisa conter os dados do tíquete do job de impressão no formato CJT.5.1.2. Retornar
A API /privet/printer/createjob retorna os seguintes dados:Nome do valor | Tipo de valor | Descrição |
---|---|---|
job_id | string | ID do job de impressão recém-criado. |
expires_in | int | Número de segundos em que este job de impressão é válido. |
Exemplo:
{ "job_id": "123", "expires_in": 600 }
5.1.3. Erros
A API /privet/printer/createjob pode retornar os seguintes erros (consulte a seção "Erros" para mais detalhes):Erro | Descrição |
---|---|
invalid_ticket | O comprovante de impressão enviado é inválido. |
printer_busy | A impressora está ocupada e não pode processar /createjob no momento. Tente de novo após o tempo limite. |
printer_error | A impressora está em estado de erro e exige interação do usuário para ser corrigida. A descrição precisa conter uma explicação mais detalhada (por exemplo, "Atolamento de papel na bandeja 1"). |
invalid_x_privet_token | O X-Privet-Token é inválido ou está vazio na solicitação. |
Se o dispositivo não estiver expondo /privet/printer/createjob, ele precisará retornar o erro HTTP 404. Se o cabeçalho X-Privet-Token estiver faltando, o dispositivo vai retornar um erro HTTP 400.
5.2. API /privet/printer/submitdoc
A API /privet/printer/submitdoc é OBRIGATÓRIA para implementar a impressão em uma rede local (off-line ou repostagem no Cloud Print). É uma solicitação HTTP POST. A API /privet/printer/submitdoc precisa verificar um cabeçalho "X-Privet-Token" válido. O dispositivo PRECISA implementar essa API no URL "/privet/printer/submitdoc":POST /privet/printer/submitdoc HTTP/1.1
Se a impressora não conseguir armazenar todos os dados no buffer interno, ela DEVE usar mecanismos TCP para diminuir a transferência de dados até imprimir uma parte do documento, disponibilizando novamente parte do buffer. Por exemplo, a impressora pode definir windowsize=0 nas camadas TCP, o que fará com que o cliente espere.
O envio de um documento para a impressora pode levar um tempo considerável. O cliente precisa poder verificar o estado da impressora e do trabalho (impressão avançada) enquanto a impressão está em andamento. Para isso, a impressora PRECISA permitir que o cliente chame as APIs /privet/info e /privet/printer/jobstate ao processar chamadas de API /privet/printer/submitdoc. Recomendamos que todos os clientes iniciem uma nova linha de execução para executar a chamada de API /privet/printer/submitdoc. Assim, a linha de execução principal pode usar as APIs /privet/info e /privet/printer/jobstate para verificar os estados da impressora e do trabalho.
Observação: ao concluir ou cancelar o trabalho de impressão local, é altamente recomendável (e será obrigatório em uma versão futura desta especificação) informar o estado final do trabalho à interface /cloudprint/submit para fins de contabilidade e experiência do usuário. Os parâmetros "printerid", "title", "contentType" e "final_semantic_state" (no formato PrintJobState) são obrigatórios, assim como os parâmetros "tag" (parâmetro repetido) e "ticket" (o tíquete do trabalho no formato CloudJobTicket). O PrintJobState fornecido precisa ser final.Ou seja, o tipo precisa ser DONE ou ABORTED, e uma causa precisa ser fornecida caso seja ABORTED. Consulte JobState para mais detalhes. Além disso, o uso da interface /cloudprint/submit para informar jobs de impressão locais não é mencionado na especificação porque essa seção descreve o uso principal da interface: enviar um job de impressão com o documento a ser impresso fornecido no parâmetro "content".
5.2.1. Entrada
A API /privet/printer/submitdoc tem os seguintes parâmetros de entrada:Nome | Valor |
---|---|
job_id | (opcional) ID do job de impressão. Pode ser omitido para impressão simples (veja acima). Precisa corresponder ao retornado pela impressora. |
user_name | (opcional) Nome de usuário legível. Isso não é definitivo e só deve ser usado para anotações de trabalhos de impressão. Se o job for postado novamente no serviço Cloud Print, essa string será anexada ao job do Cloud Print. |
client_name | (opcional) Nome do aplicativo cliente que está fazendo esta solicitação. Somente para fins de exibição. Se o job for postado novamente no serviço Cloud Print, essa string será anexada ao job do Cloud Print. |
job_name | (Opcional) Nome do trabalho de impressão a ser registrado. Se o job for postado novamente no serviço Cloud Print, essa string será anexada ao job do Cloud Print. |
off-line | (opcional) Só pode ser "offline=1". Nesse caso, a impressora só deve tentar imprimir off-line (sem postagem novamente no servidor do Cloud Print). |
O corpo da solicitação precisa conter um documento válido para impressão. "Content-Length" precisa incluir o tamanho correto da solicitação. O cabeçalho "Content-Type" precisa ser definido como o tipo MIME do documento e corresponder a um dos tipos no CDD, a menos que o CDD especifique "*/*".
É ALTAMENTE recomendável que os clientes forneçam um nome de usuário (ou e-mail) válido, um nome de cliente e um nome de trabalho com essa solicitação. Esses campos são usados apenas em interfaces para melhorar a experiência do usuário.
5.2.2. Retornar
A API /privet/printer/submitdoc retorna os seguintes dados:Nome do valor | Tipo de valor | Descrição |
---|---|---|
job_id | string | ID do trabalho de impressão recém-criado (impressão simples) ou job_id especificado na solicitação (impressão avançada). |
expires_in | int | Número de segundos em que este job de impressão é válido. |
job_type | string | Tipo de conteúdo do documento enviado. |
job_size | int de 64 bits | Tamanho dos dados de impressão em bytes. |
job_name | string | (opcional) Mesmo nome do job que na entrada (se houver). |
Exemplo:
{ "job_id": "123", "expires_in": 500, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
5.2.3. Erros
A API /privet/printer/submitdoc pode retornar os seguintes erros (consulte a seção "Erros" para mais detalhes):Erro | Descrição |
---|---|
invalid_print_job | Um ID de job inválido/expirado foi especificado na solicitação. Tente de novo após o tempo limite. |
invalid_document_type | O tipo MIME do documento não é compatível com a impressora. |
invalid_document | O documento enviado é inválido. |
document_too_large | O documento excede o tamanho máximo permitido. |
printer_busy | A impressora está ocupada e não pode processar o documento no momento. Tente de novo após o tempo limite. |
printer_error | A impressora está em estado de erro e exige interação do usuário para ser corrigida. A descrição precisa conter uma explicação mais detalhada (por exemplo, "Atolamento de papel na bandeja 1"). |
invalid_params | Parâmetros inválidos especificados na solicitação. (Parâmetros desconhecidos devem ser ignorados com segurança para compatibilidade futura) |
user_cancel | O usuário cancelou explicitamente o processo de impressão no dispositivo. |
server_error | Falha ao postar o documento no Cloud Print. |
invalid_x_privet_token | O X-Privet-Token é inválido ou está vazio na solicitação. |
Se o dispositivo não estiver expondo /privet/printer/submitdoc, ele precisará retornar o erro HTTP 404. Se o cabeçalho X-Privet-Token estiver faltando, o dispositivo vai retornar um erro HTTP 400.
Observação: a API /privet/printer/submitdoc pode exigir um tratamento especial no lado da impressora (devido à grande carga útil anexada). Em alguns casos (depende da implementação e da plataforma do servidor HTTP da impressora), a impressora pode fechar o soquete ANTES de retornar um erro HTTP. Em outros casos, a impressora pode retornar um erro 503 em vez de um erro do Privet. As impressoras DEVEM tentar ao máximo retornar Privet. No entanto, todo cliente que implementa a especificação Privet DEVE ser capaz de processar o fechamento do soquete (sem erro HTTP) e os casos de erro HTTP 503 para a API /privet/printer/submitdoc. Nesse caso, o cliente PRECISA processar como um erro "printer_busy" do Privet com "timeout" definido como 15 segundos. Para evitar novas tentativas infinitas, o cliente pode parar de tentar novamente após um número razoável de tentativas (por exemplo, 3).
5.3. API /privet/printer/jobstate
A API /privet/printer/jobstate é OPCIONAL (consulte "Impressão simples" acima). É uma solicitação HTTP GET. A API /privet/printer/jobstate PRECISA verificar se há um cabeçalho "X-Privet-Token" válido. O dispositivo PRECISA implementar essa API no URL "/privet/printer/jobstate":GET /privet/printer/jobstate HTTP/1.1
5.3.1. Entrada
A API /privet/printer/jobstate tem os seguintes parâmetros de entrada:Nome | Valor |
---|---|
job_id | ID do trabalho de impressão para retornar o status. |
5.3.2. Retornar
A API /privet/printer/jobstate retorna os seguintes dados:Nome do valor | Tipo de valor | Descrição |
---|---|---|
job_id | string | ID do trabalho de impressão para o qual as informações de status são válidas. |
estado | string | draft: o trabalho de impressão foi criado no dispositivo. Ainda não foram recebidas chamadas
/privet/printer/submitdoc.
na fila: o trabalho de impressão foi recebido e colocado na fila, mas a impressão ainda não começou. in_progress: o trabalho de impressão está em andamento. stopped: o job de impressão foi pausado, mas pode ser reiniciado manual ou automaticamente. done: o trabalho de impressão foi concluído. abortado: o trabalho de impressão falhou. |
descrição | string | (Opcional) Descrição legível por humanos do status do trabalho de impressão. Inclua informações adicionais se state for stopped ou aborted. O campo semantic_state geralmente fornece uma descrição melhor e mais significativa para o cliente. |
expires_in | int | Número de segundos em que este job de impressão é válido. |
job_type | string | (opcional) Tipo de conteúdo do documento enviado. |
job_size | int de 64 bits | (opcional) Tamanho dos dados de impressão em bytes. |
job_name | string | (opcional) Mesmo nome do job que na entrada (se houver). |
server_job_id | string | (opcional) ID do job retornado do servidor (se o job tiver sido postado no serviço do Cloud Print). Omitido para impressão off-line. |
semantic_state | JSON | (Opcional) Estado semântico do job no formato PrintJobState. |
Exemplo (impressão por relatórios usando o 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" }
Exemplo (erro de impressão off-line):
{ "job_id": "123", "state": "stopped", "description": "Out of paper", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
Exemplo (trabalho de impressão cancelado pelo usuário):
{ "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 } }
Exemplo: o trabalho de impressão foi interrompido por falta de papel. Observe a referência ao estado do dispositivo. O cliente precisa chamar a API /privet/info para receber mais detalhes sobre o estado do 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. Erros
A API /privet/printer/jobstate pode retornar os seguintes erros (consulte a seção "Erros" para mais detalhes):Erro | Descrição |
---|---|
invalid_print_job | Um ID do job inválido/expirado foi especificado na solicitação. |
server_error | Falha ao receber o status do trabalho de impressão (para trabalhos de impressão postados no Cloud Print). |
invalid_x_privet_token | O X-Privet-Token é inválido ou está vazio na solicitação. |
Se o dispositivo não estiver expondo /privet/printer/jobstate, ele precisará retornar o erro HTTP 404. Se o cabeçalho X-Privet-Token estiver faltando, o dispositivo vai retornar um erro HTTP 400.
6. Apêndice
6.1. Comportamento e configurações padrão
Esta seção explica o comportamento padrão esperado de TODOS os dispositivos compatíveis com o Privet.- Os dispositivos prontos para uso só podem oferecer suporte às APIs /privet/info e /privet/register. Todas as outras APIs (por exemplo, /privet/accesstoken, impressão local) precisam ser desativadas.
- O registro exige interação física com um dispositivo.
- O usuário PRECISA realizar uma ação física no dispositivo (por exemplo, pressionar um botão) para confirmar o acesso a ele.
- Depois que o usuário realizar a ação observada acima, a impressora vai enviar a solicitação /cloudprint/register. Ele não deve enviar essa solicitação até que a ação seja realizada (consulte o diagrama de sequência 1).
- Se o dispositivo estiver processando uma solicitação /privet/register (por exemplo, aguardando a ação acima), ele precisará rejeitar todas as outras solicitações /privet/register. Nesse caso, o dispositivo PRECISA retornar o erro device_busy.
- O dispositivo deve atingir o tempo limite de qualquer solicitação /register que não receba a ação física mencionada acima em 60 segundos. Nesse caso, o dispositivo PRECISA retornar o erro confirmation_timeout.
- Opcional: recomendado, mas não obrigatório. O seguinte pode melhorar a experiência do usuário:
- A impressora pode piscar uma luz ou a tela para indicar que o usuário precisa realizar uma ação para confirmar o registro.
- A impressora pode mostrar na tela que "está sendo registrada no Google Cloud Print para o usuário abc@def.com. Pressione OK para continuar", em que abc@def.com é o parâmetro do usuário da chamada de API /register. Isso deixaria mais claro para um usuário que:
- é o pedido de inscrição que eles estão confirmando
- o que está acontecendo se ele/ela não acionou a solicitação.
- Além de uma ação física para confirmar na impressora (por exemplo, "Pressione o botão OK"), uma impressora também pode oferecer ao usuário um botão para cancelar a solicitação (por exemplo, Pressione "Cancelar" para rejeitar. Isso permitiria que os usuários que não acionaram a solicitação de registro cancelassem antes do tempo limite de 60 segundos. Nesse caso, o dispositivo PRECISA retornar o erro user_cancel.
- Transferências de propriedade:
- O dispositivo pode ser excluído explicitamente do serviço de nuvem.
- Se o dispositivo receber uma resposta de sucesso, mas nenhuma descrição como resultado de uma chamada /cloudprint/printer (para GCP), ele precisará voltar ao modo padrão (pronto para uso).
- Se as credenciais do dispositivo não funcionarem mais (explicitamente devido à resposta "credenciais inválidas" do servidor), ele DEVERÁ voltar ao modo padrão (pronto para uso).
- A redefinição de fábrica local PRECISA limpar as credenciais do dispositivo e definir o estado padrão.
- Opcional: o dispositivo pode fornecer um item de menu para limpar as credenciais e colocá-lo no modo padrão.
- Os dispositivos que oferecem suporte a notificações XMPP PRECISAM incluir a capacidade de fazer ping no servidor. O tempo limite de ping PRECISA ser controlável pelo servidor usando "local_settings".
- O dispositivo pode fazer ping no servidor (/cloudprint/printer API para GCP, além de pings XMPP) no máximo uma vez por dia (24 horas) para garantir que eles estejam sincronizados. É recomendável aleatorizar a janela de verificação em um período de 24 a 32 horas.
- Opcional: para dispositivos Cloud Print, é recomendável, mas não obrigatório, ter uma maneira manual (botão) para permitir que o usuário inicie uma verificação de novos trabalhos de impressão no dispositivo. Algumas impressoras já têm essa opção.
- Opcional. As impressoras empresariais podem ter uma opção para desativar completamente a descoberta local. Nesse caso, o dispositivo PRECISA atualizar essas configurações locais no servidor. As novas configurações locais precisam estar vazias. Definir "local_discovery" como "false" significa que elas podem ser reativadas no serviço do GCP.
6.1.2 Diagrama de registro padrão

6.2. Ataques e prevenção de XSSI e XSRF
Esta seção explica a possibilidade de ataques XSSI e XSRF no dispositivo e como se proteger contra eles, incluindo técnicas de geração de tokens.Mais detalhes aqui: http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
Normalmente, os ataques XSSI e XSRF são possíveis quando um site usa mecanismos de autenticação de cookies. Embora o Google não use cookies com o serviço Google Cloud Printer, esses ataques ainda são possíveis. O acesso à rede local, por design, confia implicitamente nas solicitações.
6.2.1. XSSI
É possível que um site malicioso adivinhe o endereço IP e o número da porta de um dispositivo compatível com o Privet e tente chamar a API Privet usando "src=<nome da API>" dentro de uma tag <script>:<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>
Para evitar esse tipo de ataque, TODAS as chamadas da API Privet precisam exigir o cabeçalho "X-Privet-Token" na solicitação. As tags de script "src=<api>" não podem adicionar cabeçalhos, protegendo contra esse tipo de ataque.
6.2.2. XSRF
http://en.wikipedia.org/wiki/Cross-site_request_forgeryÉ possível que um site malicioso adivinhe o endereço IP e o número da porta de um dispositivo compatível com o Privet e tente chamar a API Privet usando um <iframe>, formulários ou algum outro mecanismo de carregamento entre sites. Os invasores não conseguiriam acessar os resultados da solicitação, mas, se ela realizasse uma ação (por exemplo, impressão), eles poderiam acioná-la.
Para evitar esse ataque, precisamos da seguinte proteção:
- Deixar a API /privet/info aberta para XSRF
- A API /privet/info NÃO PODE realizar nenhuma ação no dispositivo.
- Use a API /privet/info para receber x-privet-token
- Todas as outras APIs precisam verificar um x-privet-token válido no cabeçalho "X-Privet-Token".
- x-privet-token SHOULD be valid for only 24 hours.
Mesmo que um invasor consiga executar a API /privet/info, ele não poderá ler x-privet-token da resposta e, portanto, não poderá chamar nenhuma outra API.
Recomendamos gerar o token XSRF usando o seguinte algoritmo:
XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )
Elementos de geração de token XSRF:
- DELIMITER é um caractere especial, geralmente ":"
- issue_timecounter é um número de segundos desde algum evento (época para carimbo de data/hora) ou tempo de inicialização do dispositivo (para contadores de CPU). issue_timecounter aumenta constantemente quando o dispositivo está funcionando (consulte a verificação de token abaixo).
- SHA1: função de hash que usa o algoritmo SHA1.
- base64: codificação base64
- device_secret: senha específica do dispositivo. O secret do dispositivo PRECISA ser atualizado a cada reinicialização.
Formas recomendadas de gerar o secret do dispositivo:
- Gerar um novo UUID a cada reinicialização
- Gerar um número aleatório de 64 bits a cada reinicialização
O dispositivo não precisa armazenar todos os tokens XSRF emitidos. Quando o dispositivo precisa verificar a validade de um token XSRF, ele precisa decodificar o token em base64. Extraia o issue_timecounter da segunda metade (texto simples) e tente gerar o hash SHA1 de device_secret + DELIMITER + issue_timecounter, em que issue_timecounter é do token. Se o SHA1 recém-gerado corresponder ao do token, o dispositivo precisará verificar se o issue_timecounter está dentro do período de validade (24 horas) do contador de tempo atual. Para isso, o dispositivo usa o contador de tempo atual (contador da CPU, por exemplo) e subtrai issue_timecounter dele. O resultado PRECISA ser o número de segundos desde a emissão do token.
Importante:esta é a maneira recomendada de implementar a proteção contra XSRF. Os clientes da especificação Privet não devem tentar entender o token XSRF, mas tratá-lo como uma caixa preta. A Figura 6.2.3 ilustra uma maneira recomendada de implementar o X-Privet-Token e a verificação de uma solicitação típica.
6.2.3 Diagrama de sequência de geração e verificação de token X-Privet

6.3. Diagramas de fluxo de trabalho
Esta seção vai ilustrar um fluxo de trabalho em diferentes casos.6.3.1. Fluxo de trabalho da impressora pronta para uso

6.3.2. Inicialização da impressora registrada

6.3.3 Fluxo de trabalho de processamento de notificações XMPP

6.3.4. Verificar o fluxo de trabalho das configurações da impressora
