Privet to interfejs Cloud Device Local Discovery API używany przez usługi w chmurze. Ten dokument jest podzielony na te sekcje:
- Wprowadzenie: wprowadzenie do Privet
- Discovery: lokalne mechanizmy wykrywania.
- Ogłoszenia: ogłoszenia dotyczące lokalnego odkrywania
- API: prywatne interfejsy API dla ogólnych urządzeń w chmurze
- Printer API: prywatne interfejsy API używane przez drukarki.
- Dodatek: dodatkowe diagramy
1. Wprowadzenie
Urządzenia połączone z chmurą mają wiele zalet. Mogą korzystać z usług konwersji online, hostować kolejki zadań, gdy urządzenie jest offline, i być dostępne z dowolnego miejsca na świecie. Jednak w przypadku wielu urządzeń w chmurze dostępnych dla danego użytkownika musimy udostępnić metodę znajdowania najbliższego urządzenia na podstawie lokalizacji. Protokół Privet ma na celu połączenie elastyczności urządzeń w chmurze z odpowiednim mechanizmem wykrywania lokalnego, aby urządzenia można było łatwo wykrywać w nowych środowiskach.
Cele tego protokołu to:- umożliwiać wykrywanie urządzeń w chmurze w sieci lokalnej,
- rejestrować urządzenia w chmurze w usłudze w chmurze,
- powiązywać zarejestrowane urządzenia z ich reprezentacją w chmurze;
- włączyć funkcję offline,
- uprościć implementację, aby można było z niej korzystać na małych urządzeniach;
Protokół Privet składa się z 2 głównych części: wykrywania i interfejsu API. Wykrywanie służy do znajdowania urządzenia w sieci lokalnej, a interfejs API służy do uzyskiwania informacji o urządzeniu i wykonywania niektórych działań. W tym dokumencie termin „urządzenie” odnosi się do urządzenia połączonego z chmurą, które implementuje protokół Privet.
2. Odkrywanie
Wykrywanie to protokół oparty na zeroconf (mDNS + DNS-SD). Urządzenie MUSI obsługiwać adresowanie IPv4 Link-Local. Urządzenie MUSI być zgodne ze specyfikacjami mDNS i DNS-SD.
- http://www.rfc-editor.org/rfc/rfc3927.txt (IPv4 Link-local)
- http://www.rfc-editor.org/rfc/rfc4862.txt (IPv6 Link-local)
- http://www.rfc-editor.org/rfc/rfc6762.txt (mDNS)
- http://www.rfc-editor.org/rfc/rfc6763.txt (DNS-SD)
Urządzenie MUSI rozwiązywać konflikty nazw zgodnie z powyższymi specyfikacjami.
2.1. Typ usługi
W przypadku typów usług usługa DNS Service Discovery używa tego formatu: _applicationprotocol._transportprotocol. W przypadku protokołu Privet typ usługi dla DNS-SD powinien mieć postać: _privet._tcp
Urządzenie może też obsługiwać inne typy usług. Zalecamy używanie tej samej nazwy instancji usługi w przypadku wszystkich typów usług zaimplementowanych na urządzeniu. Na przykład drukarka może implementować usługi „Drukarka XYZ._privet._tcp” i „Drukarka XYZ._printer._tcp”. Ułatwi to użytkownikowi konfigurację. Klienci Privet będą jednak szukać tylko „_privet._tcp”.
Oprócz głównego typu usługi urządzenie MUSI reklamować rekordy PTR dla odpowiednich podtypów (patrz specyfikacja DNS-SD: „7.1. Selective Instance Enumeration (Subtypes)”. Format powinien być następujący: _<subtype>._sub._privet._tcp
Obecnie jedynym obsługiwanym podtypem urządzenia jest drukarka. Dlatego wszystkie drukarki MUSZĄ reklamować 2 rekordy PTR:
- _privet._tcp.local.
- _printer._sub._privet._tcp.local.
2.2. Rekord TXT
DNS Service Discovery określa pola, w których można dodać opcjonalne informacje o usłudze w rekordach TXT. Rekord TXT składa się z par klucz/wartość. Każda para klucz/wartość zaczyna się od bajtu długości, po którym następuje maksymalnie 255 bajtów tekstu. Kluczem jest tekst przed pierwszym znakiem „=” i wartością jest tekst po pierwszym znaku „=” aż do końca. Specyfikacja dopuszcza brak wartości w rekordzie. W takim przypadku nie będzie znaku „=” ani tekstu po nim. (Patrz specyfikacja DNS-SD: „6.1. Ogólne reguły formatowania rekordów DNS TXT” w sekcji „6.2. DNS-SD TXT Record Size" (Rozmiar rekordu DNS-SD TXT) w celu sprawdzenia zalecanej długości).
Privet wymaga, aby urządzenie wysyłało w rekordzie TXT te pary klucz/wartość: W ciągach tekstowych klucz/wartość wielkość liter nie jest rozróżniana, np. „CS=online” i „cs=ONLINE” to to samo. Informacje w rekordzie TXT MUSZĄ być takie same jak te, które są dostępne przez interfejs API /info (patrz sekcja 4.1). sekcja API).
Zalecamy, aby rozmiar rekordu TXT nie przekraczał 512 bajtów.
2.2.1. txtvers
Wersja struktury TXT. txtvers MUSI być pierwszym rekordem struktury TXT. Obecnie obsługiwana jest tylko wersja 1.
txtvers=1
2.2.2. ty
Zawiera nazwę urządzenia czytelną dla użytkownika. Na przykład:
ty=Google Cloud Ready Printer Model XYZ
2.2.3. note (opcjonalnie)
Zawiera nazwę urządzenia czytelną dla użytkownika. Na przykład:
note=1st floor lobby printer
Uwaga: ten klucz jest opcjonalny i można go pominąć. Jeśli jednak jest obecna, użytkownik POWINIEN mieć możliwość zmodyfikowania tej wartości. Podczas rejestracji urządzenia MUSI być użyty ten sam opis.
2.2.4. url
Adres URL serwera, z którym połączone jest to urządzenie (wraz z protokołem). Na przykład:
url=https://www.google.com/cloudprint
2.2.5. type
Lista rozdzielanych przecinkami podtypów urządzeń obsługiwanych przez to urządzenie. Format: „type=_subtype1,_subtype2”. Obecnie jedynym obsługiwanym podtypem urządzenia jest drukarka.
type=printer
Każdy wymieniony podtyp powinien być reklamowany za pomocą odpowiedniego rekordu PTR. Każdy obsługiwany podtyp usługi powinien mieć odpowiadający mu element. Nazwa podtypu usługi (<subtype>._sub._privet._tcp) powinna być tutaj równa typowi urządzenia.
2.2.6. id
Identyfikator urządzenia. Jeśli urządzenie nie zostało jeszcze zarejestrowane, ten klucz powinien być obecny, ale wartość powinna być pusta. Na przykład:
id=11111111-2222-3333-4444-555555555555 id=
2.2.7. cs
Wskazuje bieżący stan połączenia urządzenia. W tej specyfikacji zdefiniowano 4 możliwe wartości.
- „online” oznacza, że urządzenie jest obecnie połączone z chmurą.
- „offline” oznacza, że urządzenie jest dostępne w sieci lokalnej, ale nie może komunikować się z serwerem.
- „Łączenie” oznacza, że urządzenie wykonuje sekwencję uruchamiania i nie jest jeszcze w pełni online.
- „not-configured” oznacza, że dostęp do internetu na urządzeniu nie został jeszcze skonfigurowany. Ta wartość nie jest obecnie używana, ale może być przydatna w przyszłych wersjach specyfikacji.
- cs=online
- cs=offline
- cs=connecting
Jeśli urządzenie zostało zarejestrowane w chmurze, po uruchomieniu powinno sprawdzić łączność z serwerem, aby wykryć stan połączenia (np. wywołać interfejs API chmury w celu uzyskania ustawień urządzenia). Urządzenie może używać stanu połączenia z kanałem powiadomień (np. XMPP) do raportowania tej wartości. Niezarejestrowane urządzenia mogą podczas uruchamiania wysyłać ping do domeny, aby wykryć stan połączenia (np. wysyłać ping do www.google.com w przypadku urządzeń do drukowania w chmurze).
3. Ogłoszenia
Podczas uruchamiania, wyłączania lub zmiany stanu urządzenie MUSI wykonać krok ogłaszania zgodnie ze specyfikacją mDNS. POWINIEN wysłać odpowiedni komunikat co najmniej 2 razy w odstępie co najmniej 1 sekundy.
3.1. Uruchomienie
Po uruchomieniu urządzenie MUSI wykonać kroki sondowania i ogłaszania opisane w specyfikacji mDNS. W tym przypadku należy wysłać rekordy SRV, PTR i TXT. Zalecamy zgrupowanie wszystkich rekordów w jednej odpowiedzi DNS, jeśli to możliwe. W przeciwnym razie zalecamy kolejność: SRV, PTR, TXT.
3.2. Wyłączono
Podczas wyłączania urządzenia POWINNO ono powiadomić o tym wszystkie zainteresowane strony, wysyłając „pakiet pożegnalny” z TTL=0 (zgodnie z dokumentacją mDNS).
3.3 Aktualizuj
Jeśli jakiekolwiek informacje opisane w rekordzie TXT ulegną zmianie, urządzenie MUSI wysłać powiadomienie o aktualizacji. W tym przypadku wystarczy wysłać tylko nowy rekord TXT. Na przykład po zarejestrowaniu urządzenia MUSI ono wysłać komunikat z informacją o aktualizacji, w tym nowy identyfikator urządzenia.
4. Interfejs API
Po wykryciu urządzenia w chmurze komunikacja klienta z urządzeniem jest włączana bezpośrednio w sieci lokalnej. Wszystkie interfejsy API są oparte na protokole HTTP 1.1. Formaty danych są oparte na formacie JSON. Żądania API mogą być żądaniami GET lub POST.
Każde żądanie MUSI zawierać prawidłowy nagłówek „X-Privet-Token”. JEDYNYM żądaniem, które może mieć pusty nagłówek „X-Privet-Token”, jest żądanie /privet/info (pamiętaj, że nagłówek MUSI być nadal obecny). Jeśli brakuje nagłówka „X-Privet-Token”, urządzenie MUSI odpowiedzieć błędem HTTP 400:
HTTP/1.1 400 Missing X-Privet-Token header.
Jeśli nagłówek „X-Privet-Token” jest pusty lub nieprawidłowy, urządzenie MUSI odpowiedzieć „invalid X-Privet-Token error” (invalid_x_privet_token, szczegóły znajdziesz w sekcji Błędy). Jedynym wyjątkiem jest interfejs API /info. Więcej informacji o tym, dlaczego to robimy i jak generować tokeny, znajdziesz w Dodatku A: Ataki XSSI i XSRF oraz sposoby zapobiegania im.
Jeśli żądany interfejs API nie istnieje lub nie jest obsługiwany, urządzenie MUSI zwrócić błąd HTTP 404.
4.1. Dostępność interfejsu API
Zanim jakikolwiek interfejs API zostanie udostępniony (w tym interfejs API /info), urządzenie MUSI skontaktować się z serwerem, aby sprawdzić ustawienia lokalne. Ustawienia lokalne MUSZĄ być zachowywane między ponownymi uruchomieniami. Jeśli serwer jest niedostępny, należy użyć ostatnio znanych ustawień lokalnych. Jeśli urządzenie nie zostało jeszcze zarejestrowane, powinno korzystać z ustawień domyślnych.
Aby zarejestrować urządzenie, otrzymywać i aktualizować ustawienia lokalne, urządzenia Cloud Print MUSZĄ wykonać czynności opisane poniżej.
4.1.1. Rejestracja
Podczas rejestracji urządzenia MUSI ono określić parametr „local_settings” w ten sposób:
{ "current": { "local_discovery": true, "access_token_enabled": true, "printer/local_printing_enabled": true, "printer/conversion_printing_enabled": true, "xmpp_timeout_value": 300 } }
Nazwa wartości | Typ wartości | Opis |
---|---|---|
local_discovery | Wartość logiczna | Wskazuje, czy funkcja wykrywania lokalnego jest dozwolona. Jeśli wartość to „false”, wszystkie lokalne interfejsy API (w tym /info) i wykrywanie DNS-SD muszą być wyłączone. Domyślnie nowo rejestrowane urządzenia powinny przekazywać wartość „true”. |
access_token_enabled | wartość logiczna (opcjonalnie) | Wskazuje, czy interfejs API /accesstoken ma być udostępniany w sieci lokalnej. Domyślnie powinna mieć wartość „true”. |
printer/local_printing_enabled | wartość logiczna (opcjonalnie) | Wskazuje, czy funkcja drukowania lokalnego (/printer/createjob, /printer/submitdoc, /printer/jobstate) ma być udostępniana w sieci lokalnej. Domyślnie powinna mieć wartość „true”. |
printer/conversion_printing_enabled | wartość logiczna (opcjonalnie) | Wskazuje, czy drukowanie lokalne może wysyłać zadanie do serwera w celu konwersji. Ma sens tylko wtedy, gdy drukowanie lokalne jest włączone. |
xmpp_timeout_value | int (opcjonalnie) | Wskazuje liczbę sekund między pingami kanału XMPP. Domyślnie MUSI wynosić co najmniej 300 sekund (5 minut). |
Ważne: brak wartości opcjonalnej oznacza, że urządzenie w ogóle nie obsługuje odpowiedniej funkcji.
4.1.2. Uruchomienie
Po uruchomieniu urządzenie powinno skontaktować się z serwerem, aby sprawdzić, które interfejsy API są dostępne do udostępnienia w sieci lokalnej. W przypadku drukarek połączonych z Cloud Print należy wywołać:
/cloudprint/printer?printerid=<printer_id>
/cloudprint/list
Preferowany jest adres /cloudprint/printer, ale /cloudprint/list też będzie działać.
Ten interfejs API zwraca bieżące parametry urządzenia, w tym ustawienia lokalnego interfejsu API. Odpowiedź serwera będzie miała następujący format:
"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 } }
Obiekt „current” wskazuje ustawienia, które są obecnie aktywne.
Obiekt „pending” wskazuje ustawienia, które powinny zostać zastosowane na urządzeniu (tego obiektu może brakować).
Gdy urządzenie zobaczy ustawienia „oczekujące”, MUSI zaktualizować swój stan (patrz poniżej).
4.1.3. Aktualizuj
Jeśli wymagana jest aktualizacja ustawień, na urządzenie zostanie wysłane powiadomienie XMPP. Powiadomienie będzie miało następujący format:
<device_id>/update_settings
Po otrzymaniu takiego powiadomienia urządzenie MUSI wysłać zapytanie do serwera, aby pobrać najnowsze ustawienia. Urządzenia Cloud Print MUSZĄ używać:
/cloudprint/printer?printerid=<printer_id>
Gdy urządzenie zobaczy sekcję „oczekujące” w wyniku wywołania interfejsu API /cloudprint/printer (przy uruchamianiu lub z powodu powiadomienia), MUSI zaktualizować swój stan wewnętrzny, aby zapamiętać nowe ustawienia. MUSI wywołać interfejs API serwera, aby potwierdzić nowe ustawienia. W przypadku drukarek w chmurze urządzenie MUSI wywołać interfejs API /cloudprint/update i użyć parametru „local_settings” tak jak podczas rejestracji.
Podczas ponownego łączenia się z kanałem XMPP urządzenie MUSI wywołać interfejs API /cloudprint/printer, aby sprawdzić, czy od ostatniego połączenia lokalne ustawienia uległy zmianie.
4.1.3.1. Ustawienia lokalne oczekujące
Parametr „local_settings”, którego urządzenie używa do wywoływania interfejsu API serwera, NIE MOŻE zawierać sekcji „pending”.
4.1.3.2. Ustawienia lokalne – bieżące
TYLKO urządzenie może zmieniać sekcję „current” w „local_settings”. Pozostali użytkownicy będą zmieniać sekcję „Oczekujące” i czekać, aż zmiany zostaną przeniesione do sekcji „Bieżące” przez urządzenie.
4.1.4. Offline
Jeśli podczas uruchamiania nie można nawiązać połączenia z serwerem, po wyświetleniu powiadomienia urządzenie MUSI używać ostatnio znanych ustawień lokalnych.
4.1.5. Usuwanie urządzenia z usługi
Jeśli urządzenie zostało usunięte z usługi (np. GCP), na urządzenie zostanie wysłane powiadomienie XMPP. Powiadomienie będzie miało następujący format:
<device_id>/delete
Po otrzymaniu takiego powiadomienia urządzenie MUSI połączyć się z serwerem, aby sprawdzić swój stan. Urządzenia Cloud Print MUSZĄ używać:
/cloudprint/printer?printerid=<printer_id>
Urządzenie MUSI otrzymać odpowiedź HTTP z wartością success=false i bez opisu urządzenia lub drukarki. Oznacza to, że urządzenie zostało usunięte z serwera i MUSI usunąć swoje dane logowania oraz przejść do domyślnych ustawień fabrycznych.
ZA KAŻDYM razem, gdy urządzenie otrzyma odpowiedź wskazującą, że zostało usunięte w wyniku wywołania interfejsu API /cloudprint/printer (podczas uruchamiania, powiadomienia o aktualizacji ustawień, codziennego pingowania), MUSI usunąć swoje dane logowania i przejść do trybu domyślnego.
4.2. /privet/info API
Interfejs API informacji jest OBOWIĄZKOWY i musi być zaimplementowany na każdym urządzeniu. Jest to żądanie HTTP GET dotyczące adresu URL „/privet/info”: GET /privet/info HTTP/1.1
Interfejs Info API zwraca podstawowe informacje o urządzeniu i obsługiwanych przez nie funkcjach. Ten interfejs API NIE MOŻE nigdy zmieniać stanu urządzenia ani wykonywać żadnych działań, ponieważ jest podatny na ataki XSRF. Jest to JEDYNY interfejs API, który może mieć pusty nagłówek „X-Privet-Token”. Klienci powinni wywoływać interfejs API /privet/info z nagłówkiem „X-Privet-Token” ustawionym na X-Privet-Token: „”
Interfejs API informacji MUSI zwracać dane zgodne z danymi dostępnymi w rekordzie TXT podczas wykrywania.
4.2.1. Dane wejściowe
Interfejs API /privet/info nie ma parametrów wejściowych.
4.2.2. Powrót
Interfejs API /privet/info zwraca podstawowe informacje o urządzeniu i obsługiwanych funkcjach.
Kolumna TXT wskazuje odpowiednie pole w rekordzie TXT DNS-SD.
Nazwa wartości | Typ wartości | Opis | TXT |
---|---|---|---|
wersja | ciąg znaków | Najwyższa obsługiwana wersja interfejsu API (główna.pomocnicza), obecnie 1.0 | |
nazwa | ciąg znaków | Czytelna nazwa urządzenia. | ty |
opis | ciąg znaków | (opcjonalnie) Opis urządzenia. POWINNO być modyfikowane przez użytkownika. | notatka |
URL | ciąg znaków | Adres URL serwera, z którym komunikuje się to urządzenie. URL MUSI zawierać specyfikację protokołu, np. https://www.google.com/cloudprint. | URL |
typ | lista ciągów znaków, | Lista obsługiwanych typów urządzeń. | typ |
id | ciąg znaków | Identyfikator urządzenia. Jeśli urządzenie nie zostało jeszcze zarejestrowane, pole jest puste. | id |
device_state | ciąg znaków | Stan urządzenia. idle oznacza, że urządzenie jest gotowe. processing oznacza, że urządzenie jest zajęte i przez pewien czas jego funkcjonalność może być ograniczona. stopped oznacza, że urządzenie nie działa i wymaga interwencji użytkownika. | |
connection_state | ciąg znaków | Stan połączenia z serwerem (base_url):
online – połączenie jest dostępne; offline – brak połączenia; connecting – wykonywanie czynności początkowych; not-configured – połączenie nie zostało jeszcze skonfigurowane; Zarejestrowane urządzenie może zgłaszać stan połączenia na podstawie stanu kanału powiadomień (np. stan połączenia XMPP). | cs |
producent | ciąg znaków | Nazwa producenta urządzenia | |
model | ciąg znaków | Model urządzenia | |
serial_number | ciąg znaków | Unikalny identyfikator urządzenia. W tej specyfikacji MUSI to być identyfikator UUID. (GCP 1.1 spec)
(opcjonalnie) Zdecydowanie zalecamy używanie tego samego identyfikatora numeru seryjnego wszędzie, aby różni klienci mogli identyfikować to samo urządzenie. Na przykład drukarki implementujące IPP mogą używać tego identyfikatora numeru seryjnego w polu „printer-device-id”. | |
oprogramowanie układowe, | ciąg znaków | Wersja oprogramowania układowego urządzenia | |
czas działania | int | Liczba sekund od uruchomienia urządzenia. | |
setup_url | ciąg znaków | (opcjonalnie) Adres URL (wraz z protokołem) strony z instrukcjami konfiguracji | |
support_url | ciąg znaków | (opcjonalnie) Adres URL (wraz z protokołem) strony z informacjami o pomocy i najczęstszymi pytaniami. | |
update_url | ciąg znaków | (opcjonalnie) Adres URL (wraz z protokołem) strony z instrukcjami aktualizacji oprogramowania układowego | |
x-privet-token | ciąg znaków | Wartość nagłówka X-Privet-Token, która musi być przekazywana do wszystkich interfejsów API, aby zapobiegać atakom XSSI i XSRF. Więcej informacji znajdziesz w sekcji 6.1. | |
api | opis interfejsów API, | Lista obsługiwanych interfejsów API (opisana poniżej) | |
semantic_state | JSON | (opcjonalnie) Stan semantyczny urządzenia w formacie CloudDeviceState. |
api – to lista JSON zawierająca listę interfejsów API dostępnych w sieci lokalnej. Pamiętaj, że nie wszystkie interfejsy API mogą być dostępne w tym samym czasie w sieci lokalnej. Na przykład nowo podłączone urządzenie powinno obsługiwać tylko interfejs API /register:
"api": [ "/privet/register", ]
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
Obecnie dostępne są te interfejsy API:
- /privet/register – interfejs API do rejestracji urządzenia w sieci lokalnej. (szczegóły znajdziesz w sekcji /privet/register API). Ten interfejs API MUSI być ukryty po zarejestrowaniu urządzenia w chmurze.
- /privet/accesstoken – interfejs API do wysyłania żądań tokena dostępu z urządzenia (szczegółowe informacje znajdziesz w sekcji /privet/accesstoken API).
- /privet/capabilities – interfejs API do pobierania funkcji urządzenia (szczegółowe informacje znajdziesz w sekcji /privet/capabilities API).
- /privet/printer/* – interfejs API specyficzny dla typu urządzenia „drukarka”. Szczegółowe informacje znajdziesz w sekcji interfejsów API specyficznych dla drukarki.
{ "version": "1.0", "name": "Gene’s printer", "description": "Printer connected through Chrome connector", "url": "https://www.google.com/cloudprint", "type": [ "printer" ], "id": "11111111-2222-3333-4444-555555555555", "device_state": "idle", "connection_state": "online", "manufacturer": "Google", "model": "Google Chrome", "serial_number": "1111-22222-33333-4444", "firmware": "24.0.1312.52", "uptime": 600, "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en", "support_url": "http://support.google.com/cloudprint/?hl=en", "update_url": "http://support.google.com/cloudprint/?hl=en", "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659", "api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ] }
{ "version": "1.0", "name": "Gene’s printer", "description": "Printer connected through Chrome connector", "url": "https://www.google.com/cloudprint", "type": [ "printer" ], "id": "11111111-2222-3333-4444-555555555555", "device_state": "stopped", "connection_state": "online", "manufacturer": "Google", "model": "Google Chrome", "serial_number": "1111-22222-33333-4444", "firmware": "24.0.1312.52", "uptime": 600, "setup_url": "http://support.google.com/cloudprint/answer/1686197/?hl=en", "support_url": "http://support.google.com/cloudprint/?hl=en", "update_url": "http://support.google.com/cloudprint/?hl=en", "x-privet-token": "AIp06DjQd80yMoGYuGmT_VDAApuBZbInsQ:1358377509659", "api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ], "semantic_state": { "version": "1.0", "printer": { "state": "STOPPED", "marker_state": { "item": [ { "vendor_id": "ink", "state": "EXHAUSTED", "level_percent": 0 } ] } } } }
4.2.3. Błędy
Interfejs API /privet/info powinien zwracać błąd TYLKO wtedy, gdy brakuje nagłówka X-Privet-Token. Musi to być błąd HTTP 400:
HTTP/1.1 400 Missing X-Privet-Token header.
4.3. /privet/register API
Interfejs API /privet/register jest OPCJONALNY. Jest to żądanie POST HTTP. Interfejs API /privet/register MUSI sprawdzać, czy nagłówek X-Privet-Token jest prawidłowy. Urządzenie MUSI implementować ten interfejs API pod adresem URL „/privet/register”:
POST /privet/register?action=start&user=user@domain.com HTTP/1.1 POST /privet/register?action=complete&user=user@domain.com HTTP/1.1
Urządzenie powinno udostępniać interfejs API /privet/register TYLKO wtedy, gdy zezwala na rejestrację anonimową. Na przykład:
- Gdy urządzenie jest włączone (lub po kliknięciu specjalnego przycisku na urządzeniu) i nie zostało jeszcze zarejestrowane, powinno udostępniać interfejs API /privet/register, aby umożliwić użytkownikowi z sieci lokalnej przejęcie drukarki.
- Po zakończeniu rejestracji urządzenie powinno przestać udostępniać interfejs API /privet/register, aby uniemożliwić innemu użytkownikowi w sieci lokalnej ponowne przejęcie urządzenia.
- Niektóre urządzenia mogą mieć inne sposoby rejestracji i w ogóle nie powinny udostępniać interfejsu API /privet/register (np. łącznik Google Cloud Print).
Proces rejestracji składa się z 3 etapów (patrz anonimowa rejestracja w Cloud Print).
- Rozpocznij proces anonimowej rejestracji.
- Klient rozpoczyna ten proces, wywołując interfejs API /privet/register. Urządzenie może wtedy czekać na potwierdzenie użytkownika.
- Pobierz token roszczenia.
Klient wysyła zapytania, aby sprawdzić, kiedy urządzenie będzie gotowe do dalszego działania. Gdy urządzenie jest gotowe, wysyła żądanie do serwera, aby pobrać token rejestracji i adres URL rejestracji. Otrzymany token i adres URL POWINNY zostać zwrócone klientowi. Jeśli podczas tego etapu urządzenie otrzyma kolejną prośbę o rozpoczęcie rejestracji, powinno:
- Jeśli jest to ten sam użytkownik, który rozpoczął rejestrację, odrzuć wszystkie poprzednie dane (jeśli takie istnieją) i rozpocznij nowy proces rejestracji.
- Jeśli to inny użytkownik, zwróć błąd device_busy i 30-sekundowy limit czasu.
Przejdź przez proces rejestracji.
Po przejęciu urządzenia klient powinien powiadomić je o zakończeniu rejestracji. Po zakończeniu procesu rejestracji urządzenie powinno wysłać komunikat o aktualizacji, w tym nowo uzyskany identyfikator urządzenia.
Uwaga: gdy urządzenie przetwarza wywołanie interfejsu API /privet/register, nie można jednocześnie przetwarzać żadnych innych wywołań interfejsu API /privet/register. Urządzenie MUSI zwrócić błąd device_busy i przekroczyć 30-sekundowy limit czasu.
Zdecydowanie zalecamy potwierdzenie rejestracji przez użytkownika na urządzeniu. Jeśli ta funkcja jest zaimplementowana, urządzenie MUSI poczekać na potwierdzenie użytkownika PO otrzymaniu wywołania interfejsu API /privet/register?action=start. Klient będzie wywoływać interfejs API /privet/register?action=getClaimToken, aby sprawdzić, kiedy użytkownik potwierdzi rejestrację i kiedy będzie dostępny token roszczenia. Jeśli użytkownik anuluje rejestrację na urządzeniu (np. naciśnie przycisk Anuluj), musi zostać zwrócony błąd user_cancel. Jeśli użytkownik nie potwierdzi rejestracji w określonym czasie, MUSI zostać zwrócony błąd confirmation_timeout. Więcej informacji znajdziesz w sekcji dotyczącej wartości domyślnych.
4.3.1. Dane wejściowe
Interfejs API /privet/register ma te parametry wejściowe:Nazwa | Wartość |
---|---|
działanie | Może przyjmować jedną z tych wartości:
start – rozpoczęcie procesu rejestracji getClaimToken – pobranie tokena roszczenia dla urządzenia cancel – anulowanie procesu rejestracji complete – zakończenie procesu rejestracji |
użytkownik | Adres e-mail użytkownika, który przejmie to urządzenie. |
Urządzenie MUSI sprawdzać, czy adres e-mail we wszystkich działaniach (rozpoczęcie, getClaimToken, anulowanie, zakończenie) jest zgodny.
4.3.2. Powrót
Interfejs API /privet/register zwraca te dane:Nazwa wartości | Typ wartości | Opis |
---|---|---|
działanie | ciąg znaków | Takie samo działanie jak w parametrze wejściowym. |
użytkownik | ciąg tekstowy (opcjonalnie) | Ten sam użytkownik co w parametrze wejściowym (może go brakować, jeśli został pominięty w danych wejściowych). |
token | ciąg tekstowy (opcjonalnie) | Token rejestracji (obowiązkowy w przypadku odpowiedzi „getClaimToken”, pomijany w przypadku „start”, „complete” i „cancel”). |
claim_url | ciąg tekstowy (opcjonalnie) | Adres URL rejestracji (obowiązkowy w przypadku odpowiedzi „getClaimToken”, pomijany w przypadku odpowiedzi „start”, „complete”, „cancel”). W przypadku drukarek w chmurze musi to być adres „complete_invite_url” otrzymany z serwera. |
automated_claim_url | ciąg tekstowy (opcjonalnie) | Adres URL rejestracji (obowiązkowy w przypadku odpowiedzi „getClaimToken”, pomijany w przypadku odpowiedzi „start”, „complete”, „cancel”). W przypadku drukarek w chmurze musi to być adres URL „automated_invite_url” otrzymany z serwera. |
device_id | ciąg tekstowy (opcjonalnie) | Nowy identyfikator urządzenia (pominięty w przypadku odpowiedzi „start”, obowiązkowy w przypadku odpowiedzi „complete”). |
Urządzenie MUSI zwracać swój identyfikator w odpowiedzi interfejsu /privet/info API TYLKO po zakończeniu rejestracji.
Przykład 1:
{ "action": "start", "user": "user@domain.com", }
Przykład 2:
{ "action": "getClaimToken", "user": "user@domain.com", "token": "AAA111222333444555666777", "claim_url": "https://domain.com/SoMeUrL", }
Przykład 3:
{ "action": "complete", "user": "user@domain.com", "device_id": "11111111-2222-3333-4444-555555555555", }
4.3.3. Błędy
Interfejs /privet/register API może zwrócić te błędy (szczegóły znajdziesz w sekcji Błędy):Błąd | Opis |
---|---|
device_busy | Urządzenie jest zajęte i nie może wykonać żądanego działania. Spróbuj ponownie po przekroczeniu limitu czasu. |
pending_user_action | W odpowiedzi na „getClaimToken” ten błąd oznacza, że urządzenie nadal oczekuje na potwierdzenie przez użytkownika, a żądanie „getClaimToken” należy ponowić po upływie limitu czasu. |
user_cancel | Użytkownik wyraźnie anulował proces rejestracji na urządzeniu. |
confirmation_timeout | Upłynął czas na potwierdzenie przez użytkownika. |
invalid_action | Wywołano nieprawidłową akcję. Na przykład, jeśli klient wywołał działanie=complete przed działaniem=start i działaniem=getClaimToken. |
invalid_params | W żądaniu podano nieprawidłowe parametry. (Nieznane parametry należy bezpiecznie ignorować ze względu na przyszłą zgodność). Na przykład zwróć tę wartość, jeśli klient wywołał działanie=nieznane lub użytkownik=. |
device_config_error | Data/godzina (lub inne ustawienia) na urządzeniu jest nieprawidłowa. Użytkownik musi przejść na wewnętrzną stronę urządzenia i skonfigurować jego ustawienia. |
offline | Urządzenie jest obecnie w trybie offline i nie może komunikować się z serwerem. |
server_error | Błąd serwera podczas procesu rejestracji. |
invalid_x_privet_token | W żądaniu brakuje nagłówka X-Privet-Token lub jest on nieprawidłowy. |
Po pomyślnym zakończeniu rejestracji urządzenie MUSI przestać udostępniać interfejs API /privet/register. Jeśli urządzenie nie udostępnia interfejsu API /privet/register, MUSI zwrócić błąd HTTP 404. Dlatego jeśli urządzenie jest już zarejestrowane, wywołanie tego interfejsu API MUSI zwrócić kod stanu 404. Jeśli brakuje nagłówka X-Privet-Token, urządzenie MUSI zwrócić błąd HTTP 400.
4.4. Interfejs API /privet/accesstoken
Interfejs API /privet/accesstoken jest OPCJONALNY. Jest to żądanie HTTP GET. Interfejs API /privet/accesstoken MUSI sprawdzać, czy nagłówek „X-Privet-Token” jest prawidłowy. Urządzenie MUSI implementować ten interfejs API pod adresem URL „/privet/accesstoken”:GET /privet/accesstoken HTTP/1.1
Gdy urządzenie otrzyma wywołanie interfejsu API /accesstoken, powinno wywołać serwer, aby pobrać token dostępu dla danego użytkownika, i zwrócić go do klienta. Klient użyje następnie tokena dostępu, aby uzyskać dostęp do tego urządzenia przez chmurę.
Urządzenia Cloud Print MUSZĄ wywoływać ten interfejs API:
/cloudprint/proximitytoken
"proximity_token": { "user": "user@domain.com", "token": "AAA111222333444555666777", "expires_in": 600 }
4.4.1. Dane wejściowe
Interfejs API /privet/accesstoken ma te parametry wejściowe:Nazwa | Wartość |
---|---|
użytkownik | Adres e-mail użytkownika, który zamierzał użyć tego tokena dostępu. Może być pusta w żądaniu. |
4.4.2. Powrót
Interfejs API /privet/accesstoken zwraca te dane:Nazwa wartości | Typ wartości | Opis |
---|---|---|
token | ciąg znaków | Token dostępu zwrócony przez serwer |
użytkownik | ciąg znaków | Ten sam użytkownik co w parametrze wejściowym. |
expires_in | int | Liczba sekund do wygaśnięcia tego tokena. otrzymane z serwera i przekazane w tej odpowiedzi. |
Przykład:
{ "token": "AAA111222333444555666777", "user": "user@domain.com", "expires_in": 600 }
4.4.3. Błędy
Interfejs /privet/accesstoken API może zwrócić te błędy (szczegóły znajdziesz w sekcji Błędy):Błąd | Opis |
---|---|
offline | Urządzenie jest obecnie w trybie offline i nie może komunikować się z serwerem. |
access_denied | Niewystarczające uprawnienia. Odmowa dostępu. Urządzenie powinno zwracać ten błąd, gdy serwer wyraźnie odrzuci żądanie. |
invalid_params | W żądaniu podano nieprawidłowe parametry. (Nieznane parametry należy bezpiecznie ignorować ze względu na przyszłą zgodność). Na przykład jeśli klient wywołał adres /accesstoken?user= lub /accesstoken. |
server_error | Błąd serwera. |
invalid_x_privet_token | W żądaniu token X-Privet-Token jest nieprawidłowy lub pusty. |
Jeśli urządzenie nie udostępnia interfejsu API /privet/accesstoken, MUSI zwrócić błąd HTTP 404. Jeśli brakuje nagłówka X-Privet-Token, urządzenie MUSI zwrócić błąd HTTP 400.
4.5. Interfejs API /privet/capabilities
Interfejs API /privet/capabilities jest OPCJONALNY. Jest to żądanie HTTP GET. Interfejs API /privet/capabilities MUSI sprawdzać, czy nagłówek „X-Privet-Token” jest prawidłowy. Urządzenie MUSI implementować ten interfejs API pod adresem URL „/privet/capabilities”:GET /privet/capabilities HTTP/1.1
4.5.1. Dane wejściowe
Interfejs API /privet/capabilities ma te parametry wejściowe:Nazwa | Wartość |
---|---|
offline | (opcjonalnie) Może mieć tylko wartość „offline=1”. W takim przypadku urządzenie powinno zwrócić możliwości korzystania z niego w trybie offline (jeśli różnią się od możliwości w trybie online). |
4.5.2. Powrót
Interfejs API /privet/capabilities zwraca możliwości urządzenia w formacie JSON opisu urządzenia w chmurze (CDD) (szczegółowe informacje znajdziesz w dokumencie CDD). Drukarki MUSZĄ zwracać co najmniej listę obsługiwanych typów. Na przykład drukarka gotowa do pracy w chmurze, która jest obecnie online, może zwrócić (co najmniej) taki wynik:{ "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" } ] } }
Uwaga: drukarki określają priorytet obsługiwanych typów treści za pomocą kolejności. Na przykład w powyższych przykładach drukarka określa, że preferuje dane w formacie „application/pdf” od formatów „image/pwg-raster” i „image/jpeg”. Klienci powinni w miarę możliwości uwzględniać priorytetyzację drukarki (szczegóły znajdziesz w dokumencie CDD).
4.5.3. Błędy
Interfejs /privet/capabilities API może zwracać te błędy (szczegóły znajdziesz w sekcji Błędy):Błąd | Opis |
---|---|
invalid_x_privet_token | W żądaniu brakuje nagłówka X-Privet-Token lub jest on nieprawidłowy. |
Jeśli urządzenie nie udostępnia interfejsu API /privet/capabilities, MUSI zwrócić błąd HTTP 404. Jeśli brakuje nagłówka X-Privet-Token, urządzenie MUSI zwrócić błąd HTTP 400.
4.6. Błędy
Błędy są zwracane z powyższych interfejsów API w tym formacie:Nazwa wartości | Typ wartości | Opis |
---|---|---|
błąd | ciąg znaków | Typ błędu (zdefiniowany dla każdego interfejsu API) |
opis | ciąg tekstowy (opcjonalnie) | Zrozumiały dla człowieka opis błędu. |
server_api | ciąg tekstowy (opcjonalnie) | W przypadku błędu serwera to pole zawiera interfejs API serwera, który uległ awarii. |
server_code | int (opcjonalnie) | W przypadku błędu serwera to pole zawiera kod błędu zwrócony przez serwer. |
server_http_code | int (opcjonalnie) | W przypadku błędu HTTP serwera to pole zawiera kod błędu HTTP zwrócony przez serwer. |
czas oczekiwania | int (opcjonalnie) | Liczba sekund, przez które klient ma czekać przed ponowną próbą (tylko w przypadku błędów, które można naprawić). Klient MUSI losowo wybrać rzeczywisty czas oczekiwania z tego zakresu, tak aby był o 20% większy. |
Wszystkie interfejsy API MUSZĄ zwracać błąd HTTP 400, jeśli brakuje nagłówka X-Privet-Token.
HTTP/1.1 400 Missing X-Privet-Token header.
Przykład 1:
{ "error": "server_error", "description": "Service unavailable", "server_api": "/submit", "server_http_code": 503 }
Przykład 2:
{ "error": "printer_busy", "description": "Printer is currently printing other job", "timeout": 15 }
5. Printer API
Jednym z typów urządzeń obsługiwanych przez ten protokół jest drukarka. Urządzenia obsługujące ten typ MOGĄ implementować niektóre funkcje specyficzne dla drukarek. Najlepiej, aby drukowanie na drukarkach działających w chmurze odbywało się za pomocą serwera Cloud Print:

W niektórych przypadkach klient może potrzebować wysłać dokument lokalnie. Może być potrzebny, gdy klient nie ma identyfikatora Google lub nie może komunikować się z serwerem Cloud Print. W takim przypadku zadanie drukowania zostanie przesłane lokalnie do drukarki. Drukarka będzie z kolei korzystać z usługi Cloud Print do kolejkowania i konwersji zadań. Drukarka ponownie opublikuje zadanie przesłane lokalnie w usłudze Cloud Print, a następnie wyśle żądanie jego wykonania, ponieważ zostało ono przesłane przez chmurę. Ten proces zapewni elastyczność w zakresie warunków korzystania z usługi (konwersji) oraz zarządzania zadaniami drukowania i ich śledzenia.

Usługa Cloud Print implementuje konwersję, więc drukarka POWINNA reklamować obsługę wszystkich formatów wejściowych („*/*”) na liście obsługiwanych typów treści:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "*/*" } ] } }
W niektórych przypadkach pożądane jest rozwiązanie całkowicie offline. Drukarki obsługują ograniczoną liczbę formatów wejściowych, więc klient musi przekonwertować dokumenty na kilka formatów natywnie obsługiwanych przez drukarkę.

