SafeQ Workstation Client Protocol Specification

Protocol Level 4

Generic

Protocol is message oriented. Client opens connection to server. Client sends request and server returns response.

Each request from client MUST contain prefix %%%SafeQ-.

Each request from client MUST be terminated by '\n'.

Request MAY continue on next line only in defined cases, like sending block of data with defined length.

All requests MUST be encoded in UTF-8.

Request header is CASE INSENSITIVE. E.g. %%%SafeQ-Get-SomethingFancy equals to %%%safeq-get-somethingfancy, but it is recommended to use CammelCase syntax which you can see in this document.

Extra spaces in value part of request are NOT ignored and they're considered as part of value. E.g.: '%%%SafeQ-Something: hello \n' will produce value ' hello '

Communication

Client MUST initiate communication with following header:

%%%SafeQ-Check:\n

Server just ignore this message and it keeps connection alive. This command serves client to determine which server is available for printing.

Client MUST send following request to initiate communication by protocol level 4.

%%%SafeQ-ProtocolLevel:4\n

This is necessary, because it allows SafeQ to determine proper processor for protocol.

Client MAY request encrypted communication - see section Encryption.

Client MAY send information about its version:

%%%SafeQ-Version:Windows 2.0\n

Client MAY send information that communication will be compressed in ZIP:

%%%SafeQ-Compression:ZIP\n

Client MUST send data in chunks. Each chunk must begin with header:

%%%SafeQ-Data:<length in bytes>\n

Then client MUST send amount of data declared in header.

Client MUST send length 0 when it finishes sending data:

%%%SafeQ-Data:0\n

Client MAY send information about job (only in case job parsing is enabled):

%%%SafeQ-JobInfo:<number of pages> [info about page 1] [info about page 2] ...\n

Where information about each page is in the following format:

<Page Number>|<Number of copies>|<Duplex>|<Paper size>|<DPI>|<Width in pixels>x<Height in pixels>|<Color information availability>[|<Color/Mono>]

Getting values from server

Client MAY ask server for specific values with Get request. Where <VARIABLE> is replaced by name of variable

%%%SafeQ-Get-<VARIABLE>:\n

When server does not support requested value it MUST send:

%%%SafeQ-Unknown:\n

When server supports value it MUST send reponse with:

%%%SafeQ-<VARIABLE>:<VALUE>\n

Supported Get-* requests

Retrieve job status - request:

%%%SafeQ-Get-JobStatus:\n

Response:

%%%SafeQ-JobStatus:[OK|Abort]\n

Retrieve job size - request:

%%%SafeQ-Get-JobSize:\n

Response:

%%%SafeQ-JobSize:<SIZE>\n

Retrieve link for browser - request:

%%%SafeQ-Get-BrowserLink:\n

Response:

%%%SafeQ-BrowserLink:<LINK-URL_ENCODED>\n

Note: Size of browser window should be determined on client side from the HTML element body.

Retrieve permission for job parsing on client side:

%%%SafeQ-Get-JobParsing:\n

Response in case client is allowed to parse job:

%%%SafeQ-JobParsing:1\n

Request for license feature:

%%%SafeQ-Get-License:[Compression|Encryption]\n

Response:

%%%SafeQ-License:[Enabled|Disabled]\n

Request for graceful disconnect:

%%%SafeQ-Get-ConnectionClose:\n

Response:

%%%SafeQ-ConnectionClose:OK\n

Encryption

