Cây thuỷ lạp

Privet là một Cloud Device Local Discovery API (API Khám phá thiết bị cục bộ trên đám mây) được các dịch vụ đám mây sử dụng. Tài liệu này được sắp xếp thành các phần sau:

  1. Giới thiệu: giới thiệu về Privet
  2. Khám phá: cơ chế khám phá cục bộ
  3. Thông báo: thông báo về khám phá tại địa phương
  4. API: API Privet cho các thiết bị đám mây nói chung
  5. Printer API: Privet API mà máy in sử dụng
  6. Phụ lục: sơ đồ bổ sung

1. Giới thiệu

Các thiết bị kết nối với đám mây mang lại nhiều lợi ích. Chúng có thể sử dụng các dịch vụ chuyển đổi trực tuyến, lưu trữ hàng đợi công việc trong khi thiết bị không kết nối mạng và có thể truy cập từ mọi nơi trên thế giới. Tuy nhiên, vì một người dùng có thể truy cập vào nhiều thiết bị trên đám mây, nên chúng ta cần cung cấp một phương thức để tìm thiết bị gần nhất dựa trên vị trí. Mục đích của giao thức Privet là kết hợp tính linh hoạt của các thiết bị đám mây với một cơ chế khám phá cục bộ phù hợp để các thiết bị có thể dễ dàng được phát hiện trong các môi trường mới.

Mục tiêu của giao thức này là:
  • giúp các thiết bị trên đám mây có thể tìm thấy ở cục bộ
  • đăng ký thiết bị trên đám mây với một dịch vụ đám mây
  • liên kết các thiết bị đã đăng ký với bản trình bày trên đám mây của chúng
  • bật chức năng ngoại tuyến
  • đơn giản hoá việc triển khai để các thiết bị nhỏ có thể sử dụng

Giao thức Privet bao gồm 2 phần chính: khám phá và API. Tính năng khám phá được dùng để tìm thiết bị trên mạng cục bộ, còn API được dùng để lấy thông tin về thiết bị và thực hiện một số thao tác. Trong tài liệu này, thiết bị đề cập đến một thiết bị kết nối đám mây triển khai giao thức Privet.

2. Chiến dịch Khám phá

Discovery là một giao thức dựa trên zeroconf (mDNS + DNS-SD). Thiết bị PHẢI triển khai tính năng Định địa chỉ cục bộ bằng IPv4. Thiết bị PHẢI tuân thủ các thông số kỹ thuật mDNS và DNS-SD.

Thiết bị PHẢI thực hiện giải quyết xung đột tên theo quy cách nêu trên.

2.1. Loại dịch vụ

Tính năng Khám phá dịch vụ DNS sử dụng định dạng sau cho các loại dịch vụ: _applicationprotocol._transportprotocol. Trong trường hợp giao thức Privet, loại dịch vụ cho DNS-SD phải là: _privet._tcp

Thiết bị cũng có thể triển khai các loại dịch vụ khác. Bạn nên sử dụng cùng một tên thực thể dịch vụ cho tất cả các loại dịch vụ mà thiết bị triển khai. Ví dụ: máy in có thể triển khai các dịch vụ "Printer XYZ._privet._tcp" và "Printer XYZ._printer._tcp". Việc này sẽ giúp người dùng thiết lập dễ dàng hơn. Tuy nhiên, các ứng dụng Privet sẽ chỉ tìm kiếm "_privet._tcp".

Ngoài loại dịch vụ chính, thiết bị PHẢI quảng cáo bản ghi PTR cho(các) loại phụ tương ứng (xem thông số DNS-SD: "7.1. Selective Instance Enumeration (Subtypes)" (Liệt kê các thực thể có chọn lọc (Loại phụ)). Định dạng phải như sau: _<subtype>._sub._privet._tcp

Hiện tại, loại thiết bị phụ duy nhất được hỗ trợ là printer. Vì vậy, tất cả máy in ĐỀU PHẢI quảng cáo hai bản ghi PTR:

  • _privet._tcp.local.
  • _printer._sub._privet._tcp.local.

2.2. Bản ghi TXT

DNS Service Discovery xác định các trường để thêm thông tin không bắt buộc về một dịch vụ trong bản ghi TXT. Bản ghi TXT bao gồm các cặp khoá/giá trị. Mỗi cặp khoá/giá trị bắt đầu từ byte độ dài, theo sau là tối đa 255 byte văn bản. Khoá là văn bản trước ký tự "=" đầu tiên và giá trị là văn bản sau ký tự "=" đầu tiên cho đến cuối. Quy cách này không cho phép có giá trị trong bản ghi, trong trường hợp đó sẽ không có ký tự "=" HOẶC không có văn bản sau ký tự "=". (Xem quy cách DNS-SD: "6.1. Quy tắc định dạng chung cho bản ghi TXT DNS" cho định dạng bản ghi TXT DNS và "6.2. Kích thước bản ghi DNS-SD TXT" (để biết độ dài được đề xuất).

Privet yêu cầu thiết bị gửi các cặp khoá/giá trị sau trong bản ghi TXT. Chuỗi Khoá/Giá trị không phân biệt chữ hoa chữ thường, ví dụ: "CS=online" và "cs=ONLINE" là giống nhau. Thông tin trong bản ghi TXT PHẢI giống với thông tin có thể truy cập thông qua API /info (xem phần 4.1). phần API).

Bạn nên giữ kích thước bản ghi TXT dưới 512 byte.

2.2.1. txtvers

Phiên bản của cấu trúc TXT. txtvers PHẢI là bản ghi đầu tiên của cấu trúc TXT. Hiện tại, phiên bản duy nhất được hỗ trợ là 1.

txtvers=1

2.2.2. ty

Cung cấp tên dễ đọc đối với người dùng của thiết bị. Ví dụ:

ty=Google Cloud Ready Printer Model XYZ

2.2.3. ghi chú (không bắt buộc)

Cung cấp tên dễ đọc đối với người dùng của thiết bị. Ví dụ:

note=1st floor lobby printer

Lưu ý: Đây là một khoá không bắt buộc và bạn có thể bỏ qua. Tuy nhiên, nếu có, người dùng CẦN có thể sửa đổi giá trị này. Bạn PHẢI sử dụng cùng một nội dung mô tả khi đăng ký thiết bị.

2.2.4. url

URL của máy chủ mà thiết bị này kết nối (bao gồm cả giao thức). Ví dụ:

url=https://www.google.com/cloudprint

2.2.5. type

Danh sách được phân tách bằng dấu phẩy gồm các loại thiết bị phụ mà thiết bị này hỗ trợ. Định dạng là: "type=_subtype1,_subtype2". Hiện tại, loại thiết bị phụ duy nhất được hỗ trợ là printer.

type=printer

Bạn nên quảng cáo từng loại phụ được liệt kê bằng cách sử dụng một bản ghi PTR tương ứng. Đối với mỗi loại dịch vụ phụ được hỗ trợ, phải có một mục tương ứng. Tên loại phụ của dịch vụ (<subtype>._sub._privet._tcp) phải bằng với loại thiết bị tại đây.

2.2.6. id

Mã thiết bị. Nếu thiết bị chưa được đăng ký, thì khoá này phải có mặt, nhưng giá trị phải trống. Ví dụ:

  id=11111111-2222-3333-4444-555555555555
  id=

2.2.7. cs

Cho biết trạng thái kết nối hiện tại của thiết bị. Có 4 giá trị có thể có được xác định trong quy cách này.

  • "đang kết nối" cho biết thiết bị hiện đang kết nối với đám mây.
  • "ngoại tuyến" cho biết thiết bị có trên mạng cục bộ, nhưng không thể giao tiếp với máy chủ.
  • "đang kết nối" cho biết thiết bị đang thực hiện trình tự khởi động và chưa hoàn toàn kết nối mạng.
  • "not-configured" (chưa định cấu hình) cho biết bạn chưa định cấu hình quyền truy cập Internet cho thiết bị. Giá trị này hiện không được dùng, nhưng có thể hữu ích trong các phiên bản sau của quy cách.
Ví dụ:
  • cs=online
  • cs=offline
  • cs=connecting

Nếu đã đăng ký với một đám mây, thì khi khởi động, thiết bị sẽ kiểm tra khả năng kết nối với một máy chủ để phát hiện trạng thái kết nối (ví dụ: gọi API đám mây để nhận chế độ cài đặt thiết bị). Thiết bị có thể sử dụng trạng thái kết nối kênh thông báo (ví dụ: XMPP) để báo cáo giá trị này. Các thiết bị chưa đăng ký khi khởi động có thể ping một miền để phát hiện trạng thái kết nối của chúng (ví dụ: ping www.google.com cho các thiết bị in qua đám mây).

3. Thông báo

Khi khởi động, tắt hoặc thay đổi trạng thái thiết bị, thiết bị PHẢI thực hiện bước thông báo như mô tả trong quy cách mDNS. SHOULD gửi thông báo tương ứng ít nhất 2 lần, mỗi lần cách nhau ít nhất 1 giây.

3.1. Khởi động

Khi khởi động thiết bị, thiết bị PHẢI thực hiện các bước thăm dò và thông báo như mô tả trong quy cách mDNS. Trong trường hợp này, bạn nên gửi bản ghi SRV, PTR và TXT. Bạn nên nhóm tất cả các bản ghi vào một phản hồi DNS nếu có thể. Nếu không, bạn nên sử dụng thứ tự sau: SRV, PTR, bản ghi TXT.

3.2. Tắt

Khi tắt thiết bị, thiết bị NÊN cố gắng thông báo cho tất cả các bên liên quan bằng cách gửi "gói tạm biệt" có TTL=0 (như mô tả trong tài liệu mDNS).

3.3. Cập nhật

Trong trường hợp có bất kỳ thông tin nào được mô tả trong TXT thay đổi, thiết bị PHẢI gửi thông báo cập nhật. Trong trường hợp này, bạn chỉ cần gửi bản ghi TXT mới. Ví dụ: sau khi đăng ký, thiết bị PHẢI gửi một thông báo cập nhật bao gồm mã nhận dạng thiết bị mới.

4. API

Sau khi một thiết bị trên đám mây được phát hiện, giao tiếp của máy khách sẽ được bật với thiết bị đó trực tiếp qua mạng cục bộ. Tất cả API đều dựa trên HTTP 1.1. Định dạng dữ liệu dựa trên JSON. Yêu cầu API có thể là yêu cầu GET hoặc POST.

Mỗi yêu cầu PHẢI chứa một tiêu đề "X-Privet-Token" hợp lệ. YÊU CẦU DUY NHẤT được phép có tiêu đề "X-Privet-Token" trống là yêu cầu /privet/info (lưu ý rằng tiêu đề VẪN PHẢI xuất hiện). Nếu thiếu tiêu đề "X-Privet-Token", thiết bị PHẢI phản hồi bằng lỗi HTTP 400 sau:

HTTP/1.1 400 Missing X-Privet-Token header.

Nếu tiêu đề "X-Privet-Token" trống hoặc không hợp lệ, thì thiết bị PHẢI phản hồi bằng "lỗi X-Privet-Token không hợp lệ" (invalid_x_privet_token, hãy xem phần Lỗi để biết thông tin chi tiết). Trường hợp ngoại lệ duy nhất là API /info. Để xem thêm thông tin về lý do thực hiện việc này và cách tạo mã thông báo, hãy xem Phụ lục A: Tấn công và ngăn chặn XSSI và XSRF.

Nếu một API được yêu cầu không tồn tại hoặc không được hỗ trợ, thì thiết bị PHẢI trả về lỗi HTTP 404.

4.1. Khả năng sử dụng của API

Trước khi BẤT KỲ API nào được hiển thị (kể cả API /info), thiết bị PHẢI liên hệ với máy chủ để kiểm tra chế độ cài đặt cục bộ. Bạn PHẢI giữ lại các chế độ cài đặt cục bộ giữa các lần khởi động lại. Nếu máy chủ không hoạt động, bạn nên sử dụng chế độ cài đặt cục bộ đã biết gần đây nhất. Nếu chưa được đăng ký, thiết bị sẽ tuân theo các chế độ cài đặt mặc định.

Các thiết bị Cloud Print PHẢI làm theo các bước dưới đây để đăng ký, nhận và cập nhật chế độ cài đặt cục bộ.

4.1.1. Đăng ký

Khi đăng ký, thiết bị PHẢI chỉ định tham số "local_settings", như sau:

{
       "current": {
                "local_discovery": true,
                "access_token_enabled": true,
                "printer/local_printing_enabled": true,
                "printer/conversion_printing_enabled": true,
                "xmpp_timeout_value": 300
        }
}
Bạn có thể đặt các chế độ cài đặt sau:
Tên giá trịLoại giá trịMô tả
local_discoverybooleanCho biết liệu chức năng khám phá cục bộ có được phép hay không. Nếu là "false", bạn phải tắt tất cả API cục bộ (kể cả /info) và tính năng khám phá DNS-SD. Theo mặc định, các thiết bị mới đăng ký phải truyền "true".
access_token_enabledboolean (không bắt buộc)Cho biết liệu API /accesstoken có nên được hiển thị trên mạng cục bộ hay không. Theo mặc định, giá trị này phải là "true".
printer/local_printing_enabledboolean (không bắt buộc)Cho biết liệu chức năng in cục bộ (/printer/createjob, /printer/submitdoc, /printer/jobstate) có nên được hiển thị trên mạng cục bộ hay không. Theo mặc định, giá trị này phải là "true".
printer/conversion_printing_enabledboolean (không bắt buộc)Cho biết liệu hoạt động in cục bộ có thể gửi lệnh in đến máy chủ để chuyển đổi hay không. Chỉ có ý nghĩa khi bạn bật tính năng in cục bộ.
xmpp_timeout_valueint (không bắt buộc)Cho biết số giây giữa các lệnh ping của kênh XMPP. Theo mặc định, PHẢI là 300 (5 phút) trở lên.

Lưu ý quan trọng: Việc thiếu bất kỳ giá trị không bắt buộc nào cho biết thiết bị hoàn toàn không hỗ trợ chức năng tương ứng.

4.1.2. Khởi động

Khi khởi động thiết bị, thiết bị sẽ liên hệ với máy chủ để kiểm tra những API có thể được hiển thị trong mạng cục bộ. Đối với máy in kết nối với Cloud Print, máy in đó phải gọi:

/cloudprint/printer?printerid=<printer_id>
hoặc
/cloudprint/list

Bạn nên dùng /cloudprint/printer thay vì /cloudprint/list, nhưng cả hai đều hoạt động.

API này trả về các thông số hiện tại của thiết bị, bao gồm cả chế độ cài đặt cho API cục bộ. Phản hồi từ máy chủ sẽ có định dạng sau:

"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
         }
}

