zklib-ts 1.0.0-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]),
@@ -252,7 +258,7 @@ class Attendance {
252
258
  record_time;
253
259
  type;
254
260
  state;
255
- _ip;
261
+ ip;
256
262
  constructor(sn, user_id, record_time, type, state) {
257
263
  this.sn = sn;
258
264
  this.user_id = user_id;
@@ -260,9 +266,6 @@ class Attendance {
260
266
  this.type = type;
261
267
  this.state = state;
262
268
  }
263
- set ip(value) {
264
- this._ip = value;
265
- }
266
269
  }
267
270
 
268
271
  const parseHexToTime = (hex) => {
@@ -285,9 +288,9 @@ const createChkSum = (buf) => {
285
288
  else {
286
289
  chksum += buf.readUInt16LE(i);
287
290
  }
288
- chksum %= USHRT_MAX;
291
+ chksum %= Constants.USHRT_MAX;
289
292
  }
290
- chksum = USHRT_MAX - chksum - 1;
293
+ chksum = Constants.USHRT_MAX - chksum - 1;
291
294
  return chksum;
292
295
  };
293
296
  const createUDPHeader = (command, sessionId, replyId, data) => {
@@ -300,7 +303,7 @@ const createUDPHeader = (command, sessionId, replyId, data) => {
300
303
  dataBuffer.copy(buf, 8);
301
304
  const chksum2 = createChkSum(buf);
302
305
  buf.writeUInt16LE(chksum2, 2);
303
- replyId = (replyId + 1) % USHRT_MAX;
306
+ replyId = (replyId + 1) % Constants.USHRT_MAX;
304
307
  buf.writeUInt16LE(replyId, 6);
305
308
  return buf;
306
309
  };
@@ -314,7 +317,7 @@ const createTCPHeader = (command, sessionId, replyId, data) => {
314
317
  dataBuffer.copy(buf, 8);
315
318
  const chksum2 = createChkSum(buf);
316
319
  buf.writeUInt16LE(chksum2, 2);
317
- replyId = (replyId + 1) % USHRT_MAX;
320
+ replyId = (replyId + 1) % Constants.USHRT_MAX;
318
321
  buf.writeUInt16LE(replyId, 6);
319
322
  const prefixBuf = Buffer.from([0x50, 0x50, 0x82, 0x7d, 0x13, 0x00, 0x00, 0x00]);
320
323
  prefixBuf.writeUInt16LE(buf.length, 4);
@@ -515,8 +518,8 @@ class Finger {
515
518
  this.template = template;
516
519
  this.size = template.length;
517
520
  // Create mark showing first and last 8 bytes as hex
518
- const start = template.slice(0, 8).toString('hex');
519
- 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');
520
523
  this.mark = `${start}...${end}`;
521
524
  }
522
525
  /**
@@ -647,10 +650,12 @@ class ZTCP {
647
650
  face_cap = 0;
648
651
  userPacketSize = 72;
649
652
  verbose = false;
653
+ packetNumber = 0;
654
+ replyData = Buffer.from([]);
650
655
  constructor(ip, port, timeout, comm_key, verbose) {
651
656
  this.ip = ip;
652
657
  this.port = port;
653
- this.timeout = timeout;
658
+ this.timeout = timeout ? timeout : 10000;
654
659
  this.replyId = 0;
655
660
  this.comm_key = comm_key;
656
661
  this.verbose = verbose;
@@ -871,9 +876,6 @@ class ZTCP {
871
876
  else {
872
877
  this.replyId++;
873
878
  }
874
- if (this.verbose) {
875
- console.log("linea 305: replyId: ", this.replyId, " command: ", command, Object.keys(COMMANDS).find(u => COMMANDS[u] == command));
876
- }
877
879
  const buf = createTCPHeader(command, this.sessionId, this.replyId, data);
878
880
  try {
879
881
  // Write the message to the socket and wait for a response
@@ -919,8 +921,8 @@ class ZTCP {
919
921
  }
920
922
  /**
921
923
  *
922
- * @param {*} reqData - indicate the type of data that need to receive ( user or attLog)
923
- * @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
924
926
  *
925
927
  * readWithBuffer will reject error if it'wrong when starting request data
926
928
  * readWithBuffer will return { data: replyData , err: Error } when receiving requested data
@@ -935,7 +937,6 @@ class ZTCP {
935
937
  }
936
938
  catch (err) {
937
939
  reject(err);
938
- console.log(reply);
939
940
  }
940
941
  const header = decodeTCPHeader(reply.subarray(0, 16));
941
942
  switch (header.commandId) {
@@ -951,56 +952,73 @@ class ZTCP {
951
952
  const size = recvData.readUIntLE(1, 4);
952
953
  // We need to split the data to many chunks to receive , because it's to large
953
954
  // After receiving all chunk data , we concat it to TotalBuffer variable , that 's the data we want
954
- let remain = size % MAX_CHUNK;
955
- let numberChunks = Math.round(size - remain) / MAX_CHUNK;
956
- let totalPackets = numberChunks + (remain > 0 ? 1 : 0);
957
- 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([])
958
959
  let totalBuffer = Buffer.from([]);
959
960
  let realTotalBuffer = Buffer.from([]);
960
- const timeout = 10000;
961
961
  let timer = setTimeout(() => {
962
- internalCallback(replyData, new Error('TIMEOUT WHEN RECEIVING PACKET'));
963
- }, timeout);
962
+ internalCallback(this.replyData, new Error('TIMEOUT WHEN RECEIVING PACKET'));
963
+ }, this.timeout);
964
964
  const internalCallback = (replyData, err = null) => {
965
- // this.socket && this.socket.removeListener('data', handleOnData)
965
+ this.socket && this.socket.removeAllListeners('data');
966
966
  timer && clearTimeout(timer);
967
967
  resolve({ data: replyData, err });
968
968
  };
969
- const handleOnData = (reply) => {
970
- if (checkNotEventTCP(reply))
971
- return;
972
- clearTimeout(timer);
973
- timer = setTimeout(() => {
974
- internalCallback(replyData, new Error(`TIME OUT !! ${totalPackets} PACKETS REMAIN !`));
975
- }, timeout);
976
- totalBuffer = Buffer.concat([totalBuffer, reply]);
977
- const packetLength = totalBuffer.readUIntLE(4, 2);
978
- if (totalBuffer.length >= 8 + packetLength) {
979
- realTotalBuffer = Buffer.concat([realTotalBuffer, totalBuffer.subarray(16, 8 + packetLength)]);
980
- totalBuffer = totalBuffer.subarray(8 + packetLength);
981
- if ((totalPackets > 1 && realTotalBuffer.length === MAX_CHUNK + 8)
982
- || (totalPackets === 1 && realTotalBuffer.length === remain + 8)) {
983
- replyData = Buffer.concat([replyData, realTotalBuffer.subarray(8)]);
984
- totalBuffer = Buffer.from([]);
985
- realTotalBuffer = Buffer.from([]);
986
- totalPackets -= 1;
987
- cb && cb(replyData.length, size);
988
- if (totalPackets <= 0) {
989
- internalCallback(replyData);
990
- }
991
- }
992
- }
993
- };
994
969
  this.socket.once('close', () => {
995
- internalCallback(replyData, new Error('Socket is disconnected unexpectedly'));
970
+ internalCallback(this.replyData, new Error('Socket is disconnected unexpectedly'));
996
971
  });
997
- this.socket.on('data', handleOnData);
998
972
  for (let i = 0; i <= numberChunks; i++) {
999
- if (i === numberChunks) {
1000
- await this.sendChunkRequest(numberChunks * MAX_CHUNK, remain);
1001
- }
1002
- else {
1003
- 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 });
1004
1022
  }
1005
1023
  }
1006
1024
  break;
@@ -1632,32 +1650,58 @@ class ZTCP {
1632
1650
  throw err;
1633
1651
  }
1634
1652
  }
1635
- async getTemplates() {
1653
+ /**
1654
+ * Get all Finger objects
1655
+ * @returns {Record<string, Finger[]>}
1656
+ */
1657
+ async getTemplates(callbackInProcess = () => { }) {
1658
+ let templates = [];
1636
1659
  try {
1660
+ await this.getSizes();
1661
+ if (this.fp_count == 0)
1662
+ return { data: [] };
1637
1663
  await this.freeData();
1638
1664
  await this.disableDevice();
1639
1665
  const Buffer = await this.readWithBuffer(REQUEST_DATA.GET_TEMPLATES);
1640
- let templateData = Buffer.data.slice(4);
1666
+ let templateData = Buffer.data.subarray(4);
1641
1667
  let totalSize = Buffer.data.readUIntLE(0, 4);
1642
- let templates = [];
1643
1668
  while (totalSize) {
1644
- const buf = templateData.slice(0, 6);
1669
+ const buf = templateData.subarray(0, 6);
1645
1670
  const size = buf.readUIntLE(0, 2);
1646
- templates.push(new Finger(buf.readUIntLE(2, 2), buf.readUIntLE(4, 1), buf.readUIntLE(5, 1), templateData.slice(6, size)));
1647
- 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);
1648
1673
  totalSize -= size;
1649
1674
  }
1650
- return templates;
1675
+ return { data: templates };
1651
1676
  }
1652
1677
  catch (err) {
1653
- console.error('Error getting user templates: ', err);
1654
- throw err;
1678
+ this.verbose && console.log("Error getting templates", err);
1679
+ return { data: templates };
1655
1680
  }
1656
1681
  finally {
1657
1682
  await this.enableDevice();
1658
1683
  await this.freeData();
1659
1684
  }
1660
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
+ }
1661
1705
  async refreshData() {
1662
1706
  try {
1663
1707
  const reply = await this.executeCmd(COMMANDS.CMD_REFRESHDATA, '');
@@ -1955,7 +1999,7 @@ class ZTCP {
1955
1999
  }
1956
2000
  async ackOk() {
1957
2001
  try {
1958
- 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([]));
1959
2003
  this.socket.write(buf);
1960
2004
  }
1961
2005
  catch (e) {
@@ -2266,10 +2310,10 @@ class ZUDP {
2266
2310
  }
2267
2311
  };
2268
2312
  this.socket.on('message', handleOnData);
2269
- const chunkCount = Math.ceil(size / MAX_CHUNK);
2313
+ const chunkCount = Math.ceil(size / Constants.MAX_CHUNK);
2270
2314
  for (let i = 0; i < chunkCount; i++) {
2271
- const start = i * MAX_CHUNK;
2272
- 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;
2273
2317
  this.sendChunkRequest(start, chunkSize).catch(err => {
2274
2318
  internalCallback(Buffer.from([]), err);
2275
2319
  });
@@ -4,7 +4,6 @@ export declare class Attendance {
4
4
  record_time: Date;
5
5
  type?: number;
6
6
  state?: number;
7
- private _ip?;
7
+ ip?: string;
8
8
  constructor(sn: number, user_id: string, record_time: Date, type?: number, state?: number);
9
- set ip(value: string);
10
9
  }
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.0-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
- }