@samlab-corp/sfm-node 0.1.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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +479 -0
  3. package/dist/commands/data.d.ts +29 -0
  4. package/dist/commands/data.d.ts.map +1 -0
  5. package/dist/commands/data.js +176 -0
  6. package/dist/commands/data.js.map +1 -0
  7. package/dist/commands/fingerprint.d.ts +132 -0
  8. package/dist/commands/fingerprint.d.ts.map +1 -0
  9. package/dist/commands/fingerprint.js +580 -0
  10. package/dist/commands/fingerprint.js.map +1 -0
  11. package/dist/commands/firmware.d.ts +37 -0
  12. package/dist/commands/firmware.d.ts.map +1 -0
  13. package/dist/commands/firmware.js +152 -0
  14. package/dist/commands/firmware.js.map +1 -0
  15. package/dist/commands/freescan.d.ts +68 -0
  16. package/dist/commands/freescan.d.ts.map +1 -0
  17. package/dist/commands/freescan.js +202 -0
  18. package/dist/commands/freescan.js.map +1 -0
  19. package/dist/commands/index.d.ts +88 -0
  20. package/dist/commands/index.d.ts.map +1 -0
  21. package/dist/commands/index.js +104 -0
  22. package/dist/commands/index.js.map +1 -0
  23. package/dist/commands/system.d.ts +82 -0
  24. package/dist/commands/system.d.ts.map +1 -0
  25. package/dist/commands/system.js +191 -0
  26. package/dist/commands/system.js.map +1 -0
  27. package/dist/constants/crypto.d.ts +11 -0
  28. package/dist/constants/crypto.d.ts.map +1 -0
  29. package/dist/constants/crypto.js +10 -0
  30. package/dist/constants/crypto.js.map +1 -0
  31. package/dist/constants/index.d.ts +6 -0
  32. package/dist/constants/index.d.ts.map +1 -0
  33. package/dist/constants/index.js +4 -0
  34. package/dist/constants/index.js.map +1 -0
  35. package/dist/constants/packet.d.ts +17 -0
  36. package/dist/constants/packet.d.ts.map +1 -0
  37. package/dist/constants/packet.js +17 -0
  38. package/dist/constants/packet.js.map +1 -0
  39. package/dist/constants/protocol.d.ts +653 -0
  40. package/dist/constants/protocol.d.ts.map +1 -0
  41. package/dist/constants/protocol.js +422 -0
  42. package/dist/constants/protocol.js.map +1 -0
  43. package/dist/core/client.d.ts +118 -0
  44. package/dist/core/client.d.ts.map +1 -0
  45. package/dist/core/client.js +320 -0
  46. package/dist/core/client.js.map +1 -0
  47. package/dist/core/crypto.d.ts +86 -0
  48. package/dist/core/crypto.d.ts.map +1 -0
  49. package/dist/core/crypto.js +248 -0
  50. package/dist/core/crypto.js.map +1 -0
  51. package/dist/core/errors.d.ts +25 -0
  52. package/dist/core/errors.d.ts.map +1 -0
  53. package/dist/core/errors.js +66 -0
  54. package/dist/core/errors.js.map +1 -0
  55. package/dist/core/index.d.ts +15 -0
  56. package/dist/core/index.d.ts.map +1 -0
  57. package/dist/core/index.js +10 -0
  58. package/dist/core/index.js.map +1 -0
  59. package/dist/core/packet.d.ts +126 -0
  60. package/dist/core/packet.d.ts.map +1 -0
  61. package/dist/core/packet.js +267 -0
  62. package/dist/core/packet.js.map +1 -0
  63. package/dist/core/serial.d.ts +123 -0
  64. package/dist/core/serial.d.ts.map +1 -0
  65. package/dist/core/serial.js +421 -0
  66. package/dist/core/serial.js.map +1 -0
  67. package/dist/core/tcp.d.ts +58 -0
  68. package/dist/core/tcp.d.ts.map +1 -0
  69. package/dist/core/tcp.js +219 -0
  70. package/dist/core/tcp.js.map +1 -0
  71. package/dist/index.d.ts +19 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +16 -0
  74. package/dist/index.js.map +1 -0
  75. package/package.json +49 -0
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Multi-packet data transfer/receive commands
3
+ */
4
+ import { SFM_ERROR, ENCRYPTION_MODE } from "../constants";
5
+ /**
6
+ * Even/Odd byte checksum calculation
7
+ */
8
+ export function calcEvenOddChecksum(data) {
9
+ let evenSum = 0;
10
+ let oddSum = 0;
11
+ let remainder = 0;
12
+ const pairCount = data.length >= 2 ? ((data.length - 2) >>> 1) + 1 : 0;
13
+ const pairBytes = pairCount * 2;
14
+ for (let i = 0; i < pairBytes; i += 2) {
15
+ evenSum += data[i];
16
+ oddSum += data[i + 1];
17
+ }
18
+ if (pairBytes < data.length) {
19
+ remainder = data[pairBytes];
20
+ }
21
+ return (evenSum + oddSum + remainder) | 0;
22
+ }
23
+ export class DataCommands {
24
+ constructor(client) {
25
+ this.client = client;
26
+ }
27
+ /**
28
+ * Multi-packet data send
29
+ */
30
+ async send(command, data, chunkSize = 0x4000, options = {}) {
31
+ const result = await this._sendMultiPacket(command, data, chunkSize, options);
32
+ if (result.error) {
33
+ throw new Error(result.error);
34
+ }
35
+ }
36
+ /**
37
+ * Multi-packet data receive
38
+ */
39
+ async recv(command, totalSize, options = {}) {
40
+ const result = await this._recvMultiPacket(command, totalSize, options);
41
+ if (result.error) {
42
+ throw new Error(result.error);
43
+ }
44
+ return result.data ?? Buffer.alloc(0);
45
+ }
46
+ async _sendMultiPacket(command, data, chunkSize = 0x4000, options = {}) {
47
+ if (!data || data.length === 0) {
48
+ return { error: null };
49
+ }
50
+ const dataSize = data.length;
51
+ if (chunkSize > dataSize) {
52
+ chunkSize = dataSize;
53
+ }
54
+ let sendData = data;
55
+ if (this.client.secureMode && this.client.crypto) {
56
+ if (this.client.crypto.mode === ENCRYPTION_MODE.AES256_CBC) {
57
+ this.client.crypto.resetIV();
58
+ }
59
+ sendData = this.client.crypto.encryptRaw(data);
60
+ }
61
+ const totalSize = sendData.length;
62
+ const totalPackets = Math.ceil(totalSize / chunkSize);
63
+ for (let packetIndex = 0; packetIndex < totalPackets; packetIndex++) {
64
+ const offset = packetIndex * chunkSize;
65
+ const remaining = totalSize - offset;
66
+ const currentChunkSize = Math.min(chunkSize, remaining);
67
+ const param = (packetIndex << 16) | totalPackets;
68
+ const cmdResponse = await this.client.sendCommand(command, param, currentChunkSize, 0);
69
+ if (!cmdResponse.valid) {
70
+ return {
71
+ error: `Command send failed (packet ${packetIndex}): ${cmdResponse.error}`,
72
+ };
73
+ }
74
+ const chunk = sendData.subarray(offset, offset + currentChunkSize);
75
+ const writeResult = await this._writeWithTimeout(this.client.serial, chunk);
76
+ if (writeResult < 0) {
77
+ return { error: `Data write failed (packet ${packetIndex})` };
78
+ }
79
+ if (writeResult < currentChunkSize) {
80
+ return {
81
+ error: `Incomplete data write (packet ${packetIndex}): ${writeResult}/${currentChunkSize}`,
82
+ };
83
+ }
84
+ const checksumBuf = Buffer.alloc(4);
85
+ checksumBuf.writeUInt32LE(calcEvenOddChecksum(chunk) >>> 0, 0);
86
+ await this._writeWithTimeout(this.client.serial, checksumBuf);
87
+ const ackResponse = await this.client.receiveResponse();
88
+ if (!ackResponse.valid) {
89
+ return {
90
+ error: `Response receive failed (packet ${packetIndex}): ${ackResponse.error}`,
91
+ };
92
+ }
93
+ if (ackResponse.flag !== SFM_ERROR.SUCCESS) {
94
+ return {
95
+ error: `Transfer failed (packet ${packetIndex}): flag=0x${ackResponse.flag?.toString(16) ?? "??"}`,
96
+ };
97
+ }
98
+ options.onProgress?.(packetIndex, totalPackets);
99
+ }
100
+ return { error: null };
101
+ }
102
+ async _recvMultiPacket(command, totalDataSize, options = {}) {
103
+ if (totalDataSize === 0) {
104
+ return { data: Buffer.alloc(0), error: null };
105
+ }
106
+ const resultBuf = Buffer.alloc(totalDataSize);
107
+ let receivedTotal = 0;
108
+ while (receivedTotal < totalDataSize) {
109
+ const cmdResponse = await this.client.receiveResponse();
110
+ if (!cmdResponse.valid) {
111
+ return {
112
+ data: null,
113
+ error: `Command receive failed: ${cmdResponse.error}`,
114
+ };
115
+ }
116
+ const chunkSize = cmdResponse.size ?? 0;
117
+ const packetInfo = cmdResponse.param ?? 0;
118
+ const packetIndex = packetInfo >> 16;
119
+ const totalPackets = packetInfo & 0xffff;
120
+ const readTimeout = this.client._getReadTimeout(chunkSize + 4);
121
+ const chunkData = await this._readWithTimeout(this.client.serial, chunkSize + 4, readTimeout);
122
+ if (!chunkData || chunkData.length < chunkSize + 4) {
123
+ await this._sendResponseFlag(command, SFM_ERROR.SCAN_FAIL);
124
+ return {
125
+ data: null,
126
+ error: `Incomplete data receive (packet ${packetIndex})`,
127
+ };
128
+ }
129
+ const dataChunk = chunkData.subarray(0, chunkSize);
130
+ const receivedChecksum = chunkData.readUInt32LE(chunkSize);
131
+ const calculatedChecksum = calcEvenOddChecksum(dataChunk);
132
+ if (calculatedChecksum !== receivedChecksum) {
133
+ await this._sendResponseFlag(command, SFM_ERROR.SCAN_FAIL);
134
+ return {
135
+ data: null,
136
+ error: `Checksum mismatch (packet ${packetIndex})`,
137
+ };
138
+ }
139
+ dataChunk.copy(resultBuf, receivedTotal, 0, chunkSize);
140
+ receivedTotal += chunkSize;
141
+ await this._sendResponseFlag(command, SFM_ERROR.SUCCESS);
142
+ options.onProgress?.(packetIndex, totalPackets);
143
+ if (packetIndex + 1 >= totalPackets)
144
+ break;
145
+ }
146
+ if (this.client.secureMode && this.client.crypto) {
147
+ if (this.client.crypto.mode === ENCRYPTION_MODE.AES256_CBC) {
148
+ this.client.crypto.resetIV();
149
+ }
150
+ const decrypted = this.client.crypto.decryptRaw(resultBuf, totalDataSize);
151
+ return { data: decrypted, error: null };
152
+ }
153
+ return { data: resultBuf, error: null };
154
+ }
155
+ async _sendResponseFlag(command, flag) {
156
+ await this.client.sendCommand(command, 0, 0, flag);
157
+ }
158
+ async _writeWithTimeout(serial, data) {
159
+ try {
160
+ await serial.write(data);
161
+ return data.length;
162
+ }
163
+ catch {
164
+ return -1;
165
+ }
166
+ }
167
+ async _readWithTimeout(serial, length, timeoutMs = 5000) {
168
+ try {
169
+ return await serial.read(length, timeoutMs);
170
+ }
171
+ catch {
172
+ return null;
173
+ }
174
+ }
175
+ }
176
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/commands/data.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAqB1D;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAyB;IAC3D,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC;IAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,OAAO,YAAY;IACvB,YAAoB,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAEzC;;OAEG;IACH,KAAK,CAAC,IAAI,CACR,OAAe,EACf,IAAY,EACZ,SAAS,GAAG,MAAM,EAClB,UAA8B,EAAE;QAEhC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACxC,OAAO,EACP,IAAI,EACJ,SAAS,EACT,OAAO,CACR,CAAC;QACF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CACR,OAAe,EACf,SAAiB,EACjB,UAA8B,EAAE;QAEhC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACxE,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,OAAe,EACf,IAAY,EACZ,SAAS,GAAG,MAAM,EAClB,UAA8B,EAAE;QAEhC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7B,IAAI,SAAS,GAAG,QAAQ,EAAE,CAAC;YACzB,SAAS,GAAG,QAAQ,CAAC;QACvB,CAAC;QAED,IAAI,QAAQ,GAAW,IAAI,CAAC;QAE5B,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,eAAe,CAAC,UAAU,EAAE,CAAC;gBAC3D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC;QAClC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;QAEtD,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,WAAW,GAAG,YAAY,EAAE,WAAW,EAAE,EAAE,CAAC;YACpE,MAAM,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;YACvC,MAAM,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;YACrC,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAExD,MAAM,KAAK,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,GAAG,YAAY,CAAC;YACjD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAC/C,OAAO,EACP,KAAK,EACL,gBAAgB,EAChB,CAAC,CACF,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;gBACvB,OAAO;oBACL,KAAK,EAAE,+BAA+B,WAAW,MAAM,WAAW,CAAC,KAAK,EAAE;iBAC3E,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC;YACnE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,EAClB,KAAK,CACN,CAAC;YACF,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACpB,OAAO,EAAE,KAAK,EAAE,6BAA6B,WAAW,GAAG,EAAE,CAAC;YAChE,CAAC;YACD,IAAI,WAAW,GAAG,gBAAgB,EAAE,CAAC;gBACnC,OAAO;oBACL,KAAK,EAAE,iCAAiC,WAAW,MAAM,WAAW,IAAI,gBAAgB,EAAE;iBAC3F,CAAC;YACJ,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACpC,WAAW,CAAC,aAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/D,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAE9D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YACxD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;gBACvB,OAAO;oBACL,KAAK,EAAE,mCAAmC,WAAW,MAAM,WAAW,CAAC,KAAK,EAAE;iBAC/E,CAAC;YACJ,CAAC;YACD,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;gBAC3C,OAAO;oBACL,KAAK,EAAE,2BAA2B,WAAW,aAAa,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE;iBACnG,CAAC;YACJ,CAAC;YAED,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAClD,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,OAAe,EACf,aAAqB,EACrB,UAA8B,EAAE;QAEhC,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAChD,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC9C,IAAI,aAAa,GAAG,CAAC,CAAC;QAEtB,OAAO,aAAa,GAAG,aAAa,EAAE,CAAC;YACrC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YACxD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;gBACvB,OAAO;oBACL,IAAI,EAAE,IAAI;oBACV,KAAK,EAAE,2BAA2B,WAAW,CAAC,KAAK,EAAE;iBACtD,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC;YACxC,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,IAAI,CAAC,CAAC;YAC1C,MAAM,WAAW,GAAG,UAAU,IAAI,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;YAEzC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,EAClB,SAAS,GAAG,CAAC,EACb,WAAW,CACZ,CAAC;YACF,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC3D,OAAO;oBACL,IAAI,EAAE,IAAI;oBACV,KAAK,EAAE,mCAAmC,WAAW,GAAG;iBACzD,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACnD,MAAM,gBAAgB,GAAG,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAE3D,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,kBAAkB,KAAK,gBAAgB,EAAE,CAAC;gBAC5C,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC3D,OAAO;oBACL,IAAI,EAAE,IAAI;oBACV,KAAK,EAAE,6BAA6B,WAAW,GAAG;iBACnD,CAAC;YACJ,CAAC;YAED,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;YACvD,aAAa,IAAI,SAAS,CAAC;YAE3B,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;YACzD,OAAO,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAEhD,IAAI,WAAW,GAAG,CAAC,IAAI,YAAY;gBAAE,MAAM;QAC7C,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,eAAe,CAAC,UAAU,EAAE,CAAC;gBAC3D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YAC1E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC1C,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,OAAe,EACf,IAAY;QAEZ,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,MAAkB,EAClB,IAAyB;QAEzB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,MAAkB,EAClB,MAAc,EACd,SAAS,GAAG,IAAI;QAEhB,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Fingerprint enroll/verify/identify/capture commands
3
+ */
4
+ import { SFM_FLAG } from "../constants";
5
+ import type { SfmClient } from "../core";
6
+ import type { SystemCommands, CommandResult } from "./system";
7
+ interface LogOptions {
8
+ onLog?: (msg: string) => void;
9
+ }
10
+ export interface EnrollResult {
11
+ success: boolean;
12
+ step: number;
13
+ userId?: number;
14
+ error?: string;
15
+ }
16
+ export interface VerifyResult {
17
+ success: boolean;
18
+ userId?: number;
19
+ error: string | null;
20
+ }
21
+ export interface IdentifyResult {
22
+ success: boolean;
23
+ userId: number;
24
+ error: string | null;
25
+ }
26
+ export type { CommandResult } from "./system";
27
+ export interface ListUserIdsResult {
28
+ success: boolean;
29
+ userIds: number[];
30
+ count: number;
31
+ error: string | null;
32
+ }
33
+ export interface CaptureImageResult {
34
+ success: boolean;
35
+ imageData: Buffer | null;
36
+ width: number;
37
+ height: number;
38
+ error: string | null;
39
+ }
40
+ export declare class FingerprintCommands {
41
+ private client;
42
+ private system;
43
+ constructor(client: SfmClient);
44
+ /** @internal Set SystemCommands reference */
45
+ _setSystemCommands(system: SystemCommands): void;
46
+ /**
47
+ * Enroll scan 1 - send ES command + read 0x62 (scan success) + 0x61 (template 1 saved)
48
+ */
49
+ enrollScan1(userId: number, flag?: 0, { onLog }?: LogOptions): Promise<EnrollResult>;
50
+ /**
51
+ * Enroll scan 2 - read 0x62 (scan success) + 0x61 (template 2 saved)
52
+ */
53
+ enrollScan2({ onLog }?: LogOptions): Promise<EnrollResult>;
54
+ /**
55
+ * Enroll (automatically adapts to current ENROLL_MODE setting)
56
+ *
57
+ * - SCAN1 (0x30): 1 scan only
58
+ * - SCAN2_MERGE (0x31) / SCAN2_DUAL (0x41): scan 1 + scan 2
59
+ */
60
+ enroll(userId: number, flag?: 0, { onLog }?: LogOptions): Promise<EnrollResult>;
61
+ /**
62
+ * 1:1 검증 (VS: 0x08)
63
+ */
64
+ verify(userId: number, { onLog }?: LogOptions): Promise<VerifyResult>;
65
+ /**
66
+ * 1:N 식별 (IS: 0x11)
67
+ */
68
+ identify({ onLog }?: LogOptions): Promise<IdentifyResult>;
69
+ /**
70
+ * Delete specific template (DT: 0x16)
71
+ */
72
+ deleteTemplate(userId: number): Promise<CommandResult>;
73
+ /**
74
+ * Delete all templates (DA: 0x17)
75
+ */
76
+ deleteAllTemplates(): Promise<CommandResult>;
77
+ /**
78
+ * List enrolled user IDs (LT: 0x18)
79
+ */
80
+ listUserIds({ onLog }?: LogOptions): Promise<ListUserIdsResult>;
81
+ /**
82
+ * Read template from device (RTX: 0x89, ping-pong protocol)
83
+ *
84
+ * RTX response Size field: (templateCount << 16) | templateSize
85
+ * e.g. 131456 = 0x00020180 → count=2, size=384
86
+ *
87
+ * Flow: send RTX → read 384B data → send ACK (RTX) → read 384B data → ...
88
+ * Device flag: 0x74 (CONTINUE) = more chunks, 0x61 (SUCCESS) = last chunk.
89
+ */
90
+ readTemplate(userId: number, { onLog }?: LogOptions): Promise<{
91
+ success: boolean;
92
+ templateData: Buffer | null;
93
+ error: string | null;
94
+ }>;
95
+ /**
96
+ * Write template to device (ET: 0x07 — Simple Template Enrollment)
97
+ *
98
+ * Kiosk 호환 프로토콜 (rs232/fingerPrinter.js enrollByTemplate):
99
+ * 1. [Command Packet 13B] + [Template Data] + [END 0x0A] 를 한 번에 전송
100
+ * 2. 디바이스로부터 2개 응답 수신 (스캔 처리 + 최종 결과)
101
+ *
102
+ * Size field = templateData.length (원본 크기 그대로)
103
+ * 384B 단위 chunk를 각각 별도의 ET 호출로 전송
104
+ */
105
+ writeTemplate(userId: number, templateData: Buffer, flag?: (typeof SFM_FLAG)[keyof typeof SFM_FLAG], { onLog }?: LogOptions): Promise<{
106
+ success: boolean;
107
+ userId?: number;
108
+ error: string | null;
109
+ }>;
110
+ /**
111
+ * Write template to device (ETX: 0x87 — Extended Template Enrollment)
112
+ *
113
+ * Extended Data Transfer Protocol (Appendix B):
114
+ * Supports multi-chunk: 768B → 2 chunks of 384B sent in one ETX session.
115
+ *
116
+ * 1. sendCommand(ETX, userId, sizeField, flag) → SUCCESS(0x61)
117
+ * sizeField: (templateCount << 24) | (enrollCount << 16) | chunkSize
118
+ * 2. For each chunk:
119
+ * Data Packet Header(13B) + Data Body(384B) + Data Checksum(4B)
120
+ * → DATA_OK(0x83) 응답 수신
121
+ */
122
+ writeTemplateMulti(userId: number, templateData: Buffer, flag?: (typeof SFM_FLAG)[keyof typeof SFM_FLAG], { onLog }?: LogOptions): Promise<{
123
+ success: boolean;
124
+ userId?: number;
125
+ error: string | null;
126
+ }>;
127
+ /**
128
+ * Capture fingerprint image (SI: 0x15)
129
+ */
130
+ captureImage({ onLog }?: LogOptions): Promise<CaptureImageResult>;
131
+ }
132
+ //# sourceMappingURL=fingerprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/commands/fingerprint.ts"],"names":[],"mappings":"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"}