đối tượng "current" cho biết các chế độ cài đặt đang có hiệu lực tại thời điểm đó.

Đối tượng "đang chờ xử lý" cho biết những chế độ cài đặt cần được áp dụng cho thiết bị (đối tượng này có thể bị thiếu).

Sau khi thấy chế độ cài đặt "đang chờ xử lý", thiết bị PHẢI cập nhật trạng thái của mình (xem bên dưới).

4.1.3. Cập nhật

Nếu cần cập nhật chế độ cài đặt, thì một thông báo XMPP sẽ được gửi đến thiết bị. Thông báo sẽ có định dạng như sau:

<device_id>/update_settings

Khi nhận được thông báo như vậy, thiết bị PHẢI truy vấn máy chủ để nhận các chế độ cài đặt mới nhất. Các thiết bị Cloud Print PHẢI sử dụng:

/cloudprint/printer?printerid=<printer_id>

Sau khi thiết bị thấy phần "đang chờ xử lý" do API /cloudprint/printer (khi khởi động hoặc do thông báo), thiết bị PHẢI cập nhật trạng thái nội bộ để ghi nhớ các chế độ cài đặt mới. Ứng dụng PHẢI gọi API máy chủ để xác nhận chế độ cài đặt mới. Đối với Máy in trên đám mây, thiết bị PHẢI gọi API /cloudprint/update và sử dụng tham số "local_settings" như trong quá trình đăng ký.

Khi kết nối lại với kênh XMPP, thiết bị PHẢI gọi API /cloudprint/printer để kiểm tra xem chế độ cài đặt cục bộ có thay đổi kể từ lần gần đây nhất hay không.

4.1.3.1. Chế độ cài đặt cục bộ đang chờ xử lý

Tham số "local_settings" mà thiết bị dùng để gọi API máy chủ KHÔNG BAO GIỜ được chứa phần "đang chờ xử lý".

4.1.3.2. Chế độ cài đặt cục bộ hiện tại

CHỈ thiết bị mới có thể thay đổi phần "current" (hiện tại) của "local_settings" (cài đặt cục bộ). Mọi người khác sẽ thay đổi phần "đang chờ xử lý" và đợi cho đến khi các thay đổi được thiết bị truyền đến phần "hiện tại".

4.1.4. Ngoại tuyến

Khi không thể liên hệ với máy chủ trong quá trình khởi động, sau khi nhận được thông báo, thiết bị PHẢI sử dụng chế độ cài đặt cục bộ được biết gần đây nhất.

4.1.5. Xoá thiết bị khỏi dịch vụ

Nếu thiết bị đã bị xoá khỏi dịch vụ (ví dụ: GCP), thì một thông báo XMPP sẽ được gửi đến thiết bị. Thông báo sẽ có định dạng như sau:

<device_id>/delete

Khi nhận được thông báo như vậy, thiết bị PHẢI chuyển đến máy chủ để kiểm tra trạng thái của thiết bị. Các thiết bị Cloud Print PHẢI sử dụng:

/cloudprint/printer?printerid=<printer_id>

Thiết bị PHẢI nhận được câu trả lời HTTP thành công với success=false và không có nội dung mô tả về thiết bị/máy in. Điều này có nghĩa là thiết bị đã bị xoá khỏi máy chủ và thiết bị PHẢI xoá thông tin đăng nhập của mình và chuyển sang chế độ cài đặt mặc định ban đầu.

BẤT KỲ khi nào thiết bị nhận được phản hồi cho biết thiết bị đã bị xoá do API /cloudprint/printer (khởi động, thông báo cập nhật chế độ cài đặt, ping hằng ngày), thiết bị ĐỀU PHẢI xoá thông tin đăng nhập và chuyển sang chế độ mặc định.

4.2. API /privet/info

