zklib-ts 1.0.1-development → 1.0.2-development

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/dist/index.es.js CHANGED
@@ -2,103 +2,109 @@ import { Socket } from 'net';
2
2
  import { appendFile } from 'fs';
3
3
  import * as dgram from 'node:dgram';
4
4
 
5
- const COMMANDS = {
6
- CMD_CONNECT: 1000,
7
- CMD_EXIT: 1001,
8
- CMD_ENABLEDEVICE: 1002,
9
- CMD_DISABLEDEVICE: 1003,
10
- CMD_RESTART: 1004,
11
- CMD_POWEROFF: 1005,
12
- CMD_SLEEP: 1006,
13
- CMD_RESUME: 1007,
14
- CMD_CAPTUREFINGER: 1009,
15
- CMD_TEST_TEMP: 1011,
16
- CMD_CAPTUREIMAGE: 1012,
17
- CMD_REFRESHDATA: 1013,
18
- CMD_REFRESHOPTION: 1014,
19
- CMD_TESTVOICE: 1017,
20
- CMD_GET_VERSION: 1100,
21
- CMD_CHANGE_SPEED: 1101,
22
- CMD_AUTH: 1102,
23
- CMD_PREPARE_DATA: 1500,
24
- CMD_DATA: 1501,
25
- CMD_FREE_DATA: 1502,
26
- CMD_DATA_WRRQ: 1503,
27
- CMD_DATA_RDY: 1504,
28
- CMD_DB_RRQ: 7,
29
- CMD_USER_WRQ: 8,
30
- CMD_USERTEMP_RRQ: 9,
31
- CMD_USERTEMP_WRQ: 10,
32
- CMD_OPTIONS_RRQ: 11,
33
- CMD_OPTIONS_WRQ: 12,
34
- CMD_ATTLOG_RRQ: 13,
35
- CMD_CLEAR_DATA: 14,
36
- CMD_CLEAR_ATTLOG: 15,
37
- CMD_DELETE_USER: 18,
38
- CMD_DELETE_USERTEMP: 19,
39
- CMD_CLEAR_ADMIN: 20,
40
- CMD_USERGRP_RRQ: 21,
41
- CMD_USERGRP_WRQ: 22,
42
- CMD_USERTZ_RRQ: 23,
43
- CMD_USERTZ_WRQ: 24,
44
- CMD_GRPTZ_RRQ: 25,
45
- CMD_GRPTZ_WRQ: 26,
46
- CMD_TZ_RRQ: 27,
47
- CMD_TZ_WRQ: 28,
48
- CMD_ULG_RRQ: 29,
49
- CMD_ULG_WRQ: 30,
50
- CMD_UNLOCK: 31,
51
- CMD_CLEAR_ACC: 32,
52
- CMD_CLEAR_OPLOG: 33,
53
- CMD_OPLOG_RRQ: 34,
54
- CMD_GET_FREE_SIZES: 50,
55
- CMD_ENABLE_CLOCK: 57,
56
- CMD_STARTVERIFY: 60,
57
- CMD_STARTENROLL: 61,
58
- CMD_CANCELCAPTURE: 62,
59
- CMD_STATE_RRQ: 64,
60
- CMD_WRITE_LCD: 66,
61
- CMD_CLEAR_LCD: 67,
62
- CMD_GET_PINWIDTH: 69,
63
- CMD_SMS_WRQ: 70,
64
- CMD_SMS_RRQ: 71,
65
- CMD_DELETE_SMS: 72,
66
- CMD_UDATA_WRQ: 73,
67
- CMD_DELETE_UDATA: 74,
68
- CMD_DOORSTATE_RRQ: 75,
69
- CMD_WRITE_MIFARE: 76,
70
- CMD_EMPTY_MIFARE: 78,
71
- CMD_VERIFY_WRQ: 79,
72
- CMD_VERIFY_RRQ: 80,
73
- CMD_TMP_WRITE: 87,
74
- CMD_GET_USERTEMP: 88,
75
- CMD_CHECKSUM_BUFFER: 119,
76
- CMD_DEL_FPTMP: 134,
77
- CMD_GET_TIME: 201,
78
- CMD_SET_TIME: 202,
79
- CMD_REG_EVENT: 500,
80
- CMD_ACK_OK: 2000,
81
- CMD_ACK_ERROR: 2001,
82
- CMD_ACK_DATA: 2002,
83
- CMD_ACK_RETRY: 2003,
84
- CMD_ACK_REPEAT: 2004,
85
- CMD_ACK_UNAUTH: 2005,
86
- CMD_ACK_UNKNOWN: 65535,
87
- CMD_ACK_ERROR_CMD: 65533,
88
- CMD_ACK_ERROR_INIT: 65532,
89
- CMD_ACK_ERROR_DATA: 65531,
90
- EF_ATTLOG: 1,
91
- EF_FINGER: 2,
92
- EF_ENROLLUSER: 4,
93
- EF_ENROLLFINGER: 8,
94
- EF_BUTTON: 16,
95
- EF_UNLOCK: 32,
96
- EF_VERIFY: 128,
97
- EF_FPFTR: 256,
98
- EF_ALARM: 512
99
- };
100
- const USHRT_MAX = 65535;
101
- const MAX_CHUNK = 65472;
5
+ var COMMANDS;
6
+ (function (COMMANDS) {
7
+ COMMANDS[COMMANDS["CMD_ACK_DATA"] = 2002] = "CMD_ACK_DATA";
8
+ COMMANDS[COMMANDS["CMD_ACK_ERROR"] = 2001] = "CMD_ACK_ERROR";
9
+ COMMANDS[COMMANDS["CMD_ACK_ERROR_CMD"] = 65533] = "CMD_ACK_ERROR_CMD";
10
+ COMMANDS[COMMANDS["CMD_ACK_ERROR_DATA"] = 65531] = "CMD_ACK_ERROR_DATA";
11
+ COMMANDS[COMMANDS["CMD_ACK_ERROR_INIT"] = 65532] = "CMD_ACK_ERROR_INIT";
12
+ COMMANDS[COMMANDS["CMD_ACK_OK"] = 2000] = "CMD_ACK_OK";
13
+ COMMANDS[COMMANDS["CMD_ACK_REPEAT"] = 2004] = "CMD_ACK_REPEAT";
14
+ COMMANDS[COMMANDS["CMD_ACK_RETRY"] = 2003] = "CMD_ACK_RETRY";
15
+ COMMANDS[COMMANDS["CMD_ACK_UNAUTH"] = 2005] = "CMD_ACK_UNAUTH";
16
+ COMMANDS[COMMANDS["CMD_ACK_UNKNOWN"] = 65535] = "CMD_ACK_UNKNOWN";
17
+ COMMANDS[COMMANDS["CMD_ATTLOG_RRQ"] = 13] = "CMD_ATTLOG_RRQ";
18
+ COMMANDS[COMMANDS["CMD_AUTH"] = 1102] = "CMD_AUTH";
19
+ COMMANDS[COMMANDS["CMD_CANCELCAPTURE"] = 62] = "CMD_CANCELCAPTURE";
20
+ COMMANDS[COMMANDS["CMD_CAPTUREFINGER"] = 1009] = "CMD_CAPTUREFINGER";
21
+ COMMANDS[COMMANDS["CMD_CAPTUREIMAGE"] = 1012] = "CMD_CAPTUREIMAGE";
22
+ COMMANDS[COMMANDS["CMD_CHANGE_SPEED"] = 1101] = "CMD_CHANGE_SPEED";
23
+ COMMANDS[COMMANDS["CMD_CHECKSUM_BUFFER"] = 119] = "CMD_CHECKSUM_BUFFER";
24
+ COMMANDS[COMMANDS["CMD_CLEAR_ACC"] = 32] = "CMD_CLEAR_ACC";
25
+ COMMANDS[COMMANDS["CMD_CLEAR_ADMIN"] = 20] = "CMD_CLEAR_ADMIN";
26
+ COMMANDS[COMMANDS["CMD_CLEAR_ATTLOG"] = 15] = "CMD_CLEAR_ATTLOG";
27
+ COMMANDS[COMMANDS["CMD_CLEAR_DATA"] = 14] = "CMD_CLEAR_DATA";
28
+ COMMANDS[COMMANDS["CMD_CLEAR_LCD"] = 67] = "CMD_CLEAR_LCD";
29
+ COMMANDS[COMMANDS["CMD_CLEAR_OPLOG"] = 33] = "CMD_CLEAR_OPLOG";
30
+ COMMANDS[COMMANDS["CMD_CONNECT"] = 1000] = "CMD_CONNECT";
31
+ COMMANDS[COMMANDS["CMD_DATA"] = 1501] = "CMD_DATA";
32
+ COMMANDS[COMMANDS["CMD_DATA_RDY"] = 1504] = "CMD_DATA_RDY";
33
+ COMMANDS[COMMANDS["CMD_DATA_WRRQ"] = 1503] = "CMD_DATA_WRRQ";
34
+ COMMANDS[COMMANDS["CMD_DB_RRQ"] = 7] = "CMD_DB_RRQ";
35
+ COMMANDS[COMMANDS["CMD_DEL_FPTMP"] = 134] = "CMD_DEL_FPTMP";
36
+ COMMANDS[COMMANDS["CMD_DELETE_SMS"] = 72] = "CMD_DELETE_SMS";
37
+ COMMANDS[COMMANDS["CMD_DELETE_UDATA"] = 74] = "CMD_DELETE_UDATA";
38
+ COMMANDS[COMMANDS["CMD_DELETE_USER"] = 18] = "CMD_DELETE_USER";
39
+ COMMANDS[COMMANDS["CMD_DELETE_USERTEMP"] = 19] = "CMD_DELETE_USERTEMP";
40
+ COMMANDS[COMMANDS["CMD_DISABLEDEVICE"] = 1003] = "CMD_DISABLEDEVICE";
41
+ COMMANDS[COMMANDS["CMD_DOORSTATE_RRQ"] = 75] = "CMD_DOORSTATE_RRQ";
42
+ COMMANDS[COMMANDS["CMD_EMPTY_MIFARE"] = 78] = "CMD_EMPTY_MIFARE";
43
+ COMMANDS[COMMANDS["CMD_ENABLE_CLOCK"] = 57] = "CMD_ENABLE_CLOCK";
44
+ COMMANDS[COMMANDS["CMD_ENABLEDEVICE"] = 1002] = "CMD_ENABLEDEVICE";
45
+ COMMANDS[COMMANDS["CMD_EXIT"] = 1001] = "CMD_EXIT";
46
+ COMMANDS[COMMANDS["CMD_FREE_DATA"] = 1502] = "CMD_FREE_DATA";
47
+ COMMANDS[COMMANDS["CMD_GET_FREE_SIZES"] = 50] = "CMD_GET_FREE_SIZES";
48
+ COMMANDS[COMMANDS["CMD_GET_PINWIDTH"] = 69] = "CMD_GET_PINWIDTH";
49
+ COMMANDS[COMMANDS["CMD_GET_TIME"] = 201] = "CMD_GET_TIME";
50
+ COMMANDS[COMMANDS["CMD_GET_USERTEMP"] = 88] = "CMD_GET_USERTEMP";
51
+ COMMANDS[COMMANDS["CMD_GET_VERSION"] = 1100] = "CMD_GET_VERSION";
52
+ COMMANDS[COMMANDS["CMD_GRPTZ_RRQ"] = 25] = "CMD_GRPTZ_RRQ";
53
+ COMMANDS[COMMANDS["CMD_GRPTZ_WRQ"] = 26] = "CMD_GRPTZ_WRQ";
54
+ COMMANDS[COMMANDS["CMD_OPLOG_RRQ"] = 34] = "CMD_OPLOG_RRQ";
55
+ COMMANDS[COMMANDS["CMD_OPTIONS_RRQ"] = 11] = "CMD_OPTIONS_RRQ";
56
+ COMMANDS[COMMANDS["CMD_OPTIONS_WRQ"] = 12] = "CMD_OPTIONS_WRQ";
57
+ COMMANDS[COMMANDS["CMD_POWEROFF"] = 1005] = "CMD_POWEROFF";
58
+ COMMANDS[COMMANDS["CMD_PREPARE_DATA"] = 1500] = "CMD_PREPARE_DATA";
59
+ COMMANDS[COMMANDS["CMD_REFRESHDATA"] = 1013] = "CMD_REFRESHDATA";
60
+ COMMANDS[COMMANDS["CMD_REFRESHOPTION"] = 1014] = "CMD_REFRESHOPTION";
61
+ COMMANDS[COMMANDS["CMD_REG_EVENT"] = 500] = "CMD_REG_EVENT";
62
+ COMMANDS[COMMANDS["CMD_RESTART"] = 1004] = "CMD_RESTART";
63
+ COMMANDS[COMMANDS["CMD_RESUME"] = 1007] = "CMD_RESUME";
64
+ COMMANDS[COMMANDS["CMD_SET_TIME"] = 202] = "CMD_SET_TIME";
65
+ COMMANDS[COMMANDS["CMD_SLEEP"] = 1006] = "CMD_SLEEP";
66
+ COMMANDS[COMMANDS["CMD_SMS_RRQ"] = 71] = "CMD_SMS_RRQ";
67
+ COMMANDS[COMMANDS["CMD_SMS_WRQ"] = 70] = "CMD_SMS_WRQ";
68
+ COMMANDS[COMMANDS["CMD_STARTENROLL"] = 61] = "CMD_STARTENROLL";
69
+ COMMANDS[COMMANDS["CMD_STARTVERIFY"] = 60] = "CMD_STARTVERIFY";
70
+ COMMANDS[COMMANDS["CMD_STATE_RRQ"] = 64] = "CMD_STATE_RRQ";
71
+ COMMANDS[COMMANDS["CMD_TEST_TEMP"] = 1011] = "CMD_TEST_TEMP";
72
+ COMMANDS[COMMANDS["CMD_TESTVOICE"] = 1017] = "CMD_TESTVOICE";
73
+ COMMANDS[COMMANDS["CMD_TMP_WRITE"] = 87] = "CMD_TMP_WRITE";
74
+ COMMANDS[COMMANDS["CMD_TZ_RRQ"] = 27] = "CMD_TZ_RRQ";
75
+ COMMANDS[COMMANDS["CMD_TZ_WRQ"] = 28] = "CMD_TZ_WRQ";
76
+ COMMANDS[COMMANDS["CMD_UDATA_WRQ"] = 73] = "CMD_UDATA_WRQ";
77
+ COMMANDS[COMMANDS["CMD_ULG_RRQ"] = 29] = "CMD_ULG_RRQ";
78
+ COMMANDS[COMMANDS["CMD_ULG_WRQ"] = 30] = "CMD_ULG_WRQ";
79
+ COMMANDS[COMMANDS["CMD_UNLOCK"] = 31] = "CMD_UNLOCK";
80
+ COMMANDS[COMMANDS["CMD_USER_WRQ"] = 8] = "CMD_USER_WRQ";
81
+ COMMANDS[COMMANDS["CMD_USERGRP_RRQ"] = 21] = "CMD_USERGRP_RRQ";
82
+ COMMANDS[COMMANDS["CMD_USERGRP_WRQ"] = 22] = "CMD_USERGRP_WRQ";
83
+ COMMANDS[COMMANDS["CMD_USERTEMP_RRQ"] = 9] = "CMD_USERTEMP_RRQ";
84
+ COMMANDS[COMMANDS["CMD_USERTEMP_WRQ"] = 10] = "CMD_USERTEMP_WRQ";
85
+ COMMANDS[COMMANDS["CMD_USERTZ_RRQ"] = 23] = "CMD_USERTZ_RRQ";
86
+ COMMANDS[COMMANDS["CMD_USERTZ_WRQ"] = 24] = "CMD_USERTZ_WRQ";
87
+ COMMANDS[COMMANDS["CMD_VERIFY_RRQ"] = 80] = "CMD_VERIFY_RRQ";
88
+ COMMANDS[COMMANDS["CMD_VERIFY_WRQ"] = 79] = "CMD_VERIFY_WRQ";
89
+ COMMANDS[COMMANDS["CMD_WRITE_LCD"] = 66] = "CMD_WRITE_LCD";
90
+ COMMANDS[COMMANDS["CMD_WRITE_MIFARE"] = 76] = "CMD_WRITE_MIFARE";
91
+ COMMANDS[COMMANDS["EF_ALARM"] = 512] = "EF_ALARM";
92
+ COMMANDS[COMMANDS["EF_ATTLOG"] = 1] = "EF_ATTLOG";
93
+ COMMANDS[COMMANDS["EF_BUTTON"] = 16] = "EF_BUTTON";
94
+ COMMANDS[COMMANDS["EF_ENROLLFINGER"] = 8] = "EF_ENROLLFINGER";
95
+ COMMANDS[COMMANDS["EF_ENROLLUSER"] = 4] = "EF_ENROLLUSER";
96
+ COMMANDS[COMMANDS["EF_FINGER"] = 2] = "EF_FINGER";
97
+ COMMANDS[COMMANDS["EF_FPFTR"] = 256] = "EF_FPFTR";
98
+ COMMANDS[COMMANDS["EF_UNLOCK"] = 32] = "EF_UNLOCK";
99
+ COMMANDS[COMMANDS["EF_VERIFY"] = 128] = "EF_VERIFY";
100
+ })(COMMANDS || (COMMANDS = {}));
101
+ var Constants;
102
+ (function (Constants) {
103
+ Constants[Constants["USHRT_MAX"] = 65535] = "USHRT_MAX";
104
+ Constants[Constants["MAX_CHUNK"] = 65472] = "MAX_CHUNK";
105
+ Constants[Constants["MACHINE_PREPARE_DATA_1"] = 20560] = "MACHINE_PREPARE_DATA_1";
106
+ Constants[Constants["MACHINE_PREPARE_DATA_2"] = 32130] = "MACHINE_PREPARE_DATA_2";
107
+ })(Constants || (Constants = {}));
102
108
  const REQUEST_DATA = {
103
109
  DISABLE_DEVICE: Buffer.from([0, 0, 0, 0]),
104
110
  GET_REAL_TIME_EVENT: Buffer.from([0x01, 0x00, 0x00, 0x00]),
@@ -282,9 +288,9 @@ const createChkSum = (buf) => {
282
288
  else {
283
289
  chksum += buf.readUInt16LE(i);
284
290
  }
285
- chksum %= USHRT_MAX;
291
+ chksum %= Constants.USHRT_MAX;
286
292
  }
287
- chksum = USHRT_MAX - chksum - 1;
293
+ chksum = Constants.USHRT_MAX - chksum - 1;
288
294
  return chksum;
289
295
  };
