@tbsoft-gmbh/signature-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -0
- package/dist/assets-embedded.d.ts +12 -0
- package/dist/assets-embedded.js +37 -0
- package/dist/assets-embedded.js.map +1 -0
- package/dist/driver-hid.d.ts +45 -0
- package/dist/driver-hid.js +3777 -0
- package/dist/driver-hid.js.map +1 -0
- package/dist/font-8x13.d.ts +3 -0
- package/dist/font-8x13.js +145 -0
- package/dist/font-8x13.js.map +1 -0
- package/dist/hid-crypto.d.ts +58 -0
- package/dist/hid-crypto.js +138 -0
- package/dist/hid-crypto.js.map +1 -0
- package/dist/hid-display.d.ts +78 -0
- package/dist/hid-display.js +531 -0
- package/dist/hid-display.js.map +1 -0
- package/dist/hid-protocol.d.ts +227 -0
- package/dist/hid-protocol.js +2540 -0
- package/dist/hid-protocol.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +3900 -0
- package/dist/index.js.map +1 -0
- package/dist/png-decode.d.ts +14 -0
- package/dist/png-decode.js +141 -0
- package/dist/png-decode.js.map +1 -0
- package/dist/signature-renderer.d.ts +34 -0
- package/dist/signature-renderer.js +176 -0
- package/dist/signature-renderer.js.map +1 -0
- package/dist/types.d.ts +226 -0
- package/dist/types.js +46 -0
- package/dist/types.js.map +1 -0
- package/package.json +41 -0
- package/udev/99-signotec.rules +10 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { DriverConfig } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Low-level HID protocol for Signotec signing pads.
|
|
5
|
+
*
|
|
6
|
+
* Handles command framing, register reads/writes, response parsing, and retry logic.
|
|
7
|
+
* Protocol reverse-engineered from STPadLib.dll (Windows) and libSTPadLib.so (Linux).
|
|
8
|
+
*
|
|
9
|
+
* Transport: 63-byte HID output reports, no report ID prefix.
|
|
10
|
+
* - Register read: [0x01, register] → response [0x20, register, length, data...]
|
|
11
|
+
* - Register write: [0x10, register, length, data...] → response [0x20, register, ...]
|
|
12
|
+
* - Commands: raw bytes → response first nibble 0x9X for success, 0xE0 for error
|
|
13
|
+
*
|
|
14
|
+
* @module hid-protocol
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** HID command bytes. */
|
|
18
|
+
declare const CMD: {
|
|
19
|
+
readonly READ_REG: 1;
|
|
20
|
+
readonly WRITE_REG: 16;
|
|
21
|
+
readonly START_SIGN: 130;
|
|
22
|
+
readonly STOP_SIGN: 131;
|
|
23
|
+
readonly DRAW_IMAGE: 132;
|
|
24
|
+
readonly IMAGE_DONE: 133;
|
|
25
|
+
readonly ERASE_DISPLAY: 134;
|
|
26
|
+
readonly STORE_IMAGE: 137;
|
|
27
|
+
readonly SHOW_STORED: 138;
|
|
28
|
+
readonly DATA_CHUNK: 96;
|
|
29
|
+
readonly STORE_CHUNK: 112;
|
|
30
|
+
readonly SLIDESHOW_CONFIG: 164;
|
|
31
|
+
readonly EXTENDED: 168;
|
|
32
|
+
readonly ADVANCED_BUTTON: 173;
|
|
33
|
+
};
|
|
34
|
+
/** HID response byte types. */
|
|
35
|
+
declare const RESP: {
|
|
36
|
+
readonly READ: 32;
|
|
37
|
+
readonly ACK: 144;
|
|
38
|
+
readonly START_ACK: 146;
|
|
39
|
+
readonly STOP_ACK: 147;
|
|
40
|
+
readonly IMAGE_ACK: 148;
|
|
41
|
+
readonly ERROR: 224;
|
|
42
|
+
readonly IDLE: 80;
|
|
43
|
+
};
|
|
44
|
+
/** Device register addresses. */
|
|
45
|
+
declare const REG: {
|
|
46
|
+
readonly DEVICE_ID: 0;
|
|
47
|
+
readonly FW_VERSION1: 1;
|
|
48
|
+
readonly FW_VERSION2: 2;
|
|
49
|
+
readonly STATE: 16;
|
|
50
|
+
readonly CAPABILITIES: 17;
|
|
51
|
+
readonly SERIAL: 20;
|
|
52
|
+
readonly DISPLAY_WIDTH: 21;
|
|
53
|
+
readonly DISPLAY_HEIGHT: 22;
|
|
54
|
+
readonly SIGN_LEFT: 50;
|
|
55
|
+
readonly SIGN_TOP: 51;
|
|
56
|
+
readonly SIGN_RIGHT: 52;
|
|
57
|
+
readonly SIGN_BOTTOM: 53;
|
|
58
|
+
};
|
|
59
|
+
/** Signature event types received from the device. */
|
|
60
|
+
declare const SIG_EVENT: {
|
|
61
|
+
readonly PEN_UP: 64;
|
|
62
|
+
readonly PEN_DATA: 65;
|
|
63
|
+
readonly PEN_DATA_EXT: 66;
|
|
64
|
+
readonly HOTSPOT: 67;
|
|
65
|
+
};
|
|
66
|
+
type HIDDeviceHandle = {
|
|
67
|
+
on(event: string, callback: (...args: any[]) => void): void;
|
|
68
|
+
write(data: number[]): void;
|
|
69
|
+
close(): void;
|
|
70
|
+
removeAllListeners?(event?: string): void;
|
|
71
|
+
};
|
|
72
|
+
/** Device information read from pad registers. */
|
|
73
|
+
type PadInfo = {
|
|
74
|
+
serialNo: string;
|
|
75
|
+
displayWidth: number;
|
|
76
|
+
displayHeight: number;
|
|
77
|
+
sensorWidth: number;
|
|
78
|
+
sensorHeight: number;
|
|
79
|
+
deviceId: number;
|
|
80
|
+
fwMajor: number;
|
|
81
|
+
fwMinor: number;
|
|
82
|
+
capabilities: number;
|
|
83
|
+
};
|
|
84
|
+
/** Callback for signature/hotspot events from the device. */
|
|
85
|
+
type SignatureEventCallback = (type: number, data: Buffer) => void;
|
|
86
|
+
/**
|
|
87
|
+
* Low-level HID communication with a Signotec signing pad.
|
|
88
|
+
*
|
|
89
|
+
* Provides command framing, response parsing, retry logic, and all
|
|
90
|
+
* protocol operations (display, signature, flash storage, hotspots).
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const protocol = new HidProtocol({ commandTimeout: 5000 });
|
|
95
|
+
* const devices = protocol.listDevices();
|
|
96
|
+
* protocol.open(devices[0].path);
|
|
97
|
+
* await protocol.eraseDisplay();
|
|
98
|
+
* protocol.close();
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
declare class HidProtocol {
|
|
102
|
+
private device;
|
|
103
|
+
private pending;
|
|
104
|
+
private signatureCallback;
|
|
105
|
+
private disconnectCallback;
|
|
106
|
+
private connected;
|
|
107
|
+
private closing;
|
|
108
|
+
private HID;
|
|
109
|
+
private log;
|
|
110
|
+
private config;
|
|
111
|
+
/** Cached USB device descriptors from last listDevices() call (for USB fallback). */
|
|
112
|
+
private usbDeviceMap;
|
|
113
|
+
constructor(config?: DriverConfig);
|
|
114
|
+
/**
|
|
115
|
+
* Discover all connected Signotec pads.
|
|
116
|
+
* Tries node-hid first; falls back to raw USB enumeration (libusb) if no
|
|
117
|
+
* HID devices are found (e.g., Windows without HID class driver).
|
|
118
|
+
* @returns Array of device descriptors (never throws).
|
|
119
|
+
*/
|
|
120
|
+
listDevices(): Array<{
|
|
121
|
+
path: string;
|
|
122
|
+
serialNumber: string;
|
|
123
|
+
product: string;
|
|
124
|
+
}>;
|
|
125
|
+
/** Log diagnostic info when no devices are found. */
|
|
126
|
+
private logDiscoveryDiagnostics;
|
|
127
|
+
/**
|
|
128
|
+
* Open a device by its path (HID path or USB path).
|
|
129
|
+
* USB paths start with "usb:" and use the raw USB transport fallback.
|
|
130
|
+
* @throws Error if the device cannot be opened.
|
|
131
|
+
*/
|
|
132
|
+
open(devicePath: string): void;
|
|
133
|
+
/** Close the device connection and release resources. */
|
|
134
|
+
close(): void;
|
|
135
|
+
/** Check if the device connection is alive. */
|
|
136
|
+
isConnected(): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Verify the device is actually responsive (sends a register read and checks response).
|
|
139
|
+
* Useful after reconnection or before starting a session.
|
|
140
|
+
*/
|
|
141
|
+
isResponsive(): Promise<boolean>;
|
|
142
|
+
/** Register a callback for device disconnect events. */
|
|
143
|
+
onDisconnect(cb: (() => void) | null): void;
|
|
144
|
+
/** Register a callback for signature/hotspot events from the device. */
|
|
145
|
+
onSignatureEvent(cb: SignatureEventCallback | null): void;
|
|
146
|
+
private send;
|
|
147
|
+
/**
|
|
148
|
+
* Send a command and wait for the response.
|
|
149
|
+
* @returns Response buffer, or null on timeout/error.
|
|
150
|
+
*/
|
|
151
|
+
sendCommand(bytes: number[], timeout?: number): Promise<Buffer | null>;
|
|
152
|
+
/**
|
|
153
|
+
* Send a command with automatic retry on failure.
|
|
154
|
+
* @param bytes Command bytes to send
|
|
155
|
+
* @param validateFn Function to check if response is valid (defaults to non-null + non-error)
|
|
156
|
+
* @param timeout Timeout per attempt
|
|
157
|
+
* @param maxRetries Max retry count (from config if not specified)
|
|
158
|
+
*/
|
|
159
|
+
sendCommandWithRetry(bytes: number[], validateFn?: (resp: Buffer) => boolean, timeout?: number, maxRetries?: number): Promise<Buffer | null>;
|
|
160
|
+
/** Send raw bytes without waiting for a response (fire-and-forget). */
|
|
161
|
+
sendRaw(bytes: number[]): void;
|
|
162
|
+
/**
|
|
163
|
+
* Send a bulk data chunk for image transfers.
|
|
164
|
+
* @param cmdByte Command byte (0x60 for display, 0x70 for flash store)
|
|
165
|
+
* @param data Source buffer
|
|
166
|
+
* @param offset Starting offset in data
|
|
167
|
+
* @param maxPayload Max bytes per chunk (default 62)
|
|
168
|
+
*/
|
|
169
|
+
private sendChunk;
|
|
170
|
+
private handleData;
|
|
171
|
+
/** Read a device register. Returns the data portion or null on error/timeout. */
|
|
172
|
+
readRegister(reg: number): Promise<Buffer | null>;
|
|
173
|
+
/** Write a 4-byte little-endian value to a register. */
|
|
174
|
+
writeRegister(reg: number, value: number): Promise<boolean>;
|
|
175
|
+
/** Read full device info from registers. */
|
|
176
|
+
getDeviceInfo(): Promise<PadInfo>;
|
|
177
|
+
/** Erase the pad display (clear to white). */
|
|
178
|
+
eraseDisplay(): Promise<boolean>;
|
|
179
|
+
/**
|
|
180
|
+
* Send monochrome 1bpp bitmap data to the pad display.
|
|
181
|
+
* Protocol: 0x84 header → 0x60 data chunks → 0x85 done.
|
|
182
|
+
* Automatically inverts polarity (pad uses 1=black, framebuffer uses 0=black).
|
|
183
|
+
*/
|
|
184
|
+
drawImage(x: number, y: number, width: number, height: number, bitmapData: Buffer): Promise<boolean>;
|
|
185
|
+
/**
|
|
186
|
+
* Store a 1bpp bitmap to the pad's non-volatile flash as standby image.
|
|
187
|
+
* Persists across power cycles and USB disconnects.
|
|
188
|
+
*
|
|
189
|
+
* Protocol: 0x89 header → 0x70 data chunks → 0xA4 standby config.
|
|
190
|
+
* Flash uses direct polarity (opposite of display), auto-detected.
|
|
191
|
+
*/
|
|
192
|
+
storeStandbyImage(width: number, height: number, bitmapData: Buffer): Promise<boolean>;
|
|
193
|
+
/**
|
|
194
|
+
* Show the stored standby image from flash on the display.
|
|
195
|
+
* Command 0x8A = "draw stored image" (from APIClosePad → APIDrawStoredImage).
|
|
196
|
+
*
|
|
197
|
+
* Single HID command - no image data transfer. Works regardless of who
|
|
198
|
+
* stored the image (our library, Signotec SlideShow tool, etc.)
|
|
199
|
+
*/
|
|
200
|
+
showStandbyFromFlash(): Promise<boolean>;
|
|
201
|
+
/**
|
|
202
|
+
* Send a slideshow/standby configuration command (0xA4).
|
|
203
|
+
* Automatically wraps in 0xA8 for Sigma pads (which don't support direct 0xA4).
|
|
204
|
+
*/
|
|
205
|
+
private sendSlideshowConfig;
|
|
206
|
+
/** Set the signature capture rectangle (left, top, width, height → registers 0x32-0x35). */
|
|
207
|
+
setSignRect(left: number, top: number, width: number, height: number): Promise<boolean>;
|
|
208
|
+
/** Clear all hotspot areas. */
|
|
209
|
+
clearHotSpots(): Promise<boolean>;
|
|
210
|
+
/**
|
|
211
|
+
* Add a hotspot (touch-sensitive button area).
|
|
212
|
+
* @param index Hotspot index (0-based)
|
|
213
|
+
* @param left X position
|
|
214
|
+
* @param top Y position
|
|
215
|
+
* @param width Width in pixels
|
|
216
|
+
* @param height Height in pixels
|
|
217
|
+
*/
|
|
218
|
+
addHotSpot(index: number, left: number, top: number, width: number, height: number): Promise<boolean>;
|
|
219
|
+
/** Enable hotspot monitoring (call after addHotSpot). */
|
|
220
|
+
enableHotspotMonitoring(): Promise<boolean>;
|
|
221
|
+
/** Start signature capture. Protocol: [0x82, 0x00, 0x00, 0x00, 0x00]. */
|
|
222
|
+
startSignature(): Promise<boolean>;
|
|
223
|
+
/** Stop signature capture. */
|
|
224
|
+
stopSignature(): Promise<boolean>;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export { CMD, type HIDDeviceHandle, HidProtocol, type PadInfo, REG, RESP, SIG_EVENT, type SignatureEventCallback };
|