API thông tin là BẮT BUỘC và MỌI thiết bị đều PHẢI triển khai API này. Đây là yêu cầu HTTP GET cho URL "/privet/info": GET /privet/info HTTP/1.1

API thông tin trả về thông tin cơ bản về một thiết bị và chức năng mà thiết bị đó hỗ trợ. API này không bao giờ được thay đổi trạng thái thiết bị hoặc thực hiện bất kỳ hành động nào, vì API này dễ bị tấn công XSRF. Đây là API DUY NHẤT được phép có tiêu đề "X-Privet-Token" trống. Các ứng dụng nên gọi API /privet/info với tiêu đề "X-Privet-Token" được đặt thành X-Privet-Token: ""

API thông tin PHẢI trả về dữ liệu nhất quán với dữ liệu có trong bản ghi TXT trong quá trình khám phá.

4.2.1. Đầu vào

API /privet/info không có tham số đầu vào.

4.2.2. Cầu thủ trả bóng

API /privet/info trả về thông tin cơ bản về thiết bị và chức năng được hỗ trợ.

Cột TXT cho biết trường tương ứng trong bản ghi TXT DNS-SD.

Tên giá trịLoại giá trịMô tảTXT
versionchuỗiPhiên bản cao nhất (major.minor) của API được hỗ trợ, hiện là 1.0
tênchuỗiTên dễ đọc của thiết bị.ty
mô tảchuỗi(không bắt buộc) Nội dung mô tả về thiết bị. Người dùng CÓ THỂ sửa đổi.ghi chú
urlchuỗiURL của máy chủ mà thiết bị này đang giao tiếp. URL PHẢI có quy cách giao thức, ví dụ: https://www.google.com/cloudprint.url
loạidanh sách chuỗiDanh sách các loại thiết bị được hỗ trợ.loại
idchuỗiMã thiết bị, trống nếu thiết bị chưa được đăng ký. id
device_statechuỗiTrạng thái của thiết bị.
idle có nghĩa là thiết bị đã sẵn sàng
processing có nghĩa là thiết bị đang bận và chức năng có thể bị hạn chế trong một khoảng thời gian
stopped có nghĩa là thiết bị không hoạt động và người dùng cần can thiệp
connection_statechuỗiTrạng thái kết nối với máy chủ (base_url)
online – có kết nối
offline – không có kết nối
connecting – đang thực hiện các bước khởi động
not-configured – chưa thiết lập kết nối
Một thiết bị đã đăng ký có thể báo cáo trạng thái kết nối dựa trên trạng thái của kênh thông báo (ví dụ: trạng thái kết nối XMPP).
cs
nhà sản xuấtchuỗiTên của nhà sản xuất thiết bị
kiểu máychuỗiMẫu thiết bị
serial_numberchuỗiGiá trị nhận dạng riêng biệt của thiết bị. Trong quy cách này, đây PHẢI là một UUID. (GCP 1.1 spec)
(không bắt buộc) Bạn nên sử dụng cùng một mã nhận dạng số sê-ri ở mọi nơi để các ứng dụng có thể xác định cùng một thiết bị. Ví dụ: những máy in triển khai IPP có thể sử dụng mã nhận dạng số sê-ri này trong trường "printer-device-id".
chương trình cơ sởchuỗiPhiên bản chương trình cơ sở của thiết bị
thời gian hoạt độngintSố giây kể từ khi thiết bị khởi động.
setup_urlchuỗi(không bắt buộc) URL (bao gồm cả giao thức) của trang có hướng dẫn thiết lập
support_urlchuỗi(không bắt buộc) URL (bao gồm cả giao thức) của trang có thông tin hỗ trợ, câu hỏi thường gặp
update_urlchuỗi(không bắt buộc) URL (bao gồm cả giao thức) của trang có hướng dẫn cập nhật chương trình cơ sở
x-privet-tokenchuỗiGiá trị của tiêu đề X-Privet-Token phải được truyền đến tất cả các API để ngăn chặn các cuộc tấn công XSSI và XSRF. Hãy xem phần 6.1 để biết thông tin chi tiết.
apinội dung mô tả về APIDanh sách các API được hỗ trợ (được mô tả bên dưới)
semantic_stateJSON(không bắt buộc) Trạng thái ngữ nghĩa của thiết bị ở định dạng CloudDeviceState.

api – là một danh sách JSON chứa danh sách các API có sẵn thông qua mạng cục bộ. Xin lưu ý rằng không phải API nào cũng có thể hoạt động cùng lúc trên mạng cục bộ. Ví dụ: một thiết bị mới kết nối chỉ nên hỗ trợ API /register:

"api": [
        "/privet/register",
]
Sau khi hoàn tất quá trình đăng ký thiết bị, thiết bị KHÔNG NÊN tiếp tục hỗ trợ API /register. Thiết bị cũng nên kiểm tra với dịch vụ để cung cấp những API có thể hiển thị qua mạng cục bộ. Ví dụ:
"api": [
        "/privet/accesstoken",
        "/privet/capabilities",
        "/privet/printer/submitdoc",
]

