Registration Timed Out. Please Try Again. Google Cloud Print
Privet is a Cloud Device Local Discovery API used by cloud services. This document is organized into the following sections:
- Introduction: introduction to Privet
- Discovery: local discovery mechanisms
- Announcements: local discovery announcements
- API: Privet APIs for full general cloud devices
- Printer API: Privet APIs used by printers
- Appendix: supplemental diagrams
1. Introduction
Cloud connected devices have many benefits. They can use online conversion services, host job queues while the device is offline, and be accessible from anywhere in the world. Nonetheless, with many cloud devices accessible by a given user, nosotros need to provide a method for finding the nearest device based on location. The purpose of the Privet protocol is to demark the flexibility of cloud devices with a suitable local discovery mechanism then that devices are easily discovered in new environments.
The goals of this protocol are:
- make deject devices locally discoverable
- register cloud devices with a cloud service
- acquaintance registered devices with their deject representation
- enable offline functionality
- simplify implementation so that pocket-sized devices can employ it
The Privet protocol consists of two main parts: discovery and API. Discovery is used to observe the device on the local network, and the API is used to get information about the device and perform some deportment. Throughout this document, the device refers to a cloud connected device implementing the Privet protocol.
2. Discovery
Discovery is a zeroconf based (mDNS + DNS-SD) protocol. The device MUST implement IPv4 Link-Local Addressing. The device MUST comply with the mDNS and DNS-SD specs.
- 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)
The device MUST perform name conflict resolution co-ordinate to the to a higher place specifications.
ii.1. Service Blazon
DNS Service Discovery uses the following format for service types: _applicationprotocol._transportprotocol. In the case of the Privet protocol, the service type for DNS-SD should be: _privet._tcp
The device tin can implement other service types also. It is advised to utilise the same service instance name for all service types implemented by the device. For instance: a printer may implement "Printer XYZ._privet._tcp" and "Printer XYZ._printer._tcp" services. It volition simplify setup for the user. Still, Privet clients will expect but for "_privet._tcp".
In addition to the primary service type, the device MUST advertise the PTR records for its corresponding subtype(s) (run across DNS-SD spec: "7.1. Selective Instance Enumeration (Subtypes)"). Format should exist following: _<subtype>._sub._privet._tcp
Currently the just device subtype supported is printer. So, all printers MUST advertise two PTR records:
- _privet._tcp.local.
- _printer._sub._privet._tcp.local.
2.2. TXT record
The DNS Service Discovery defines fields to add optional information about a service in the TXT records. A TXT record consists of key/value pairs. Each key/value pair starts from the length byte followed by up to 255 bytes of text. The central is the text earlier the first '=' character and the value is the text after the kickoff '=' character until the finish. The specification allows for no value in the record, in such example the volition exist no '=' character OR no text after the '=' graphic symbol. (See DNS-SD spec: "6.1. Full general Format Rules for DNS TXT Records" for the DNS TXT tape format and "vi.two. DNS-SD TXT Record Size" for the recommended length).
Privet requires the device to send the following central/value pairs in the TXT record. Key/Value strings are case-insensitive, for instance "CS=online" and "cs=ONLINE" are the same. Information in the TXT record MUST be the aforementioned as attainable through /info API (run across 4.1. API section).
It is recommended to proceed TXT tape size under 512 bytes.
ii.2.1. txtvers
Version of the TXT structure. txtvers MUST be the beginning tape of the TXT structure. Currently the only supported version is 1.
txtvers=1
ii.2.2. ty
Provides a user-readable name of the device. For example:
ty=Google Cloud Set Printer Model XYZ
2.ii.3. note (optional)
Provides a user-readable name of the device. For example:
note=1st floor lobby printer
Note: This is an optional central and may exist skipped. Withal, if present, user SHOULD be able to alter this value. The same description MUST be used when registering device.
ii.2.4. url
Server URL this device is connected to (including protocol). For example:
url=https://www.google.com/cloudprint
2.2.5. type
Comma-separated list of device subtypes supported past this device. Format is: "blazon=_subtype1,_subtype2". Currently, the simply supported device subtype is printer.
type=printer
Each subtype listed should exist advertised using a corresponding PTR record. For each supported service subtype, at that place should be ane corresponding item. Service subtype name (<subtype>._sub._privet._tcp) should exist equal to device blazon here.
two.ii.6. id
Device ID. If the device has not been registered nonetheless, this fundamental should be present, simply value should be empty. For example:
id=11111111-2222-3333-4444-555555555555 id=
2.ii.7. cs
Indicates the device'due south electric current connection state. Four possible values are defined in this spec.
- "online" indicates that the device is currently connected to the deject.
- "offline" indicates that the device is bachelor on the local network, but can't talk to the server.
- "connecting" indicates that the device is performing its startup sequence and is not fully online nevertheless.
- "not-configured" indicates that the device's internet access has not been configured withal. This value is not currently used, but may be useful in hereafter versions of the specification.
For example:
- cs=online
- cs=offline
- cs=connecting
If the device has been registered with a deject, on startup it should check connectivity with a server to discover its connection state (for example, calling cloud API to get device settings). The device may employ its notifications channel (e.g. XMPP) connection country to report this value. Unregistered devices on startup may ping a domain in order to discover their connexion state (for example, ping www.google.com for cloud impress devices).
iii. Announcements
On device startup, shutdown or state change, the device MUST perform the announcement footstep every bit described in the mDNS specification. It SHOULD send the respective announcement at to the lowest degree twice with at least a ane-second interval between them.
3.1. Startup
On device startup it MUST perform probing and announcing steps as described in the mDNS specification. SRV, PTR and TXT records should be sent in this case. It is recommended to group all records into one DNS response if possible. If not, the following order is recommended: SRV, PTR, TXT records.
3.ii. Shutdown
On device shutdown it SHOULD attempt to notify all interested parties well-nigh information technology by sending a "good day packet" with TTL=0 (as described in mDNS documentation).
3.3. Update
In case of any information described in TXT has changed, the device MUST send an update announcement. Information technology is enough to only ship the new TXT record in this case. For example, after a device is registered, it MUST send an update proclamation including the new device id.
iv. API
Later a cloud device has been discovered, customer communication is enabled with the device directly over the local network. All APIs are HTTP 1.1 based. Data formats are JSON based. API requests may exist Become or Mail requests.
Each request MUST incorporate a valid "X-Privet-Token" header. The Only asking immune to have an empty "X-Privet-Token" header is the /privet/info request (note that the header MUST even so be present). If the "Ten-Privet-Token" header is missing, the device MUST respond with the following HTTP 400 error:
HTTP/1.ane 400 Missing X-Privet-Token header.
If "X-Privet-Token" header is empty or invalid, the device MUST reply with "invalid X-Privet-Token error" (invalid_x_privet_token, see Errors department for details). The but exception is the /info API. To encounter more than info on why this is done and how tokens should exist generated, see Appendix A: XSSI and XSRF attacks and prevention.
If a requested API does not exist or is non supported, the device MUST return an HTTP 404 mistake.
4.1. API availability
Before ANY API is exposed (including the /info API), the device MUST contact the server to check local settings. Local settings MUST be preserved between restarts. If the server is not available, the last known local settings should be used. If the device has non been registered still, it should follow the default settings.
Deject Print devices MUST follow the steps below to register, receive and update local settings.
four.1.1. Registration
When the device registers, information technology MUST specify the "local_settings" parameter, as follows:
{ "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": truthful, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 } }
The post-obit settings tin exist prepare:
Value Proper noun | Value Type | Description |
---|---|---|
local_discovery | boolean | Indicates if local discovery functionality is allowed. If "false", all local API (including /info) and DNS-SD discovery must exist disabled. By default, newly registering devices should pass "true". |
access_token_enabled | boolean (optional) | Indicates if /accesstoken API should be exposed on the local network. Past default should be "true". |
printer/local_printing_enabled | boolean (optional) | Indicates if local press functionality (/printer/createjob, /printer/submitdoc, /printer/jobstate) should be exposed on the local network. Past default should be "true". |
printer/conversion_printing_enabled | boolean (optional) | Indicates if local printing may send chore to server for conversion. Simply makes sense when local press is enabled. |
xmpp_timeout_value | int (optional) | Indicates the number of seconds between XMPP channel pings. By default MUST be 300 (five minutes) or more. |
Important: The lack of any optional value indicates that the respective functionality is completely unsupported past the device.
4.1.two. Startup
On device startup, it should contact the server to check what APIs are available to exist exposed in the local network. For printers connected to Cloud Print, they should phone call:
/cloudprint/printer?printerid=<printer_id>
or
/cloudprint/listing
/cloudprint/printer is preferred over /cloudprint/listing, just both will work.
This API returns current device parameters, including settings for local API. The reply from the server will have the post-obit format:
"local_settings": { "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": truthful, "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": simulated, "xmpp_timeout_value": 500 } }
"current" object indicates settings that are in effect at the moment.
"pending" object indicates settings that should be applied to the device (this object may be missing).
Once the device sees "pending" settings, it MUST update its state (see below).
4.1.3. Update
If settings update is needed, an XMPP notification will exist sent to the device. The notification will be in the post-obit format:
<device_id>/update_settings
On receiving such a notification, the device MUST query the server to get the latest settings. Cloud Print devices MUST use:
/cloudprint/printer?printerid=<printer_id>
Once the device sees "pending" section equally a result of the /cloudprint/printer API (at startup or due to the notification), it MUST update its internal state to remember the new settings. It MUST call the server API to confirm the new settings. For Cloud Printers, the device MUST call /cloudprint/update API and use "local_settings" parameter as during registration.
When re-connecting to XMPP aqueduct, the device MUST call /cloudprint/printer API to check if local settings has been changed since the last time.
four.1.3.ane. Local Settings Pending
"local_settings" parameter that device uses to call server API MUST NEVER contain "pending" section.
four.1.three.2. Local Settings Current
Only the device can change the "current" section of the "local_settings". Everybody else volition change the "pending" section, and wait until changes get propagated to the "current" section by the device.
4.1.iv. Offline
When unable to contact the server during startup, after notification, device MUST use last known local settings.
iv.1.5. Deleting device from the service
If the device has been deleted from the service (GCP for example), an XMPP notification will exist sent to the device. The notification will be in the following format:
<device_id>/delete
On receiving such a notification, the device MUST go to the server to check its state. Cloud Impress devices MUST use:
/cloudprint/printer?printerid=<printer_id>
The device MUST receive a successful HTTP answer with success=false and no device/printer description. It means device has been removed from the server, and the device MUST erase its credentials and become to default factory settings fashion.
ANY time the device receives a reply indicating information technology has been deleted as a upshot of the /cloudprint/printer API (startup, update settings notification, daily ping), it MUST delete its credentials and get to default style.
iv.two. /privet/info API
The info API is MANDATORY and MUST be implemented by every device. It is an HTTP Go request for "/privet/info" url: GET /privet/info HTTP/1.1
The info API returns basic information well-nigh a device and functionality information technology supports. This API MUST never alter the device status or perform any action, since it is vulnerable to XSRF attacks. This is the ONLY API allowed to have an empty "Ten-Privet-Token" header. Clients should phone call /privet/info API with "10-Privet-Token" header set to X-Privet-Token: ""
The info API MUST return data consistent with data bachelor in the TXT record during discovery.
four.2.1. Input
/privet/info API has no input parameters.
4.2.2. Return
/privet/info API returns basic information almost device and supported functionality.
The TXT column indicates the respective field in the DNS-SD TXT record.
Value Proper noun | Value Blazon | Clarification | TXT |
---|---|---|---|
version | string | Highest version (major.minor) of API supported, currently i.0 | |
proper noun | cord | Homo readable proper noun of the device. | ty |
description | cord | (optional) Device description. SHOULD be modifiable past user. | note |
url | string | URL of the server this device is talking to. URL MUST include protocol specification, for instance: https://www.google.com/cloudprint. | url |
blazon | list of strings | List of device types supported. | type |
id | string | Device id, empty if device has not been registered yet. | id |
device_state | string | State of the device. idle means device is fix processing means device is decorated and functionality may be limited for some time stopped means device is not working and user intervention is required | |
connection_state | string | State of the connectedness to the server (base_url) online - connection available offline - no connection connecting - performing startup steps not-configured - connection has not been configured yet A registered device may report its connection state based on the state of the notification channel (due east.chiliad. XMPP connection state). | cs |
manufacturer | string | Name of the device manufacturer | |
model | string | Model of the device | |
serial_number | string | Unique device identifier. In this spec, this MUST exist a UUID. (GCP one.1 spec) (optional) Nosotros strongly recommend using the aforementioned serial number ID everywhere, then different clients tin can identify the aforementioned device. For example, printers implementing IPP may utilize this serial number ID in "printer-device-id" field. | |
firmware | string | Device firmware version | |
uptime | int | Number of seconds from the device kick. | |
setup_url | string | (optional) URL (including protocol) of the folio with setup instructions | |
support_url | string | (optional) URL (including protocol) of the page with support, FAQ information | |
update_url | string | (optional) URL (including protocol) of the folio with update firmware instructions | |
x-privet-token | string | Value of the X-Privet-Token header that has to be passed to all APIs to prevent XSSI and XSRF attacks. See vi.ane. for details. | |
api | description of APIs | List of supported APIs (described below) | |
semantic_state | JSON | (optional) Semantic land of the device in CloudDeviceState format. |
api - is a JSON list containing the listing of APIs available through the local network. Note that not all APIs may exist available at the same time over the local network. For example, a newly connected device should merely support the /register api:
"api": [ "/privet/annals", ]
Once device registration is consummate, the device SHOULD stop supporting the /register API. The device should as well check with the service to provide what APIs can be exposed over the local network. For example:
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
The following APIs are available at this fourth dimension:
- /privet/register - API for device registration over the local network. (run into /privet/annals API for details). This API MUST be hidden once the device is successfully registered in the deject.
- /privet/accesstoken - API to request access token from the device (see /privet/accesstoken API for details).
- /privet/capabilities - API to call up device capabilities (see /privet/capabilities API for details).
- /privet/printer/* - API specific to the device type "printer", run across printer specific APIs for details.
Here is an case of the /privet/info response. (Notation the lack of the /privet/register API, since this is already registered device):
{ "version": "1.0", "name": "Factor'southward 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", ] }
Hither is an example of the /privet/info response for a printer that ran out of ink (observe semantic_state field):
{ "version": "i.0", "proper noun": "Factor'south 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/respond/1686197/?hl=en", "support_url": "http://support.google.com/cloudprint/?hl=en", "update_url": "http://support.google.com/cloudprint/?hl=en", "ten-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659", "api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ], "semantic_state": { "version": "i.0", "printer": { "state": "STOPPED", "marker_state": { "item": [ { "vendor_id": "ink", "state": "EXHAUSTED", "level_percent": 0 } ] } } } }
4.2.3. Errors
/privet/info API should ONLY return an fault if X-Privet-Token header is missing. It MUST be HTTP 400 error:
HTTP/1.ane 400 Missing X-Privet-Token header.
iv.3. /privet/register API
/privet/register API is OPTIONAL. It is an HTTP Postal service request. /privet/register API MUST check for a valid X-Privet-Token header. Device MUST implement this API on "/privet/annals" url:
Post /privet/register?action=offset&user=user@domain.com HTTP/1.1 POST /privet/annals?action=complete&user=user@domain.com HTTP/ane.1
The device should expose /privet/register API ONLY when it allows anonymous registration at the moment. For instance:
- When the device is turned on (or after clicking a special push on the device) and has not been registered yet, information technology should expose the /privet/register API to allow a user from the local network to claim the printer.
- Later on registration is complete, the device should stop exposing the /privet/register API to forestall another user on the local network from reclaiming the device.
- Some devices may have different ways to register devices and should not expose the /privet/register API at all (for example, Chrome Cloud Impress connector).
The registration procedure consists of three steps (see anonymous registration for Cloud Print).
- Initiate anonymous registration process.
- A client initiates this process by calling the /privet/annals API. The device may wait for user confirmation at that time.
- Get merits token.
The client polls to find out when the device is set to continue. In one case the device is ready, it sends a asking to the server to retrieve registration token and registration URL. Received token and URL SHOULD be returned to the client. During this step, if the device receives another call to initialize registration, it should:
- If this is the same user who started registration - drop all previous information (if any) and beginning a new registration process.
- If this is dissimilar user - return device_busy error and xxx seconds timeout.
Complete registration process.
Afterward the client has claimed the device, the customer should notify the device to complete registration. Once the registration procedure is complete, the device should transport an update announcement, including the newly acquired device id.
Note: When the device is processing a /privet/annals API call, no other /privet/register API calls may exist candy simultaneously. The device MUST render the device_busy error and 30 seconds timeout.
User confirmation for registration on the device is HIGHLY recommended. If implemented, the device MUST wait for user confirmation Later on it receives a /privet/register?action=start API call. The client will be calling /privet/register?activeness=getClaimToken API to notice out when user confirmation is complete and claim token is available. If the user cancels registration on the device (e.thou. presses the Cancel button), the user_cancel error MUST exist returned. If the user has not confirmed registration within a certain timeframe, the confirmation_timeout mistake MUST exist returned. See defaults section for more details.
4.3.1. Input
/privet/register API has the post-obit input parameters:
Name | Value |
---|---|
action | Can be i of the post-obit: beginning - to start registration process getClaimToken - retrieve claim token for the device cancel - to cancel registration process complete - to complete registration procedure |
user | E-mail of the user who will merits this device. |
The device MUST check that the email address from all actions (start, getClaimToken, cancel, complete) matches.
4.iii.2. Return
/privet/register API returns post-obit data:
Value proper noun | Value blazon | Description |
---|---|---|
action | string | Same activity as in input parameter. |
user | string (optional) | Same user as in input parameter (may be missing, if omitted in the input). |
token | string (optional) | Registration token (mandatory for "getClaimToken" response, omitted for "start", "complete", "abolish"). |
claim_url | string (optional) | Registration URL (mandatory for "getClaimToken" response, omitted for "start", "complete", "cancel"). For Cloud Printers it must be the "complete_invite_url" received from the server. |
automated_claim_url | string (optional) | Registration URL (mandatory for "getClaimToken" response, omitted for "get-go", "complete", "abolish"). For Cloud Printers it must be the "automated_invite_url" received from the server. |
device_id | cord (optional) | New device id (omitted for "outset" response, mandatory for "complete"). |
The device MUST return its device id in the /privet/info API response ONLY after registration is consummate.
Example 1:
{ "action": "beginning", "user": "user@domain.com", }
Example 2:
{ "action": "getClaimToken", "user": "user@domain.com", "token": "AAA111222333444555666777", "claim_url": "https://domain.com/SoMeUrL", }
Example 3:
{ "activeness": "consummate", "user": "user@domain.com", "device_id": "11111111-2222-3333-4444-555555555555", }
4.three.3. Errors
/privet/annals API may return post-obit errors (see Errors section for details):
Fault | Description |
---|---|
device_busy | The device is busy and can't perform the requested activity. Retry later timeout. |
pending_user_action | In response to "getClaimToken" this error indicates that the device is still awaiting user confirmation, and "getClaimToken" request should be retried after timeout. |
user_cancel | User explicitly cancelled registration procedure from the device. |
confirmation_timeout | User confirmation times out. |
invalid_action | Invalid action is chosen. For case, if client called action=complete before calling action=start and activeness=getClaimToken. |
invalid_params | Invalid parameters specified in the asking. (Unknown parameters should exist safely ignored for time to come compatibility). For example, return this if the customer called action=unknown or user=. |
device_config_error | Date/Time (or some other settings) is wrong on the device side. User needs to go (to device internal website) and configure device settings. |
offline | The device is currently offline and can't talk to the server. |
server_error | Server error during registration process. |
invalid_x_privet_token | 10-Privet-Token is invalid or empty in the request. |
The device MUST stop exposing the /privet/register API after registration has been successfully completed. If the device is not exposing the /privet/register API, it MUST return HTTP 404 error. Therefore, if a device is already registered, calling this API MUST return 404. If the Ten-Privet-Token header is missing, the device MUST return HTTP 400 error.
iv.iv. /privet/accesstoken API
/privet/accesstoken API is OPTIONAL. It is an HTTP GET asking. /privet/accesstoken API MUST check for a valid "X-Privet-Token" header. The device MUST implement this API on the "/privet/accesstoken" url:
Become /privet/accesstoken HTTP/1.1
When the device receives the /accesstoken API call, it should call the server to think the access token for the given user and return the token to the client. The client will then utilize the access token to access this device through the cloud.
Cloud Print devices MUST call the post-obit API:
/cloudprint/proximitytoken
and pass "printerid=<printer_id>" and "user" parameter from the local API. If successful, the server response will contain the following object:
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }
Cloud Impress devices MUST laissez passer the value of the "proximity_token" object in the response to local /privet/accesstoken API calls. It is more than advantageous (future-proof) if the device can pass ALL parameters (including ones that are not described in this spec).
four.4.1. Input
/privet/accesstoken API has the following input parameters:
Name | Value |
---|---|
user | Electronic mail of the user who intended to use this access token. May be empty in the request. |
4.iv.two. Render
/privet/accesstoken API returns following data:
Value name | Value type | Clarification |
---|---|---|
token | cord | Access token returned by the server |
user | string | Same user as in input parameter. |
expires_in | int | Number of seconds until this token expires. Received from the server and passed in this response. |
Example:
{ "token": "AAA111222333444555666777", "user": "user@domain.com", "expires_in": 600 }
iv.four.3. Errors
/privet/accesstoken API may return the following errors (see Errors section for details):
Error | Description |
---|---|
offline | Device is currently offline and can't talk to the server. |
access_denied | Insufficient rights. Access denied. The device should return this mistake when the request has been explicitly denied past the server. |
invalid_params | Invalid parameters specified in the asking. (Unknown parameters should be safely ignored for futurity compatibility). For example, if customer called /accesstoken?user= or /accesstoken. |
server_error | Server error. |
invalid_x_privet_token | 10-Privet-Token is Invalid or empty in the request. |
If the device is not exposing the /privet/accesstoken API, information technology MUST return HTTP 404 fault. If the X-Privet-Token header is missing, the device MUST return HTTP 400 error.
4.5. /privet/capabilities API
/privet/capabilities API is OPTIONAL. It is an HTTP Get request. /privet/capabilities API MUST check for a valid "X-Privet-Token" header. The device MUST implement this API on "/privet/capabilities" url:
Get /privet/capabilities HTTP/ane.ane
When the device receives /capabilities API call, if the device is able, it SHOULD contact the server to get updated capabilities. For example, if a printer supports posting a print task (received locally) to itself through the Cloud Print service, it should return capabilities that the Cloud Print service would return. Cloud Print in this case may modify the original printer capabilities by adding new features it may perform before sending job to the printer. The virtually common case is a listing of supported document types. If the printer is offline, it should return document types it supports. However, if the printer is online and registered with Cloud Print information technology MUST return "*/*" every bit one of the supported types. The Cloud Print service will perform the necessary conversion in this example. For offline printing, the printer MUST support at least the "image/pwg-raster" format.
4.5.1. Input
/privet/capabilities API has the following input parameters:
Name | Value |
---|---|
offline | (optional) Tin only be "offline=1". In this case the device should render capabilities for offline utilize (if they are different from "online" capabilities). |
iv.5.2. Render
/privet/capabilities API returns device capabilities in the Cloud Device Clarification (CDD) JSON format (run across the CDD document for details). Printers at minimum MUST return a list of supported types here. For instance, a Cloud Ready printer that is currently online may return something like this (at minimum):
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "application/pdf", "min_version": "1.4" }, { "content_type": "image/pwg-raster" }, { "content_type": "epitome/jpeg" }, { "content_type": "*/*" } ] } }
and when information technology'southward disconnected from the server, information technology may render:
{ "version": "one.0", "printer": { "supported_content_type": [ { "content_type": "application/pdf", "min_version": "i.iv" }, { "content_type": "image/pwg-raster" }, { "content_type": "prototype/jpeg" } ] } }
Annotation: Printers express supported content type priority using lodge. For example, in the samples above, the printer specifies that it prefers "application/pdf" data over "image/pwg-raster" and "prototype/jpeg". Clients should respect printer prioritization if possible (see the CDD certificate for details).
4.5.3. Errors
/privet/capabilities API may render post-obit errors (see Errors section for details):
Mistake | Description |
---|---|
invalid_x_privet_token | X-Privet-Token is invalid or empty in the request. |
If the device is not exposing the /privet/capabilities API, it MUST return HTTP 404 mistake. If the 10-Privet-Token header is missing, the device MUST return HTTP 400 mistake.
4.6. Errors
Errors are returned from the higher up APIs in the post-obit format:
Value proper name | Value type | Description |
---|---|---|
mistake | cord | Error type (defined per API) |
description | cord (optional) | Human readable clarification of the error. |
server_api | string (optional) | In case of server error, this field contains the server API that failed. |
server_code | int (optional) | In case of server error, this field contains that mistake code that the server returned. |
server_http_code | int (optional) | In case of server HTTP error, this field contains HTTP mistake code server returned. |
timeout | int (optional) | Number of seconds for client to wait earlier retrying (for recoverable errors only). Client MUST randomize actual timeout from this value to a value that is + 20%. |
All APIs MUST return HTTP 400 error if X-Privet-Token header is missing.
HTTP/one.1 400 Missing X-Privet-Token header.
Example ane:
{ "error": "server_error", "description": "Service unavailable", "server_api": "/submit", "server_http_code": 503 }
Example 2:
{ "fault": "printer_busy", "description": "Printer is currently printing other job", "timeout": fifteen }
5. Printer API
One of the device types this protocol supports is type printer. Devices supporting this type MAY implement some functionality specific to printers. Ideally, printing to cloud-ready printers volition go through a Cloud Print server:
In some cases a client may demand to transport a document locally. It may be needed when customer does not take a Google ID or is unable to talk to the Cloud Print server. In such case, the impress job will be submitted locally to the printer. The printer, in plow, volition apply the Cloud Print service for job queueing and conversion. The printer will re-post the job submitted locally to the Cloud Print service and and so asking it, since it was submitted through the deject. This procedure will provide a flexible user experience in terms of service (conversion) and print task direction/tracking.
Since the Cloud Print service implements conversion, the printer SHOULD advertise supporting all input formats ("*/*") among the listing of the supported content types:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
In some cases a completely offline solution is desired. Since printers support a express number of input formats, a client will need to convert documents to a few natively supported printer formats.
This spec REQUIRES all printers to support at least the PWG Raster ("paradigm/pwg-raster") format for the offline press case. A printer may support other formats (for example JPEG) and if a client supports information technology, information technology may send documents in that format. The printer MUST expose supported types through the /capabilities API, for example:
{ "version": "one.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }
There are two ways a client may initiate printing over the local network.
Simple printing - client sends the certificate over the local network to /submitdoc API (without specifying the job_id parameter). The submitted certificate will be printed using default print ticket settings and no impress job statuses are needed. If the printer ONLY supports this type of printing, it MUST advertise Merely /submitdoc API in the /privet/info API response.
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
Avant-garde printing - customer should get-go create a print job on the printer past calling the /privet/printer/createjob API with a valid CJT job ticket in the asking. The printer MUST store the print ticket in memory and return a job_id back to the client. Then the customer will telephone call the /printer/submitdoc API and specify the previously received job_id. At that time the printer volition start printing. The client will poll the printer for print chore condition by calling the /privet/printer/jobstate API.
In a multi-client environment, there is no guarantee how this API is chosen. It is possible for ane client to telephone call /createjob betwixt another client's /createjob->/submitdoc calls. To eliminate possible deadlocks and improve usability, nosotros recommended having a small queue of pending print jobs on the printer (at least three-5):
- /createjob takes the kickoff available spot in the queue.
- Job lifetime (in the queue) is at to the lowest degree 5 minutes.
- If all spots in the queue are taken, then the oldest, non-printing job shall exist removed and a new one will be placed there.
- If in that location is a print job currently press on the device (simple or avant-garde printing), /submitdoc should return status decorated and propose a timeout to retry this print job.
- If /submitdoc refers to a job that has been removed from the queue (due to replacement or timeout), the printer should return an error invalid_print_job and the client volition retry the process from the /createjob step. The customer MUST await for a random timeout period of upwards to five seconds before retrying.
If retentivity constraints prevent storing multiple awaiting jobs on the device, information technology is possible to have a queue of 1 print job long. It should yet follow the same protocol as above. Afterward a job has completed or failed with an error, the printer should store information about the job'due south status for at least 5 minutes. The queue size for storing completed task statuses should exist at least 10. If there are more chore statuses that need to be stored, the oldest 1 may exist removed from the queue before the 5 infinitesimal timeout.
Note: For at present clients will poll for task condition. In the time to come, we may crave the printer to send TXT DNS notification when Any print chore status has changed.
v.1. /privet/printer/createjob API
/privet/printer/createjob API is OPTIONAL (see Simple Press above). It is an HTTP Postal service request. /privet/printer/createjob API MUST bank check for a valid "X-Privet-Token" header. The device MUST implement this API on "/privet/printer/createjob" url:
POST /privet/printer/createjob HTTP/1.i
When receiving /privet/printer/createjob API telephone call, the printer MUST create a new print chore ID, shop the received print ticket in the CJT format, and return print job id back to the client.
v.ane.1. Input
/privet/printer/createjob API has no input parameters in URL. The request trunk should comprise the print job ticket data in CJT format.
5.1.two. Render
/privet/printer/createjob API returns the following information:
Value name | Value type | Description |
---|---|---|
job_id | string | ID of the newly created print job. |
expires_in | int | Number of seconds this impress job is valid. |
Example:
{ "job_id": "123", "expires_in": 600 }
five.ane.3. Errors
/privet/printer/createjob API may return the following errors (see Errors section for details):
Error | Description |
---|---|
invalid_ticket | Submitted print ticket is invalid. |
printer_busy | Printer is busy and can't currently process /createjob. Retry later on timeout. |
printer_error | Printer is in error state and requires user interaction to ready it. Description should contain more detailed explanation (e.g. "Paper jam in Tray 1"). |
invalid_x_privet_token | X-Privet-Token is invalid or empty in the asking. |
If device is not exposing /privet/printer/createjob it MUST return HTTP 404 mistake. If X-Privet-Token header is missing, the device MUST return HTTP 400 error.
5.2. /privet/printer/submitdoc API
/privet/printer/submitdoc API is REQUIRED to implement printing over a local network (offline or repost to Deject Print). It is an HTTP POST asking. /privet/printer/submitdoc API MUST bank check for a valid "X-Privet-Token" header. The device MUST implement this API on "/privet/printer/submitdoc" url:
POST /privet/printer/submitdoc HTTP/1.i
When receiving the /privet/printer/submitdoc API call, the printer should start printing. If it is unable to brainstorm printing, it MUST return the error printer_busy and a recommended timeout catamenia for the customer to await earlier trying again.
If the printer is not able to hold all of the data in its internal buffer, it SHOULD use TCP mechanisms to ho-hum down data transfer until it prints a portion of the document, making part of the buffer available over again. (For example, the printer may set up windowsize=0 on TCP layers, which will make the customer look.)
Submitting a document to the printer may take a significant amount of time. The client should be able to check the state of the printer and job (advanced printing) while printing is in progress. In order to do that, the printer MUST permit the customer to call the /privet/info and /privet/printer/jobstate APIs while processing /privet/printer/submitdoc API calls. It is recommended for all clients to start a new thread to execute the /privet/printer/submitdoc API phone call, so that the main thread can utilize the /privet/info and /privet/printer/jobstate APIs to check printer and chore states.
Annotation: Upon completion or abortion of the local print job, it is strongly recommended (and will be required in a future version of this spec) to report the final state of the job to the /cloudprint/submit interface for accounting and user experience purposes. The parameters "printerid", "title", "contentType" and "final_semantic_state" (in PrintJobState format) are required, and the parameters "tag" (repeated parameter) and "ticket" (the ticket of the job in CloudJobTicket format). Annotation that the provided PrintJobState must actually be concluding, i.e. its blazon must be DONE or ABORTED, and a crusade must be provided in the case that it is ABORTED (come across JobState for details). Likewise note that this use of the /cloudprint/submit interface to report local print jobs is non mentioned in its specification because that section is intended to draw the interface's principal use: submitting a print task with the document to print provided in the "content" parameter.
5.2.1. Input
/privet/printer/submitdoc API has the following input parameters:
Name | Value |
---|---|
job_id | (optional) Print job id. May exist omitted for simple press case (see in a higher place). Must lucifer the one returned past the printer. |
user_name | (optional) Human being readable user name. This is not definitive, and should only be used for print job annotations. If job is re-posted to the Cloud Impress service this string should be attached to the Deject Print task. |
client_name | (optional) Proper noun of the customer application making this request. For display purposes just. If task is re-posted to the Cloud Print service this string should be attached to the Cloud Print job. |
job_name | (optional) Proper name of the print job to exist recorded. If job is re-posted to the Cloud Impress service this string should be attached to the Cloud Print job. |
offline | (optional) Could only be "offline=1". In this example printer should simply attempt press offline (no re-post to Cloud Print server). |
Request body should incorporate a valid certificate for press. "Content-Length" should include the correct length of the asking. "Content-Type" header should exist set up to document MIME type and friction match one of the types in the CDD (unless CDD specifies "*/*").
Clients are HIGHLY recommended to provide a valid user name (or e-mail), a client name and a chore name with this asking. Those fields are only used in UIs to improve user experience.
5.ii.2. Return
/privet/printer/submitdoc API returns following information:
Value proper noun | Value type | Description |
---|---|---|
job_id | string | ID of the newly created print chore (simple press) or job_id specified in the request (advanced printing). |
expires_in | int | Number of seconds this print job is valid. |
job_type | string | Content-type of the submitted document. |
job_size | int 64 flake | Size of the print data in bytes. |
job_name | cord | (optional) Same job proper noun as in input (if any). |
Example:
{ "job_id": "123", "expires_in": 500, "job_type": "awarding/pdf", "job_size": 123456, "job_name": "My PDF certificate" }
5.2.3. Errors
/privet/printer/submitdoc API may return the following errors (see Errors section for details):
Error | Description |
---|---|
invalid_print_job | Invalid/expired job id is specified in the request. Retry later on timeout. |
invalid_document_type | Document MIME-blazon is not supported by the printer. |
invalid_document | Submitted document is invalid. |
document_too_large | Document exceeds maximum size allowed. |
printer_busy | Printer is busy and can't currently process certificate. Retry after timeout. |
printer_error | Printer is in fault state and requires user interaction to fix it. Description should contain more detailed explanation (e.g. "Paper jam in Tray one"). |
invalid_params | Invalid parameters specified in the request. (Unknown parameters should be safely ignored for future compatibility) |
user_cancel | User explicitly cancelled printing process from the device. |
server_error | Posting document to Deject Print has failed. |
invalid_x_privet_token | X-Privet-Token is invalid or empty in the asking. |
If the device is not exposing /privet/printer/submitdoc, information technology MUST render HTTP 404 error. If the X-Privet-Token header is missing, the device MUST return HTTP 400 error.
Note: /privet/printer/submitdoc API may require special handling on printer side (because of the large payload attached). In some cases (depends on the printer HTTP server implementation and platform), printer may close socket Before returning HTTP error. In other, printer may return 503 error (instead of Privet error). Printers SHOULD try as much as possible to return Privet. However, every client implementing Privet specification SHOULD be able to handle socket shut (no HTTP error) and 503 HTTP mistake cases for /privet/printer/submitdoc API. In this case, client SHOULD handle it as a Privet "printer_busy" error with "timeout" set to 15 seconds. To avoid infinite retries, client may stop retrying subsequently a reasonable number of attempts (for example, iii).
5.3. /privet/printer/jobstate API
/privet/printer/jobstate API is OPTIONAL (see Elementary Printing above). It is an HTTP Go request. /privet/printer/jobstate API MUST check for a valid "X-Privet-Token" header. The device MUST implement this API on "/privet/printer/jobstate" url:
GET /privet/printer/jobstate HTTP/1.1
When receiving a /privet/printer/jobstate API phone call, a printer should return the status of the requested impress job or invalid_print_job mistake.
5.three.1. Input
/privet/printer/jobstate API has following input parameters:
Name | Value |
---|---|
job_id | Impress job ID to return status for. |
five.3.ii. Return
/privet/printer/jobstate API returns the post-obit data:
Value name | Value type | Description |
---|---|---|
job_id | string | Print job id there status information is for. |
state | string | draft - print job has been created on the device (no /privet/printer/submitdoc calls have been received notwithstanding). queued - print task has been received and queued, but press has not started yet. in_progress - print job is in the progress of press. stopped - impress chore has been paused, but can be restarted manually or automatically. washed - print task is done. aborted - print job failed. |
description | cord | (optional) Human readable description of the print job status. Should include additional information if land< is stopped or aborted. The semantic_state field ordinarily provides better and more meaningful clarification to the client. |
expires_in | int | Number of seconds this print chore is valid. |
job_type | string | (optional) Content-type of the submitted document. |
job_size | int 64 chip | (optional) Size of the print data in bytes. |
job_name | string | (optional) Aforementioned task name as in input (if any). |
server_job_id | string | (optional) ID of the chore returned from the server (if job has been posted to Cloud Print service). Omitted for offline printing. |
semantic_state | JSON | (optional) Semantic state of the task in PrintJobState format. |
Example (printing by reporting through 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" }
Example (offline press error):
{ "job_id": "123", "state": "stopped", "clarification": "Out of newspaper", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
Example (print job aborted by the user):
{ "job_id": "123", "state": "aborted", "description": "User action", "expires_in": 100, "job_type": "awarding/pdf", "job_size": 123456, "job_name": "My PDF document", "semantic_state": { "version": "1.0", "country": { "type": "ABORTED", "user_action_cause": {"action_code": "CANCELLED"} }, "pages_printed": vii } }
Example (print job stopped due to out of paper). Notice the reference to the device country. The customer volition need to call the /privet/info API to get more details about the device country:
{ "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": vii } }
5.iii.three. Errors
/privet/printer/jobstate API may return the post-obit errors (see Errors department for details):
Error | Description |
---|---|
invalid_print_job | Invalid/expired chore ID is specified in the request. |
server_error | Getting print job status (for print jobs posted to Cloud Impress) has failed. |
invalid_x_privet_token | X-Privet-Token is invalid or empty in the asking. |
If device is non exposing /privet/printer/jobstate, information technology MUST return HTTP 404 fault. If the X-Privet-Token header is missing, the device MUST render HTTP 400 error.
6. Appendix
6.1. Default beliefs and settings
This section will explain the default behavior we await from ALL Privet-compatible devices.
- Out-of-the-box devices should support only /privet/info and /privet/register APIs. All other APIs (e.thousand. /privet/accesstoken, local press) should be disabled.
- Registration requires physical interaction with a device.
- User MUST accept a physical action on the device (e.g., pressing a button) to confirm their access to the device.
- Afterwards the user takes the action noted above, the printer should ship the /cloudprint/register request. It should not ship this asking until after the activeness is taken (see Sequence Diagram 1).
- If the device is processing a /privet/register request (for example, waiting on the activeness above), it must reject all other /privet/register requests. The device MUST return the device_busy fault in this instance.
- The device should timeout any /register request that does not receive the physical activity mentioned above within 60 seconds. The device MUST return the confirmation_timeout error in this example.
- Optional: Recommended but not required, the following may improve user experience:
- The printer might wink a light or its screen to bespeak that the user needs to take an action to confirm registration.
- The printer might land on its screen that 'it is being registered to Google Cloud Print for user 'abc@def.com' - press OK to keep', where abc@def.com is the user parameter from the /register API telephone call. This would make it clearer to a user that:
- it is their registration request that they are confirming
- what is happening if s/he didn't trigger the request.
- In add-on to a physical action to confirm from the printer (eastward.g., 'Press the OK button'), a printer may too offering the user a button to cancel the request (e.g., 'Press Abolish to reject'). This would allow users who did not trigger the registration request to abolish it before the 60 second timeout. The device MUST return the user_cancel error in this case.
- Buying transfers:
- The device may be deleted explicitly from the Cloud service.
- If the device receives success, only no device clarification as a consequence of /cloudprint/printer (for GCP) call, it MUST revert to default (out-of-the-box) manner.
- If the device's credentials no longer work (explicitly because of "invalid credentials" response from the server), it MUST revert to default (out-of-the-box) style.
- Local factory reset MUST clear device'southward credentials and set up information technology to default country.
- Optional: The device may provide a bill of fare item to clear credentials and put information technology into default style.
- Devices supporting XMPP notifications MUST include the ability to ping the server. The ping timeout MUST exist controllable from the server through "local_settings".
- The device may explicitly ping the server (/cloudprint/printer API for GCP, in addition to XMPP pings) no more often than once a mean solar day (24 hours) to brand sure they are in sync. It is recommended to randomize the check window inside 24-32 hour window.
- Optional: For Cloud Print devices, it is recommended but not required to take a transmission way (push button) to allow the user to initiate a cheque for new print jobs from the device. Some printers already have this.
- Optional. Enterprise printers may take an option to disable local discovery completely. In such case, the device MUST update these local settings on the server. New local settings MUST be empty (setting "local_discovery" to "simulated", means that it can be re-enabled from the GCP Service).
six.one.two Default Registration Diagram
6.two. XSSI and XSRF attacks and prevention
This department will explain the possibility of XSSI and XSRF attacks on the device and how to protect from them (including token generation techniques).
More details are hither: http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
Unremarkably, XSSI and XSRF attacks are possible when a site is using cookie hallmark mechanisms. While Google doesn't employ cookies with their Deject Print Service, such attacks are yet possible. Local network access, past pattern, implicitly trusts requests.
6.ii.1. XSSI
Information technology is possible for a malicious website to guess the IP address and port number of a Privet-compatible device and to endeavor to call the Privet API using "src=<api name>" within of a <script> tag:
<script blazon="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>
Without protection, malicious websites would be able to execute API calls and access results.
To prevent this blazon of attack, ALL Privet API calls MUST crave the "X-Privet-Token" header in the asking. "src=<api>" script tags are non able to add headers, finer guarding against this blazon of assail.
six.2.2. XSRF
http://en.wikipedia.org/wiki/Cross-site_request_forgery
It is possible for a malicious website to judge the IP accost and port number of a Privet-compatible device and attempt to call Privet API using an <iframe>, forms, or some other cross-website loading mechanism. Attackers would not be able to access the results of the request, simply if the asking would perform an activeness (e.g. press), they could trigger it.
To preclude this attack, we crave the following protection:
- Leave /privet/info API open to XSRF
- /privet/info API MUST Non perform whatsoever deportment on the device
- Employ /privet/info API to receive x-privet-token
- All other APIs MUST bank check for a valid x-privet-token in "X-Privet-Token" header.
- x-privet-token SHOULD be valid for only 24 hours.
Even if an assailant is able to execute the /privet/info API, they would non be able to read x-privet-token from the response and therefore would not be able to call whatsoever other API.
It is strongly recommended to generate the XSRF token using the post-obit algorithm:
XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )
XSRF Token Generation Elements:
- DELIMITER is a special character, usually ':'
- issue_timecounter is a number of seconds since some event (epoch for timestamp) or device kick time (for CPU counters). issue_timecounter is constantly increasing when the device is upwardly and running (see token verification below).
- SHA1 - hash function using SHA1 algorithm
- base64 - base64 encoding
- device_secret - hugger-mugger specific to the device. Device secret MUST exist updated on every restart.
Recommended ways to generate device secret:
- Generate a new UUID on every restart
- Generate a 64 flake random number on every restart
The device is not required to store all of the XSRF tokens it has issued. When the device needs to verify a XSRF token for validity, it should base64-decode the token. Become the issue_timecounter from the second half (cleartext), and try to produce SHA1 hash of device_secret + DELIMITER + issue_timecounter where issue_timecounter is from the token. If the newly generated SHA1 matches the one in the token, device must now cheque if the issue_timecounter is within the validity menstruum from (24 hours) of the electric current time counter. To do and so, device takes the current fourth dimension counter (CPU counter for example) and subtracts issue_timecounter from it. The consequence MUST exist the number of seconds since token issue.
Important: This is the recommended way to implement XSRF protection. Clients of the Privet specification shall not try to sympathize XSRF token, instead they shall treat is as a blackbox. Figure 6.2.3 illustrates a recommended style to implement the 10-Privet-Token and verification of a typical request.
6.ii.iii 10-Privet Token Generation and Verification Sequence Diagram
six.three. Workflow diagrams
This department will illustrate a workflow in different cases.
6.3.ane. Printer out of the box workflow
vi.3.2. Registered printer startup
half-dozen.three.3 XMPP notifications handling workflow
6.3.4. Check printer settings workflow
alfordandesch1958.blogspot.com
Source: https://developers.google.com/cloud-print/docs/privet
0 Response to "Registration Timed Out. Please Try Again. Google Cloud Print"
Publicar un comentario