290
296
  const createUDPHeader = (command, sessionId, replyId, data) => {
@@ -297,7 +303,7 @@ const createUDPHeader = (command, sessionId, replyId, data) => {
297
303
  dataBuffer.copy(buf, 8);
298
304
  const chksum2 = createChkSum(buf);
299
305
  buf.writeUInt16LE(chksum2, 2);
300
- replyId = (replyId + 1) % USHRT_MAX;
306
+ replyId = (replyId + 1) % Constants.USHRT_MAX;
301
307
  buf.writeUInt16LE(replyId, 6);
302
308
  return buf;
303
309
  };
@@ -311,7 +317,7 @@ const createTCPHeader = (command, sessionId, replyId, data) => {
311
317
  dataBuffer.copy(buf, 8);
312
318
  const chksum2 = createChkSum(buf);
313
319
  buf.writeUInt16LE(chksum2, 2);
314
- replyId = (replyId + 1) % USHRT_MAX;
320
+ replyId = (replyId + 1) % Constants.USHRT_MAX;
315
321
  buf.writeUInt16LE(replyId, 6);
316
322
  const prefixBuf = Buffer.from([0x50, 0x50, 0x82, 0x7d, 0x13, 0x00, 0x00, 0x00]);
317
323
  prefixBuf.writeUInt16LE(buf.length, 4);
@@ -512,8 +518,8 @@ class Finger {
512
518
  this.template = template;
513
519
  this.size = template.length;
514
520
  // Create mark showing first and last 8 bytes as hex
515
- const start = template.slice(0, 8).toString('hex');
516
- const end = template.slice(-8).toString('hex');
521
+ const start = Uint8Array.prototype.slice.call(template, 0, 8).toString('hex');
522
+ const end = Uint8Array.prototype.slice.call(template, -8).toString('hex');
517
523
  this.mark = `${start}...${end}`;
518
524
  }
519
525
  /**
@@ -644,10 +650,12 @@ class ZTCP {
644
650
  face_cap = 0;
645
651
  userPacketSize = 72;
646
652
  verbose = false;
653
+ packetNumber = 0;
654
+ replyData = Buffer.from([]);
647
655
  constructor(ip, port, timeout, comm_key, verbose) {
648
656
  this.ip = ip;
649
657
  this.port = port;
650
- this.timeout = timeout;
658
+ this.timeout = timeout ? timeout : 10000;
651
659
  this.replyId = 0;
652
660
  this.comm_key = comm_key;
653
661
  this.verbose = verbose;
@@ -868,9 +876,6 @@ class ZTCP {
868
876
  else {
869
877
  this.replyId++;
870
878
  }
871
- if (this.verbose) {
872
- console.log("linea 305: replyId: ", this.replyId, " command: ", command, Object.keys(COMMANDS).find(u => COMMANDS[u] == command));
873
- }
874
879
  const buf = createTCPHeader(command, this.sessionId, this.replyId, data);
875
880
  try {
876
881
  // Write the message to the socket and wait for a response
@@ -916,8 +921,8 @@ class ZTCP {
916
921
  }
917
922
  /**
918
923
  *
919
- * @param {*} reqData - indicate the type of data that need to receive ( user or attLog)
920
- * @param {*} cb - callback is triggered when receiving packets
924
+ * @param {Buffer} reqData - indicate the type of data that need to receive ( user or attLog)
925
+ * @param {Function} cb - callback is triggered when receiving packets
921
926
  *
922
927
  * readWithBuffer will reject error if it'wrong when starting request data
923
928
  * readWithBuffer will return { data: replyData , err: Error } when receiving requested data
@@ -932,7 +937,6 @@ class ZTCP {
932
937
  }
933
938
  catch (err) {
934
939
  reject(err);
935
- console.log(reply);
936
940
  }
937
941
  const header = decodeTCPHeader(reply.subarray(0, 16));
938
942
  switch (header.commandId) {
@@ -948,56 +952,73 @@ class ZTCP {
948
952
  const size = recvData.readUIntLE(1, 4);
949
953
  // We need to split the data to many chunks to receive , because it's to large
950
954
  // After receiving all chunk data , we concat it to TotalBuffer variable , that 's the data we want
951
- let remain = size % MAX_CHUNK;
952
- let numberChunks = Math.round(size - remain) / MAX_CHUNK;
953
- let totalPackets = numberChunks + (remain > 0 ? 1 : 0);
954
- let replyData = Buffer.from([]);
955
+ let remain = size % Constants.MAX_CHUNK;
956
+ let numberChunks = Math.round(size - remain) / Constants.MAX_CHUNK;
957
+ this.packetNumber = numberChunks + (remain > 0 ? 1 : 0);
958
+ //let replyData = Buffer.from([])
955
959
  let totalBuffer = Buffer.from([]);
956
960
  let realTotalBuffer = Buffer.from([]);
957
- const timeout = 10000;
958
961
  let timer = setTimeout(() => {
959
- internalCallback(replyData, new Error('TIMEOUT WHEN RECEIVING PACKET'));
960
- }, timeout);
962
+ internalCallback(this.replyData, new Error('TIMEOUT WHEN RECEIVING PACKET'));
963
+ }, this.timeout);
961
964
  const internalCallback = (replyData, err = null) => {
962
- // this.socket && this.socket.removeListener('data', handleOnData)
965
+ this.socket && this.socket.removeAllListeners('data');
963
966
  timer && clearTimeout(timer);
964
967
  resolve({ data: replyData, err });
965
968
  };
966
- const handleOnData = (reply) => {
967
- if (checkNotEventTCP(reply))
968
- return;
969
- clearTimeout(timer);
970
- timer = setTimeout(() => {
971
- internalCallback(replyData, new Error(`TIME OUT !! ${totalPackets} PACKETS REMAIN !`));
972
- }, timeout);
973
- totalBuffer = Buffer.concat([totalBuffer, reply]);
974
- const packetLength = totalBuffer.readUIntLE(4, 2);
975
- if (totalBuffer.length >= 8 + packetLength) {
976
- realTotalBuffer = Buffer.concat([realTotalBuffer, totalBuffer.subarray(16, 8 + packetLength)]);
977
- totalBuffer = totalBuffer.subarray(8 + packetLength);
978
- if ((totalPackets > 1 && realTotalBuffer.length === MAX_CHUNK + 8)
979
- || (totalPackets === 1 && realTotalBuffer.length === remain + 8)) {
980
- replyData = Buffer.concat([replyData, realTotalBuffer.subarray(8)]);
981
- totalBuffer = Buffer.from([]);
982
- realTotalBuffer = Buffer.from([]);
983
- totalPackets -= 1;
984
- cb && cb(replyData.length, size);
985
- if (totalPackets <= 0) {
986
- internalCallback(replyData);
987
- }
988
- }
989
- }
990
- };
991
969
  this.socket.once('close', () => {
992
- internalCallback(replyData, new Error('Socket is disconnected unexpectedly'));
970
+ internalCallback(this.replyData, new Error('Socket is disconnected unexpectedly'));
993
971
  });
994
- this.socket.on('data', handleOnData);
995
972
  for (let i = 0; i <= numberChunks; i++) {
996
- if (i === numberChunks) {
997
- await this.sendChunkRequest(numberChunks * MAX_CHUNK, remain);
998
- }
999
- else {
1000
- await this.sendChunkRequest(i * MAX_CHUNK, MAX_CHUNK);
973
+ const data = await new Promise((resolve2, reject2) => {
974
+ try {
975
+ this.sendChunkRequest(i * Constants.MAX_CHUNK, (i === numberChunks)
976
+ ? remain
977
+ : Constants.MAX_CHUNK);
978
+ this.socket.on('data', (reply) => {
979
+ clearTimeout(timer);
980
+ timer = setTimeout(() => {
981
+ internalCallback(this.replyData, new Error(`TIME OUT !! ${this.packetNumber} PACKETS REMAIN !`));
982
+ }, this.timeout);
983
+ const headers = decodeTCPHeader(reply);
984
+ if (COMMANDS[headers.commandId]) {
985
+ switch (headers.commandId) {
986
+ case COMMANDS.CMD_ACK_OK:
987
+ case COMMANDS.CMD_DATA:
988
+ this.verbose && console.log("CMD received: ", COMMANDS[headers.commandId]);
989
+ break;
990
+ case COMMANDS.CMD_PREPARE_DATA:
991
+ this.verbose && console.log("CMD received: ", COMMANDS[headers.commandId]);
992
+ this.verbose && console.log(`recieve chunk: prepare data size is ${headers.payloadSize}`);
993
+ break;
994
+ default:
995
+ break;
996
+ }
997
+ }
998
+ totalBuffer = Buffer.concat([totalBuffer, reply]);
999
+ const packetLength = totalBuffer.readUIntLE(4, 2);
1000
+ if (totalBuffer.length >= 8 + packetLength) {
1001
+ realTotalBuffer = Buffer.concat([realTotalBuffer, totalBuffer.subarray(16, 8 + packetLength)]);
1002
+ totalBuffer = totalBuffer.subarray(8 + packetLength);
1003
+ if ((this.packetNumber > 1 && realTotalBuffer.length === (Constants.MAX_CHUNK + 8))
1004
+ || (this.packetNumber === 1 && realTotalBuffer.length === remain + 8)) {
1005
+ this.packetNumber--;
1006
+ cb && cb(realTotalBuffer.length, size);
1007
+ resolve2(realTotalBuffer.subarray(8));
1008
+ totalBuffer = Buffer.from([]);
1009
+ realTotalBuffer = Buffer.from([]);
1010
+ }
1011
+ }
1012
+ });
1013
+ }
1014
+ catch (e) {
1015
+ reject2(e);
1016
+ }
1017
+ });
1018
+ this.replyData = Buffer.concat([this.replyData, data]);
1019
+ this.socket.removeAllListeners('data');
1020
+ if (this.packetNumber <= 0) {
1021
+ resolve({ data: this.replyData });
1001
1022
  }
1002
1023
  }
1003
1024
  break;
@@ -1629,32 +1650,58 @@ class ZTCP {
1629
1650
  throw err;
1630
1651
  }
1631
1652
  }
1632
- async getTemplates() {
1653
+ /**
1654
+ * Get all Finger objects
1655
+ * @returns {Record<string, Finger[]>}
1656
+ */
1657
+ async getTemplates(callbackInProcess = () => { }) {
1658
+ let templates = [];
1633
1659
  try {
1660
+ await this.getSizes();
1661
+ if (this.fp_count == 0)
1662
+ return { data: [] };
1634
1663
  await this.freeData();
1635
1664
  await this.disableDevice();
1636
1665
  const Buffer = await this.readWithBuffer(REQUEST_DATA.GET_TEMPLATES);
1637
- let templateData = Buffer.data.slice(4);
1666
+ let templateData = Buffer.data.subarray(4);
1638
1667
  let totalSize = Buffer.data.readUIntLE(0, 4);
1639
- let templates = [];
1640
1668
  while (totalSize) {
1641
- const buf = templateData.slice(0, 6);
1669
+ const buf = templateData.subarray(0, 6);
1642
1670
  const size = buf.readUIntLE(0, 2);
1643
- templates.push(new Finger(buf.readUIntLE(2, 2), buf.readUIntLE(4, 1), buf.readUIntLE(5, 1), templateData.slice(6, size)));
1644
- templateData = templateData.slice(size);
1671
+ templates.push(new Finger(buf.readUIntLE(2, 2), buf.readUIntLE(4, 1), buf.readUIntLE(5, 1), templateData.subarray(6, size)));
1672
+ templateData = templateData.subarray(size);
1645
1673
  totalSize -= size;
1646
1674
  }
1647
- return templates;
1675
+ return { data: templates };
1648
1676
  }
1649
1677
  catch (err) {
1650
- console.error('Error getting user templates: ', err);
1651
- throw err;
1678
+ this.verbose && console.log("Error getting templates", err);
1679
+ return { data: templates };
1652
1680
  }
1653
1681
  finally {
1654
1682
  await this.enableDevice();
1655
1683
  await this.freeData();
1656
1684
  }
1657
1685
  }
1686
+ /**
1687
+ * Return size
1688
+ * @param packet
1689
+ */
1690
+ testTcpTop(packet) {
1691
+ // Check if packet is too small
1692
+ if (packet.length <= 8)
1693
+ return 0;
1694
+ // Extract header values using little-endian format
1695
+ const headerValue1 = packet.readUInt16LE(0);
1696
+ const headerValue2 = packet.readUInt16LE(2);
1697
+ const size = packet.readUInt32LE(4);
1698
+ // Check if magic numbers match
1699
+ if (headerValue1 === Constants.MACHINE_PREPARE_DATA_1 &&
1700
+ headerValue2 === Constants.MACHINE_PREPARE_DATA_2) {
1701
+ return size;
1702
+ }
1703
+ return 0;
1704
+ }
1658
1705
  async refreshData() {
1659
1706
  try {
1660
1707
  const reply = await this.executeCmd(COMMANDS.CMD_REFRESHDATA, '');
@@ -1952,7 +1999,7 @@ class ZTCP {
1952
1999
  }
1953
2000
  async ackOk() {
1954
2001
  try {
1955
- const buf = createTCPHeader(COMMANDS.CMD_ACK_OK, this.sessionId, USHRT_MAX - 1, Buffer.from([]));
2002
+ const buf = createTCPHeader(COMMANDS.CMD_ACK_OK, this.sessionId, Constants.USHRT_MAX - 1, Buffer.from([]));
1956
2003
  this.socket.write(buf);
1957
2004
  }
1958
2005
  catch (e) {
@@ -2263,10 +2310,10 @@ class ZUDP {
2263
2310
  }
2264
2311
  };
2265
2312
  this.socket.on('message', handleOnData);
2266
- const chunkCount = Math.ceil(size / MAX_CHUNK);
2313
+ const chunkCount = Math.ceil(size / Constants.MAX_CHUNK);
2267
2314
  for (let i = 0; i < chunkCount; i++) {
2268
- const start = i * MAX_CHUNK;
2269
- const chunkSize = (i === chunkCount - 1) ? size % MAX_CHUNK : MAX_CHUNK;
2315
+ const start = i * Constants.MAX_CHUNK;
2316
+ const chunkSize = (i === chunkCount - 1) ? size % Constants.MAX_CHUNK : Constants.MAX_CHUNK;
2270
2317
  this.sendChunkRequest(start, chunkSize).catch(err => {
2271
2318
  internalCallback(Buffer.from([]), err);
2272
2319
  });
package/dist/ztcp.d.ts CHANGED
@@ -32,6 +32,8 @@ export declare class ZTCP {
32
32
  private face_cap;
33
33
  private userPacketSize;
34
34
  private verbose;
35
+ private packetNumber;
36
+ private replyData;
35
37
  constructor(ip: string, port: number, timeout: number, comm_key: number, verbose: boolean);
36
38
  createSocket(cbError: any, cbClose: any): Promise<unknown>;
37
39
  connect(): Promise<boolean>;
@@ -47,16 +49,16 @@ export declare class ZTCP {
47
49
  * reject error when command fail and resolve data when success
48
50
  */
49
51
  executeCmd(command: number, data: Buffer | string | ArrayBuffer): Promise<Buffer>;
50
- sendChunkRequest(start: number, size: number): Promise<any>;
52
+ sendChunkRequest(start: number, size: number): Promise<void>;
51
53
  /**
52
54
  *
53
- * @param {*} reqData - indicate the type of data that need to receive ( user or attLog)
54
- * @param {*} cb - callback is triggered when receiving packets
55
+ * @param {Buffer} reqData - indicate the type of data that need to receive ( user or attLog)
56
+ * @param {Function} cb - callback is triggered when receiving packets
55
57
  *
56
58
  * readWithBuffer will reject error if it'wrong when starting request data
57
59
  * readWithBuffer will return { data: replyData , err: Error } when receiving requested data
58
60
  */
59
- readWithBuffer(reqData: Buffer | string, cb?: any): Promise<Record<string, Buffer | number>>;
61
+ readWithBuffer(reqData: Buffer | string, cb?: Function): Promise<Record<string, Buffer | number>>;
60
62
  /**
61
63
  * reject error when starting request data
62
64
  * @return {Record<string, User[] | Error>} when receiving requested data
@@ -121,7 +123,16 @@ export declare class ZTCP {
121
123
  clearAttendanceLog(): Promise<Buffer<ArrayBufferLike>>;
122
124
  clearData(): Promise<Buffer<ArrayBufferLike>>;
123
125
  getRealTimeLogs(cb?: (realTimeLog: RealTimeLog) => void): Promise<void>;
124
- getTemplates(): Promise<Finger[]>;
126
+ /**
127
+ * Get all Finger objects
128
+ * @returns {Record<string, Finger[]>}
129
+ */
130
+ getTemplates(callbackInProcess?: any): Promise<Record<string, Finger[]>>;
131
+ /**
132
+ * Return size
133
+ * @param packet
134
+ */
135
+ testTcpTop(packet: any): any;
125
136
  refreshData(): Promise<boolean>;
126
137
  sendWithBuffer(buffer: Buffer): Promise<unknown>;
127
138
  sendChunk(commandString: Buffer): Promise<unknown>;
@@ -141,7 +152,7 @@ export declare class ZTCP {
141
152
  * @returns {Promise<void>}
142
153
  * @throws {ZKErrorResponse} If registration fails
143
154
  */
144
- regEvent(flags: any): Promise<void>;
155
+ regEvent(flags: number): Promise<void>;
145
156
  ackOk(): Promise<void>;
146
157
  cancelCapture(): Promise<boolean>;
147
158
  verifyUser(uid: number): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zklib-ts",
3
- "version": "1.0.1-development",
3
+ "version": "1.0.2-development",
4
4
  "description": "Unofficial zkteco library allows Node.js developers to easily interface with ZK BioMetric Fingerprint Attendance Devices",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -1,12 +0,0 @@
1
- /**
2
- * Represents an Attendance Records
3
- */
4
- export declare class Attendance {
5
- private sn;
6
- private user_id;
7
- private record_time;
8
- private type?;
9
- private state?;
10
- private ip?;
11
- constructor(sn: number, user_id: string, record_time: Date, type?: number, state?: number);
12
- }
@@ -1,35 +0,0 @@
1
- /**
2
- * Represents a fingerprint template with associated metadata
3
- */
4
- export declare class Finger {
5
- uid: number;
6
- fid: number;
7
- valid: number;
8
- template: Buffer;
9
- size: number;
10
- readonly mark: string;
11
- /**
12
- * Creates a new Finger instance
13
- * @param uid User internal reference
14
- * @param fid Finger ID (value >= 0 && value <= 9)
15
- * @param valid Flag indicating 0 = invalid | 1 = valid | 3 = duress
16
- * @param template Fingerprint template data buffer
17
- */
18
- constructor(uid: number, fid: number, valid: number, template: Buffer);
19
- /**
20
- * Packs the fingerprint data with metadata into a Buffer
21
- * @returns Buffer containing packed fingerprint data
22
- */
23
- repack(): Buffer;
24
- /**
25
- * Packs only the fingerprint template data into a Buffer
26
- * @returns Buffer containing just the template data
27
- */
28
- repackOnly(): Buffer;
29
- /**
30
- * Compares this fingerprint with another for equality
31
- * @param other Another Finger instance to compare with
32
- * @returns true if all properties and template data match
33
- */
34
- equals(other: Finger): boolean;
35
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * Represents a User as is from ZkDevice and contain methods
3
- * */
4
- export declare class User {
5
- uid: number;
6
- name: string;
7
- privilege: number;
8
- password: string;
9
- group_id: string | number;
10
- user_id: string;
11
- card: number;
12
- /**
13
- * Creates a new User instance
14
- * @param uid User ID
15
- * @param name User name
16
- * @param privilege Privilege level
17
- * @param password User password (default: "")
18
- * @param group_id Group ID (default: "")
19
- * @param user_id Alternate user ID (default: "")
20
- * @param card Card number (default: 0)
21
- */
22
- constructor(uid: number, name: string, privilege: number, password?: string, group_id?: string | number, user_id?: string, card?: number);
23
- private ensureEncoding;
24
- repack29(): Buffer;
25
- repack73(): Buffer;
26
- }