Hiện tại, bạn có thể sử dụng các API sau:

  • /privet/register – API để đăng ký thiết bị qua mạng cục bộ. (xem API /privet/register để biết thông tin chi tiết). API này PHẢI bị ẩn sau khi thiết bị được đăng ký thành công trên đám mây.
  • /privet/accesstoken – API để yêu cầu mã truy cập từ thiết bị (xem API /privet/accesstoken để biết thông tin chi tiết).
  • /privet/capabilities – API để truy xuất các chức năng của thiết bị (xem API /privet/capabilities để biết thông tin chi tiết).
  • /privet/printer/* – API dành riêng cho loại thiết bị "máy in", hãy xem API dành riêng cho máy in để biết thông tin chi tiết.
Sau đây là ví dụ về phản hồi /privet/info. (Lưu ý rằng không có API /privet/register vì đây là thiết bị đã đăng ký):
{
        "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",
        ]
}
Sau đây là ví dụ về phản hồi /privet/info cho một máy in hết mực (lưu ý trường 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. Lỗi

API /privet/info CHỈ trả về lỗi nếu thiếu tiêu đề X-Privet-Token. ĐÓ PHẢI là lỗi HTTP 400:

HTTP/1.1 400 Missing X-Privet-Token header.

4.3. /privet/register API

API /privet/register là KHÔNG BẮT BUỘC. Đây là một yêu cầu POST qua HTTP. API /privet/register PHẢI kiểm tra tiêu đề X-Privet-Token hợp lệ. Thiết bị PHẢI triển khai API này trên 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

Thiết bị CHỈ nên hiển thị API /privet/register khi cho phép đăng ký ẩn danh tại thời điểm đó. Ví dụ:

  • Khi được bật (hoặc sau khi nhấp vào một nút đặc biệt trên thiết bị) và chưa được đăng ký, thiết bị sẽ hiển thị API /privet/register để cho phép người dùng trên mạng cục bộ xác nhận quyền sở hữu máy in.
  • Sau khi hoàn tất quá trình đăng ký, thiết bị sẽ ngừng hiển thị API /privet/register để ngăn người dùng khác trên mạng cục bộ yêu cầu lại thiết bị.
  • Một số thiết bị có thể có nhiều cách đăng ký thiết bị và hoàn toàn không được hiển thị API /privet/register (ví dụ: trình kết nối Chrome Cloud Print).

Quy trình đăng ký bao gồm 3 bước (xem phần đăng ký ẩn danh cho Cloud Print).

  1. Bắt đầu quy trình đăng ký ẩn danh.
  2. Một ứng dụng sẽ bắt đầu quy trình này bằng cách gọi API /privet/register. Thiết bị có thể chờ người dùng xác nhận vào thời điểm đó.
  3. Nhận mã thông báo yêu cầu.

Ứng dụng sẽ thăm dò ý kiến để biết thời điểm thiết bị sẵn sàng tiếp tục. Sau khi thiết bị đã sẵn sàng, thiết bị sẽ gửi một yêu cầu đến máy chủ để truy xuất mã thông báo đăng ký và URL đăng ký. Mã thông báo và URL đã nhận PHẢI được trả về cho ứng dụng. Trong bước này, nếu nhận được một cuộc gọi khác để khởi động quá trình đăng ký, thiết bị sẽ:

  • Nếu đây là người dùng đã bắt đầu quy trình đăng ký – hãy loại bỏ tất cả dữ liệu trước đó (nếu có) và bắt đầu một quy trình đăng ký mới.
  • Nếu đây là một người dùng khác, hãy trả về lỗi device_busy và thời gian chờ 30 giây.

Hoàn tất quy trình đăng ký.

Sau khi ứng dụng đã xác nhận quyền sở hữu thiết bị, ứng dụng phải thông báo cho thiết bị để hoàn tất quy trình đăng ký. Sau khi hoàn tất quy trình đăng ký, thiết bị sẽ gửi một thông báo cập nhật, bao gồm cả mã thiết bị mới nhận được.

Lưu ý: Khi thiết bị đang xử lý lệnh gọi API /privet/register, không có lệnh gọi API /privet/register nào khác có thể được xử lý đồng thời. Thiết bị PHẢI trả về lỗi device_busy và thời gian chờ 30 giây.

Bạn NÊN xác nhận người dùng để đăng ký trên thiết bị. Nếu được triển khai, thiết bị PHẢI đợi người dùng xác nhận SAU KHI nhận được lệnh gọi API /privet/register?action=start.  Ứng dụng sẽ gọi API /privet/register?action=getClaimToken để biết thời điểm người dùng hoàn tất việc xác nhận và mã thông báo yêu cầu có sẵn. Nếu người dùng huỷ đăng ký trên thiết bị (ví dụ: nhấn nút Huỷ), thì bạn PHẢI trả về lỗi user_cancel. Nếu người dùng chưa xác nhận đăng ký trong một khoảng thời gian nhất định, thì bạn PHẢI trả về lỗi confirmation_timeout. Hãy xem phần mặc định để biết thêm thông tin chi tiết.

4.3.1. Đầu vào

API /privet/register có các tham số đầu vào sau:
TênGiá trị
hành độngCó thể là một trong những giá trị sau:
start – để bắt đầu quy trình đăng ký
getClaimToken – truy xuất mã thông báo xác nhận quyền sở hữu cho thiết bị
cancel – để huỷ quy trình đăng ký
complete – để hoàn tất quy trình đăng ký
người dùngEmail của người dùng sẽ yêu cầu quyền sở hữu thiết bị này.

Thiết bị PHẢI kiểm tra để đảm bảo địa chỉ email trong tất cả các thao tác (start, getClaimToken, cancel, complete) đều khớp.

4.3.2. Cầu thủ trả bóng

API /privet/register trả về dữ liệu sau:
Tên giá trịLoại giá trịMô tả
hành độngchuỗiThực hiện cùng một thao tác như trong tham số đầu vào.
người dùngchuỗi (không bắt buộc)Cùng một người dùng như trong tham số đầu vào (có thể bị thiếu nếu bị bỏ qua trong đầu vào).
mã thông báochuỗi (không bắt buộc)Mã thông báo đăng ký (bắt buộc đối với phản hồi "getClaimToken", bị bỏ qua đối với "start", "complete", "cancel").
claim_urlchuỗi (không bắt buộc)URL đăng ký (bắt buộc đối với phản hồi "getClaimToken", bị bỏ qua đối với "start", "complete", "cancel"). Đối với Cloud Printer, đây phải là "complete_invite_url" nhận được từ máy chủ.
automated_claim_urlchuỗi (không bắt buộc)URL đăng ký (bắt buộc đối với phản hồi "getClaimToken", bị bỏ qua đối với "start", "complete", "cancel"). Đối với Máy in đám mây, đó phải là "automated_invite_url" nhận được từ máy chủ.
device_idchuỗi (không bắt buộc)Mã nhận dạng thiết bị mới (bị bỏ qua đối với phản hồi "start", bắt buộc đối với "complete").

Thiết bị CHỈ ĐƯỢC PHÉP trả về mã nhận dạng thiết bị trong phản hồi API /privet/info SAU KHI hoàn tất quá trình đăng ký.

Ví dụ 1:

{
        "action": "start",
        "user": "user@domain.com",
}

Ví dụ 2:

{
        "action": "getClaimToken",
        "user": "user@domain.com",
        "token": "AAA111222333444555666777",
        "claim_url": "https://domain.com/SoMeUrL",
}

Ví dụ 3:

{
        "action": "complete",
        "user": "user@domain.com",
        "device_id": "11111111-2222-3333-4444-555555555555",
}

4.3.3. Lỗi

API /privet/register có thể trả về các lỗi sau (xem phần Lỗi để biết thông tin chi tiết):
LỗiMô tả
device_busyThiết bị đang bận và không thể thực hiện thao tác bạn yêu cầu. Thử lại sau khi hết thời gian chờ.
pending_user_actionĐể phản hồi "getClaimToken", lỗi này cho biết rằng thiết bị vẫn đang chờ người dùng xác nhận và yêu cầu "getClaimToken" sẽ được thử lại sau khi hết thời gian chờ.
user_cancelNgười dùng đã huỷ rõ ràng quy trình đăng ký trên thiết bị.
confirmation_timeoutHết thời gian xác nhận của người dùng.
invalid_actionHành động không hợp lệ được gọi. Ví dụ: nếu ứng dụng gọi action=complete trước khi gọi action=start và action=getClaimToken.
invalid_paramsCác tham số không hợp lệ được chỉ định trong yêu cầu. (Bạn nên bỏ qua các tham số không xác định để đảm bảo khả năng tương thích trong tương lai). Ví dụ: trả về giá trị này nếu ứng dụng gọi action=unknown hoặc user=.
device_config_errorNgày/giờ (hoặc một số chế độ cài đặt khác) không chính xác ở phía thiết bị. Người dùng cần truy cập (vào trang web nội bộ của thiết bị) và định cấu hình các chế độ cài đặt thiết bị.
ngoại tuyếnThiết bị hiện không kết nối mạng và không thể giao tiếp với máy chủ.
server_errorĐã xảy ra lỗi máy chủ trong quá trình đăng ký.
invalid_x_privet_tokenX-Privet-Token không hợp lệ hoặc trống trong yêu cầu.

Thiết bị PHẢI ngừng hiển thị API /privet/register sau khi hoàn tất thành công quá trình đăng ký. Nếu không hiển thị API /privet/register, thiết bị PHẢI trả về lỗi HTTP 404. Do đó, nếu một thiết bị đã được đăng ký, việc gọi API này PHẢI trả về lỗi 404. Nếu thiếu tiêu đề X-Privet-Token, thiết bị PHẢI trả về lỗi HTTP 400.

4.4. /privet/accesstoken API

API /privet/accesstoken là KHÔNG BẮT BUỘC. Đây là một yêu cầu HTTP GET. API /privet/accesstoken PHẢI kiểm tra tiêu đề "X-Privet-Token" hợp lệ. Thiết bị PHẢI triển khai API này trên URL "/privet/accesstoken":
GET /privet/accesstoken HTTP/1.1

Khi nhận được lệnh gọi API /accesstoken, thiết bị sẽ gọi máy chủ để truy xuất mã truy cập cho người dùng đã cho và trả mã thông báo về cho máy khách. Sau đó, ứng dụng khách sẽ dùng mã thông báo truy cập để truy cập vào thiết bị này thông qua đám mây.

Các thiết bị Cloud Print PHẢI gọi API sau:

/cloudprint/proximitytoken
và truyền thông số "printerid=<printer_id>" và "user" từ API cục bộ. Nếu thành công, phản hồi của máy chủ sẽ chứa đối tượng sau:
"proximity_token": {
        "user": "user@domain.com",
        "token": "AAA111222333444555666777",
        "expires_in": 600
}
Các thiết bị Cloud Print PHẢI truyền giá trị của đối tượng "proximity_token" trong phản hồi đến các lệnh gọi API /privet/accesstoken cục bộ. Sẽ có lợi hơn (đảm bảo cho tương lai) nếu thiết bị có thể truyền TẤT CẢ các tham số (kể cả những tham số không được mô tả trong quy cách này).

4.4.1. Đầu vào

API /privet/accesstoken có các tham số đầu vào sau:
TênGiá trị
người dùngEmail của người dùng dự định sử dụng mã truy cập này. Có thể trống trong yêu cầu.

4.4.2. Cầu thủ trả bóng

API /privet/accesstoken trả về dữ liệu sau:
Tên giá trịLoại giá trịMô tả
mã thông báochuỗiMã truy cập do máy chủ trả về
người dùngchuỗiCùng một người dùng như trong tham số đầu vào.
expires_inintSố giây cho đến khi mã thông báo này hết hạn. Nhận được từ máy chủ và được truyền trong phản hồi này.

Ví dụ:

{
        "token": "AAA111222333444555666777",
        "user": "user@domain.com",
        "expires_in": 600
}

4.4.3. Lỗi

API /privet/accesstoken có thể trả về các lỗi sau (xem phần Lỗi để biết thông tin chi tiết):
LỗiMô tả
ngoại tuyếnThiết bị hiện không kết nối mạng và không thể giao tiếp với máy chủ.
access_deniedKhông đủ quyền. Quyền truy cập bị từ chối. Thiết bị sẽ trả về lỗi này khi máy chủ từ chối rõ ràng yêu cầu.
invalid_paramsCác tham số không hợp lệ được chỉ định trong yêu cầu. (Bạn nên bỏ qua các tham số không xác định để đảm bảo khả năng tương thích trong tương lai). Ví dụ: nếu ứng dụng gọi /accesstoken?user= hoặc /accesstoken.
server_errorLỗi máy chủ.
invalid_x_privet_tokenX-Privet-Token không hợp lệ hoặc trống trong yêu cầu.

Nếu không hiển thị API /privet/accesstoken, thì thiết bị PHẢI trả về lỗi HTTP 404. Nếu thiếu tiêu đề X-Privet-Token, thiết bị PHẢI trả về lỗi HTTP 400.

4.5. /privet/capabilities API

API /privet/capabilities là KHÔNG BẮT BUỘC. Đây là một yêu cầu HTTP GET. API /privet/capabilities PHẢI kiểm tra tiêu đề "X-Privet-Token" hợp lệ. Thiết bị PHẢI triển khai API này trên URL "/privet/capabilities":
GET /privet/capabilities HTTP/1.1
Khi nhận được lệnh gọi API /capabilities, nếu có thể, thiết bị NÊN liên hệ với máy chủ để nhận các tính năng mới. Ví dụ: nếu một máy in hỗ trợ việc đăng một lệnh in (nhận cục bộ) cho chính nó thông qua dịch vụ Cloud Print, thì máy in đó sẽ trả về các chức năng mà dịch vụ Cloud Print sẽ trả về. Trong trường hợp này, Cloud Print có thể thay đổi các chức năng ban đầu của máy in bằng cách thêm các tính năng mới mà Cloud Print có thể thực hiện trước khi gửi lệnh in đến máy in. Trường hợp phổ biến nhất là danh sách các loại tài liệu được hỗ trợ. Nếu không có mạng, máy in sẽ trả về các loại tài liệu mà máy in hỗ trợ. Tuy nhiên, nếu máy in đang trực tuyến và đã đăng ký với Cloud Print, thì máy in ĐƯỢC YÊU CẦU trả về "*/*" làm một trong các loại được hỗ trợ. Trong trường hợp này, dịch vụ Cloud Print sẽ thực hiện quy trình chuyển đổi cần thiết. Đối với tính năng in ngoại tuyến, máy in PHẢI hỗ trợ ít nhất định dạng "image/pwg-raster".