Client MAY request encryption - via TLS - STARTTLS. (Further info about STARTTLS - http://en.wikipedia.org/wiki/STARTTLS)

%%%SafeQ-Get-Encryption:TLS\n

Server MUST respond:

  • in case of success %%%SafeQ-Encryption:OK\n

  • in case of failure %%%SafeQ-Encryption:FAILED\n

After acknowledging encryption from server side client MUST initiate TLS handshake.

Authentication

It is possible to authenticate user. The Client MUST send at least one of the following headers:

%%%SafeQ-Login:<LOGIN>\n
%%%SafeQ-Password:<PASSWORD>\n
%%%SafeQ-Card:<CARD>\n

Client MUST send request for verification of above user credentials:

%%%SafeQ-Get-Authentication:<METHOD>\n

Methods: LOGIN, PASSWORD, CARD

Server MUST respond:

  • in case of success %%%SafeQ-Authentication:OK\n

  • in case of failure %%%SafeQ-Authentication:FAILED\n

  • in case of email duplicity %%%SafeQ-Authentication:FAILED DUPLICATE EMAIL\n

If CARD is used, SafeQ server (CML/ORS) does not convert the card numbers received in any way before searching for them in the database/cache.

Trusted client

The simplest way how to authenticate user is to send his SafeQ login in header.

%%%SafeQ-For:<LOGIN>\n

Queue specification

Client MAY specify printing queue (e.g.: Secure):

%%%SafeQ-LP:<QUEUE-NAME>\n

Tags

It is possible to set tags to job by sending following command.

It is possible to add user tag to queue name. Add tag name after queue name, delimiter is semicolon:

%%%SafeQ-LP:<QUEUE-NAME>:<TAG-NAME>\n

You can specify more tags, delimiter is comma. Do not add any extra spaces:

%%%SafeQ-LP:<QUEUE-NAME>:<TAG-NAME>,<TAG-NAME>,<TAG-NAME>\n

Tags are case sensitive.

Document

It is possible to set further information to document by following headers.

Set document title:

%%%SafeQ-Title:<TITLE>\n

Set note to document. Note MUST not contain EOL:

%%%SafeQ-Note:<TEXT>\n

Set name of sender's machine to the job:

%%%Safeq-MachineName:<TEXT>\n

In case job is cancelled by user (job may be incomplete), the following header is sent (before end of job data header - %%%SafeQ-Data:0\n):

%%%SafeQ-JobStatus:Cancelled\n

Client MUST NOT send any further SafeQ-Data block with non-zero size of data block. If such a block occurs then server terminates connection because of protocol violation.

Finishing options

It is possible to set finishing options by sending following commands before sending last block of data.

Set number of copies:

%%%SafeQ-Finishing-Copies:<NUMBER>\n

Set job as duplex:

%%%SafeQ-Finishing-Duplex:<DUPLEX-VALUE>\n

Where <DUPLEX-VALUE> is one of: None, ShortEdge, LongEdge

Set job as black and white:

%%%SafeQ-Finishing-BW:<BOOLEAN>\n

Set job to use stapler:

%%%SafeQ-Finishing-Stapler:<BOOLEAN>\n

Values

  • STRING - any string, it must not contain \n character

  • NUMBER - long number in Java, not float

  • BOOLEAN - true or false

Examples

It is possible to send job from command line. You can use netcat tool. Just store data into file in Unix format (\n as line delimiter).

Netcat command:

nc localhost 9100 < job-file.txt

Netcat with timeout 2 seconds (Win):

nc \-w 2 localhost 9100 < job-file.txt

Simple job with "testuser" account

%%%SafeQ-Check:
%%%SafeQ-ProtocolLevel:4
%%%SafeQ-For:testuser
%%%SafeQ-Title:Test Page
%%%SafeQ-Version:Windows 2.0
%%%SafeQ-Note:Note
%%%SafeQ-Domain:YSOFT
%%%SafeQ-MachineName:PC054
%%%SafeQ-Get-BrowserLink:
%%%SafeQ-JobID:2
%%%SafeQ-Data:3
abc%%%SafeQ-Data:0

Some comments on .NET implementation

The protocol works wit sessions, one session = one TCP connection. The best way to send

// all commands of the session encoded in UTF-8
byte [][] commands;
 
// The memory stream capacity must be exactly the total size of input buffers (no trailing '\0' characters)
using (var stream = new MemoryStream(commands.Select(c => c.Length).Sum()))
{
foreach (var cmd in commands)
{
stream.Write(cmd);
}
}
 
// Everything must be inside one TCP connection
var connection = new TcpClient(address, port).GetStream();
var buffer = stream.GetBuffer();
connection.Write(buffer, 0, buffer.Length);
connection.Close();

Protocol Level 3 and older

YSoft SafeQ is able to receive data using TCP data stream. This stream, sent by YSoft SafeQ Client, contains some text fields (metadata), followed by raw print job data. Here is an example of data stream including most frequently used metadata:

%%%SmartQ-CodePage: codepage
%%%SmartQ-For: username
%%%SmartQ-Title: title%%%SmartQ-LP: queue
%%%SmartQ-Sec: secureid
%%%SmartQ-Domain: domain
%%%SmartQ-JobID: jobid
%%%SmartQ-Zip: zip
<raw print job data>

Legend:

codepage: encoding mode for subsequent text fields - value "65001" means UTF-8.

username: login name of the user.

queue: queue on YSoft SafeQ server, where job will be stored (note: queue must match queue on YSoft SafeQ).

title: print job title.

secureid: unique security identifier obtained by user authentication (replaces username).

domain: specifies domain of workstation, which is sending the print job to SafeQ.

jobid: local job identifier.

zip: indicates that following print job data is compressed.