Privet はクラウド サービスによって使用される Cloud Device Local Discovery API です。このドキュメントは、次のセクションから構成されています。
- はじめに: Privet の概要
- 検出: ローカルの検出メカニズム
- お知らせ: ローカルの調査に関するお知らせ
- API: 一般的なクラウド デバイス向けの Privet API
- Printer API: プリンタで使用される Privet API
- 付録: 補足図
1. はじめに
クラウド接続デバイスには、多くのメリットがあります。オンライン コンバージョン サービスを使用したり、デバイスがオフラインのときにジョブキューをホストしたりして、どこからでもアクセスできます。しかし、多くのユーザーがクラウド デバイスを使用してアクセスできる状態であれば、位置情報に基づいて最も近いデバイスを見つけるための手段を提供する必要があります。Privet プロトコルは、新しいローカル デバイスでデバイスを簡単に検出できるように、クラウド デバイスの柔軟性と適切なローカル ディスカバリのメカニズムを結び付けることを目的としています。
このプロトコルの目標は次のとおりです。- クラウド デバイスをローカルで検出可能にする
- クラウド デバイスをクラウド サービスに登録する
- 登録済みのデバイスをクラウド表現に関連付ける
- オフライン機能を有効にする
- 実装を簡素化し、小型デバイスで活用できる
Privet プロトコルは、検出と API の 2 つの主要部分で構成されています。検出はローカル ネットワーク上のデバイスを検出するために使用され、API はデバイスに関する情報を取得していくつかのアクションを実行するために使用されます。このドキュメント全体を通して、デバイスは Privet プロトコルを実装するクラウド接続デバイスを指します。
2. Discovery
検出は 0conf ベース(mDNS + DNS-SD)のプロトコルで、デバイスは、IPv4 リンクローカル アドレス設定を実装しなければなりません。デバイスは、mDNS と DNS-SD の仕様に準拠している必要があります。
- http://www.rfc-editor.org/rfc/rfc3927.txt(IPv4 リンクローカル)
- http://www.rfc-editor.org/rfc/rfc4862.txt(IPv6 リンクローカル)
- http://www.rfc-editor.org/rfc/rfc6762.txt(mDNS)
- http://www.rfc-editor.org/rfc/rfc6763.txt(DNS-SD)
デバイスは、上記の仕様に従って名前の競合の解決を実施しなければなりません。
2.1. サービスの種類
DNS Service Discovery では、サービスタイプに _applicationprotocol._transportprotocol の形式を使用します。Privet プロトコルの場合、DNS-SD のサービス タイプは _privet._tcp になります。
デバイスは他のサービスタイプも実装できます。デバイスによって実装されるすべてのサービスタイプで同じサービス インスタンス名を使用することをおすすめします。たとえば、プリンタが「プリンタ XYZ._privet._tcp"」や「プリンタ XYZ._printer._tcp"」サービスを実装している場合があります。ユーザーの設定を簡素化できます。ただし、Privet クライアントは "_privet._tcp" のみを探します。
デバイスは、メインのサービスタイプに加えて、対応するサブタイプの PTR レコードをアドバタイズしなければなりません(DNS-SD 仕様: "7.1 を参照)。Selection Instance Enumeration(Subtypes)")。 次のような形式にする必要があります。 _<subtype>._sub._privet._tcp
現在、サポートされているデバイスのサブタイプは printer のみです。そのため、すべてのプリンタは、次の 2 つの PTR レコードをアドバタイズしなければなりません。
- _privet._tcp.local
- _printer._sub._privet._tcp.local
2.2. TXT レコード
DNS Service Discovery では、サービスに関する任意の情報を TXT レコードに追加するフィールドが定義されています。TXT レコードは Key-Value ペアで構成されます。各 Key-Value ペアは、長さバイトから始まり、その後に最大 255 バイトのテキストが続きます。キーは最初の「=」文字の前のテキストであり、値は最初の「=」文字の後のテキストです。この仕様では、レコードに値を指定することができません。この場合、値が「=」にならないか、「=」文字の後にテキストがなくなります。(DNS-SD の仕様: "6.1. DNS TXT レコードの一般的な形式ルール(DNS TXT レコードの形式)&6.2。DNS-SD TXT レコードのサイズ(推奨の長さ)。
Privet では、デバイスから TXT レコードで次の Key-Value ペアを送信する必要があります。Key-Value の文字列では、大文字と小文字は区別されません。たとえば、"CS=online" と "cs=Online" は同じです。TXT レコードの情報は、/info API を介してアクセスできる情報と同じでなければなりません(4.1.「API」セクションなど)。
TXT レコードのサイズは 512 バイト以下にすることをおすすめします。
2.2.1. txtvers
TXT 構造のバージョン。txtvers は TXT 構造の最初のレコードでなければなりません。現在サポートされているバージョンは 1 のみです。
txtvers=1
2.2.2. ty
ユーザーが読み取り可能なデバイス名を指定します。次に例を示します。
ty=Google Cloud Ready Printer Model XYZ
2.2.3. メモ(省略可)
ユーザーが読み取り可能なデバイス名を指定します。次に例を示します。
note=1st floor lobby printer
注: これは省略可能なキーで、スキップできます。ただし、存在する場合、ユーザーはこの値を変更できるべきです。デバイスを登録する際にも同じ説明を使用しなければなりません。
2.2.4. URL
このデバイスが接続されているサーバー URL(プロトコルを含む)。次に例を示します。
url=https://www.google.com/cloudprint
2.2.5. タイプ
このデバイスでサポートされているデバイスのサブタイプのカンマ区切りリスト。形式は、"type=_subtype1,_subtype2" です。現在、サポートされているデバイスのサブタイプは printer のみです。
type=printer
リストされた各サブタイプは、対応する PTR レコードを使用してアドバタイズする必要があります。サポートされているサービス サブタイプごとに、対応する項目が 1 つ必要です。サービスのサブタイプ名(<subtype>._sub._privet._tcp)は、ここでデバイスタイプと同じにする必要があります。
2.2.6. ID
デバイス ID。デバイスがまだ登録されていない場合は、このキーが存在する必要がありますが、値は空である必要があります。次に例を示します。
id=11111111-2222-3333-4444-555555555555 id=
2.2.7. cs
デバイスの現在の接続状態を示します。この仕様では 4 つの有効な値が定義されています。
- "online" は、デバイスが現在クラウドに接続されていることを示します。
- "Offline" デバイスはローカル ネットワークで利用可能だが、サーバーと通信できないことを示します。
- "connecting" デバイスは起動シーケンスを実行しており、まだ完全にはオンラインではないことを示します。
- "not-configure" は、デバイスのインターネット アクセスがまだ設定されていないことを示します。この値は現在使用されていませんが、仕様の今後のバージョンで役立つ可能性があります。
- cs=オンライン
- cs=オフライン
- cs=接続中
デバイスがクラウドに登録されている場合、起動時にサーバーとの接続をチェックして接続状態を検出する必要があります(たとえば、Cloud API を呼び出してデバイス設定を取得します)。デバイスは、通知チャネル(XMPP など)の接続状態を使用して、この値を報告できます。未登録のデバイスは、起動時に接続状態を検出するためにドメインを ping することがあります(たとえば、クラウド プリント デバイスの場合は www.google.com に ping を実行します)。
3. お知らせ
デバイスの起動、シャットダウン、状態変化時には、デバイスは mDNS 仕様に記載されているとおり、アナウンスメント ステップを実行しなければなりません。対応するお知らせを、少なくとも 1 秒の間隔を空けて 2 回以上送信すべきです。
3.1. 起動
mDNS 仕様に記載されているとおり、デバイスの起動時にプローブとアナウンスの手順を実行しなければなりません。この場合は、SRV、PTR、TXT レコードを送信する必要があります。可能であれば、すべてのレコードを 1 つの DNS レスポンスにグループ化することをおすすめします。そうでない場合は、SRV、PTR、TXT レコードの順序をおすすめします。
3.2. シャットダウン
デバイスのシャットダウン時に、TTL=0 で「さようならパケット」を送信して、すべての関係者に通知しようとするべきです(mDNS のドキュメントを参照)。
3.3. 更新
TXT に記載されている情報が変更された場合、デバイスはアップデートの通知を送信しなければなりません。この場合は新しい TXT レコードを送信するだけで十分です。たとえば、デバイスを登録したら、新しいデバイス ID を含むアップデート通知を送信しなければなりません。
4. API
クラウド デバイスが検出されると、ローカル ネットワーク上でデバイスとのクライアント通信が直接有効になります。すべての API は HTTP 1.1 をベースとしています。データ形式は JSON ベースです。API リクエストは、GET リクエストまたは POST リクエストです。
各リクエストには、有効な「X-Privet-Token」ヘッダーが含まれていなければなりません。「&Xt-Privet-Token"」というヘッダーにできるのは /privet/info リクエストだけです(このヘッダーは引き続き存在する必要があります)。&Xt-Privet-Token" ヘッダーがない場合、デバイスは次の HTTP 400 エラーで応答しなければなりません。
HTTP/1.1 400 Missing X-Privet-Token header.
&Xt-Privet-Token" ヘッダーが空または無効の場合、デバイスは「無効な X-Privet-Token エラー」と応答する必要があります(invalid_x_privet_token。詳しくはエラーのセクションをご覧ください)。唯一の例外は /info API です。理由とトークンの生成方法について詳しくは、付録 A: XSSI と XSRF の攻撃と防止をご覧ください。
リクエストされた API が存在しない場合、またはサポートされていない場合、デバイスは HTTP 404 エラーを返さなければなりません。
4.1. API の可用性
API が公開される前に(/info API を含む)、デバイスはサーバーに接続してローカル設定をチェックしなければなりません。ローカル設定は再起動後も保持しなければなりません。サーバーが利用できない場合は、最後に認識されたローカル設定が使用されます。デバイスがまだ登録されていない場合は、デフォルト設定に従う必要があります。
クラウド プリント デバイスは、下記の手順に沿ってローカル設定を登録、受信、更新する必要があります。
4.1.1. 登録
デバイスは登録時に、次のように &localtsettings_quot; パラメータを指定しなければなりません。
{ "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 } }次の設定が可能です。
値の名前 | 値の型 | 説明 |
---|---|---|
ローカル検出 | boolean | ローカル検出機能が許可されているかどうかを示します。「false」の場合、すべてのローカル API(/info を含む)と DNS-SD の検出を無効にする必要があります。デフォルトでは、新しく登録したデバイスは「true」を渡す必要があります。 |
access_token_enabled | boolean(省略可) | /accesstoken API をローカル ネットワークで公開するかどうかを示します。デフォルトでは「true」です。 |
printer/local_printing_enabled | boolean(省略可) | ローカル印刷機能(/printer/createjob、/printer/submitdoc、/printer/jobstate)をローカル ネットワークに公開する必要があるかどうかを示します。デフォルトでは「true」です。 |
プリンタ/コンバージョン印刷印刷が有効 | boolean(省略可) | ローカル印刷が変換のためにジョブをサーバーに送信する可能性があるかどうかを示します。ローカル印刷が有効になっている場合にのみ意味を持ちます。 |
XMPP_timeout_value | int(省略可) | XMPP チャネル ping 間の秒数を示します。デフォルトでは 300(5 分)以上でなければなりません。 |
重要: 省略可能な値がない場合は、対応する機能がデバイスで完全にサポートされていません。
4.1.2. 起動
デバイスの起動時に、サーバーに接続して、ローカル ネットワークに公開できる API を確認する必要があります。クラウド プリントに接続しているプリンタの場合は、
/cloudprint/printer?printerid=<printer_id>または
/cloudprint/list
/BackendConfig/list よりも /redeem/printer が優先されますが、どちらも機能します。
この API は、現在のデバイス パラメータ(ローカル API の設定など)を返します。サーバーからの応答は次の形式になります。
"local_settings": { "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 }, "pending": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": false, "printer/conversion_printing_enabled": false, "xmpp_timeout_value": 500 } }
"current" オブジェクトは、現時点で有効な設定を示します。
"pending" オブジェクトは、デバイスに適用する必要がある設定を示します(このオブジェクトは存在しない可能性があります)。
デバイスが「保留中」の設定を認識したら、その状態を更新しなければなりません(下記参照)。
4.1.3. 更新
設定の更新が必要な場合は、デバイスに XMPP 通知が送信されます。通知は次の形式になります。
<device_id>/update_settings
このような通知を受け取った場合、デバイスはサーバーに最新の設定を取得するよう照会しなければなりません。クラウド プリント デバイスは以下を使用しなければなりません。
/cloudprint/printer?printerid=<printer_id>
(起動時または通知により)/prem/printer API の結果として「保留中」セクションを確認した後、デバイスは内部状態を更新して新しい設定を記憶しなければなりません。サーバー API を呼び出して新しい設定を確認しなければなりません。クラウド プリンタの場合、デバイスは /redeem/update API を呼び出し、登録時と同様に &local_settings" パラメータを使用しなければなりません。
XMPP チャネルに再接続する際、デバイスは /BackendConfig/printer API を呼び出して、ローカル設定が最後に変更されたかどうかを確認します。
4.1.3.1. ローカル設定が保留中です
"local_settings" デバイスがサーバー API の呼び出しに使用するパラメータには、"pending" セクションが含まれてはなりません。
4.1.3.2現在のローカル設定
デバイスのみが「local_settings」の「current」セクションを変更できます。 他のユーザーは、保留中のセクションを変更し、デバイスがその変更をセクションに反映するまで待機します。
4.1.4. オフライン
起動時にサーバーに接続できない場合、通知の後、デバイスは最後に確認されたローカル設定を使用しなければなりません。
4.1.5. サービスからデバイスを削除する
デバイスがサービス(GCP など)から削除された場合、XMPP 通知がデバイスに送信されます。通知は次の形式になります。
<device_id>/delete
このような通知を受け取ったデバイスは、サーバーに移動して状態をチェックしなければなりません。クラウド プリント デバイスは以下を使用しなければなりません。
/cloudprint/printer?printerid=<printer_id>
デバイスは、success=false で、デバイス/プリンタの説明なしで、成功した HTTP 応答を受信しなければなりません。つまり、デバイスはサーバーから削除され、認証情報を消去してデフォルトの出荷時設定モードに移行しなければなりません。
4.2. /privet/info API
Info API は必須であり、すべてのデバイスで実装しなければならない。これは "/privet/info" の HTTP GET リクエストです。url: GET /privet/info HTTP/1.1
Info API は、デバイスとサポートする機能に関する基本情報を返します。この API は XSRF 攻撃に対して脆弱であるため、デバイスのステータスを変更したり、アクションを実行したりしてはなりません。この API では、空の「X-Privet-Token"」ヘッダーを使用できます。クライアントは、&pritt-X-Privet-Token" ヘッダーを X-Privet-Token に設定して /privet/info API を呼び出す必要があります。 ""
Info API は、検出中に TXT レコードで利用可能なデータと一致するデータを返さなければなりません。
4.2.1. 入力
/privet/info API には入力パラメータがありません。
4.2.2. 戻る
/privet/info API は、デバイスとサポートされている機能に関する基本情報を返します。
TXT 列は DNS-SD TXT レコード内の対応するフィールドを表します。
値の名前 | 値の型 | 説明 | TXT |
---|---|---|---|
version | 文字列 | サポートされている API の最新バージョン(major.minor)で、現在は 1.0 | |
名前 | 文字列 | 人間が読める形式のデバイス名。 | ty |
description | 文字列 | (省略可)デバイスの説明。ユーザーが変更できるべきです。 | メモ |
url | 文字列 | このデバイスと通信しているサーバーの URL。URL にはプロトコル仕様を含める必要があります(例: https://www.google.com/redeem)。 | url |
タイプ | 文字列のリスト | サポートされているデバイスタイプのリスト。 | タイプ |
id | 文字列 | デバイス ID。デバイスがまだ登録されていない場合は空。 | id |
デバイスの状態 | 文字列 | デバイスの状態。 アイドルは、デバイスの準備が整っていることを表します。 処理は、デバイスがビジー状態であり、機能が一時的に制限される可能性があることを意味します。 停止は、デバイスが動作しておらず、ユーザーの操作が必要なことを意味します。 | |
connection_state | 文字列 | サーバーへの接続状態(base_url)
オンライン - 利用可能な接続 オフライン - 接続なし 接続 - 起動手順の実施 未構成 - 接続がまだ設定されていません 登録済みデバイスは、通知チャネルの状態に基づいて接続状態を報告できます(XMPP 接続状態など)。 | cs |
メーカー | 文字列 | デバイスのメーカーの名前 | |
model | 文字列 | デバイスのモデル | |
シリアル番号 | 文字列 | デバイス固有の ID です。この仕様では、これは UUID でなければなりません。(GCP 1.1 仕様) (省略可)異なるクライアントが同じデバイスを識別できるように、どこでも同じシリアル番号 ID を使用することを強くおすすめします。たとえば、IPP を実装するプリンタは、[printer-device-id"] フィールドでこのシリアル番号 ID を使用できます。 | |
ファームウェア | 文字列 | デバイスのファームウェア バージョン | |
稼働時間 | int | デバイスの起動からの秒数。 | |
setup_url | 文字列 | (省略可)設定手順が記載されたページの URL(プロトコルを含む) | |
support_url | 文字列 | (省略可)サポートがあるページの URL(プロトコルを含む)、よくある質問情報 | |
update_url | 文字列 | (省略可)ファームウェアの更新手順を含むページの URL(プロトコルを含む) | |
X Privet トークン | 文字列 | XSSI 攻撃と XSRF 攻撃を防ぐために、すべての API に渡す必要がある X-Privet-Token ヘッダーの値。詳しくは 6.1 をご覧ください。 | |
api | API の説明 | サポートされている API のリスト(後述) | |
意味的状態 | JSON | (省略可)CloudDeviceState 形式のデバイスのセマンティック状態。 |
api - ローカル ネットワークで使用できる API のリストを含む JSON リスト。すべての API がローカル ネットワーク経由で同時に利用できるわけではありません。たとえば、新しく接続されたデバイスは /register API のみをサポートする必要があります。
"api": [ "/privet/register", ]デバイスの登録が完了したら、デバイスは /register API のサポートを停止すべきです。デバイスは、ローカル ネットワークを介して公開される API を提供するために、サービスも確認する必要があります。例:
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
現在、以下の API を使用できます。
- /privet/register - ローカル ネットワーク経由でデバイスを登録するための API。(詳細については、/privet/register API をご覧ください)。デバイスがクラウドに正常に登録されたら、この API を非表示にしなければなりません。
- /privet/accesstoken - デバイスからアクセス トークンをリクエストするための API(詳細については /privet/accesstoken API をご覧ください)。
- /privet/features - デバイスの機能を取得するための API(詳細は /privet/features API をご覧ください)。
- /privet/printer/* - デバイスタイプ「printer」に固有の API。詳細については、プリンタ固有の API をご覧ください。
{ "version": "1.0", "name": "Gene’s printer", "description": "Printer connected through Chrome connector", "url": "https://www.google.com/cloudprint", "type": [ "printer" ], "id": "11111111-2222-3333-4444-555555555555", "device_state": "idle", "connection_state": "online", "manufacturer": "Google", "model": "Google Chrome", "serial_number": "1111-22222-33333-4444", "firmware": "24.0.1312.52", "uptime": 600, "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en", "support_url": "http://support.google.com/cloudprint/?hl=en", "update_url": "http://support.google.com/cloudprint/?hl=en", "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659", "api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ] }インクが不足したプリンタの /privet/info レスポンスの例を以下に示します( Semantic_state フィールドに注目してください)。
{ "version": "1.0", "name": "Gene’s printer", "description": "Printer connected through Chrome connector", "url": "https://www.google.com/cloudprint", "type": [ "printer" ], "id": "11111111-2222-3333-4444-555555555555", "device_state": "stopped", "connection_state": "online", "manufacturer": "Google", "model": "Google Chrome", "serial_number": "1111-22222-33333-4444", "firmware": "24.0.1312.52", "uptime": 600, "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en", "support_url": "http://support.google.com/cloudprint/?hl=en", "update_url": "http://support.google.com/cloudprint/?hl=en", "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659", "api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ], "semantic_state": { "version": "1.0", "printer": { "state": "STOPPED", "marker_state": { "item": [ { "vendor_id": "ink", "state": "EXHAUSTED", "level_percent": 0 } ] } } } }
4.2.3. エラー
/privet/info API は、X-Privet-Token ヘッダーがない場合にのみエラーを返します。HTTP 400 エラーでなければなりません。
HTTP/1.1 400 Missing X-Privet-Token header.
4.3. /privet/register API
/privet/register API の使用は任意です。これは HTTP POST リクエストです。/privet/register API は、有効な X-Privet-Token ヘッダーを確認しなければなりません。デバイスは、この API を "/privet/register" url に実装しなければなりません。
POST /privet/register?action=start&user=user@domain.com HTTP/1.1 POST /privet/register?action=complete&user=user@domain.com HTTP/1.1
現時点で匿名登録が可能な場合にのみ、デバイスで /privet/register API を公開する必要があります。次に例を示します。
- デバイスの電源がオンになったとき(またはデバイスの特別なボタンをクリックした後)で、まだ登録されていない場合は、ローカル ネットワークからユーザーがプリンタを取得できるように /privet/register API を公開する必要があります。
- 登録が完了すると、ローカル ネットワーク上の別のユーザーがデバイスを再利用できないようにするため、デバイスは /privet/register API の公開を停止します。
- デバイスによっては、デバイスの登録方法が異なることがあるため、/privet/register API を公開しないでください(Chrome クラウド プリント コネクタなど)。
登録プロセスは 3 つのステップで構成されます(クラウド プリントの匿名登録をご覧ください)。
- 匿名での登録プロセスを開始します。
- クライアントは、/privet/register API を呼び出してこのプロセスを開始します。デバイスはその時点でユーザーの確認を待つことができます。
- 要求トークンを取得します。
デバイスが続行する準備ができているかどうかをポーリングします。デバイスの準備ができると、登録トークンと登録 URL を取得するリクエストをサーバーに送信します。受信したトークンと URL は、クライアントに返すべきです。このステップで、登録を初期化する別の呼び出しをデバイスが受け取った場合、:
- 登録を開始したのと同じユーザーの場合、以前のデータ(ある場合)をすべて削除し、新しい登録プロセスを開始します。
- 別のユーザーの場合、device_busy エラーと 30 秒のタイムアウトを返します。
登録プロセスを完了します。
クライアントがデバイスを申請したら、クライアントはデバイスに登録を完了するよう通知する必要があります。登録プロセスが完了すると、新しく取得したデバイス ID を含むアップデートの通知がデバイスから送信されます。
注: デバイスが /privet/register API 呼び出しを処理している場合、他の /privet/register API 呼び出しが同時に処理されることはありません。デバイスは、device_busy エラーと 30 秒のタイムアウトを返さなければなりません。
ユーザー自身でデバイスの登録を確認することを強くおすすめします。実装された場合、デバイスは /privet/register?action=start API 呼び出しを受け取った後にユーザーの確認を待つ必要があります。クライアントは /privet/register?action=getClaimToken API を呼び出して、ユーザーの確認が完了し、要求トークンが使用可能になったときに通知します。ユーザーがデバイスで登録をキャンセルした場合(たとえば、キャンセル ボタンを押した場合)は、user_cancel エラーを返さなければなりません。ユーザーが特定の期間内に登録を確認しなかった場合、confirm_timeout エラーを返さなければなりません。詳しくは、デフォルトのセクションをご覧ください。
4.3.1. 入力
/privet/register API には次の入力パラメータがあります。名前 | 価値 |
---|---|
アクション | 次のいずれかになります。
start - 登録プロセスを開始 getClaimToken - デバイスの要求トークンを取得 cancel - 登録プロセスをキャンセル complete - 登録プロセスを完了 |
ユーザー | このデバイスを申請するユーザーのメールアドレス。 |
デバイスは、すべてのアクション(start、getClaimToken、cancel、complete)のメールアドレスが一致することを確認する必要があります。
4.3.2. 戻る
/privet/register API は次のデータを返します。値の名前 | 値のタイプ | 説明 |
---|---|---|
アクション | 文字列 | 入力パラメータと同じアクションです。 |
ユーザー | 文字列(省略可) | 入力パラメータと同じユーザー(入力で省略された場合は欠落している場合がある)。 |
token | 文字列(省略可) | 登録トークン(&gett;getClaimToken" レスポンスの場合は必須。"start"、"complete"、"cancel" の場合は省略されます)。 |
申し立ての URL | 文字列(省略可) | 登録 URL("getClaimToken" レスポンスの場合は必須。開始&&tt; start"、"complete"、"cancel" は省略)。クラウド プリンタの場合は、サーバーから受信された &completet_Invite_url" である必要があります。 |
自動申し立て URL | 文字列(省略可) | 登録 URL("getClaimToken" レスポンスの場合は必須。開始&&tt; start"、"complete"、"cancel" は省略)。クラウド プリンタでは、サーバーからの「auto_Invite_url"」を受信している必要があります。 |
デバイス ID | 文字列(省略可) | 新しいデバイス ID(「開始」のレスポンスでは省略し、「完了」では必須)。 |
登録の完了後にのみ、デバイスは /privet/info API レスポンスでデバイス ID を返さなければなりません。
例 1:
{ "action": "start", "user": "user@domain.com", }
例 2:
{ "action": "getClaimToken", "user": "user@domain.com", "token": "AAA111222333444555666777", "claim_url": "https://domain.com/SoMeUrL", }
例 3:
{ "action": "complete", "user": "user@domain.com", "device_id": "11111111-2222-3333-4444-555555555555", }
4.3.3. エラー
/privet/register API から次のエラーが返される場合があります(詳しくは「エラー」セクションをご覧ください)エラー | 説明 |
---|---|
デバイスが使用中 | デバイスがビジー状態で、リクエストされた操作を実行できません。タイムアウト後に再試行してください。 |
pending_user_action | &gett;getClaimToken" に応答します。このエラーは、デバイスがユーザーの確認待ちであることを示しています。&gett;getClaimToken" リクエストはタイムアウト後に再試行されます。 |
user_cancel | ユーザーがデバイスから登録プロセスを明示的にキャンセルしました。 |
確認_タイムアウト | ユーザー確認がタイムアウトしました。 |
Invalid_action | 無効なアクションが呼び出されます。たとえば、クライアントが action=start と action=getClaimToken を呼び出す前に action=complete を呼び出した場合、 |
Invalid_params | リクエストで指定されたパラメータが無効です。(今後の互換性のために、不明なパラメータは無視してかまいません)。たとえば、クライアントが action=unknown または user= を呼び出した場合にこれを返します。 |
デバイス設定エラー | デバイス側の日付と時刻(またはその他の設定)が間違っている。ユーザーは(デバイスの内部ウェブサイトに移動して)デバイス設定を行う必要があります。 |
オフライン | デバイスは現在オフラインのため、サーバーと通信できません。 |
サーバーエラー | 登録プロセス中にサーバーエラーが発生しました。 |
invalid_x_privet_token | X-Privet-Token が、リクエストが無効または空です。 |
登録が正常に完了したら、デバイスは /privet/register API の公開を停止しなければなりません。デバイスが /privet/register API を公開していない場合は、HTTP 404 エラーを返さなければなりません。したがって、デバイスがすでに登録されている場合は、この API を呼び出すと 404 を返さなければなりません。X-Privet-Token ヘッダーがない場合、デバイスは HTTP 400 エラーを返さなければなりません。
4.4. /privet/accesstoken
/privet/accesstoken API はオプションです。これは HTTP GET リクエストです。/privet/accesstoken API は、有効な "X-Privet-Token" ヘッダーを確認しなければなりません。デバイスは、この API を "/privet/accesstoken" URL に実装しなければなりません。GET /privet/accesstoken HTTP/1.1
デバイスは、/accesstoken API 呼び出しを受信すると、サーバーを呼び出して特定のユーザーのアクセス トークンを取得し、トークンをクライアントに返します。クライアントはアクセス トークンを使用して、クラウド経由でこのデバイスにアクセスします。
クラウド プリント デバイスは、次の API を呼び出す必要があります。
/cloudprint/proximitytokenそして、ローカル API から "printerid=<printer_id>" および "user" パラメータを渡します。成功した場合、サーバー レスポンスには次のオブジェクトが含まれます。
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }クラウド プリント デバイスは、レスポンス内の &近接/トークン API 呼び出しの値をローカル /privet/accesstoken API 呼び出しに渡す必要があります。すべてのパラメータ(この仕様に記載されていないパラメータを含む)をデバイスが渡せると、より有利(将来性が高い)になります。
4.4.1. 入力
/privet/accesstoken API には次の入力パラメータがあります。名前 | 価値 |
---|---|
ユーザー | このアクセス トークンの使用を試みたユーザーのメールアドレス。リクエストで空になっている場合もあります。 |
4.4.2. 戻る
/privet/accesstoken API は、以下のデータを返します。値の名前 | 値のタイプ | 説明 |
---|---|---|
token | 文字列 | サーバーから返されたアクセス トークン |
ユーザー | 文字列 | 入力パラメータと同じユーザーです。 |
expires_in | int | このトークンが期限切れになるまでの秒数。サーバーから受信し、このレスポンスで渡します。 |
例:
{ "token": "AAA111222333444555666777", "user": "user@domain.com", "expires_in": 600 }
4.4.3. エラー
/privet/accesstoken API は、次のエラーを返すことがあります(詳しくは、エラーのセクションをご覧ください)。エラー | 説明 |
---|---|
オフライン | デバイスは現在オフラインのため、サーバーと通信できません。 |
アクセス拒否 | 十分な権限がありません。アクセスが拒否されました。サーバーがリクエストを明示的に拒否した場合、デバイスはこのエラーを返します。 |
Invalid_params | リクエストで指定されたパラメータが無効です。(今後の互換性のために、不明なパラメータは無視してかまいません)。たとえば、クライアントが /accesstoken?user= または /accesstoken を呼び出した場合。 |
サーバーエラー | サーバーエラーです。 |
invalid_x_privet_token | X-Privet-Token が、リクエストが無効または空です。 |
デバイスが /privet/accesstoken API を公開していない場合は、HTTP 404 エラーを返さなければなりません。X-Privet-Token ヘッダーがない場合、デバイスは HTTP 400 エラーを返さなければなりません。
4.5. /privet/features API
/privet/features API は省略可能です。これは HTTP GET リクエストです。/privet/features API は、有効な "X-Privet-Token" ヘッダーを確認しなければなりません。デバイスは、この API を "/privet/features" url: に実装しなければなりません。GET /privet/capabilities HTTP/1.1デバイスは /features API 呼び出しを受け取ったとき、更新された機能を取得するためにサーバーと通信すべきです。たとえば、プリンタがローカルで受信した印刷ジョブをクラウド プリント サービス経由で自身に送信する場合は、クラウド プリント サービスが返す機能を返す必要があります。この場合、クラウド プリントは、プリンタにジョブを送信する前に実行する新機能を追加して、元のプリンタ機能を変更することがあります。最も一般的なのは、サポートされているドキュメント タイプのリストです。プリンタがオフラインの場合は、サポートしているドキュメント タイプが返されます。ただし、プリンタがオンラインであり、クラウド プリントに登録されている場合は、サポートされているタイプとして「*/*"」を返さなければなりません。この場合は、必要な変更がクラウド プリント サービスで実行されます。オフライン印刷の場合、プリンタは少なくとも「画像/pwg-raster」形式をサポートしなければなりません。
4.5.1. 入力
/privet/features API には次の入力パラメータがあります。名前 | 価値 |
---|---|
オフライン | (省略可)オフライン名 1 のみを使用できます。この場合、デバイスはオフラインで使用できる機能(「オンライン」機能と異なる場合)を返す必要があります。 |
4.5.2. 戻る
/privet/features API はデバイス機能を Cloud Device Description(CDD)JSON 形式で返します(詳しくは CDD ドキュメントをご覧ください)。プリンタは、少なくともサポートされているタイプのリストをここに返さなければなりません。たとえば、現在オンラインのクラウド対応プリンタは、少なくとも次のような内容を返します。{ "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" } ] } }
注: プリンタは、サポートされているコンテンツ タイプの優先順位を順序を使用して表します。たとえば、上記のサンプルでは、プリンタが "image/pwg-raster" と "image/jpeg" よりもデータを優先するよう指定しています。可能であれば、クライアントはプリンタの優先度設定に従う必要があります(詳細については、CDD ドキュメントをご覧ください)。
4.5.3. エラー
/privet/features API から次のエラーが返されることがあります(詳しくは「エラー」セクションをご覧ください)エラー | 説明 |
---|---|
invalid_x_privet_token | X-Privet-Token が、リクエストが無効または空です。 |
デバイスが /privet/features API を公開していない場合は、HTTP 404 エラーを返さなければなりません。X-Privet-Token ヘッダーがない場合、デバイスは HTTP 400 エラーを返さなければなりません。
4.6. エラー
上記の API から、次の形式でエラーが返されます。値の名前 | 値のタイプ | 説明 |
---|---|---|
error | 文字列 | エラーの種類(API ごとに定義) |
description | 文字列(省略可) | 人が読める形式のエラーの説明。 |
server_api | 文字列(省略可) | サーバーエラーの場合、このフィールドに失敗したサーバー API が含まれます。 |
サーバーコード | int(省略可) | サーバーエラーの場合、このフィールドには、サーバーから返されたエラーコードが含まれます。 |
server_http_code | int(省略可) | サーバー HTTP エラーの場合、このフィールドには、返された HTTP エラーコード サーバーが含まれます。 |
timeout | int(省略可) | クライアントが再試行するまで待機する秒数(回復可能なエラーの場合のみ)。クライアントは、実際のタイムアウトをこの値から +20% の値にランダム化しなければなりません。 |
X-Privet-Token ヘッダーがない場合、すべての API は HTTP 400 エラーを返さなければなりません。
HTTP/1.1 400 X-Privet-Token ヘッダーがありません。
例 1:
{ "error": "server_error", "description": "Service unavailable", "server_api": "/submit", "server_http_code": 503 }
例 2:
{ "error": "printer_busy", "description": "Printer is currently printing other job", "timeout": 15 }
5. プリンタ API
このプロトコルがサポートするデバイスタイプの一つは、タイププリンタです。このタイプをサポートするデバイスは、プリンタに固有の機能を実装しても構いません。クラウド対応プリンタへの印刷は、クラウド プリント サーバーで行うのが理想的です。
場合によっては、クライアントがドキュメントをローカルに送信する必要があります。クライアントが Google ID を持たない場合、またはクラウド プリント サーバーと通信できない場合に必要になることがあります。その場合は、印刷ジョブがローカルでプリンタに送信されます。プリンタは、ジョブのキューイングと変換にクラウド プリント サービスを使用します。プリンタは、ローカルで送信されたジョブをクラウド プリント サービスに送信し直して、クラウド経由で送信したジョブに再度リクエストします。このプロセスは、サービス(変換)と印刷ジョブの管理/トラッキングに関して柔軟に対応できます。
クラウド プリント サービスは変換を実装しているため、プリンタは、サポートされているコンテンツ タイプのリスト内のすべての入力形式("*/*")をサポートすべきです。
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
完全なオフラインのソリューションが必要な場合もあります。プリンタでサポートされる入力形式の数は限られているため、クライアントはドキュメントをネイティブでサポートされている数件のプリンタ形式に変換する必要があります。
この仕様では、すべてのプリンタでオフライン印刷のケースの PWG ラスター("image/pwg-raster")形式をサポートする必要があります。プリンタが他の形式(JPEG など)をサポートしている場合、クライアントでサポートされていれば、その形式でドキュメントを送信できます。プリンタは、次のように、/features API を介してサポートされているタイプを公開しなければなりません。
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }クライアントがローカル ネットワークを介して印刷を開始する方法は 2 つあります。
シンプルな印刷 - クライアントはローカル ネットワーク経由で /submitdoc API にドキュメントを送信します(job_id パラメータは指定しません)。送信したドキュメントはデフォルトの印刷チケット設定を使用して印刷されます。印刷ジョブのステータスは必要ありません。プリンタでこのタイプの印刷のみがサポートされている場合は、/privet /info API レスポンスでのみ/submitdoc API をアドバタイズしなければなりません。
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
高度な印刷 - クライアントは、リクエストで有効な CJT ジョブチケットを指定して /privet/printer/createjob API を呼び出し、プリンタで印刷ジョブを作成する必要があります。プリンタは、印刷チケットをメモリに保存し、job_id をクライアントに返す必要があります。次に、クライアントは /printer/submitdoc API を呼び出して、以前に受信した job_id を指定します。この時点で、プリンタが印刷を開始します。クライアントは、/privet/printer/jobstate API を呼び出して、プリンタの印刷ジョブのステータスをポーリングします。
マルチクライアント環境では、この API の呼び出し方法に保証はありません。あるクライアントが、別のクライアントの /createjob->/submitdoc 呼び出しの間に /createjob を呼び出すことができます。デッドロックの可能性をなくし、ユーザビリティを向上させるために、プリンタで保留中の印刷ジョブの小さなキュー(3 ~ 5 個以上)を用意することをおすすめします。
- /createjob はキュー内で最初に使用可能になる場所を取得します。
- ジョブの有効期間(キュー内)が 5 分以上である。
- キュー内のすべてのスポットが取得されると、最も古い印刷されていないジョブが削除され、新しいジョブが配置されます。
- 現在、デバイスで印刷ジョブ(簡易印刷または高度な印刷)が行われている場合、/submitdoc はビジー状態を返し、この印刷ジョブを再試行するためのタイムアウトを提案する必要があります。
- /submitdoc が(置換またはタイムアウトによって)キューから削除されたジョブを参照した場合、プリンタはエラー invalid_print_job を返し、クライアントは /createjob ステップでプロセスを再試行します。クライアントは、再試行するまで最大 5 秒間のランダムなタイムアウト時間を待機しなければなりません。
メモリの制約により、複数の保留中のジョブがデバイスに保存できない場合は、1 つの印刷ジョブのキューが長くなる可能性があります。前と同じプロトコルに従う必要があります。ジョブが完了するか、エラーが発生して失敗した場合、プリンタはジョブのステータスに関する情報を 5 分以上保存する必要があります。完了したジョブ ステータスを保存するためのキューサイズは 10 以上である必要があります。保存する必要のあるジョブ ステータスがさらにある場合は、最も古いステータスを 5 分間のタイムアウト前にキューから削除できます。
注: 現在のところ、クライアントはジョブ ステータスをポーリングします。今後、いずれかの印刷ジョブ ステータスが変更されたときに、プリンタから TXT DNS 通知の送信が求められる可能性があります。
5.1. /privet/printer/createjob API
/privet/printer/createjob API はオプションです(上記の「シンプルな印刷」をご覧ください)。これは HTTP POST リクエストです。/privet/printer/createjob API は、有効な "X-Privet-Token" ヘッダーを確認しなければなりません。 デバイスは、この API を "/privet/printer/createjob" url に実装しなければなりません。url:
POST /privet/printer/createjob HTTP/1.1/privet/printer/createjob API 呼び出しを受け取ると、プリンタは新しい印刷ジョブ ID を作成し、受け取った印刷チケットを CJT 形式で保存して、印刷ジョブ ID をクライアントに返す必要があります。
5.1.1. 入力
/privet/printer/createjob API には、URL に入力パラメータがありません。リクエストの本文には、CJT 形式の印刷ジョブ チケットデータを含める必要があります。5.1.2. 戻る
/privet/printer/createjob API は次のデータを返します。値の名前 | 値のタイプ | 説明 |
---|---|---|
job_id | 文字列 | 新しく作成された印刷ジョブの ID。 |
expires_in | int | この印刷ジョブが有効な秒数。 |
例:
{ "job_id": "123", "expires_in": 600 }
5.1.3. エラー
/privet/printer/createjob API から次のエラーが返されることがあります(詳しくは「エラー」セクションをご覧ください)。エラー | 説明 |
---|---|
Invalid_Ticket | 送信された印刷チケットが無効です。 |
プリンタが混雑している | プリンタがビジー状態で、現在 /createjob を処理できません。タイムアウト後に再試行してください。 |
プリンタエラー | プリンタがエラー状態にあり、修正するにはユーザーの操作が必要です。 説明に、より詳細な説明を記載する必要があります(例: 「トレイ 1 の用紙ジャム」)。 |
invalid_x_privet_token | X-Privet-Token が、リクエストが無効または空です。 |
デバイスが /privet/printer/createjob を公開していない場合は、HTTP 404 エラーを返さなければなりません。X-Privet-Token ヘッダーがない場合、デバイスは HTTP 400 エラーを返さなければなりません。
5.2. /privet/printer/submitdoc API
ローカル ネットワーク経由の印刷(オフラインまたはクラウド プリントへの再投稿)を実装するには、/privet/printer/submitdoc API が必要です。これは HTTP POST リクエストです。/privet/printer/submitdoc API は、有効な「X-Privet-Token"」ヘッダーをチェックしなければなりません。デバイスは、この API を "/privet/printer/submitdoc" url:POST /privet/printer/submitdoc HTTP/1.1に実装しなければなりません。/privet/printer/submitdoc API 呼び出しを受け取ったとき、プリンタは印刷を開始する必要があります。印刷を開始できない場合は、エラー printin_busy と、クライアントが再試行するまで待機する推奨タイムアウト期間を返す必要があります。
内部バッファにすべてのデータを保持できない場合、プリンタは、ドキュメントの一部を出力して TCP メカニズムを使用してデータ転送速度を遅くし、バッファの一部を再び利用できるようにすべきです。(たとえば、プリンタで TCP レイヤに windowsize=0 を設定すると、クライアントが待機状態になります)。
プリンタにドキュメントを送信すると、処理に時間がかかることがあります。クライアントは、印刷中にプリンタとジョブの状態(高度な印刷)を確認できます。 そのためには、プリンタは、/privet/printer/submitdoc API 呼び出しの処理中に、クライアントが/privet/info API と /privet/printer/jobstate API を呼び出せるようにしなければなりません。すべてのクライアントが新しいスレッドを開始して /privet/printer/submitdoc API 呼び出しを行うことをおすすめします。これにより、メインスレッドは /privet/info API と /privet/printer/jobstate API を使用してプリンタとジョブの状態を確認できるようになります。
注: ローカル印刷ジョブが完了または中断したら、会計処理とユーザー エクスペリエンスの目的で、ジョブの最終的な状態を /prem/submit インターフェースに報告することを強くおすすめします(また、この仕様の将来のバージョンで必要になります)。パラメータ「printerid"」、「&titlet」、「quot;contentType」または指定された PrintJobState は実際には最終状態である必要があります。つまり、そのタイプは DONE または ABORTED である必要があります。また、ABORTED の場合は原因を指定する必要があります(詳細については JobState をご覧ください)。また、ローカル印刷ジョブを報告するための /BackendConfig/submit インターフェースの使用については、仕様には記載されていません。このセクションはインターフェースの主要な用途である &contentt.quot; パラメータで提供するドキュメントとともに印刷ジョブを送信することを目的としているためです。
5.2.1. 入力
/privet/printer/submitdoc API には、次の入力パラメータがあります。名前 | 価値 |
---|---|
job_id | (省略可)印刷ジョブ ID。単純な印刷の場合は省略できます(上記参照)。プリンタから返されたものと一致する必要があります。 |
ユーザー名 | (省略可)人が読める形式のユーザー名。これは確実なものではなく、印刷ジョブのアノテーションにのみ使用してください。ジョブをクラウド プリント サービスに再投稿する場合は、この文字列をクラウド プリント ジョブに添付する必要があります。 |
クライアント名 | (省略可)このリクエストを行うクライアント アプリケーションの名前。表示のみを目的としています。ジョブをクラウド プリント サービスに再投稿する場合は、この文字列をクラウド プリント ジョブに添付する必要があります。 |
ジョブ名 | (省略可)記録する印刷ジョブの名前。ジョブをクラウド プリント サービスに再投稿する場合は、この文字列をクラウド プリント ジョブに添付する必要があります。 |
オフライン | (省略可)オフライン値=1 の場合のみ設定できます。この場合、プリンタはオフラインで印刷することのみを試みる必要があります(クラウド プリント サーバーに再投稿しないでください)。 |
リクエストの本文には、印刷する有効なドキュメントが含まれている必要があります。"Content-Length" リクエストの長さを正しく含める必要があります。"Content-Type" ヘッダーは、ドキュメントの MIME タイプに設定し、CDD のタイプのいずれかと一致する必要があります(CDD が "*/*" を指定している場合を除く)。
このリクエストには、有効なユーザー名(またはメールアドレス)とクライアント名およびジョブ名を指定することを強くおすすめします。これらのフィールドは、ユーザー エクスペリエンスの向上のために UI でのみ使用されます。
5.2.2. 戻る
/privet/printer/submitdoc API は、以下のデータを返します。値の名前 | 値のタイプ | 説明 |
---|---|---|
job_id | 文字列 | 新しく作成された印刷ジョブの ID(簡単な印刷)またはリクエストで指定された job_id(高度な印刷) |
expires_in | int | この印刷ジョブが有効な秒数。 |
ジョブタイプ | 文字列 | 送信したドキュメントのコンテンツ タイプ。 |
ジョブサイズ | 整数 64 ビット | 印刷データのサイズ(バイト単位)。 |
ジョブ名 | 文字列 | (省略可)入力と同じジョブ名(存在する場合)。 |
例:
{ "job_id": "123", "expires_in": 500, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
5.2.3. エラー
/privet/printer/submitdoc API は、次のエラーを返す場合があります(詳しくは、エラーのセクションをご覧ください)。エラー | 説明 |
---|---|
invalid_print_job(無効な印刷ジョブ) | リクエストに無効な/期限切れのジョブ ID が指定されています。タイムアウト後に再試行してください。 |
無効なドキュメント タイプ | ドキュメントの MIME タイプはプリンタでサポートされていません。 |
無効なドキュメント | 送信されたドキュメントは無効です。 |
ドキュメントサイズが大きすぎます | ドキュメントが最大サイズを超えています。 |
プリンタが混雑している | プリンタがビジー状態で、現在ドキュメントを処理できません。タイムアウト後に再試行してください。 |
プリンタエラー | プリンタがエラー状態にあり、修正するにはユーザーの操作が必要です。 説明に、より詳細な説明を記載する必要があります(例: 「トレイ 1 の用紙ジャム」)。 |
Invalid_params | リクエストで指定されたパラメータが無効です。(今後の互換性のために、不明なパラメータは無視してください)。 |
user_cancel | ユーザーがデバイスから印刷プロセスを明示的にキャンセルした。 |
サーバーエラー | クラウド プリントにドキュメントを投稿できませんでした。 |
invalid_x_privet_token | X-Privet-Token が、リクエストが無効または空です。 |
デバイスが /privet/printer/submitdoc を公開していない場合は、HTTP 404 エラーを返さなければなりません。X-Privet-Token ヘッダーがない場合、デバイスは HTTP 400 エラーを返さなければなりません。
注: /privet/printer/submitdoc API では、ペイロードが大容量のため、プリンタ側では特別な処理が必要になることがあります。プリンタの HTTP サーバーの実装とプラットフォームによっては、HTTP エラーを返す前にプリンタがソケットを閉じてしまうことがあります。それ以外では、プリンタは(Privet エラーではなく)503 エラーを返すことがあります。プリンタは、できる限り Privet を返そうとすべきです。ただし、Privet 仕様を実装するすべてのクライアントは、ソケットのクローズ(HTTP エラーなし)と /privet/printer/submitdoc API の 503 HTTP エラーケースを処理できるべきです。この場合、クライアントは Privet "printer_busy" エラーと "timeout" 15 秒に設定されたものとして処理すべきです。無限再試行を避けるために、クライアントは一定の試行回数(たとえば 3 回)後に再試行を停止できます。
5.3. /privet/printer/jobstate API
/privet/printer/jobstate API はオプションです(上記の「シンプルな印刷」をご覧ください)。これは HTTP GET リクエストです。/privet/printer/jobstate API は、有効な "X-Privet-Token" ヘッダーを確認しなければなりません。デバイスは、この API を "/privet/printer/jobstate" url に実装しなければなりません。GET /privet/printer/jobstate HTTP/1.1/privet/printer/jobstate API 呼び出しを受信すると、プリンタは、指定された印刷ジョブのステータスまたは invalid_print_job エラーを返す必要があります。
5.3.1. 入力
/privet/printer/jobstate API には、次の入力パラメータがあります。名前 | 価値 |
---|---|
job_id | ステータスを返すジョブ ID を出力します。 |
5.3.2. 戻る
/privet/printer/jobstate API は、次のデータを返します。値の名前 | 値のタイプ | 説明 |
---|---|---|
job_id | 文字列 | 該当するステータス情報の印刷ジョブ ID。 |
state | 文字列 | 未公開 - 印刷ジョブがデバイスに作成されている(/privet/printer/submitdoc 呼び出しはまだ受信されていない)。 キューに格納済み - 印刷ジョブを受信してキューに追加しましたが、印刷はまだ開始されていません。 in_progress - 印刷ジョブが印刷中です。 停止 - 印刷ジョブは一時停止されましたが、手動または自動で再開できます。 done - 印刷ジョブが完了しました。 aborted - 印刷ジョブが失敗しました。 |
description | 文字列 | (省略可)人が読める形式の印刷ジョブのステータスの説明。state< が停止または中止された場合は、追加情報を含める必要があります。通常、semantic_state フィールドにより、クライアントによりわかりやすく有意な説明が提供されます。 |
expires_in | int | この印刷ジョブが有効な秒数。 |
ジョブタイプ | 文字列 | (省略可)送信したドキュメントのコンテンツ タイプ。 |
ジョブサイズ | 整数 64 ビット | (省略可)印刷データのサイズ(バイト単位)。 |
ジョブ名 | 文字列 | (省略可)入力と同じジョブ名(存在する場合)。 |
server_job_id | 文字列 | (省略可)サーバーから返されたジョブの ID(ジョブがクラウド プリント サービスに送信された場合)。オフライン印刷の場合は省略します。 |
意味的状態 | JSON | (省略可)PrintJobState 形式のジョブのセマンティック状態。 |
例(クラウド プリントから報告することで印刷):
{ "job_id": "123", "state": "in_progress", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document", "server_job_id": "1111-2222-3333-4444" }
例(オフライン印刷エラー):
{ "job_id": "123", "state": "stopped", "description": "Out of paper", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
例(ユーザーが中止した印刷ジョブ):
{ "job_id": "123", "state": "aborted", "description": "User action", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document", "semantic_state": { "version": "1.0", "state": { "type": "ABORTED", "user_action_cause": {"action_code": "CANCELLED"} }, "pages_printed": 7 } }
例(用紙切れのため印刷ジョブが停止した)。デバイスの状態への参照に注意してください。クライアントは、デバイスの状態に関する詳細情報を取得するために、/privet/info API を呼び出す必要があります。
{ "job_id": "123", "state": "stopped", "description": "Out of paper", "expires_in": 100, "job_type": "application/pdf", "job_size": "123456", "job_name": "My PDF document", "semantic_state": { "version": "1.0", "state": { "type": "STOPPED", "device_state_cause": {"error_code": "INPUT_TRAY"} }, "pages_printed": 7 } }
5.3.3. エラー
/privet/printer/jobstate API は、次のエラーを返す場合があります(詳細については、「エラー」セクションをご覧ください)。エラー | 説明 |
---|---|
invalid_print_job(無効な印刷ジョブ) | リクエストに無効な/期限切れのジョブ ID が指定されています。 |
サーバーエラー | 印刷ジョブのステータス(クラウド プリントに投稿された印刷ジョブの場合)を取得できませんでした。 |
invalid_x_privet_token | X-Privet-Token が、リクエストが無効または空です。 |
デバイスが /privet/printer/jobstate を公開していない場合は、HTTP 404 エラーを返さなければなりません。X-Privet-Token ヘッダーがない場合、デバイスは HTTP 400 エラーを返さなければなりません。
6. 付録
6.1. デフォルトの動作と設定
このセクションでは、Privet 互換のすべてのデバイスで想定されるデフォルトの動作について説明します。- すぐに使用できるデバイスは、/privet/info API と /privet/register API のみをサポートする必要があります。他のすべての API(/privet/accesstoken、ローカル印刷など)を無効にする必要があります。
- 登録には、デバイスの物理的な操作が必要です。
- ユーザーは、デバイスへのアクセスを確かめるために、デバイスへの物理的なアクション(ボタンを押すなど)をしなければなりません。
- ユーザーが上記の操作を行った後、プリンタは /BackendConfig/register リクエストを送信する必要があります。このリクエストは、アクションが行われるまで送信しないでください(シーケンス図 1 を参照)。
- デバイスが /privet/register リクエストを処理している場合(たとえば、上記のアクションを待機している場合)、デバイスは他のすべての /privet/register リクエストを拒否する必要があります。この場合、デバイスは device_busy エラーを返さなければなりません。
- デバイスは、60 秒以内に上記の物理的なアクションを受け取らない /register リクエストをタイムアウトする必要があります。デバイスは、この場合は confirm_timeout エラーを返さなければなりません。
- 省略可能: 推奨されるものですが、ユーザー エクスペリエンスが向上することがあります。
- プリンタがライトや画面を点滅させて、登録の確認の操作をユーザーに求めることがあります。
- プリンタに「Google Cloud Print にユーザー「abc@def.com」に登録しています」というメッセージが画面に表示される場合があります。続行するには、[OK] を押します。abc@def.com は、/register API 呼び出しのユーザー パラメータです。これにより、ユーザーには以下のことが明確になります。
- ドメイン所有者の確認を求める登録リクエストです
- リクエストをトリガーしなかった場合はどうなりますか?
- プリンタから確認する物理的な操作に加えて(例:[OK ボタンを押してください])、プリンターでユーザーがリクエストをキャンセルするためのボタンを表示する場合があります(例: [キャンセルを押してキャンセルしてください])。これにより、登録リクエストをトリガーしなかったユーザーは、60 秒のタイムアウト前にキャンセルできます。この場合、デバイスは user_cancel エラーを返さなければなりません。
- オーナー権限の譲渡:
- デバイスがクラウド サービスから明示的に削除されることがあります。
- デバイスは、正常に受信したものの、/prem/printer(GCP 用)呼び出しの結果としてデバイスの説明を受け取らない場合、デフォルト(初期状態)モードに戻さなければなりません。
- デバイスの認証情報が機能しなくなった場合(サーバーからの応答が明示的に無効なために明示的に)は、デフォルト(初期状態)モードに戻す必要があります。
- ローカルで出荷時設定へのリセットの場合は、デバイスの認証情報を削除し、デフォルトの状態に設定しなければなりません。
- 省略可: デバイスに、認証情報を消去してデフォルト モードにするメニュー項目が表示されることがあります。
- XMPP 通知をサポートするデバイスには、サーバーに ping する機能が含まれなければなりません。ping タイムアウトは、local_settings" でサーバーから制御できなければなりません。
- デバイスが正常に同期されていることを確認するために、サーバーは 1 日に 1 回(24 時間)サーバーに対して明示的に ping を実行する(XMPP ping に加えて GCP の場合は /BackendConfig/printer API)場合があります。チェック ウィンドウは 24 ~ 32 時間以内にランダム化することをおすすめします。
- (省略可)クラウド プリント デバイスの場合、ユーザーがデバイスから新しい印刷ジョブの確認を開始できるように、手動の方法(ボタン)は不要です。一部のプリンタには、すでにこれがあります。
- (省略可)企業のプリンタによっては、ローカル検出を完全に無効にすることもできます。そのような場合、デバイスはサーバーでこれらのローカル設定を更新しなければなりません。新しいローカル設定は空にしなければなりません(「local_discovery"」を「false」に設定すると、GCP サービスから再度有効にできます)。
6.1.2 デフォルトの登録図
6.2. XSSI と XSRF の攻撃と防止
このセクションでは、デバイスに対する XSSI 攻撃と XSRF 攻撃の可能性と、その保護方法(トークン生成の手法を含む)について説明します。詳しくはこちらをご覧ください。 http://dataLayersecurity.blogspot.com/2011/05/website-security-for-webmasters.html
通常、サイトが Cookie 認証メカニズムを使用している場合、XSSI 攻撃と XSRF 攻撃が発生する可能性があります。Google はクラウド プリント サービスで Cookie を使用していませんが、こうした攻撃は依然として発生する可能性があります。ローカル ネットワークへのアクセスは、意図的に暗黙的にリクエストを信頼します。
6.2.1. XSSI
悪意のあるウェブサイトが Privet 対応デバイスの IP アドレスやポート番号を推測し、<t;script> タグ内で Privet API を呼び出そうとする可能性があります。保護しない場合、悪意のあるウェブサイトが API 呼び出しを実行して結果にアクセスできる可能性があります。このタイプの攻撃を防ぐため、すべての Privet API 呼び出しは、リクエストに &X-Privet-Token" ヘッダーがなければなりません。"src=<api>" スクリプトタグはヘッダーを追加できないため、この種の攻撃を効果的に防ぎます。
6.2.2. XSRF ; XSRF(# スペースや統一性の問題で必要な場合は略語も可)
http://ja.wikipedia.org/wiki/Cross-site_request_forgery攻撃者はリクエストの結果にアクセスできませんが、リクエストがアクション(印刷など)を実行すれば、トリガーされる可能性があります。この攻撃を防ぐには、次の保護が必要です。
- /privet/info API を XSRF に開放する
- /privet/info API は、デバイスに対していかなるアクションも実行してはなりません
- /privet/info API を使用して x-privet-token を受信する
- 他のすべての API は、"X-Privet-Token" ヘッダーで有効な x-privet-token をチェックしなければなりません。
- x-privet-token は、24 時間のみ有効であるべきです。
攻撃者が /privet/info API を実行できたとしても、レスポンスから x-privet-token を読み取ることができないため、他の API を呼び出すことはできません。
次のアルゴリズムを使用して XSRF トークンを生成することを強くおすすめします。
XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )
XSRF トークン生成の要素:
- ↗は特殊文字(通常は「:」)
- issue_timecounter は、なんらかのイベント(タイムスタンプの場合はエポック)またはデバイスの起動時間(CPU カウンタの場合)からの秒数です。issue_timecounter は、デバイスが稼働しているときは常に増加しています(下記のトークンの確認を参照)。
- SHA1 - SHA1 アルゴリズムを使用したハッシュ関数
- base64 - base64 エンコード
- device_secret - デバイス固有のシークレット。デバイス シークレットは再起動のたびに更新しなければなりません。
デバイスのシークレットを生成するおすすめの方法:
- 再起動のたびに新しい UUID を生成する
- 再起動のたびに 64 ビットの乱数を生成する
デバイスに発行された XSRF トークンをすべて保存する必要はありません。デバイスで XSRF トークンの有効性を確認する必要がある場合は、トークンを Base64 デコードする必要があります。後半の issue_timecounter(クリアテキスト)を取得し、device_secret + DELIMITER + issue_timecounter の SHA1 ハッシュを作成してみます。ここで、issue_timecounter はトークンからのものです。新しく生成された SHA1 がトークンの SHA1 と一致する場合、デバイスは、issue_timecounter が現在の時刻カウンタの有効期間(24 時間)内に収まっているかどうかを確認する必要があります。そのため、デバイスは現在の時刻カウンタ(CPU カウンタなど)を取得し、それから issue_timecounter を引きます。結果は、トークンの問題が発生してからの秒数でなければなりません。
重要: XSRF 対策を実装する場合は、この方法をおすすめします。Privet 仕様のクライアントは、XSRF トークンを理解しようとせず、ブラックボックスとして扱うものとします。図 6.2.3 は、X-Privet-Token を実装し、一般的なリクエストの検証を行う際に推奨される方法を示しています。