4.5.1. Đầu vào

API /privet/capabilities có các tham số đầu vào sau:
TênGiá trị
ngoại tuyến(không bắt buộc) Chỉ có thể là "offline=1". Trong trường hợp này, thiết bị sẽ trả về các chức năng để sử dụng khi không có mạng (nếu các chức năng này khác với các chức năng "khi có mạng").

4.5.2. Cầu thủ trả bóng

API /privet/capabilities trả về các chức năng của thiết bị ở định dạng JSON Mô tả thiết bị trên đám mây (CDD) (xem tài liệu CDD để biết thông tin chi tiết). Máy in TỐI THIỂU PHẢI trả về danh sách các loại được hỗ trợ tại đây. Ví dụ: một máy in kết nối đám mây hiện đang trực tuyến có thể trả về một nội dung như sau (tối thiểu):
{
        "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": "*/*" }
                ]
        }
}
và khi bị ngắt kết nối khỏi máy chủ, nó có thể trả về:
{
        "version": "1.0",
        "printer": {
                "supported_content_type": [
                        {
                                "content_type": "application/pdf",
                                "min_version": "1.4"
                        },
                        { "content_type": "image/pwg-raster" },
                        { "content_type": "image/jpeg" }
                ]
        }
}

Lưu ý: Máy in thể hiện mức độ ưu tiên của loại nội dung được hỗ trợ bằng cách sử dụng thứ tự. Ví dụ: trong các mẫu ở trên, máy in chỉ định rằng máy in ưu tiên dữ liệu "application/pdf" hơn "image/pwg-raster" và "image/jpeg". Nếu có thể, các ứng dụng nên tuân thủ thứ tự ưu tiên của máy in (xem tài liệu CDD để biết thông tin chi tiết).

4.5.3. Lỗi

API /privet/capabilities có thể trả về các lỗi sau (xem phần Lỗi để biết thông tin chi tiết):
LỗiMô tả
invalid_x_privet_tokenX-Privet-Token không hợp lệ hoặc trống trong yêu cầu.

Nếu không hiển thị API /privet/capabilities, thiết bị PHẢI trả về lỗi HTTP 404. Nếu thiếu tiêu đề X-Privet-Token, thiết bị PHẢI trả về lỗi HTTP 400.

4.6. Lỗi

Các lỗi được trả về từ những API nêu trên ở định dạng sau:
Tên giá trịLoại giá trịMô tả
errorchuỗiLoại lỗi (được xác định theo từng API)
mô tảchuỗi (không bắt buộc)Nội dung mô tả lỗi mà con người có thể đọc được.
server_apichuỗi (không bắt buộc)Trong trường hợp xảy ra lỗi máy chủ, trường này chứa API máy chủ bị lỗi.
server_codeint (không bắt buộc)Trong trường hợp xảy ra lỗi máy chủ, trường này chứa mã lỗi mà máy chủ đã trả về.
server_http_codeint (không bắt buộc)Trong trường hợp xảy ra lỗi HTTP của máy chủ, trường này chứa mã lỗi HTTP mà máy chủ trả về.
tạm ngừngint (không bắt buộc)Số giây mà ứng dụng sẽ đợi trước khi thử lại (chỉ dành cho các lỗi có thể khắc phục). Ứng dụng PHẢI ngẫu nhiên hoá thời gian chờ thực tế từ giá trị này thành một giá trị là + 20%.

Tất cả các API PHẢI trả về lỗi HTTP 400 nếu thiếu tiêu đề X-Privet-Token.

HTTP/1.1 400 Thiếu tiêu đề X-Privet-Token.

Ví dụ 1:

{
        "error": "server_error",
        "description": "Service unavailable",
        "server_api": "/submit",
        "server_http_code": 503
}

Ví dụ 2:

{
        "error": "printer_busy",
        "description": "Printer is currently printing other job",
        "timeout": 15
}

5. Printer API

Một trong những loại thiết bị mà giao thức này hỗ trợ là máy in. Các thiết bị hỗ trợ loại này CÓ THỂ triển khai một số chức năng dành riêng cho máy in. Lý tưởng nhất là việc in tới máy in kết nối đám mây sẽ thông qua một máy chủ Cloud Print:

Trong một số trường hợp, khách hàng có thể cần gửi tài liệu tại địa phương. Có thể cần đến khi máy khách không có mã nhận dạng Google hoặc không thể giao tiếp với máy chủ Cloud Print. Trong trường hợp đó, lệnh in sẽ được gửi cục bộ đến máy in. Đến lượt, máy in sẽ sử dụng dịch vụ Cloud Print để xếp hàng và chuyển đổi lệnh in. Máy in sẽ đăng lại lệnh in đã gửi cục bộ lên dịch vụ Cloud Print rồi yêu cầu lệnh in đó, vì lệnh in được gửi qua đám mây. Quy trình này sẽ mang đến trải nghiệm linh hoạt cho người dùng về dịch vụ (chuyển đổi) và việc quản lý/theo dõi lệnh in.

Vì dịch vụ Cloud Print triển khai quy trình chuyển đổi, nên máy in NÊN quảng cáo hỗ trợ tất cả các định dạng đầu vào ("*/*") trong danh sách các loại nội dung được hỗ trợ:

{
        "version": "1.0",
        "printer": {
                "supported_content_type": [
                        { "content_type": "image/pwg-raster" },
                        { "content_type": "*/*" }
                ]
        }
}

Trong một số trường hợp, bạn muốn có một giải pháp hoàn toàn ngoại tuyến. Vì máy in chỉ hỗ trợ một số định dạng đầu vào, nên ứng dụng khách sẽ cần chuyển đổi tài liệu sang một số định dạng máy in được hỗ trợ gốc.

Quy cách này YÊU CẦU tất cả các máy in phải hỗ trợ ít nhất định dạng PWG Raster ("image/pwg-raster") cho trường hợp in ngoại tuyến. Máy in có thể hỗ trợ các định dạng khác (ví dụ: JPEG) và nếu một máy khách hỗ trợ định dạng đó, thì máy khách có thể gửi tài liệu ở định dạng đó. Máy in PHẢI hiển thị các loại được hỗ trợ thông qua API /capabilities, ví dụ:

{
        "version": "1.0",
        "printer": {
                "supported_content_type": [
                        { "content_type": "image/pwg-raster" },
                        { "content_type": "image/jpeg" }
                ]
        }
}
Có hai cách để ứng dụng có thể bắt đầu in qua mạng cục bộ.

In đơn giản – ứng dụng gửi tài liệu qua mạng cục bộ đến API /submitdoc (không chỉ định tham số job_id). Tài liệu đã gửi sẽ được in bằng chế độ cài đặt vé in mặc định và không cần trạng thái lệnh in. Nếu MÁY IN CHỈ hỗ trợ loại in này, thì MÁY IN CHỈ ĐƯỢC quảng cáo API /submitdoc trong phản hồi API /privet/info.

"api": [
        "/privet/accesstoken",
        "/privet/capabilities",
        "/privet/printer/submitdoc",
]

In nâng cao – trước tiên, ứng dụng phải tạo một lệnh in trên máy in bằng cách gọi API /privet/printer/createjob với một vé lệnh CJT hợp lệ trong yêu cầu. Máy in PHẢI lưu trữ phiếu in trong bộ nhớ và trả về job_id cho ứng dụng. Sau đó, ứng dụng sẽ gọi API /printer/submitdoc và chỉ định job_id đã nhận trước đó. Lúc đó, máy in sẽ bắt đầu in. Ứng dụng sẽ thăm dò máy in để biết trạng thái lệnh in bằng cách gọi API /privet/printer/jobstate.