Ta specyfikacja WYMAGA, aby wszystkie drukarki obsługiwały co najmniej format PWG Raster („image/pwg-raster”) w przypadku drukowania offline. Drukarka może obsługiwać inne formaty (np. JPEG), a jeśli klient je obsługuje, może wysyłać dokumenty w tym formacie. Drukarka MUSI udostępniać obsługiwane typy za pomocą interfejsu API /capabilities, np.:
{ "version": "1.0", "printer": { "supported_content_type": [ { "content_type": "image/pwg-raster" }, { "content_type": "image/jpeg" } ] } }
Proste drukowanie – klient wysyła dokument przez sieć lokalną do interfejsu API /submitdoc (bez określania parametru job_id). Przesłany dokument zostanie wydrukowany przy użyciu domyślnych ustawień biletu drukowania i nie są potrzebne żadne stany zadania drukowania. Jeśli drukarka obsługuje TYLKO ten typ drukowania, MUSI reklamować TYLKO interfejs API /submitdoc w odpowiedzi interfejsu API /privet/info.
"api": [ "/privet/accesstoken", "/privet/capabilities", "/privet/printer/submitdoc", ]
Drukowanie zaawansowane – klient powinien najpierw utworzyć zadanie drukowania na drukarce, wywołując interfejs API /privet/printer/createjob z prawidłowym biletem zadania CJT w żądaniu. Drukarka MUSI zapisać bilet wydruku w pamięci i zwrócić identyfikator zadania do klienta. Następnie klient wywoła interfejs API /printer/submitdoc i określi wcześniej otrzymany job_id. W tym momencie drukarka rozpocznie drukowanie. Klient będzie odpytywać drukarkę o stan zadania drukowania, wywołując interfejs API /privet/printer/jobstate.
W środowisku z wieloma klientami nie ma gwarancji, jak ten interfejs API jest wywoływany. Jeden klient może wywołać /createjob między wywołaniami /createjob->/submitdoc innego klienta. Aby wyeliminować możliwe zakleszczenia i zwiększyć użyteczność, zalecamy utworzenie na drukarce małej kolejki oczekujących zadań drukowania (co najmniej 3–5):
- /createjob zajmuje pierwsze dostępne miejsce w kolejce.
- Czas życia zadania (w kolejce) wynosi co najmniej 5 minut.
- Jeśli wszystkie miejsca w kolejce są zajęte, najstarsze zadanie drukowania, które nie zostało jeszcze wydrukowane, zostanie usunięte, a na jego miejsce zostanie wstawione nowe.
- Jeśli na urządzeniu jest obecnie drukowane zadanie (drukowanie proste lub zaawansowane), /submitdoc powinno zwrócić stan zajętości i zaproponować limit czasu na ponowienie próby tego zadania drukowania.
- Jeśli /submitdoc odnosi się do zadania, które zostało usunięte z kolejki (z powodu zastąpienia lub przekroczenia limitu czasu), drukarka powinna zwrócić błąd invalid_print_job, a klient ponowi próbę od kroku /createjob. Klient MUSI odczekać losowy okres do 5 sekund, zanim spróbuje ponownie.
Jeśli ograniczenia pamięci uniemożliwiają przechowywanie na urządzeniu wielu oczekujących zadań, kolejka może zawierać tylko 1 zadanie drukowania. Nadal powinien on być zgodny z protokołem opisanym powyżej. Po zakończeniu zadania lub niepowodzeniu z powodu błędu drukarka powinna przechowywać informacje o stanie zadania przez co najmniej 5 minut. Rozmiar kolejki do przechowywania stanów ukończonych zadań powinien wynosić co najmniej 10. Jeśli trzeba zapisać więcej stanów zadań, najstarszy z nich może zostać usunięty z kolejki przed upływem 5-minutowego limitu czasu.
Uwaga: na razie klienci będą odpytywać o stan zadania. W przyszłości możemy wymagać, aby drukarka wysyłała powiadomienie DNS TXT, gdy zmieni się stan DOWOLNEGO zadania drukowania.
5.1. /privet/printer/createjob API
Interfejs API /privet/printer/createjob jest OPCJONALNY (patrz sekcja Proste drukowanie powyżej). Jest to żądanie HTTP POST. Interfejs API /privet/printer/createjob MUSI sprawdzać, czy nagłówek „X-Privet-Token” jest prawidłowy. Urządzenie MUSI implementować ten interfejs API pod adresem URL „/privet/printer/createjob”:
POST /privet/printer/createjob HTTP/1.1
5.1.1. Dane wejściowe
Interfejs API /privet/printer/createjob nie ma parametrów wejściowych w adresie URL. Treść żądania powinna zawierać dane zlecenia drukowania w formacie CJT.5.1.2. Powrót
Interfejs API /privet/printer/createjob zwraca te dane:Nazwa wartości | Typ wartości | Opis |
---|---|---|
job_id | ciąg znaków | Identyfikator nowo utworzonego zadania drukowania. |
expires_in | int | Liczba sekund, przez które to zadanie drukowania jest ważne. |
Przykład:
{ "job_id": "123", "expires_in": 600 }
5.1.3. Błędy
Interfejs /privet/printer/createjob API może zwracać te błędy (szczegółowe informacje znajdziesz w sekcji Błędy):Błąd | Opis |
---|---|
invalid_ticket | Przesłany bilet drukowania jest nieprawidłowy. |
printer_busy | Drukarka jest zajęta i nie może obecnie przetworzyć żądania /createjob. Spróbuj ponownie po przekroczeniu limitu czasu. |
printer_error | Drukarka jest w stanie błędu i wymaga interakcji użytkownika, aby go naprawić. Opis powinien zawierać bardziej szczegółowe wyjaśnienie (np. „Zacięcie papieru w podajniku 1”). |
invalid_x_privet_token | W żądaniu brakuje nagłówka X-Privet-Token lub jest on nieprawidłowy. |
Jeśli urządzenie nie udostępnia interfejsu /privet/printer/createjob, MUSI zwrócić błąd HTTP 404. Jeśli brakuje nagłówka X-Privet-Token, urządzenie MUSI zwrócić błąd HTTP 400.
5.2. /privet/printer/submitdoc API
Interfejs /privet/printer/submitdoc API jest WYMAGANY do wdrożenia drukowania w sieci lokalnej (offline lub przekazywania do Cloud Print). Jest to żądanie POST HTTP. Interfejs API /privet/printer/submitdoc MUSI sprawdzać, czy nagłówek „X-Privet-Token” jest prawidłowy. Urządzenie MUSI implementować ten interfejs API pod adresem URL „/privet/printer/submitdoc”:POST /privet/printer/submitdoc HTTP/1.1
Jeśli drukarka nie jest w stanie pomieścić wszystkich danych w wewnętrznym buforze, POWINNA używać mechanizmów TCP, aby spowolnić przesyłanie danych do momentu wydrukowania części dokumentu i ponownego udostępnienia części bufora. (Na przykład drukarka może ustawić windowsize=0 w warstwach TCP, co spowoduje, że klient będzie czekać).
Przesłanie dokumentu do drukarki może zająć sporo czasu. Klient powinien mieć możliwość sprawdzenia stanu drukarki i zadania (drukowanie zaawansowane) podczas drukowania. Aby to zrobić, drukarka MUSI zezwalać klientowi na wywoływanie interfejsów API /privet/info i /privet/printer/jobstate podczas przetwarzania wywołań interfejsu API /privet/printer/submitdoc. Zalecamy, aby wszyscy klienci rozpoczynali nowy wątek w celu wykonania wywołania interfejsu API /privet/printer/submitdoc, aby główny wątek mógł używać interfejsów API /privet/info i /privet/printer/jobstate do sprawdzania stanu drukarki i zadań.
Uwaga: po zakończeniu lub przerwaniu lokalnego zadania drukowania zdecydowanie zalecamy (w przyszłej wersji tej specyfikacji będzie to wymagane) zgłoszenie stanu końcowego zadania do interfejsu /cloudprint/submit w celu rozliczenia i poprawy komfortu użytkownika. Wymagane są parametry „printerid”, „title”, „contentType” i „final_semantic_state” (w formacie PrintJobState) oraz parametry „tag” (powtarzany parametr) i „ticket” (bilet zadania w formacie CloudJobTicket). Pamiętaj, że podany stan PrintJobState musi być ostateczny, tzn. jego typ musi mieć wartość DONE lub ABORTED, a w przypadku wartości ABORTED należy podać przyczynę (szczegółowe informacje znajdziesz w sekcji JobState). Pamiętaj też, że to użycie interfejsu /cloudprint/submit do zgłaszania lokalnych zadań drukowania nie jest wymienione w jego specyfikacji, ponieważ ta sekcja ma opisywać główne zastosowanie interfejsu: przesyłanie zadania drukowania z dokumentem do wydrukowania podanym w parametrze „content”.
5.2.1. Dane wejściowe
Interfejs API /privet/printer/submitdoc ma te parametry wejściowe:Nazwa | Wartość |
---|---|
job_id | (opcjonalnie) Identyfikator zadania drukowania. Można pominąć w przypadku prostego drukowania (patrz wyżej). Musi być zgodny z wartością zwróconą przez drukarkę. |
user_name | (opcjonalnie) Nazwa użytkownika czytelna dla człowieka. Nie jest to ostateczna wartość i należy jej używać tylko w przypadku adnotacji dotyczących zadań drukowania. Jeśli zadanie zostanie ponownie opublikowane w usłudze Cloud Print, ten ciąg znaków powinien zostać dołączony do zadania Cloud Print. |
client_name | (opcjonalnie) Nazwa aplikacji klienckiej, która wysyła to żądanie. Tylko do wyświetlania. Jeśli zadanie zostanie ponownie opublikowane w usłudze Cloud Print, ten ciąg znaków powinien zostać dołączony do zadania Cloud Print. |
job_name | (opcjonalnie) Nazwa zadania drukowania, które ma zostać zarejestrowane. Jeśli zadanie zostanie ponownie opublikowane w usłudze Cloud Print, ten ciąg znaków powinien zostać dołączony do zadania Cloud Print. |
offline | (opcjonalnie) Może mieć tylko wartość „offline=1”. W takim przypadku drukarka powinna spróbować drukować tylko w trybie offline (bez ponownego wysyłania do serwera Cloud Print). |
Treść żądania powinna zawierać prawidłowy dokument do wydrukowania. Pole „Content-Length” powinno zawierać prawidłową długość żądania. Nagłówek „Content-Type” powinien być ustawiony na typ MIME dokumentu i pasować do jednego z typów w CDD (chyba że CDD określa „*/*”).
Zdecydowanie zalecamy, aby klienci podawali w tej prośbie prawidłową nazwę użytkownika (lub adres e-mail), nazwę klienta i nazwę zadania. Te pola są używane tylko w interfejsach, aby zwiększyć wygodę użytkowników.
5.2.2. Powrót
Interfejs API /privet/printer/submitdoc zwraca te dane:Nazwa wartości | Typ wartości | Opis |
---|---|---|
job_id | ciąg znaków | Identyfikator nowo utworzonego zadania drukowania (proste drukowanie) lub identyfikator zadania podany w żądaniu (zaawansowane drukowanie). |
expires_in | int | Liczba sekund, przez które to zadanie drukowania jest ważne. |
job_type | ciąg znaków | Typ treści przesłanego dokumentu. |
job_size | int 64-bitowy | Rozmiar danych wydruku w bajtach. |
job_name | ciąg znaków | (opcjonalnie) Taka sama nazwa zadania jak w danych wejściowych (jeśli występuje). |
Przykład:
{ "job_id": "123", "expires_in": 500, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
5.2.3. Błędy
Interfejs API /privet/printer/submitdoc może zwracać te błędy (szczegółowe informacje znajdziesz w sekcji Błędy):Błąd | Opis |
---|---|
invalid_print_job | W żądaniu podano nieprawidłowy lub wygasły identyfikator zadania. Ponów próbę po przekroczeniu limitu czasu. |
invalid_document_type | Drukarka nie obsługuje typu MIME dokumentu. |
invalid_document | Przesłany dokument jest nieprawidłowy. |
document_too_large | Dokument przekracza maksymalny dozwolony rozmiar. |
printer_busy | Drukarka jest zajęta i nie może obecnie przetworzyć dokumentu. Spróbuj ponownie po przekroczeniu limitu czasu. |
printer_error | Drukarka jest w stanie błędu i wymaga interakcji użytkownika, aby go naprawić. Opis powinien zawierać bardziej szczegółowe wyjaśnienie (np. „Zacięcie papieru w podajniku 1”). |
invalid_params | W żądaniu podano nieprawidłowe parametry. (Nieznane parametry należy bezpiecznie ignorować ze względu na przyszłą zgodność) |
user_cancel | Użytkownik anulował proces drukowania na urządzeniu. |
server_error | Nie udało się opublikować dokumentu w Cloud Print. |
invalid_x_privet_token | W żądaniu brakuje nagłówka X-Privet-Token lub jest on nieprawidłowy. |
Jeśli urządzenie nie udostępnia adresu /privet/printer/submitdoc, MUSI zwrócić błąd HTTP 404. Jeśli brakuje nagłówka X-Privet-Token, urządzenie MUSI zwrócić błąd HTTP 400.
Uwaga: interfejs API /privet/printer/submitdoc może wymagać specjalnej obsługi po stronie drukarki (ze względu na duży rozmiar dołączonego ładunku). W niektórych przypadkach (zależnych od implementacji serwera HTTP drukarki i platformy) drukarka może zamknąć gniazdo PRZED zwróceniem błędu HTTP. W innych przypadkach drukarka może zwrócić błąd 503 (zamiast błędu Privet). Drukarki POWINNY w miarę możliwości zwracać wartość Privet. Każdy klient implementujący specyfikację Privet powinien jednak obsługiwać zamknięcie gniazda (bez błędu HTTP) i błędy HTTP 503 w przypadku interfejsu API /privet/printer/submitdoc. W takim przypadku klient powinien traktować to jako błąd prywatny „printer_busy” z parametrem „timeout” ustawionym na 15 sekund. Aby uniknąć nieskończonych ponownych prób, klient może przestać ponawiać próby po rozsądnej liczbie prób (np. 3).
5.3. /privet/printer/jobstate API
Interfejs /privet/printer/jobstate API jest OPCJONALNY (patrz Proste drukowanie powyżej). Jest to żądanie HTTP GET. Interfejs API /privet/printer/jobstate MUSI sprawdzać, czy nagłówek „X-Privet-Token” jest prawidłowy. Urządzenie MUSI implementować ten interfejs API pod adresem URL „/privet/printer/jobstate”:GET /privet/printer/jobstate HTTP/1.1
5.3.1. Dane wejściowe
Interfejs API /privet/printer/jobstate ma te parametry wejściowe:Nazwa | Wartość |
---|---|
job_id | Identyfikator zadania drukowania, dla którego chcesz zwrócić stan. |
5.3.2. Powrót
Interfejs API /privet/printer/jobstate zwraca te dane:Nazwa wartości | Typ wartości | Opis |
---|---|---|
job_id | ciąg znaków | Identyfikator zadania drukowania, którego dotyczą informacje o stanie. |
stan | ciąg znaków | draft – zadanie drukowania zostało utworzone na urządzeniu (nie otrzymano jeszcze wywołań /privet/printer/submitdoc).
queued – zadanie drukowania zostało odebrane i umieszczone w kolejce, ale drukowanie jeszcze się nie rozpoczęło. in_progress – zadanie drukowania jest w trakcie drukowania. zatrzymano – zadanie drukowania zostało wstrzymane, ale można je ponownie uruchomić ręcznie lub automatycznie. done – zadanie drukowania zostało wykonane. Przerwano – nie udało się wykonać zadania drukowania. |
opis | ciąg znaków | (opcjonalnie) Opis stanu zadania drukowania zrozumiały dla człowieka. Powinny zawierać dodatkowe informacje, jeśli state jest stopped lub aborted. Pole semantic_state zwykle zawiera lepszy i bardziej znaczący opis dla klienta. |
expires_in | int | Liczba sekund, przez które to zadanie drukowania jest ważne. |
job_type | ciąg znaków | (Opcjonalnie) Typ treści przesłanego dokumentu. |
job_size | int 64-bitowy | (opcjonalnie) Rozmiar danych wydruku w bajtach. |
job_name | ciąg znaków | (opcjonalnie) Taka sama nazwa zadania jak w danych wejściowych (jeśli występuje). |
server_job_id | ciąg znaków | (opcjonalnie) Identyfikator zadania zwrócony przez serwer (jeśli zadanie zostało opublikowane w usłudze Cloud Print). Pominięte w przypadku drukowania offline. |
semantic_state | JSON | (opcjonalnie) Stan semantyczny zadania w formacie PrintJobState. |
Przykład (drukowanie przez raportowanie za pomocą 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" }
Przykład (błąd drukowania offline):
{ "job_id": "123", "state": "stopped", "description": "Out of paper", "expires_in": 100, "job_type": "application/pdf", "job_size": 123456, "job_name": "My PDF document" }
Przykład (zadanie drukowania przerwane przez użytkownika):
{ "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 } }
Przykład (zadanie drukowania zostało zatrzymane z powodu braku papieru). Zwróć uwagę na odniesienie do stanu urządzenia. Klient musi wywołać interfejs API /privet/info, aby uzyskać więcej informacji o stanie urządzenia:
{ "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. Błędy
Interfejs /privet/printer/jobstate API może zwrócić te błędy (szczegóły znajdziesz w sekcji Błędy):Błąd | Opis |
---|---|
invalid_print_job | Żądanie zawiera nieprawidłowy lub wygasły identyfikator zadania. |
server_error | Nie udało się uzyskać stanu zadania drukowania (w przypadku zadań drukowania opublikowanych w Cloud Print). |
invalid_x_privet_token | W żądaniu brakuje nagłówka X-Privet-Token lub jest on nieprawidłowy. |
Jeśli urządzenie nie udostępnia adresu /privet/printer/jobstate, MUSI zwrócić błąd HTTP 404. Jeśli brakuje nagłówka X-Privet-Token, urządzenie MUSI zwrócić błąd HTTP 400.
6. Dodatek
6.1. Domyślne działanie i ustawienia
W tej sekcji wyjaśnimy domyślne zachowanie, którego oczekujemy od WSZYSTKICH urządzeń zgodnych z Privet.- Urządzenia po wyjęciu z pudełka powinny obsługiwać tylko interfejsy API /privet/info i /privet/register. Wszystkie inne interfejsy API (np. /privet/accesstoken, drukowanie lokalne) powinny być wyłączone.
- Rejestracja wymaga fizycznego kontaktu z urządzeniem.
- Użytkownik MUSI wykonać fizyczne działanie na urządzeniu (np. nacisnąć przycisk), aby potwierdzić dostęp do urządzenia.
- Gdy użytkownik wykona opisaną powyżej czynność, drukarka powinna wysłać żądanie /cloudprint/register. Nie powinien wysyłać tego żądania, dopóki nie zostanie podjęte działanie (patrz diagram sekwencji 1).
- Jeśli urządzenie przetwarza żądanie /privet/register (np. oczekuje na działanie opisane powyżej), musi odrzucić wszystkie inne żądania /privet/register. W takim przypadku urządzenie MUSI zwrócić błąd device_busy.
- Urządzenie powinno przekroczyć limit czasu dla każdego żądania /register, które nie otrzyma opisanego powyżej działania fizycznego w ciągu 60 sekund. W takim przypadku urządzenie MUSI zwrócić błąd confirmation_timeout.
- Opcjonalne: zalecane, ale nie wymagane. Poniższe elementy mogą poprawić wygodę użytkowników:
- Drukarka może migać światłem lub wyświetlać komunikat na ekranie, aby poinformować użytkownika, że musi podjąć działanie w celu potwierdzenia rejestracji.
- Na ekranie drukarki może pojawić się komunikat „Rejestracja w Google Cloud Print dla użytkownika „abc@def.com” – naciśnij OK, aby kontynuować”, gdzie abc@def.com to parametr użytkownika z wywołania interfejsu API /register. Dzięki temu użytkownik będzie miał pewność, że:
- potwierdzają swoją prośbę o rejestrację;
- co się dzieje, jeśli nie wywołał(-a) prośby.
- Oprócz fizycznego działania potwierdzającego na drukarce (np. „Naciśnij przycisk OK”), drukarka może też udostępnić użytkownikowi przycisk anulowania żądania (np. „Naciśnij Anuluj, aby odrzucić”). Umożliwi to użytkownikom, którzy nie zainicjowali prośby o rejestrację, anulowanie jej przed upływem 60-sekundowego limitu czasu. W takim przypadku urządzenie MUSI zwrócić błąd user_cancel.
- Przeniesienia własności:
- Urządzenie może zostać wyraźnie usunięte z usługi w chmurze.
- Jeśli urządzenie otrzyma odpowiedź o sukcesie, ale w wyniku wywołania /cloudprint/printer (w przypadku GCP) nie otrzyma opisu urządzenia, MUSI wrócić do trybu domyślnego (fabrycznego).
- Jeśli dane logowania urządzenia przestaną działać (wyraźnie z powodu odpowiedzi serwera „nieprawidłowe dane logowania”), urządzenie MUSI wrócić do domyślnego trybu (po wyjęciu z pudełka).
- Lokalne przywrócenie ustawień fabrycznych MUSI wyczyścić dane logowania urządzenia i przywrócić je do stanu domyślnego.
- Opcjonalnie: urządzenie może udostępniać element menu umożliwiający wyczyszczenie danych logowania i przejście do trybu domyślnego.
- Urządzenia obsługujące powiadomienia XMPP MUSZĄ mieć możliwość pingowania serwera. Limit czasu pingowania MUSI być kontrolowany przez serwer za pomocą parametru „local_settings”.
- Aby zapewnić synchronizację, urządzenie może wysyłać pingi do serwera (interfejs API /cloudprint/printer w przypadku GCP, a także pingi XMPP) nie częściej niż raz dziennie (co 24 godziny). Zalecamy losowe określanie okna sprawdzania w przedziale 24–32 godzin.
- Opcjonalnie: w przypadku urządzeń Cloud Print zalecamy, ale nie wymagamy, aby użytkownik miał możliwość ręcznego (za pomocą przycisku) sprawdzania, czy na urządzeniu nie ma nowych zadań drukowania. Niektóre drukarki mają już tę funkcję.
- Opcjonalnie. Drukarki dla firm mogą mieć opcję całkowitego wyłączenia lokalnego wykrywania. W takim przypadku urządzenie MUSI zaktualizować te ustawienia lokalne na serwerze. Nowe ustawienia lokalne MUSZĄ być puste (ustawienie „local_discovery” na „false” oznacza, że można je ponownie włączyć w usłudze GCP).
6.1.2 Domyślny diagram rejestracji

6.2. Ataki XSSI i XSRF oraz zapobieganie im
W tej sekcji wyjaśnimy, jak urządzenie może być narażone na ataki typu XSSI i XSRF oraz jak się przed nimi chronić (w tym techniki generowania tokenów).Więcej informacji znajdziesz tutaj: http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
Ataki XSSI i XSRF są zwykle możliwe, gdy witryna korzysta z mechanizmów uwierzytelniania za pomocą plików cookie. Usługa Cloud Print Google nie używa plików cookie, ale takie ataki są nadal możliwe. Dostęp przez sieć lokalną z założenia domyślnie ufa żądaniom.
6.2.1. XSSI
Złośliwa witryna może odgadnąć adres IP i numer portu urządzenia zgodnego z Privet i spróbować wywołać interfejs Privet API za pomocą „src=<nazwa interfejsu API>” w tagu <script>:<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>
Aby zapobiec tego typu atakom, WSZYSTKIE wywołania interfejsu API Privet MUSZĄ wymagać nagłówka „X-Privet-Token” w żądaniu. Tagi skryptu „src=<api>” nie mogą dodawać nagłówków, co skutecznie chroni przed tego typu atakami.
6.2.2. XSRF
http://en.wikipedia.org/wiki/Cross-site_request_forgeryZłośliwa strona internetowa może odgadnąć adres IP i numer portu urządzenia zgodnego z Privet i spróbować wywołać interfejs Privet API za pomocą elementu <iframe>, formularzy lub innego mechanizmu ładowania między witrynami. Osoby atakujące nie będą miały dostępu do wyników żądania, ale jeśli żądanie spowoduje wykonanie działania (np. drukowania), będą mogły je wywołać.
Aby zapobiec temu atakowi, wymagamy następującej ochrony:
- Pozostawienie interfejsu API /privet/info otwartego na XSRF
- Interfejs API /privet/info NIE MOŻE wykonywać żadnych działań na urządzeniu.
- Użyj interfejsu API /privet/info, aby otrzymać x-privet-token
- Wszystkie inne interfejsy API MUSZĄ sprawdzać, czy w nagłówku „X-Privet-Token” znajduje się prawidłowy token x-privet-token.
- x-privet-token powinien być ważny tylko przez 24 godziny.
Nawet jeśli atakujący zdoła wykonać wywołanie interfejsu API /privet/info, nie będzie mógł odczytać tokena x-privet-token z odpowiedzi, a tym samym nie będzie mógł wywołać żadnego innego interfejsu API.
Zdecydowanie zalecamy wygenerowanie tokena XSRF za pomocą tego algorytmu:
XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )
Elementy generowania tokena XSRF:
- DELIMITER to znak specjalny, zwykle „:”.
- issue_timecounter to liczba sekund od jakiegoś zdarzenia (epoki sygnatury czasowej) lub czasu uruchomienia urządzenia (w przypadku liczników procesora). Wartość issue_timecounter stale rośnie, gdy urządzenie jest włączone i działa (patrz weryfikacja tokena poniżej).
- SHA1 – funkcja skrótu wykorzystująca algorytm SHA1.
- base64 – kodowanie base64
- device_secret – hasło specyficzne dla urządzenia. Obiekt tajny urządzenia MUSI być aktualizowany przy każdym ponownym uruchomieniu.
Zalecane sposoby generowania klucza tajnego urządzenia:
- Generowanie nowego identyfikatora UUID przy każdym ponownym uruchomieniu
- Generuj 64-bitową liczbę losową przy każdym ponownym uruchomieniu
Urządzenie nie musi przechowywać wszystkich wydanych tokenów XSRF. Gdy urządzenie musi sprawdzić ważność tokena XSRF, powinno go zdekodować w formacie base64. Pobierz issue_timecounter z drugiej połowy (tekst jawny) i spróbuj wygenerować skrót SHA1 z device_secret + DELIMITER + issue_timecounter, gdzie issue_timecounter pochodzi z tokena. Jeśli nowo wygenerowany SHA1 pasuje do tego w tokenie, urządzenie musi teraz sprawdzić, czy issue_timecounter mieści się w okresie ważności (24 godziny) od bieżącego licznika czasu. W tym celu urządzenie pobiera bieżący licznik czasu (np. licznik procesora) i odejmuje od niego wartość issue_timecounter. Wynikiem MUSI być liczba sekund od wydania tokena.
Ważne: jest to zalecany sposób wdrażania ochrony przed XSRF. Klienci specyfikacji Privet nie powinni próbować zrozumieć tokena XSRF, ale traktować go jako czarną skrzynkę. Na rysunku 6.2.3 przedstawiono zalecany sposób implementacji nagłówka X-Privet-Token i weryfikacji typowego żądania.
6.2.3 Schemat sekwencji generowania i weryfikacji tokena X-Privet

6.3. Diagramy przepływu pracy
W tej sekcji przedstawimy proces w różnych przypadkach.6.3.1. Proces konfiguracji drukarki po wyjęciu z pudełka

6.3.2. Uruchomienie zarejestrowanej drukarki

6.3.3 Przepływ pracy związany z obsługą powiadomień XMPP

6.3.4. Sprawdzanie ustawień drukarki
