SpringCore Direct over USB

Overview

SpringCore Direct is a versatile protocol that allows the host to control the SpringCore device independently of its operating mode and independently of its communication interface (USB, BLE, ...).

This chapter details the implementation of SpringCore Direct over the USB interface.

The higher level protocol is documented in its own chapter: Direct Protocol.

Controlling the device's user interface (and many other features) is detailed in Direct Protocol : Control Class and operating the device in Smart Reader Mode in Smart Reader Operation : Protocol and API.

USB endpoints

The SpringCore Direct USB implementation uses the following endpoints to communicate with the host computer:

Endpoint Purpose Size Protocol
Control Initial setup
Bulk_Out Commands 64B See Direct Protocol and Direct protocol over USB below
Bulk_In Responses 64B See Direct Protocol and Direct protocol over USB below
Interrupt_In Events 64B See Direct Protocol and Direct protocol over USB below

Drivers and software implementation

The SpringCore USB Direct protocol uses three USB endpoints: BulkIn, BulkOut, InterruptIn. Any generic driver supporting this three types of endpoints is suitable to convey the messages. Therefore, and to suppress the need of writing (and having to maintain) a specific driver for every operating system, SpringCore devices use only generic drivers for SpringCore Direct over USB: WinUSB for Microsoft Windows computers, and libusb on UNIX systems, including Linux and Apple Mac OS X.

WinUSB

Microsoft has defined its specific extension to the standard USB descriptors. Using a WCID (Windows compatibility identifier) entry in its string and custom descriptors, a SpringCore device automates the installation of the WinUSB driver on Windows 10 systems.

The SpringCore device is then made available to the applications through the WinUSB library (winusb.dll) and recognized by the GUID {C3B50BD1-8D68-4196-8FCC-04B8A3B4837E}.

libusb

On UNIX systems, SpringCore devices should be accessed using the libusb0 library. Pay attention that on most systems, accessing the hardware directly through this library is possible only with root priviledges.

Direct protocol over USB

Every message starts with a PCB (Protocol Control Byte), followed by the CLAss, then the LENgth and the payload. The length is expressed either on 2 bytes or on 4 bytes, depending on bit 4 in the PCB.

As a general rule, it is forbidden for both the host and device to send an extended frame when the payload fits in a short frame.

Short frames

Short frames (LENgth on 2 bytes) are suitable for payload up to 64kB. Bit 4 in the PCB is set to 0 for short frames.

Byte Name Description
0 PCB Protocol Control Byte - see section "PCB" below
1 CLAss Class of command or response
2-3 LENgth Length of payload minus 1 (0000 = 1 to FFFF = 65536), MSB-first
4-N Payload Up to 64kB

Extended frames

Extended frames (LENgth on 4 bytes) are suitable for payload over 64kB. Bit 4 in the PCB is set to 1 for extended frames.

Byte Name Description
0 PCB Protocol Control Byte - see section "PCB" below
1 CLAss Class of command or response
2-5 LENgth Length of payload minus 1 (00010000 to 00FFFFFF), MSB-first
6-N Payload More than 64kB

PCB for BulkIn and BulkOut endpoints

Bit Name Description
7 Way 0: host to device
1: device to host
6 Channel must be 0 for bulk
5 Secure must be 0 for plain communication
4 Header type 0: short header (LENgth on 2 bytes)
1: long header (LENgth on 4 bytes)
3-0 Sequence Sequence number. Incremented by the host (modulo 16) and echoed by the device.

PCB for InterruptIn endpoint

Bit Name Description
7 Way 1: device to host
6 Channel must be 1 for interrupt
5 Secure must be 0 for plain communication
4 Header type must be 0
(long header not supported on InterruptIn)
3-0 Sequence Sequence number. Incremented by the device (modulo 16).

Rules for the Bulk_In and Bulk_Out endpoints

Handling of LEN

Both endpoints use a 4-byte or 6-byte header that specifies the type of the message and the (total) length of the payload.

The sender SHALL NOT use a long (6-byte) header if the length would fit in a short (4-byte) header.

Anyway, the receiver SHALL accept a long header in any case.

Chaining

If the header + payload don't fit in a single 64-byte buffer, a chaining happens.

The sender SHALL fill-up the endpoint buffer.

During chaining, the receiver SHALL consider an incomplete endpoint buffer as a protocol error.

ZLP

The sender SHALL NOT terminate a transmission by a ZLP.

Anyway, the receiver SHALL accept (and ignore) ZLPs.

Half-duplex communication

All messages go as command/response pairs:

  • the host sends a command over Bulk_Out,
  • the device processes the command and sends its response over BulkIn.

The host SHALL NOT send a new command before it has received a response to the previous one, or a timeout has occurred (timeouts are defined in next section).

The device SHALL NOT send a response without having received a valid command.

Timeout

The timeout for Bulk_Out command to Bulk_In response is fixed to 1000ms.

If the device is not able to terminate the execution of the command within 1000ms, it SHALL anyway send a response using the PROTOCOL Class and the TIME_EXTENSION_REQUEST Status.

The host SHALL then send a TIME_EXTENSION_ACK Instruction or a CANCEL Instruction.

The device SHALL NOT send another response before having received either Instruction.

Rules for the Interrupt_In endpoint

Handling of LEN

The endpoint uses a 4-byte header.

The device SHALL NOT send more than 64kB of payload to the host over the Interrupt_In endpoint.

Chaining

If the header + payload don't fit in a single 64-byte buffer, a chaining happens.

The device SHALL fill-up the endpoint buffer.

During chaining, the host SHALL consider an incomplete endpoint buffer as a protocol error.

ZLP

The device SHALL NOT terminate a transmission by a ZLP.

Anyway, the host SHALL accept (and ignore) ZLPs.