Trong môi trường nhiều khách hàng, không có gì đảm bảo cách gọi API này. Một ứng dụng có thể gọi /createjob giữa các lệnh gọi /createjob->/submitdoc của một ứng dụng khác. Để loại bỏ các tình trạng tắc nghẽn có thể xảy ra và cải thiện khả năng sử dụng, bạn nên có một hàng đợi nhỏ gồm các lệnh in đang chờ xử lý trên máy in (ít nhất là 3-5):

  • /createjob sẽ chiếm vị trí đầu tiên có sẵn trong hàng đợi.
  • Thời gian tồn tại của công việc (trong hàng đợi) là ít nhất 5 phút.
  • Nếu tất cả các vị trí trong hàng đợi đều đã được sử dụng, thì lệnh in cũ nhất sẽ bị xoá và một lệnh in mới sẽ được đặt vào đó.
  • Nếu có một lệnh in đang in trên thiết bị (in đơn giản hoặc nâng cao), /submitdoc sẽ trả về trạng thái bận và đề xuất thời gian chờ để thử lại lệnh in này.
  • Nếu /submitdoc đề cập đến một công việc đã bị xoá khỏi hàng đợi (do thay thế hoặc hết thời gian chờ), thì máy in sẽ trả về lỗi invalid_print_job và ứng dụng sẽ thử lại quy trình từ bước /createjob. Ứng dụng PHẢI đợi một khoảng thời gian chờ ngẫu nhiên tối đa 5 giây trước khi thử lại.

Nếu các hạn chế về bộ nhớ ngăn việc lưu trữ nhiều công việc đang chờ xử lý trên thiết bị, thì có thể có một hàng đợi dài 1 công việc in. Thao tác này vẫn phải tuân theo giao thức tương tự như trên. Sau khi hoàn tất hoặc gặp lỗi, máy in phải lưu trữ thông tin về trạng thái của công việc trong ít nhất 5 phút. Kích thước hàng đợi để lưu trữ trạng thái công việc đã hoàn thành phải ít nhất là 10. Nếu có nhiều trạng thái công việc cần được lưu trữ, trạng thái cũ nhất có thể bị xoá khỏi hàng đợi trước khi hết thời gian chờ 5 phút.

Lưu ý: Hiện tại, các ứng dụng sẽ thăm dò trạng thái của công việc. Trong tương lai, chúng tôi có thể yêu cầu máy in gửi thông báo DNS TXT khi CÓ BẤT KỲ trạng thái lệnh in nào thay đổi.

5.1. /privet/printer/createjob API

API /privet/printer/createjob là KHÔNG BẮT BUỘC (xem phần In đơn giản ở trên). Đây là một yêu cầu HTTP POST. API /privet/printer/createjob PHẢI kiểm tra tiêu đề "X-Privet-Token" hợp lệ. Thiết bị PHẢI triển khai API này trên URL "/privet/printer/createjob":

POST /privet/printer/createjob HTTP/1.1
Khi nhận được lệnh gọi API /privet/printer/createjob, máy in PHẢI tạo một mã nhận dạng lệnh in mới, lưu trữ vé in đã nhận ở định dạng CJT và trả mã nhận dạng lệnh in về cho máy khách.

5.1.1. Đầu vào

API /privet/printer/createjob không có tham số đầu vào trong URL. Nội dung yêu cầu phải chứa dữ liệu vé lệnh in ở định dạng CJT.

5.1.2. Cầu thủ trả bóng

API /privet/printer/createjob trả về dữ liệu sau:
Tên giá trịLoại giá trịMô tả
job_idchuỗiMã nhận dạng của lệnh in mới tạo.
expires_inintSố giây mà lệnh in này có hiệu lực.

Ví dụ:

{
        "job_id": "123",
        "expires_in": 600
}

5.1.3. Lỗi

API /privet/printer/createjob có thể trả về các lỗi sau (xem phần Lỗi để biết thông tin chi tiết):
LỗiMô tả
invalid_ticketPhiếu in đã gửi không hợp lệ.
printer_busyMáy in đang bận và hiện không thể xử lý /tạo lệnh in. Thử lại sau khi hết thời gian chờ.
printer_errorMáy in đang ở trạng thái lỗi và cần có sự can thiệp của người dùng để khắc phục. Nội dung mô tả phải có nội dung giải thích chi tiết hơn (ví dụ: "Kẹt giấy ở Khay 1").
invalid_x_privet_tokenX-Privet-Token không hợp lệ hoặc trống trong yêu cầu.

Nếu thiết bị không hiển thị /privet/printer/createjob, thì thiết bị ĐƯỢC PHÉP trả về lỗi HTTP 404. Nếu thiếu tiêu đề X-Privet-Token, thiết bị PHẢI trả về lỗi HTTP 400.

5.2. /privet/printer/submitdoc API

Bạn BẮT BUỘC phải triển khai API /privet/printer/submitdoc để triển khai tính năng in qua mạng cục bộ (ngoại tuyến hoặc đăng lại lên Cloud Print). Đây là một yêu cầu POST qua HTTP. API /privet/printer/submitdoc PHẢI kiểm tra tiêu đề "X-Privet-Token" hợp lệ. Thiết bị PHẢI triển khai API này trên URL "/privet/printer/submitdoc":
POST /privet/printer/submitdoc HTTP/1.1
Khi nhận được lệnh gọi API /privet/printer/submitdoc, máy in sẽ bắt đầu in. Nếu không thể bắt đầu in, thì máy in PHẢI trả về lỗi printer_busy và khoảng thời gian chờ được đề xuất để ứng dụng đợi trước khi thử lại.

Nếu không thể lưu giữ tất cả dữ liệu trong bộ đệm trong của mình, thì máy in NÊN sử dụng các cơ chế TCP để làm chậm quá trình truyền dữ liệu cho đến khi in một phần của tài liệu, nhờ đó, một phần của bộ đệm sẽ có sẵn trở lại. (Ví dụ: máy in có thể đặt windowsize=0 trên các lớp TCP, điều này sẽ khiến máy khách phải chờ.)

Việc gửi tài liệu đến máy in có thể mất nhiều thời gian. Ứng dụng có thể kiểm tra trạng thái của máy in và lệnh in (in nâng cao) trong khi quá trình in đang diễn ra. Để làm như vậy, máy in PHẢI cho phép ứng dụng gọi các API /privet/info và /privet/printer/jobstate trong khi xử lý các lệnh gọi API /privet/printer/submitdoc. Tất cả các ứng dụng nên bắt đầu một luồng mới để thực thi lệnh gọi API /privet/printer/submitdoc, để luồng chính có thể sử dụng các API /privet/info và /privet/printer/jobstate để kiểm tra trạng thái của máy in và lệnh.

Lưu ý: Sau khi hoàn tất hoặc huỷ bỏ lệnh in cục bộ, bạn nên (và sẽ phải làm trong phiên bản sau của quy cách này) báo cáo trạng thái cuối cùng của lệnh in cho giao diện /cloudprint/submit vì mục đích kế toán và trải nghiệm người dùng. Các tham số "printerid", "title", "contentType" và "final_semantic_state" (ở định dạng PrintJobState) là bắt buộc, còn các tham số "tag" (tham số lặp lại) và "ticket" (vé của công việc ở định dạng CloudJobTicket). Xin lưu ý rằng PrintJobState được cung cấp thực sự phải là trạng thái cuối cùng, tức là loại của trạng thái này phải là DONE hoặc ABORTED và bạn phải cung cấp nguyên nhân trong trường hợp trạng thái là ABORTED (xem JobState để biết thông tin chi tiết). Cũng lưu ý rằng việc sử dụng giao diện /cloudprint/submit này để báo cáo các lệnh in cục bộ không được đề cập trong thông số kỹ thuật của giao diện vì phần đó nhằm mục đích mô tả mục đích sử dụng chính của giao diện: gửi lệnh in cùng với tài liệu cần in được cung cấp trong tham số "content" (nội dung).

5.2.1. Đầu vào

API /privet/printer/submitdoc có các tham số đầu vào sau:
TênGiá trị
job_id(không bắt buộc) Mã nhận dạng lệnh in. Có thể bỏ qua đối với trường hợp in đơn giản (xem ở trên). Phải khớp với giá trị do máy in trả về.
user_name(không bắt buộc) Tên người dùng dễ đọc. Đây không phải là thông tin chính xác và chỉ nên dùng cho chú thích lệnh in. Nếu lệnh in được đăng lại lên dịch vụ Cloud Print, thì chuỗi này sẽ được đính kèm vào lệnh in trên Cloud Print.
client_name(không bắt buộc) Tên của ứng dụng khách đưa ra yêu cầu này. Chỉ dùng cho mục đích hiển thị. Nếu công việc được đăng lại lên dịch vụ Cloud Print, chuỗi này sẽ được đính kèm vào công việc Cloud Print.
job_name(không bắt buộc) Tên của lệnh in cần được ghi lại. Nếu công việc được đăng lại lên dịch vụ Cloud Print, chuỗi này sẽ được đính kèm vào công việc Cloud Print.
ngoại tuyến(không bắt buộc) Chỉ có thể là "offline=1". Trong trường hợp này, máy in chỉ nên thử in khi không có mạng (không đăng lại lên máy chủ Cloud Print).

Nội dung yêu cầu phải chứa một tài liệu hợp lệ để in. "Content-Length" phải có độ dài chính xác của yêu cầu. Tiêu đề "Content-Type" phải được đặt thành loại MIME của tài liệu và khớp với một trong các loại trong CDD (trừ phi CDD chỉ định "*/*").

Khách hàng NÊN cung cấp tên người dùng (hoặc email), tên khách hàng và tên công việc hợp lệ cùng với yêu cầu này. Những trường này chỉ được dùng trong giao diện người dùng để cải thiện trải nghiệm người dùng.

5.2.2. Cầu thủ trả bóng

API /privet/printer/submitdoc trả về dữ liệu sau:
Tên giá trịLoại giá trịMô tả
job_idchuỗiMã nhận dạng của lệnh in mới tạo (in đơn giản) hoặc job_id được chỉ định trong yêu cầu (in nâng cao).
expires_inintSố giây mà lệnh in này có hiệu lực.
job_typechuỗiLoại nội dung của giấy tờ bạn gửi.
job_sizeint 64 bitKích thước của dữ liệu in tính bằng byte.
job_namechuỗi(không bắt buộc) Tên công việc giống như trong dữ liệu đầu vào (nếu có).

Ví dụ:

{
        "job_id": "123",
        "expires_in": 500,
        "job_type": "application/pdf",
        "job_size": 123456,
        "job_name": "My PDF document"
}

5.2.3. Lỗi

API /privet/printer/submitdoc có thể trả về các lỗi sau (xem phần Lỗi để biết thông tin chi tiết):
LỗiMô tả
invalid_print_jobMã công việc không hợp lệ/đã hết hạn được chỉ định trong yêu cầu. Thử lại sau khi hết thời gian chờ.
invalid_document_typeMáy in không hỗ trợ loại MIME của tài liệu.
invalid_documentGiấy tờ bạn gửi không hợp lệ.
document_too_largeTài liệu vượt quá kích thước tối đa cho phép.
printer_busyMáy in đang bận và hiện không thể xử lý tài liệu. Thử lại sau khi hết thời gian chờ.
printer_errorMáy in đang ở trạng thái lỗi và cần có sự can thiệp của người dùng để khắc phục. Nội dung mô tả phải có nội dung giải thích chi tiết hơn (ví dụ: "Kẹt giấy ở Khay 1").
invalid_paramsCác tham số không hợp lệ được chỉ định trong yêu cầu. (Bạn nên bỏ qua các thông số không xác định để đảm bảo khả năng tương thích trong tương lai)
user_cancelNgười dùng đã huỷ rõ ràng quy trình in trên thiết bị.
server_errorKhông đăng được tài liệu lên Cloud Print.
invalid_x_privet_tokenX-Privet-Token không hợp lệ hoặc trống trong yêu cầu.

Nếu thiết bị không hiển thị /privet/printer/submitdoc, thì thiết bị ĐƯỢC PHÉP trả về lỗi HTTP 404. Nếu thiếu tiêu đề X-Privet-Token, thiết bị PHẢI trả về lỗi HTTP 400.

Lưu ý: API /privet/printer/submitdoc có thể yêu cầu xử lý đặc biệt ở phía máy in (do tải trọng lớn được đính kèm). Trong một số trường hợp (tuỳ thuộc vào quá trình triển khai máy chủ HTTP của máy in và nền tảng), máy in có thể đóng ổ cắm TRƯỚC KHI trả về lỗi HTTP. Trong trường hợp khác, máy in có thể trả về lỗi 503 (thay vì lỗi Privet). Máy in NÊN cố gắng hết sức để trả về Privet. Tuy nhiên, mọi ứng dụng triển khai quy cách Privet ĐỀU PHẢI có thể xử lý trường hợp đóng ổ cắm (không có lỗi HTTP) và lỗi HTTP 503 cho API /privet/printer/submitdoc. Trong trường hợp này, ứng dụng NÊN xử lý lỗi này dưới dạng lỗi "printer_busy" của Privet với "timeout" được đặt thành 15 giây. Để tránh thử lại vô hạn, ứng dụng có thể ngừng thử lại sau một số lần thử hợp lý (ví dụ: 3 lần).

5.3. /privet/printer/jobstate API

API /privet/printer/jobstate là KHÔNG BẮT BUỘC (xem phần In đơn giản ở trên). Đây là một yêu cầu HTTP GET. API /privet/printer/jobstate PHẢI kiểm tra tiêu đề "X-Privet-Token" hợp lệ. Thiết bị PHẢI triển khai API này trên URL "/privet/printer/jobstate":
GET /privet/printer/jobstate HTTP/1.1
Khi nhận được lệnh gọi API /privet/printer/jobstate, máy in sẽ trả về trạng thái của lệnh in được yêu cầu hoặc lỗi invalid_print_job.

5.3.1. Đầu vào

API /privet/printer/jobstate có các tham số đầu vào sau:
TênGiá trị
job_idMã lệnh in để trả về trạng thái.

5.3.2. Cầu thủ trả bóng

API /privet/printer/jobstate trả về dữ liệu sau:
Tên giá trịLoại giá trịMô tả
job_idchuỗiMã lệnh in có thông tin trạng thái.
tiểu bangchuỗidraft – lệnh in đã được tạo trên thiết bị (chưa nhận được lệnh gọi /privet/printer/submitdoc).
queued – lệnh in đã được nhận và đưa vào hàng đợi, nhưng chưa bắt đầu in.
in_progress – lệnh in đang trong quá trình in.
stopped – lệnh in đã bị tạm dừng nhưng có thể được khởi động lại theo cách thủ công hoặc tự động.
done – lệnh in đã hoàn tất.
bị huỷ – lệnh in không thành công.
mô tảchuỗi(không bắt buộc) Nội dung mô tả mà con người đọc được về trạng thái lệnh in. Bạn nên thêm thông tin nếu state< là stopped hoặc aborted. Trường semantic_state thường cung cấp nội dung mô tả tốt hơn và có ý nghĩa hơn cho ứng dụng.
expires_inintSố giây mà lệnh in này có hiệu lực.
job_typechuỗi(không bắt buộc) Loại nội dung của tài liệu được gửi.
job_sizeint 64 bit(không bắt buộc) Kích thước của dữ liệu in tính bằng byte.
job_namechuỗi(không bắt buộc) Tên công việc giống như trong dữ liệu đầu vào (nếu có).
server_job_idchuỗi(không bắt buộc) Mã nhận dạng của công việc do máy chủ trả về (nếu công việc đã được đăng lên dịch vụ Cloud Print). Bị bỏ qua khi in ngoại tuyến.
semantic_stateJSON(không bắt buộc) Trạng thái ngữ nghĩa của lệnh in ở định dạng PrintJobState.

Ví dụ (in bằng cách báo cáo thông qua 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"
}

Ví dụ (lỗi in ngoại tuyến):

{
        "job_id": "123",
        "state": "stopped",
        "description": "Out of paper",
        "expires_in": 100,
        "job_type": "application/pdf",
        "job_size": 123456,
        "job_name": "My PDF document"
}

Ví dụ (người dùng huỷ lệnh in):

{
        "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
        }
}

Ví dụ (lệnh in dừng do hết giấy). Lưu ý đến thông tin tham chiếu về trạng thái thiết bị. Ứng dụng sẽ cần gọi API /privet/info để biết thêm thông tin chi tiết về trạng thái thiết bị:

{
        "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. Lỗi

API /privet/printer/jobstate có thể trả về các lỗi sau (xem phần Lỗi để biết thông tin chi tiết):
LỗiMô tả
invalid_print_jobMã công việc không hợp lệ/đã hết hạn được chỉ định trong yêu cầu.
server_errorKhông lấy được trạng thái lệnh in (đối với các lệnh in được đăng lên Cloud Print).
invalid_x_privet_tokenX-Privet-Token không hợp lệ hoặc trống trong yêu cầu.

Nếu thiết bị không hiển thị /privet/printer/jobstate, thì thiết bị ĐƯỢC PHÉP trả về lỗi HTTP 404. Nếu thiếu tiêu đề X-Privet-Token, thiết bị PHẢI trả về lỗi HTTP 400.

6. Phụ lục

6.1. Hành vi và chế độ cài đặt mặc định

Phần này sẽ giải thích hành vi mặc định mà chúng tôi mong đợi ở TẤT CẢ các thiết bị tương thích với Privet.
  • Các thiết bị dùng ngay chỉ nên hỗ trợ API /privet/info/privet/register. Tất cả các API khác (ví dụ: /privet/accesstoken, in cục bộ) đều phải bị vô hiệu hoá.
  • Bạn cần tương tác trực tiếp với thiết bị để đăng ký.
    • Người dùng PHẢI thực hiện một thao tác thực trên thiết bị (ví dụ: nhấn nút) để xác nhận quyền truy cập vào thiết bị.
    • Sau khi người dùng thực hiện thao tác nêu trên, máy in sẽ gửi yêu cầu /cloudprint/register. Không được gửi yêu cầu này cho đến khi thực hiện xong hành động (xem Sơ đồ trình tự 1).
    • Nếu đang xử lý yêu cầu /privet/register (ví dụ: đang chờ hành động ở trên), thì thiết bị phải từ chối tất cả các yêu cầu /privet/register khác. Trong trường hợp này, thiết bị PHẢI trả về lỗi device_busy.
    • Thiết bị sẽ hết thời gian chờ cho mọi yêu cầu /register không nhận được hành động thực tế nêu trên trong vòng 60 giây. Trong trường hợp này, thiết bị PHẢI trả về lỗi confirmation_timeout.
    • Không bắt buộc: Bạn nên dùng nhưng không bắt buộc, những thuộc tính sau đây có thể cải thiện trải nghiệm người dùng:
      • Máy in có thể nhấp nháy đèn hoặc màn hình để cho biết người dùng cần thực hiện một hành động để xác nhận việc đăng ký.
      • Màn hình của máy in có thể hiển thị thông báo "Máy in đang được đăng ký với Google Cloud Print cho người dùng "abc@def.com" – nhấn OK để tiếp tục", trong đó abc@def.com  là thông số người dùng từ lệnh gọi API /register. Điều này sẽ giúp người dùng hiểu rõ hơn rằng:
        • đó là yêu cầu đăng ký mà họ đang xác nhận
        • điều gì sẽ xảy ra nếu người dùng đó không kích hoạt yêu cầu.
      • Ngoài thao tác thực tế để xác nhận trên máy in (ví dụ: "Nhấn nút OK"), máy in cũng có thể cung cấp cho người dùng một nút để huỷ yêu cầu (ví dụ: "Nhấn Huỷ để từ chối"). Điều này sẽ cho phép những người dùng không kích hoạt yêu cầu đăng ký huỷ yêu cầu đó trước khi hết thời gian chờ 60 giây. Trong trường hợp này, thiết bị PHẢI trả về lỗi user_cancel.
  • Chuyển quyền sở hữu:
    • Thiết bị có thể bị xoá rõ ràng khỏi dịch vụ đám mây.
      • Nếu thiết bị nhận được kết quả thành công nhưng không có nội dung mô tả thiết bị do lệnh gọi /cloudprint/printer (đối với GCP), thì thiết bị PHẢI quay về chế độ mặc định (mới mua).
      • Nếu thông tin xác thực của thiết bị không còn hoạt động (rõ ràng là do máy chủ phản hồi "thông tin xác thực không hợp lệ"), thì thiết bị PHẢI quay về chế độ mặc định (mới mua).
    • Thao tác đặt lại về trạng thái ban đầu tại chỗ PHẢI xoá thông tin đăng nhập của thiết bị và đặt thiết bị về trạng thái mặc định.
    • Không bắt buộc: Thiết bị có thể cung cấp một mục trong trình đơn để xoá thông tin đăng nhập và chuyển thiết bị sang chế độ mặc định.
  • Các thiết bị hỗ trợ thông báo XMPP PHẢI có khả năng ping máy chủ. Máy chủ PHẢI kiểm soát được thời gian chờ ping thông qua "local_settings".
  • Thiết bị có thể ping rõ ràng máy chủ (API /cloudprint/printer cho GCP, ngoài các lệnh ping XMPP) không quá một lần mỗi ngày (24 giờ) để đảm bảo chúng được đồng bộ hoá. Bạn nên chọn ngẫu nhiên khoảng thời gian kiểm tra trong khoảng từ 24 đến 32 giờ.
  • Không bắt buộc nhưng bạn nên có cách thủ công (nút) để cho phép người dùng bắt đầu kiểm tra các lệnh in mới từ thiết bị Cloud Print. Một số máy in đã có tính năng này.
  • Không bắt buộc. Máy in doanh nghiệp có thể có lựa chọn tắt hoàn toàn tính năng khám phá cục bộ. Trong trường hợp đó, thiết bị PHẢI cập nhật các chế độ cài đặt cục bộ này trên máy chủ. Các chế độ cài đặt cục bộ MỚI phải trống (đặt "local_discovery" thành "false", tức là bạn có thể bật lại chế độ này từ Dịch vụ GCP).

6.1.2 Sơ đồ đăng ký mặc định

6.2. Tấn công và ngăn chặn XSSI và XSRF

Phần này sẽ giải thích khả năng xảy ra các cuộc tấn công XSSI và XSRF trên thiết bị, cũng như cách bảo vệ thiết bị khỏi các cuộc tấn công đó (bao gồm cả kỹ thuật tạo mã thông báo).
Bạn có thể xem thêm thông tin tại đây: http://googleonlinesecurity.blogspot.com/2011/05/website-security-for-webmasters.html
Thông thường, các cuộc tấn công XSSI và XSRF có thể xảy ra khi một trang web đang sử dụng cơ chế xác thực bằng cookie. Mặc dù Google không sử dụng cookie với Dịch vụ Cloud Print, nhưng những cuộc tấn công như vậy vẫn có thể xảy ra. Theo thiết kế, quyền truy cập mạng cục bộ ngầm tin tưởng các yêu cầu.

6.2.1. XSSI

Một trang web độc hại có thể đoán địa chỉ IP và số cổng của một thiết bị tương thích với Privet, đồng thời cố gắng gọi API Privet bằng cách sử dụng "src=<api name>" bên trong thẻ <script>:
<script type="text/javascript" src="http://192.168.1.42:8080/privet/info"></script>
Nếu không có biện pháp bảo vệ, các trang web độc hại sẽ có thể thực hiện lệnh gọi API và truy cập vào kết quả.
Để ngăn chặn loại tấn công này, TẤT CẢ các lệnh gọi API Privet ĐỀU PHẢI yêu cầu tiêu đề "X-Privet-Token" trong yêu cầu. Thẻ tập lệnh "src=<api>" không thể thêm tiêu đề, giúp bảo vệ hiệu quả trước kiểu tấn công này.

6.2.2. XSRF

http://en.wikipedia.org/wiki/Cross-site_request_forgery
Một trang web độc hại có thể đoán địa chỉ IP và số cổng của một thiết bị tương thích với Privet, đồng thời cố gắng gọi API Privet bằng cách sử dụng <iframe>, biểu mẫu hoặc một số cơ chế tải trên nhiều trang web khác. Kẻ tấn công sẽ không thể truy cập vào kết quả của yêu cầu, nhưng nếu yêu cầu thực hiện một hành động (ví dụ: in), thì chúng có thể kích hoạt yêu cầu đó.

Để ngăn chặn cuộc tấn công này, chúng tôi yêu cầu bạn áp dụng biện pháp bảo vệ sau:

  • Để lại API /privet/info mở cho XSRF
  • API /privet/info KHÔNG ĐƯỢC thực hiện bất kỳ thao tác nào trên thiết bị
  • Sử dụng API /privet/info để nhận x-privet-token
  • Tất cả các API khác PHẢI kiểm tra x-privet-token hợp lệ trong tiêu đề "X-Privet-Token".
  • x-privet-token CHỈ có hiệu lực trong 24 giờ.

Ngay cả khi kẻ tấn công có thể thực thi API /privet/info, chúng cũng không thể đọc x-privet-token từ phản hồi và do đó không thể gọi bất kỳ API nào khác.

Bạn nên tạo mã thông báo XSRF bằng thuật toán sau:

XSRF_token = base64( SHA1(device_secret + DELIMITER + issue_timecounter) + DELIMITER + issue_timecounter )

Các phần tử tạo mã thông báo XSRF:

  • DELIMITER là một ký tự đặc biệt, thường là ":"
  • issue_timecounter là số giây kể từ một sự kiện nào đó (thời gian bắt đầu cho dấu thời gian) hoặc thời gian khởi động thiết bị (đối với bộ đếm CPU). issue_timecounter liên tục tăng khi thiết bị hoạt động (xem phần xác minh mã thông báo bên dưới).
  • SHA1 – hàm băm sử dụng thuật toán SHA1
  • base64 – mã hoá base64
  • device_secret – khoá bí mật dành riêng cho thiết bị. Bạn PHẢI cập nhật khoá bí mật của thiết bị mỗi khi khởi động lại.

Các cách được đề xuất để tạo khoá bí mật của thiết bị:

  • Tạo một UUID mới trong mỗi lần khởi động lại
  • Tạo một số ngẫu nhiên 64 bit cho mỗi lần khởi động lại

Thiết bị không bắt buộc phải lưu trữ tất cả mã thông báo XSRF mà thiết bị đã phát hành. Khi cần xác minh mã thông báo XSRF để đảm bảo tính hợp lệ, thiết bị sẽ phải giải mã mã thông báo base64. Lấy issue_timecounter từ nửa sau (văn bản thuần tuý) và cố gắng tạo hàm băm SHA1 của device_secret + DELIMITER + issue_timecounter, trong đó issue_timecounter là từ mã thông báo. Nếu SHA1 mới tạo khớp với SHA1 trong mã thông báo, thì thiết bị hiện phải kiểm tra xem issue_timecounter có nằm trong khoảng thời gian hợp lệ (24 giờ) của bộ đếm thời gian hiện tại hay không. Để làm như vậy, thiết bị sẽ lấy bộ đếm thời gian hiện tại (ví dụ: bộ đếm CPU) và trừ issue_timecounter khỏi bộ đếm đó. Kết quả PHẢI là số giây kể từ khi mã thông báo được phát hành.

Lưu ý quan trọng: Đây là cách nên dùng để triển khai biện pháp bảo vệ XSRF. Các ứng dụng của quy cách Privet không được cố gắng tìm hiểu mã thông báo XSRF mà phải coi đó là một hộp đen. Hình 6.2.3 minh hoạ một cách nên dùng để triển khai X-Privet-Token và xác minh một yêu cầu thông thường.

6.2.3 Sơ đồ trình tự xác minh và tạo mã thông báo X-Privet

6.3. Sơ đồ quy trình công việc

Phần này sẽ minh hoạ một quy trình làm việc trong nhiều trường hợp.

6.3.1. Quy trình làm việc khi sử dụng máy in lần đầu

6.3.2. Khởi động máy in đã đăng ký

6.3.3 Quy trình xử lý thông báo XMPP

6.3.4. Quy trình kiểm tra chế độ cài đặt máy in