secs4js 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 (129) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +442 -0
  3. package/lib/core/AbstractSecsCommunicator.d.ts +76 -0
  4. package/lib/core/AbstractSecsCommunicator.d.ts.map +1 -0
  5. package/lib/core/AbstractSecsCommunicator.js +85 -0
  6. package/lib/core/AbstractSecsCommunicator.js.map +1 -0
  7. package/lib/core/AbstractSecsMessage.d.ts +36 -0
  8. package/lib/core/AbstractSecsMessage.d.ts.map +1 -0
  9. package/lib/core/AbstractSecsMessage.js +66 -0
  10. package/lib/core/AbstractSecsMessage.js.map +1 -0
  11. package/lib/core/enums/HsmsSsControlType.d.ts +59 -0
  12. package/lib/core/enums/HsmsSsControlType.d.ts.map +1 -0
  13. package/lib/core/enums/HsmsSsControlType.js +105 -0
  14. package/lib/core/enums/HsmsSsControlType.js.map +1 -0
  15. package/lib/core/enums/RejectReason.d.ts +11 -0
  16. package/lib/core/enums/RejectReason.d.ts.map +1 -0
  17. package/lib/core/enums/RejectReason.js +13 -0
  18. package/lib/core/enums/RejectReason.js.map +1 -0
  19. package/lib/core/enums/SecsItemType.d.ts +33 -0
  20. package/lib/core/enums/SecsItemType.d.ts.map +1 -0
  21. package/lib/core/enums/SecsItemType.js +22 -0
  22. package/lib/core/enums/SecsItemType.js.map +1 -0
  23. package/lib/core/enums/SelectStatus.d.ts +11 -0
  24. package/lib/core/enums/SelectStatus.d.ts.map +1 -0
  25. package/lib/core/enums/SelectStatus.js +13 -0
  26. package/lib/core/enums/SelectStatus.js.map +1 -0
  27. package/lib/core/secs2item/AbstractSecs2Item.d.ts +34 -0
  28. package/lib/core/secs2item/AbstractSecs2Item.d.ts.map +1 -0
  29. package/lib/core/secs2item/AbstractSecs2Item.js +59 -0
  30. package/lib/core/secs2item/AbstractSecs2Item.js.map +1 -0
  31. package/lib/core/secs2item/Secs2ItemAscii.d.ts +18 -0
  32. package/lib/core/secs2item/Secs2ItemAscii.d.ts.map +1 -0
  33. package/lib/core/secs2item/Secs2ItemAscii.js +27 -0
  34. package/lib/core/secs2item/Secs2ItemAscii.js.map +1 -0
  35. package/lib/core/secs2item/Secs2ItemBinary.d.ts +11 -0
  36. package/lib/core/secs2item/Secs2ItemBinary.d.ts.map +1 -0
  37. package/lib/core/secs2item/Secs2ItemBinary.js +22 -0
  38. package/lib/core/secs2item/Secs2ItemBinary.js.map +1 -0
  39. package/lib/core/secs2item/Secs2ItemBoolean.d.ts +12 -0
  40. package/lib/core/secs2item/Secs2ItemBoolean.d.ts.map +1 -0
  41. package/lib/core/secs2item/Secs2ItemBoolean.js +27 -0
  42. package/lib/core/secs2item/Secs2ItemBoolean.js.map +1 -0
  43. package/lib/core/secs2item/Secs2ItemFactory.d.ts +27 -0
  44. package/lib/core/secs2item/Secs2ItemFactory.d.ts.map +1 -0
  45. package/lib/core/secs2item/Secs2ItemFactory.js +56 -0
  46. package/lib/core/secs2item/Secs2ItemFactory.js.map +1 -0
  47. package/lib/core/secs2item/Secs2ItemList.d.ts +11 -0
  48. package/lib/core/secs2item/Secs2ItemList.d.ts.map +1 -0
  49. package/lib/core/secs2item/Secs2ItemList.js +26 -0
  50. package/lib/core/secs2item/Secs2ItemList.js.map +1 -0
  51. package/lib/core/secs2item/Secs2ItemNumeric.d.ts +14 -0
  52. package/lib/core/secs2item/Secs2ItemNumeric.d.ts.map +1 -0
  53. package/lib/core/secs2item/Secs2ItemNumeric.js +128 -0
  54. package/lib/core/secs2item/Secs2ItemNumeric.js.map +1 -0
  55. package/lib/core/secs2item/Secs2ItemParser.d.ts +12 -0
  56. package/lib/core/secs2item/Secs2ItemParser.d.ts.map +1 -0
  57. package/lib/core/secs2item/Secs2ItemParser.js +74 -0
  58. package/lib/core/secs2item/Secs2ItemParser.js.map +1 -0
  59. package/lib/gem/Clock.d.ts +21 -0
  60. package/lib/gem/Clock.d.ts.map +1 -0
  61. package/lib/gem/Clock.js +65 -0
  62. package/lib/gem/Clock.js.map +1 -0
  63. package/lib/gem/Gem.d.ts +55 -0
  64. package/lib/gem/Gem.d.ts.map +1 -0
  65. package/lib/gem/Gem.js +137 -0
  66. package/lib/gem/Gem.js.map +1 -0
  67. package/lib/helper/Secs2ItemHelper.d.ts +96 -0
  68. package/lib/helper/Secs2ItemHelper.d.ts.map +1 -0
  69. package/lib/helper/Secs2ItemHelper.js +135 -0
  70. package/lib/helper/Secs2ItemHelper.js.map +1 -0
  71. package/lib/hsms/HsmsActiveCommunicator.d.ts +29 -0
  72. package/lib/hsms/HsmsActiveCommunicator.d.ts.map +1 -0
  73. package/lib/hsms/HsmsActiveCommunicator.js +123 -0
  74. package/lib/hsms/HsmsActiveCommunicator.js.map +1 -0
  75. package/lib/hsms/HsmsCommunicator.d.ts +70 -0
  76. package/lib/hsms/HsmsCommunicator.d.ts.map +1 -0
  77. package/lib/hsms/HsmsCommunicator.js +322 -0
  78. package/lib/hsms/HsmsCommunicator.js.map +1 -0
  79. package/lib/hsms/HsmsMessage.d.ts +92 -0
  80. package/lib/hsms/HsmsMessage.d.ts.map +1 -0
  81. package/lib/hsms/HsmsMessage.js +163 -0
  82. package/lib/hsms/HsmsMessage.js.map +1 -0
  83. package/lib/hsms/HsmsPassiveCommunicator.d.ts +48 -0
  84. package/lib/hsms/HsmsPassiveCommunicator.d.ts.map +1 -0
  85. package/lib/hsms/HsmsPassiveCommunicator.js +304 -0
  86. package/lib/hsms/HsmsPassiveCommunicator.js.map +1 -0
  87. package/lib/hsms/enums/HsmsControlType.d.ts +15 -0
  88. package/lib/hsms/enums/HsmsControlType.d.ts.map +1 -0
  89. package/lib/hsms/enums/HsmsControlType.js +17 -0
  90. package/lib/hsms/enums/HsmsControlType.js.map +1 -0
  91. package/lib/hsms/enums/RejectReason.d.ts +11 -0
  92. package/lib/hsms/enums/RejectReason.d.ts.map +1 -0
  93. package/lib/hsms/enums/RejectReason.js +13 -0
  94. package/lib/hsms/enums/RejectReason.js.map +1 -0
  95. package/lib/hsms/enums/SelectStatus.d.ts +11 -0
  96. package/lib/hsms/enums/SelectStatus.d.ts.map +1 -0
  97. package/lib/hsms/enums/SelectStatus.js +13 -0
  98. package/lib/hsms/enums/SelectStatus.js.map +1 -0
  99. package/lib/index.d.ts +28 -0
  100. package/lib/index.js +29 -0
  101. package/lib/secs1/Secs1Communicator.d.ts +51 -0
  102. package/lib/secs1/Secs1Communicator.d.ts.map +1 -0
  103. package/lib/secs1/Secs1Communicator.js +342 -0
  104. package/lib/secs1/Secs1Communicator.js.map +1 -0
  105. package/lib/secs1/Secs1Message.d.ts +21 -0
  106. package/lib/secs1/Secs1Message.d.ts.map +1 -0
  107. package/lib/secs1/Secs1Message.js +77 -0
  108. package/lib/secs1/Secs1Message.js.map +1 -0
  109. package/lib/secs1/Secs1MessageBlock.d.ts +23 -0
  110. package/lib/secs1/Secs1MessageBlock.d.ts.map +1 -0
  111. package/lib/secs1/Secs1MessageBlock.js +86 -0
  112. package/lib/secs1/Secs1MessageBlock.js.map +1 -0
  113. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.d.ts +23 -0
  114. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.d.ts.map +1 -0
  115. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.js +82 -0
  116. package/lib/secs1/Secs1OnTcpIpActiveCommunicator.js.map +1 -0
  117. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.d.ts +19 -0
  118. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.d.ts.map +1 -0
  119. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.js +49 -0
  120. package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.js.map +1 -0
  121. package/lib/secs1/Secs1SerialCommunicator.d.ts +18 -0
  122. package/lib/secs1/Secs1SerialCommunicator.d.ts.map +1 -0
  123. package/lib/secs1/Secs1SerialCommunicator.js +59 -0
  124. package/lib/secs1/Secs1SerialCommunicator.js.map +1 -0
  125. package/lib/sml/SmlParser.d.ts +27 -0
  126. package/lib/sml/SmlParser.d.ts.map +1 -0
  127. package/lib/sml/SmlParser.js +184 -0
  128. package/lib/sml/SmlParser.js.map +1 -0
  129. package/package.json +53 -0
@@ -0,0 +1,322 @@
1
+ import { AbstractSecsCommunicator } from "../core/AbstractSecsCommunicator.js";
2
+ import { HsmsControlType } from "./enums/HsmsControlType.js";
3
+ import { RejectReason } from "./enums/RejectReason.js";
4
+ import { HsmsMessage } from "./HsmsMessage.js";
5
+ import { SelectStatus } from "./enums/SelectStatus.js";
6
+
7
+ //#region src/hsms/HsmsCommunicator.ts
8
+ let HsmsState = /* @__PURE__ */ function(HsmsState$1) {
9
+ HsmsState$1["NotConnected"] = "NotConnected";
10
+ HsmsState$1["Connected"] = "Connected";
11
+ HsmsState$1["Selected"] = "Selected";
12
+ return HsmsState$1;
13
+ }({});
14
+ var HsmsCommunicator = class extends AbstractSecsCommunicator {
15
+ ip;
16
+ port;
17
+ socket = null;
18
+ state = HsmsState.NotConnected;
19
+ buffer = Buffer.alloc(0);
20
+ t7Timer = null;
21
+ t8Timer = null;
22
+ get connectionState() {
23
+ return this.state;
24
+ }
25
+ constructor(config) {
26
+ super(config);
27
+ this.ip = config.ip;
28
+ this.port = config.port;
29
+ }
30
+ async sendBuffer(buffer) {
31
+ const socket = this.socket;
32
+ if (!socket || socket.destroyed) throw new Error("Socket not connected");
33
+ return new Promise((resolve, reject) => {
34
+ socket.write(buffer, (err) => {
35
+ if (err) reject(err);
36
+ else resolve();
37
+ });
38
+ });
39
+ }
40
+ createMessage(stream, func, wBit, body, systemBytes) {
41
+ return new HsmsMessage(stream, func, wBit, body, systemBytes, this.deviceId, 0, HsmsControlType.Data);
42
+ }
43
+ handleSocketEvents(socket) {
44
+ this.socket = socket;
45
+ this.state = HsmsState.Connected;
46
+ this.resetT7Timer();
47
+ this.emit("connected");
48
+ socket.on("data", (data) => {
49
+ this.buffer = Buffer.concat([this.buffer, data]);
50
+ this.resetT8Timer();
51
+ this.processBuffer();
52
+ if (this.buffer.length === 0) this.clearT8Timer();
53
+ });
54
+ socket.on("close", () => {
55
+ this.rejectAllTransactions(/* @__PURE__ */ new Error("Socket closed"));
56
+ this.clearT7Timer();
57
+ this.clearT8Timer();
58
+ this.buffer = Buffer.alloc(0);
59
+ this.state = HsmsState.NotConnected;
60
+ this.socket = null;
61
+ this.emit("disconnected");
62
+ });
63
+ socket.on("end", () => {
64
+ if (this.socket && !this.socket.destroyed) this.socket.destroy();
65
+ });
66
+ socket.on("error", (err) => {
67
+ this.emit("error", err);
68
+ if (!socket.destroyed) socket.destroy();
69
+ });
70
+ }
71
+ resetT7Timer() {
72
+ this.clearT7Timer();
73
+ if (this.timeoutT7 <= 0) return;
74
+ this.t7Timer = setTimeout(() => {
75
+ this.t7Timer = null;
76
+ if (this.state === HsmsState.Selected) return;
77
+ const socket = this.socket;
78
+ if (socket && !socket.destroyed) {
79
+ this.emit("error", /* @__PURE__ */ new Error("T7 Timeout"));
80
+ socket.destroy();
81
+ }
82
+ }, this.timeoutT7 * 1e3);
83
+ }
84
+ clearT7Timer() {
85
+ if (this.t7Timer) {
86
+ clearTimeout(this.t7Timer);
87
+ this.t7Timer = null;
88
+ }
89
+ }
90
+ resetT8Timer() {
91
+ this.clearT8Timer();
92
+ if (this.timeoutT8 <= 0) return;
93
+ this.t8Timer = setTimeout(() => {
94
+ this.t8Timer = null;
95
+ const socket = this.socket;
96
+ if (socket && !socket.destroyed && this.buffer.length > 0) {
97
+ this.emit("error", /* @__PURE__ */ new Error("T8 Timeout"));
98
+ socket.destroy();
99
+ }
100
+ }, this.timeoutT8 * 1e3);
101
+ }
102
+ clearT8Timer() {
103
+ if (this.t8Timer) {
104
+ clearTimeout(this.t8Timer);
105
+ this.t8Timer = null;
106
+ }
107
+ }
108
+ processBuffer() {
109
+ while (true) {
110
+ if (this.buffer.length < 4) return;
111
+ const length = this.buffer.readUInt32BE(0);
112
+ if (length < 10) {
113
+ const socket = this.socket;
114
+ this.emit("error", /* @__PURE__ */ new Error("Receive message size < 10"));
115
+ this.buffer = Buffer.alloc(0);
116
+ if (socket && !socket.destroyed) socket.destroy();
117
+ return;
118
+ }
119
+ if (this.buffer.length < 4 + length) return;
120
+ const msgBuffer = this.buffer.subarray(0, 4 + length);
121
+ this.buffer = this.buffer.subarray(4 + length);
122
+ try {
123
+ const msg = HsmsMessage.fromBuffer(msgBuffer);
124
+ this.processHsmsMessage(msg);
125
+ } catch (err) {
126
+ if (err instanceof Error) this.emit("error", /* @__PURE__ */ new Error(`Failed to parse HSMS message: ${err.message}`));
127
+ else this.emit("error", /* @__PURE__ */ new Error(`Failed to parse HSMS message: ${String(err)}`));
128
+ }
129
+ }
130
+ }
131
+ processHsmsMessage(msg) {
132
+ if (msg.sType !== HsmsControlType.Data) {
133
+ this.handleControlMessage(msg);
134
+ return;
135
+ }
136
+ if (this.state !== HsmsState.Selected) {
137
+ this.sendReject(msg, RejectReason.NotSelected);
138
+ return;
139
+ }
140
+ super.handleMessage(msg);
141
+ }
142
+ handleControlMessage(msg) {
143
+ switch (msg.sType) {
144
+ case HsmsControlType.SelectReq:
145
+ this.handleSelectReq(msg);
146
+ break;
147
+ case HsmsControlType.SelectRsp:
148
+ this.handleSelectRsp(msg);
149
+ break;
150
+ case HsmsControlType.DeselectReq:
151
+ this.handleDeselectReq(msg);
152
+ break;
153
+ case HsmsControlType.DeselectRsp:
154
+ this.handleDeselectRsp(msg);
155
+ break;
156
+ case HsmsControlType.LinkTestReq:
157
+ this.handleLinkTestReq(msg);
158
+ break;
159
+ case HsmsControlType.LinkTestRsp:
160
+ this.handleLinkTestRsp(msg);
161
+ break;
162
+ case HsmsControlType.SeparateReq:
163
+ this.handleSeparateReq(msg);
164
+ break;
165
+ case HsmsControlType.RejectReq: break;
166
+ default:
167
+ this.sendReject(msg, msg.pType !== 0 ? RejectReason.NotSupportTypeP : RejectReason.NotSupportTypeS);
168
+ break;
169
+ }
170
+ }
171
+ handleSelectReq(msg) {
172
+ if (this.state === HsmsState.Selected) this.sendSelectRsp(msg, SelectStatus.Actived);
173
+ else {
174
+ this.state = HsmsState.Selected;
175
+ this.clearT7Timer();
176
+ this.sendSelectRsp(msg, SelectStatus.Success);
177
+ this.emit("selected");
178
+ }
179
+ }
180
+ handleSelectRsp(msg) {
181
+ const tx = this._transactions.get(msg.systemBytes);
182
+ if (tx) {
183
+ const status = msg.func;
184
+ if (status === SelectStatus.Success || status === SelectStatus.Actived) {
185
+ this.state = HsmsState.Selected;
186
+ this.clearT7Timer();
187
+ this.emit("selected");
188
+ }
189
+ clearTimeout(tx.timer);
190
+ this._transactions.delete(msg.systemBytes);
191
+ tx.resolve(msg);
192
+ } else this.sendReject(msg, RejectReason.TransactionNotOpen);
193
+ }
194
+ handleLinkTestReq(msg) {
195
+ this.sendLinkTestRsp(msg);
196
+ }
197
+ handleLinkTestRsp(msg) {
198
+ const tx = this._transactions.get(msg.systemBytes);
199
+ if (tx) {
200
+ clearTimeout(tx.timer);
201
+ this._transactions.delete(msg.systemBytes);
202
+ tx.resolve(msg);
203
+ } else this.sendReject(msg, RejectReason.TransactionNotOpen);
204
+ }
205
+ handleDeselectReq(msg) {
206
+ if (this.state === HsmsState.Selected) {
207
+ this.state = HsmsState.Connected;
208
+ this.resetT7Timer();
209
+ this.sendDeselectRsp(msg, SelectStatus.Success);
210
+ this.emit("deselected");
211
+ return;
212
+ }
213
+ this.sendDeselectRsp(msg, SelectStatus.NotReady);
214
+ }
215
+ handleDeselectRsp(msg) {
216
+ const tx = this._transactions.get(msg.systemBytes);
217
+ if (tx) {
218
+ if (msg.func === SelectStatus.Success) {
219
+ this.state = HsmsState.Connected;
220
+ this.resetT7Timer();
221
+ this.emit("deselected");
222
+ }
223
+ clearTimeout(tx.timer);
224
+ this._transactions.delete(msg.systemBytes);
225
+ tx.resolve(msg);
226
+ } else this.sendReject(msg, RejectReason.TransactionNotOpen);
227
+ }
228
+ handleSeparateReq(_msg) {
229
+ const socket = this.socket;
230
+ this.state = HsmsState.Connected;
231
+ this.clearT7Timer();
232
+ if (socket && !socket.destroyed) socket.destroy();
233
+ }
234
+ async sendSelectRsp(req, status) {
235
+ const rsp = HsmsMessage.selectRsp(req, status);
236
+ await this.sendBuffer(rsp.toBuffer());
237
+ }
238
+ async sendDeselectRsp(req, status) {
239
+ const rsp = HsmsMessage.deselectRsp(req, status);
240
+ await this.sendBuffer(rsp.toBuffer());
241
+ }
242
+ async sendLinkTestRsp(req) {
243
+ const rsp = HsmsMessage.linkTestRsp(req);
244
+ await this.sendBuffer(rsp.toBuffer());
245
+ }
246
+ async sendReject(req, reason) {
247
+ const rsp = HsmsMessage.rejectReq(req, reason);
248
+ await this.sendBuffer(rsp.toBuffer());
249
+ }
250
+ async send(stream, func, wBit, body = null) {
251
+ if (this.state !== HsmsState.Selected) throw new Error("HSMS not selected");
252
+ return super.send(stream, func, wBit, body);
253
+ }
254
+ async sendSelectReq() {
255
+ const systemBytes = this.getNextSystemBytes();
256
+ const msg = HsmsMessage.selectReq(systemBytes);
257
+ return new Promise((resolve, reject) => {
258
+ const timer = setTimeout(() => {
259
+ this._transactions.delete(systemBytes);
260
+ const socket = this.socket;
261
+ if (socket && !socket.destroyed) socket.destroy();
262
+ reject(/* @__PURE__ */ new Error("T6 Timeout waiting for Select Rsp"));
263
+ }, this.timeoutT6 * 1e3);
264
+ this._transactions.set(systemBytes, {
265
+ resolve: (rsp) => {
266
+ resolve(rsp.func);
267
+ },
268
+ reject,
269
+ timer
270
+ });
271
+ this.sendBuffer(msg.toBuffer()).catch((err) => {
272
+ clearTimeout(timer);
273
+ this._transactions.delete(systemBytes);
274
+ reject(err instanceof Error ? err : new Error(String(err)));
275
+ });
276
+ });
277
+ }
278
+ async sendLinkTestReq() {
279
+ const systemBytes = this.getNextSystemBytes();
280
+ const msg = HsmsMessage.linkTestReq(systemBytes);
281
+ return new Promise((resolve, reject) => {
282
+ const timer = setTimeout(() => {
283
+ this._transactions.delete(systemBytes);
284
+ const socket = this.socket;
285
+ if (socket && !socket.destroyed) socket.destroy();
286
+ reject(/* @__PURE__ */ new Error("T6 Timeout waiting for LinkTest Rsp"));
287
+ }, this.timeoutT6 * 1e3);
288
+ this._transactions.set(systemBytes, {
289
+ resolve: () => {
290
+ resolve();
291
+ },
292
+ reject,
293
+ timer
294
+ });
295
+ this.sendBuffer(msg.toBuffer()).catch((err) => {
296
+ clearTimeout(timer);
297
+ this._transactions.delete(systemBytes);
298
+ reject(err instanceof Error ? err : new Error(String(err)));
299
+ });
300
+ });
301
+ }
302
+ async sendSeparateReq() {
303
+ const systemBytes = this.getNextSystemBytes();
304
+ const msg = HsmsMessage.separateReq(systemBytes);
305
+ await this.sendBuffer(msg.toBuffer());
306
+ const socket = this.socket;
307
+ this.state = HsmsState.Connected;
308
+ this.clearT7Timer();
309
+ if (socket && !socket.destroyed) socket.destroy();
310
+ }
311
+ rejectAllTransactions(err) {
312
+ for (const [systemBytes, tx] of this._transactions) {
313
+ clearTimeout(tx.timer);
314
+ tx.reject(err);
315
+ this._transactions.delete(systemBytes);
316
+ }
317
+ }
318
+ };
319
+
320
+ //#endregion
321
+ export { HsmsCommunicator, HsmsState };
322
+ //# sourceMappingURL=HsmsCommunicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HsmsCommunicator.js","names":[],"sources":["../../src/hsms/HsmsCommunicator.ts"],"sourcesContent":["import { Socket } from \"net\";\nimport {\n\tAbstractSecsCommunicator,\n\tSecsCommunicatorConfig,\n\tSecsCommunicatorEvents,\n} from \"../core/AbstractSecsCommunicator.js\";\nimport { SecsMessage } from \"../core/AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"../core/secs2item/AbstractSecs2Item.js\";\nimport { HsmsMessage } from \"./HsmsMessage.js\";\nimport { HsmsControlType } from \"./enums/HsmsControlType.js\";\nimport { SelectStatus } from \"./enums/SelectStatus.js\";\nimport { RejectReason } from \"./enums/RejectReason.js\";\n\nexport enum HsmsState {\n\tNotConnected = \"NotConnected\",\n\tConnected = \"Connected\", // TCP Connected\n\tSelected = \"Selected\", // HSMS Selected\n}\n\n/**\n * @description HsmsCommunicatorConfig is the configuration interface for HsmsCommunicator.\n * @param ip The IP address of the remote device.\n * @param port The port number of the remote device.\n * @param linkTestInterval The interval in milliseconds to send link test messages.\n */\nexport interface HsmsCommunicatorConfig extends SecsCommunicatorConfig {\n\tip: string;\n\tport: number;\n\tlinkTestInterval?: number;\n}\n\nexport interface HsmsCommunicatorEvents extends SecsCommunicatorEvents {\n\tselected: [];\n\tdeselected: [];\n}\n\nexport abstract class HsmsCommunicator extends AbstractSecsCommunicator<HsmsCommunicatorEvents> {\n\tpublic ip: string;\n\tpublic port: number;\n\n\tprotected socket: Socket | null = null;\n\tprotected state: HsmsState = HsmsState.NotConnected;\n\tprivate buffer: Buffer = Buffer.alloc(0);\n\tprivate t7Timer: NodeJS.Timeout | null = null;\n\tprivate t8Timer: NodeJS.Timeout | null = null;\n\n\t// T6 Timer (Control Transaction)\n\t// We use the same _transactions map for Control messages if they expect reply\n\n\tpublic get connectionState(): HsmsState {\n\t\treturn this.state;\n\t}\n\n\tconstructor(config: HsmsCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.ip = config.ip;\n\t\tthis.port = config.port;\n\t}\n\n\tprotected async sendBuffer(buffer: Buffer): Promise<void> {\n\t\tconst socket = this.socket;\n\t\tif (!socket || socket.destroyed) {\n\t\t\tthrow new Error(\"Socket not connected\");\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tsocket.write(buffer, (err) => {\n\t\t\t\tif (err) reject(err);\n\t\t\t\telse resolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprotected createMessage(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null,\n\t\tsystemBytes: number,\n\t): SecsMessage {\n\t\t// For Data messages, pType=0, sType=0 (Data)\n\t\treturn new HsmsMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit,\n\t\t\tbody,\n\t\t\tsystemBytes,\n\t\t\tthis.deviceId,\n\t\t\t0,\n\t\t\tHsmsControlType.Data,\n\t\t);\n\t}\n\n\tprotected handleSocketEvents(socket: Socket) {\n\t\tthis.socket = socket;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.resetT7Timer();\n\t\tthis.emit(\"connected\");\n\n\t\tsocket.on(\"data\", (data) => {\n\t\t\tthis.buffer = Buffer.concat([this.buffer, data]);\n\t\t\tthis.resetT8Timer();\n\t\t\tthis.processBuffer();\n\t\t\tif (this.buffer.length === 0) {\n\t\t\t\tthis.clearT8Timer();\n\t\t\t}\n\t\t});\n\n\t\tsocket.on(\"close\", () => {\n\t\t\tthis.rejectAllTransactions(new Error(\"Socket closed\"));\n\t\t\tthis.clearT7Timer();\n\t\t\tthis.clearT8Timer();\n\t\t\tthis.buffer = Buffer.alloc(0);\n\t\t\tthis.state = HsmsState.NotConnected;\n\t\t\tthis.socket = null;\n\t\t\tthis.emit(\"disconnected\");\n\t\t});\n\n\t\tsocket.on(\"end\", () => {\n\t\t\tif (this.socket && !this.socket.destroyed) {\n\t\t\t\tthis.socket.destroy();\n\t\t\t}\n\t\t});\n\n\t\tsocket.on(\"error\", (err) => {\n\t\t\tthis.emit(\"error\", err);\n\t\t\tif (!socket.destroyed) {\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate resetT7Timer() {\n\t\tthis.clearT7Timer();\n\t\tif (this.timeoutT7 <= 0) return;\n\t\tthis.t7Timer = setTimeout(() => {\n\t\t\tthis.t7Timer = null;\n\t\t\tif (this.state === HsmsState.Selected) return;\n\t\t\tconst socket = this.socket;\n\t\t\tif (socket && !socket.destroyed) {\n\t\t\t\tthis.emit(\"error\", new Error(\"T7 Timeout\"));\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t}, this.timeoutT7 * 1000);\n\t}\n\n\tprivate clearT7Timer() {\n\t\tif (this.t7Timer) {\n\t\t\tclearTimeout(this.t7Timer);\n\t\t\tthis.t7Timer = null;\n\t\t}\n\t}\n\n\tprivate resetT8Timer() {\n\t\tthis.clearT8Timer();\n\t\tif (this.timeoutT8 <= 0) return;\n\t\tthis.t8Timer = setTimeout(() => {\n\t\t\tthis.t8Timer = null;\n\t\t\tconst socket = this.socket;\n\t\t\tif (socket && !socket.destroyed && this.buffer.length > 0) {\n\t\t\t\tthis.emit(\"error\", new Error(\"T8 Timeout\"));\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t}, this.timeoutT8 * 1000);\n\t}\n\n\tprivate clearT8Timer() {\n\t\tif (this.t8Timer) {\n\t\t\tclearTimeout(this.t8Timer);\n\t\t\tthis.t8Timer = null;\n\t\t}\n\t}\n\n\tprivate processBuffer() {\n\t\twhile (true) {\n\t\t\tif (this.buffer.length < 4) return;\n\n\t\t\tconst length = this.buffer.readUInt32BE(0);\n\t\t\tif (length < 10) {\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tthis.emit(\"error\", new Error(\"Receive message size < 10\"));\n\t\t\t\tthis.buffer = Buffer.alloc(0);\n\t\t\t\tif (socket && !socket.destroyed) {\n\t\t\t\t\tsocket.destroy();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.buffer.length < 4 + length) return;\n\n\t\t\tconst msgBuffer = this.buffer.subarray(0, 4 + length);\n\t\t\tthis.buffer = this.buffer.subarray(4 + length);\n\n\t\t\ttry {\n\t\t\t\tconst msg = HsmsMessage.fromBuffer(msgBuffer);\n\t\t\t\tthis.processHsmsMessage(msg);\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\tnew Error(`Failed to parse HSMS message: ${err.message}`),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\tnew Error(`Failed to parse HSMS message: ${String(err)}`),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate processHsmsMessage(msg: HsmsMessage) {\n\t\t// Handle Control Messages\n\t\tif (msg.sType !== HsmsControlType.Data) {\n\t\t\tthis.handleControlMessage(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle Data Messages\n\t\tif (this.state !== HsmsState.Selected) {\n\t\t\tvoid this.sendReject(msg, RejectReason.NotSelected);\n\t\t\treturn;\n\t\t}\n\n\t\tsuper.handleMessage(msg);\n\t}\n\n\tprivate handleControlMessage(msg: HsmsMessage) {\n\t\tswitch (msg.sType as HsmsControlType) {\n\t\t\tcase HsmsControlType.SelectReq:\n\t\t\t\tthis.handleSelectReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.SelectRsp:\n\t\t\t\tthis.handleSelectRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.DeselectReq:\n\t\t\t\tthis.handleDeselectReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.DeselectRsp:\n\t\t\t\tthis.handleDeselectRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.LinkTestReq:\n\t\t\t\tthis.handleLinkTestReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.LinkTestRsp:\n\t\t\t\tthis.handleLinkTestRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.SeparateReq:\n\t\t\t\tthis.handleSeparateReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.RejectReq:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tvoid this.sendReject(\n\t\t\t\t\tmsg,\n\t\t\t\t\tmsg.pType !== 0\n\t\t\t\t\t\t? RejectReason.NotSupportTypeP\n\t\t\t\t\t\t: RejectReason.NotSupportTypeS,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprotected handleSelectReq(msg: HsmsMessage) {\n\t\t// Subclasses might override, but default behavior:\n\t\t// If already selected, return Actived/AlreadyUsed?\n\t\t// If not, accept.\n\n\t\t// Note: HSMS-SS says only one host.\n\t\tif (this.state === HsmsState.Selected) {\n\t\t\tvoid this.sendSelectRsp(msg, SelectStatus.Actived); // Or AlreadyUsed?\n\t\t} else {\n\t\t\tthis.state = HsmsState.Selected;\n\t\t\tthis.clearT7Timer();\n\t\t\tvoid this.sendSelectRsp(msg, SelectStatus.Success);\n\t\t\tthis.emit(\"selected\");\n\t\t}\n\t}\n\n\tprotected handleSelectRsp(msg: HsmsMessage) {\n\t\t// Check if we are waiting for this.\n\t\t// Usually managed by sendSelectReq promise.\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\t// If status is Success, set state to Selected\n\t\t\t// msg.func holds the status (byte 3) if we mapped it correctly in HsmsMessage.fromBuffer\n\t\t\t// In HsmsMessage.fromBuffer, for Control msg, func = byte 3.\n\t\t\tconst status = msg.func as SelectStatus;\n\t\t\tif (status === SelectStatus.Success || status === SelectStatus.Actived) {\n\t\t\t\tthis.state = HsmsState.Selected;\n\t\t\t\tthis.clearT7Timer();\n\t\t\t\tthis.emit(\"selected\");\n\t\t\t}\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleLinkTestReq(msg: HsmsMessage) {\n\t\tvoid this.sendLinkTestRsp(msg);\n\t}\n\n\tprotected handleLinkTestRsp(msg: HsmsMessage) {\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleDeselectReq(msg: HsmsMessage) {\n\t\tif (this.state === HsmsState.Selected) {\n\t\t\tthis.state = HsmsState.Connected;\n\t\t\tthis.resetT7Timer();\n\t\t\tvoid this.sendDeselectRsp(msg, SelectStatus.Success);\n\t\t\tthis.emit(\"deselected\");\n\t\t\treturn;\n\t\t}\n\t\tvoid this.sendDeselectRsp(msg, SelectStatus.NotReady);\n\t}\n\n\tprotected handleDeselectRsp(msg: HsmsMessage) {\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tconst status = msg.func as SelectStatus;\n\t\t\tif (status === SelectStatus.Success) {\n\t\t\t\tthis.state = HsmsState.Connected;\n\t\t\t\tthis.resetT7Timer();\n\t\t\t\tthis.emit(\"deselected\");\n\t\t\t}\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleSeparateReq(_msg: HsmsMessage) {\n\t\tconst socket = this.socket;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.clearT7Timer();\n\t\tif (socket && !socket.destroyed) {\n\t\t\tsocket.destroy();\n\t\t}\n\t}\n\n\t// Helper senders\n\tprotected async sendSelectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.selectRsp(req, status);\n\t\tawait this.sendBuffer(rsp.toBuffer());\n\t}\n\n\tprotected async sendDeselectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.deselectRsp(req, status);\n\t\tawait this.sendBuffer(rsp.toBuffer());\n\t}\n\n\tprotected async sendLinkTestRsp(req: HsmsMessage) {\n\t\tconst rsp = HsmsMessage.linkTestRsp(req);\n\t\tawait this.sendBuffer(rsp.toBuffer());\n\t}\n\n\tprotected async sendReject(req: HsmsMessage, reason: RejectReason) {\n\t\tconst rsp = HsmsMessage.rejectReq(req, reason);\n\t\tawait this.sendBuffer(rsp.toBuffer());\n\t}\n\n\toverride async send(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<SecsMessage | null> {\n\t\tif (this.state !== HsmsState.Selected) {\n\t\t\tthrow new Error(\"HSMS not selected\");\n\t\t}\n\t\treturn super.send(stream, func, wBit, body);\n\t}\n\n\t// Public control methods\n\tpublic async sendSelectReq(): Promise<SelectStatus> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.selectReq(systemBytes);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tif (socket && !socket.destroyed) socket.destroy();\n\t\t\t\treject(new Error(\"T6 Timeout waiting for Select Rsp\"));\n\t\t\t}, this.timeoutT6 * 1000);\n\n\t\t\tthis._transactions.set(systemBytes, {\n\t\t\t\tresolve: (rsp) => {\n\t\t\t\t\tresolve(rsp.func as SelectStatus);\n\t\t\t\t},\n\t\t\t\treject,\n\t\t\t\ttimer,\n\t\t\t});\n\n\t\t\tthis.sendBuffer(msg.toBuffer()).catch((err: unknown) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t});\n\t}\n\n\tpublic async sendLinkTestReq(): Promise<void> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.linkTestReq(systemBytes);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tif (socket && !socket.destroyed) socket.destroy();\n\t\t\t\treject(new Error(\"T6 Timeout waiting for LinkTest Rsp\"));\n\t\t\t}, this.timeoutT6 * 1000);\n\n\t\t\tthis._transactions.set(systemBytes, {\n\t\t\t\tresolve: () => {\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\treject,\n\t\t\t\ttimer,\n\t\t\t});\n\n\t\t\tthis.sendBuffer(msg.toBuffer()).catch((err: unknown) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t});\n\t}\n\n\tpublic async sendSeparateReq(): Promise<void> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.separateReq(systemBytes);\n\t\tawait this.sendBuffer(msg.toBuffer());\n\t\tconst socket = this.socket;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.clearT7Timer();\n\t\tif (socket && !socket.destroyed) {\n\t\t\tsocket.destroy();\n\t\t}\n\t}\n\n\tprivate rejectAllTransactions(err: Error) {\n\t\tfor (const [systemBytes, tx] of this._transactions) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\ttx.reject(err);\n\t\t\tthis._transactions.delete(systemBytes);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { AbstractSecs2Item } from "../core/secs2item/AbstractSecs2Item.js";
2
+ import { SecsMessage } from "../core/AbstractSecsMessage.js";
3
+ import { RejectReason } from "./enums/RejectReason.js";
4
+
5
+ //#region src/hsms/HsmsMessage.d.ts
6
+
7
+ /**
8
+ * @description HsmsMessage is the class that represents an HSMS message.
9
+ * @param stream The stream number of the message.
10
+ * @param func The function number of the message.
11
+ * @param wBit The W-Bit of the message.
12
+ * @param body The body of the message.
13
+ * @param systemBytes The system bytes of the message.
14
+ * @param deviceId The device ID of the message.
15
+ * @param pType The P-Type of the message.
16
+ * @param sType The S-Type of the message.
17
+ */
18
+ declare class HsmsMessage extends SecsMessage {
19
+ readonly pType: number;
20
+ readonly sType: number;
21
+ constructor(stream: number, func: number, wBit: boolean, body: AbstractSecs2Item | null, systemBytes: number, deviceId: number, pType?: number, sType?: number);
22
+ /**
23
+ * @description Encodes the message to a buffer (Length + Header + Body).
24
+ */
25
+ toBuffer(): Buffer;
26
+ /**
27
+ * @description Checks if the message is a data message.
28
+ * @description data message: deviceId not 0xFF 0xFF and header[4] and header[5] are 0.
29
+ * @returns True if the message is a data message, false otherwise.
30
+ */
31
+ isDataMessage(): boolean;
32
+ /**
33
+ * @description Creates an HsmsMessage from a buffer.
34
+ * @param buffer The buffer containing the message data.
35
+ * @returns The HsmsMessage object.
36
+ */
37
+ static fromBuffer(buffer: Buffer): HsmsMessage;
38
+ /**
39
+ * @description Creates a Select Request message.
40
+ * @param systemBytes The system bytes of the message.
41
+ * @returns The HsmsMessage object.
42
+ */
43
+ static selectReq(systemBytes: number): HsmsMessage;
44
+ /**
45
+ * @description Creates a Select Response message.
46
+ * @param req The Select Request message.
47
+ * @param status The status of the response.
48
+ * @returns The HsmsMessage object.
49
+ */
50
+ static selectRsp(req: HsmsMessage, status: number): HsmsMessage;
51
+ /**
52
+ * @description Creates a Deselect Request message.
53
+ * @param systemBytes The system bytes of the message.
54
+ * @returns The HsmsMessage object.
55
+ */
56
+ static deselectReq(systemBytes: number): HsmsMessage;
57
+ /**
58
+ * @description Creates a Deselect Response message.
59
+ * @param req The Deselect Request message.
60
+ * @param status The status of the response.
61
+ * @returns The HsmsMessage object.
62
+ */
63
+ static deselectRsp(req: HsmsMessage, status: number): HsmsMessage;
64
+ /**
65
+ * @description Creates a Link Test Request message.
66
+ * @param systemBytes The system bytes of the message.
67
+ * @returns The HsmsMessage object.
68
+ */
69
+ static linkTestReq(systemBytes: number): HsmsMessage;
70
+ /**
71
+ * @description Creates a Link Test Response message.
72
+ * @param req The Link Test Request message.
73
+ * @returns The HsmsMessage object.
74
+ */
75
+ static linkTestRsp(req: HsmsMessage): HsmsMessage;
76
+ /**
77
+ * @description Creates a Reject Request message.
78
+ * @param req The message that triggered the reject.
79
+ * @param reason The reason for the reject.
80
+ * @returns The HsmsMessage object.
81
+ */
82
+ static rejectReq(req: HsmsMessage, reason: RejectReason): HsmsMessage;
83
+ /**
84
+ * @description Creates a Separate Request message.
85
+ * @param systemBytes The system bytes of the message.
86
+ * @returns The HsmsMessage object.
87
+ */
88
+ static separateReq(systemBytes: number): HsmsMessage;
89
+ }
90
+ //#endregion
91
+ export { HsmsMessage };
92
+ //# sourceMappingURL=HsmsMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HsmsMessage.d.ts","names":[],"sources":["../../src/hsms/HsmsMessage.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAiBA;;;;;;;;;AA2MyB,cA3MZ,WAAA,SAAoB,WAAA,CA2MR;EAA8B,SAAA,KAAA,EAAA,MAAA;EAkBb,SAAA,KAAA,EAAA,MAAA;EAkBjB,WAAA,CAAA,MAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,OAAA,EAAA,IAAA,EA1OjB,iBA0OiB,GAAA,IAAA,EAAA,WAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,KAAA,CAAA,EAAA,MAAA,EAAA,KAAA,CAAA,EAAA,MAAA;EAAc;;;EAmBoB,QAAA,CAAA,CAAA,EAjP9C,MAiP8C;EAsBjB;;;;;;;;;;;4BA9Lf,SAAS;;;;;;yCAyDI;;;;;;;wBAmBjB,8BAA8B;;;;;;2CAkBX;;;;;;;0BAmBjB,8BAA8B;;;;;;2CAkBb;;;;;;0BAkBjB,cAAc;;;;;;;wBAmBhB,qBAAqB,eAAe;;;;;;2CAsBjB"}
@@ -0,0 +1,163 @@
1
+ import { SecsMessage } from "../core/AbstractSecsMessage.js";
2
+ import { Secs2ItemParser } from "../core/secs2item/Secs2ItemParser.js";
3
+ import { HsmsControlType } from "./enums/HsmsControlType.js";
4
+ import { RejectReason } from "./enums/RejectReason.js";
5
+
6
+ //#region src/hsms/HsmsMessage.ts
7
+ /**
8
+ * @description HsmsMessage is the class that represents an HSMS message.
9
+ * @param stream The stream number of the message.
10
+ * @param func The function number of the message.
11
+ * @param wBit The W-Bit of the message.
12
+ * @param body The body of the message.
13
+ * @param systemBytes The system bytes of the message.
14
+ * @param deviceId The device ID of the message.
15
+ * @param pType The P-Type of the message.
16
+ * @param sType The S-Type of the message.
17
+ */
18
+ var HsmsMessage = class HsmsMessage extends SecsMessage {
19
+ constructor(stream, func, wBit, body, systemBytes, deviceId, pType = 0, sType = 0) {
20
+ super(stream, func, wBit, body, systemBytes, deviceId);
21
+ this.pType = pType;
22
+ this.sType = sType;
23
+ }
24
+ /**
25
+ * @description Encodes the message to a buffer (Length + Header + Body).
26
+ */
27
+ toBuffer() {
28
+ const bodyBuffer = this.body ? this.body.toBuffer() : Buffer.alloc(0);
29
+ const header = Buffer.alloc(10);
30
+ if (this.isDataMessage()) header.writeUInt16BE(this.deviceId, 0);
31
+ else header.writeUInt16BE(65535, 0);
32
+ if (this.isDataMessage()) {
33
+ let b2 = this.stream;
34
+ if (this.wBit) b2 |= 128;
35
+ header.writeUInt8(b2, 2);
36
+ header.writeUInt8(this.func, 3);
37
+ } else {
38
+ header.writeUInt8(this.stream, 2);
39
+ header.writeUInt8(this.func, 3);
40
+ }
41
+ header.writeUInt8(this.pType, 4);
42
+ header.writeUInt8(this.sType, 5);
43
+ header.writeUInt32BE(this.systemBytes, 6);
44
+ const length = header.length + bodyBuffer.length;
45
+ const lengthBuffer = Buffer.alloc(4);
46
+ lengthBuffer.writeUInt32BE(length, 0);
47
+ return Buffer.concat([
48
+ lengthBuffer,
49
+ header,
50
+ bodyBuffer
51
+ ]);
52
+ }
53
+ /**
54
+ * @description Checks if the message is a data message.
55
+ * @description data message: deviceId not 0xFF 0xFF and header[4] and header[5] are 0.
56
+ * @returns True if the message is a data message, false otherwise.
57
+ */
58
+ isDataMessage() {
59
+ return this.sType === HsmsControlType.Data;
60
+ }
61
+ /**
62
+ * @description Creates an HsmsMessage from a buffer.
63
+ * @param buffer The buffer containing the message data.
64
+ * @returns The HsmsMessage object.
65
+ */
66
+ static fromBuffer(buffer) {
67
+ if (buffer.length < 14) throw new Error("Buffer too short for HSMS message");
68
+ const header = buffer.subarray(4, 14);
69
+ const bodyBuffer = buffer.subarray(14);
70
+ const sessionId = header.readUInt16BE(0);
71
+ const byte2 = header.readUInt8(2);
72
+ const byte3 = header.readUInt8(3);
73
+ const pType = header.readUInt8(4);
74
+ const sType = header.readUInt8(5);
75
+ const systemBytes = header.readUInt32BE(6);
76
+ let stream = 0;
77
+ let func = 0;
78
+ let wBit = false;
79
+ const deviceId = sessionId;
80
+ let body = null;
81
+ if (sType === HsmsControlType.Data) {
82
+ stream = byte2 & 127;
83
+ wBit = (byte2 & 128) !== 0;
84
+ func = byte3;
85
+ if (bodyBuffer.length > 0) body = Secs2ItemParser.fromBuffer(bodyBuffer).item;
86
+ } else {
87
+ stream = byte2;
88
+ func = byte3;
89
+ }
90
+ return new HsmsMessage(stream, func, wBit, body, systemBytes, deviceId, pType, sType);
91
+ }
92
+ /**
93
+ * @description Creates a Select Request message.
94
+ * @param systemBytes The system bytes of the message.
95
+ * @returns The HsmsMessage object.
96
+ */
97
+ static selectReq(systemBytes) {
98
+ return new HsmsMessage(0, 0, false, null, systemBytes, 65535, 0, HsmsControlType.SelectReq);
99
+ }
100
+ /**
101
+ * @description Creates a Select Response message.
102
+ * @param req The Select Request message.
103
+ * @param status The status of the response.
104
+ * @returns The HsmsMessage object.
105
+ */
106
+ static selectRsp(req, status) {
107
+ return new HsmsMessage(0, status, false, null, req.systemBytes, 65535, 0, HsmsControlType.SelectRsp);
108
+ }
109
+ /**
110
+ * @description Creates a Deselect Request message.
111
+ * @param systemBytes The system bytes of the message.
112
+ * @returns The HsmsMessage object.
113
+ */
114
+ static deselectReq(systemBytes) {
115
+ return new HsmsMessage(0, 0, false, null, systemBytes, 65535, 0, HsmsControlType.DeselectReq);
116
+ }
117
+ /**
118
+ * @description Creates a Deselect Response message.
119
+ * @param req The Deselect Request message.
120
+ * @param status The status of the response.
121
+ * @returns The HsmsMessage object.
122
+ */
123
+ static deselectRsp(req, status) {
124
+ return new HsmsMessage(0, status, false, null, req.systemBytes, 65535, 0, HsmsControlType.DeselectRsp);
125
+ }
126
+ /**
127
+ * @description Creates a Link Test Request message.
128
+ * @param systemBytes The system bytes of the message.
129
+ * @returns The HsmsMessage object.
130
+ */
131
+ static linkTestReq(systemBytes) {
132
+ return new HsmsMessage(0, 0, false, null, systemBytes, 65535, 0, HsmsControlType.LinkTestReq);
133
+ }
134
+ /**
135
+ * @description Creates a Link Test Response message.
136
+ * @param req The Link Test Request message.
137
+ * @returns The HsmsMessage object.
138
+ */
139
+ static linkTestRsp(req) {
140
+ return new HsmsMessage(0, 0, false, null, req.systemBytes, 65535, 0, HsmsControlType.LinkTestRsp);
141
+ }
142
+ /**
143
+ * @description Creates a Reject Request message.
144
+ * @param req The message that triggered the reject.
145
+ * @param reason The reason for the reject.
146
+ * @returns The HsmsMessage object.
147
+ */
148
+ static rejectReq(req, reason) {
149
+ return new HsmsMessage(reason === RejectReason.NotSupportTypeP ? req.pType : req.sType, reason, false, null, req.systemBytes, 65535, 0, HsmsControlType.RejectReq);
150
+ }
151
+ /**
152
+ * @description Creates a Separate Request message.
153
+ * @param systemBytes The system bytes of the message.
154
+ * @returns The HsmsMessage object.
155
+ */
156
+ static separateReq(systemBytes) {
157
+ return new HsmsMessage(0, 0, false, null, systemBytes, 65535, 0, HsmsControlType.SeparateReq);
158
+ }
159
+ };
160
+
161
+ //#endregion
162
+ export { HsmsMessage };
163
+ //# sourceMappingURL=HsmsMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HsmsMessage.js","names":["body: AbstractSecs2Item | null"],"sources":["../../src/hsms/HsmsMessage.ts"],"sourcesContent":["import { SecsMessage } from \"../core/AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"../core/secs2item/AbstractSecs2Item.js\";\nimport { HsmsControlType } from \"./enums/HsmsControlType.js\";\nimport { RejectReason } from \"./enums/RejectReason.js\";\nimport { Secs2ItemParser } from \"../core/secs2item/Secs2ItemParser.js\";\n\n/**\n * @description HsmsMessage is the class that represents an HSMS message.\n * @param stream The stream number of the message.\n * @param func The function number of the message.\n * @param wBit The W-Bit of the message.\n * @param body The body of the message.\n * @param systemBytes The system bytes of the message.\n * @param deviceId The device ID of the message.\n * @param pType The P-Type of the message.\n * @param sType The S-Type of the message.\n */\nexport class HsmsMessage extends SecsMessage {\n\tconstructor(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null,\n\t\tsystemBytes: number,\n\t\tdeviceId: number,\n\t\tpublic readonly pType = 0,\n\t\tpublic readonly sType = 0,\n\t) {\n\t\tsuper(stream, func, wBit, body, systemBytes, deviceId);\n\t}\n\n\t/**\n\t * @description Encodes the message to a buffer (Length + Header + Body).\n\t */\n\ttoBuffer(): Buffer {\n\t\tconst bodyBuffer = this.body ? this.body.toBuffer() : Buffer.alloc(0);\n\t\tconst header = Buffer.alloc(10);\n\n\t\t// Byte 0-1: Session ID (Device ID) or 0xFFFF\n\t\tif (this.isDataMessage()) {\n\t\t\theader.writeUInt16BE(this.deviceId, 0);\n\t\t} else {\n\t\t\theader.writeUInt16BE(0xffff, 0);\n\t\t}\n\n\t\t// Byte 2: Stream / WBit (only for Data)\n\t\t// Byte 3: Function (only for Data)\n\t\tif (this.isDataMessage()) {\n\t\t\tlet b2 = this.stream;\n\t\t\tif (this.wBit) {\n\t\t\t\tb2 |= 0x80;\n\t\t\t}\n\t\t\theader.writeUInt8(b2, 2);\n\t\t\theader.writeUInt8(this.func, 3);\n\t\t} else {\n\t\t\t// For control messages, byte 2 and 3 depend on type\n\t\t\t// But typically 0 unless SelectStatus/RejectReason\n\t\t\t// We will handle specific construction in static methods\n\t\t\t// Here we assume pType and sType are set correctly for Control Messages\n\t\t\t// Wait, P-Type is Byte 4, S-Type is Byte 5.\n\t\t\t// Byte 2 and 3 are 0 for most control messages.\n\t\t\t// EXCEPT Select Response (Byte 3 = Status) and Reject (Byte 3 = Reason).\n\t\t\t// But those are stored in 'sType' or 'func' or similar?\n\t\t\t// In this class, I store pType and sType (Byte 4, 5).\n\t\t\t// Where do I store Byte 2 and 3 for Control Messages?\n\t\t\t// The Python code:\n\t\t\t// Select Response: h10bytes = ... 0x00, select_status ...\n\t\t\t// Reject: ... b2, reject_reason ...\n\n\t\t\t// I should allow passing byte 2 and 3 specifically or handle it via polymorphism.\n\t\t\t// To keep it simple, I will use 'stream' and 'func' to hold Byte 2 and 3 for Control Messages too,\n\t\t\t// even if they don't mean Stream/Function.\n\n\t\t\theader.writeUInt8(this.stream, 2);\n\t\t\theader.writeUInt8(this.func, 3);\n\t\t}\n\n\t\t// Byte 4: P-Type\n\t\theader.writeUInt8(this.pType, 4);\n\n\t\t// Byte 5: S-Type\n\t\theader.writeUInt8(this.sType, 5);\n\n\t\t// Byte 6-9: System Bytes\n\t\theader.writeUInt32BE(this.systemBytes, 6);\n\n\t\tconst length = header.length + bodyBuffer.length;\n\t\tconst lengthBuffer = Buffer.alloc(4);\n\t\tlengthBuffer.writeUInt32BE(length, 0);\n\n\t\treturn Buffer.concat([lengthBuffer, header, bodyBuffer]);\n\t}\n\n\t/**\n\t * @description Checks if the message is a data message.\n\t * @description data message: deviceId not 0xFF 0xFF and header[4] and header[5] are 0.\n\t * @returns True if the message is a data message, false otherwise.\n\t */\n\tisDataMessage(): boolean {\n\t\treturn (this.sType as HsmsControlType) === HsmsControlType.Data;\n\t}\n\n\t/**\n\t * @description Creates an HsmsMessage from a buffer.\n\t * @param buffer The buffer containing the message data.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic fromBuffer(buffer: Buffer): HsmsMessage {\n\t\tif (buffer.length < 14) {\n\t\t\tthrow new Error(\"Buffer too short for HSMS message\");\n\t\t}\n\n\t\t// Bytes 0-3: Length (ignored here, assumed to be correct or handled by framer)\n\t\tconst header = buffer.subarray(4, 14);\n\t\tconst bodyBuffer = buffer.subarray(14);\n\n\t\tconst sessionId = header.readUInt16BE(0);\n\t\tconst byte2 = header.readUInt8(2);\n\t\tconst byte3 = header.readUInt8(3);\n\t\tconst pType = header.readUInt8(4);\n\t\tconst sType = header.readUInt8(5);\n\t\tconst systemBytes = header.readUInt32BE(6);\n\n\t\tlet stream = 0;\n\t\tlet func = 0;\n\t\tlet wBit = false;\n\t\tconst deviceId = sessionId;\n\t\tlet body: AbstractSecs2Item | null = null;\n\n\t\tif ((sType as HsmsControlType) === HsmsControlType.Data) {\n\t\t\tstream = byte2 & 0x7f;\n\t\t\twBit = (byte2 & 0x80) !== 0;\n\t\t\tfunc = byte3;\n\n\t\t\tif (bodyBuffer.length > 0) {\n\t\t\t\tconst result = Secs2ItemParser.fromBuffer(bodyBuffer);\n\t\t\t\tbody = result.item;\n\t\t\t}\n\t\t} else {\n\t\t\t// Control Message\n\t\t\t// Mapping Byte 2/3 to stream/func to preserve data (e.g. Select Status)\n\t\t\tstream = byte2;\n\t\t\tfunc = byte3;\n\t\t\t// deviceId is usually ignored or 0xFFFF, but we keep what we read\n\t\t}\n\n\t\treturn new HsmsMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit,\n\t\t\tbody,\n\t\t\tsystemBytes,\n\t\t\tdeviceId,\n\t\t\tpType,\n\t\t\tsType,\n\t\t);\n\t}\n\n\t// Factory methods for Control Messages\n\t/**\n\t * @description Creates a Select Request message.\n\t * @param systemBytes The system bytes of the message.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic selectReq(systemBytes: number): HsmsMessage {\n\t\treturn new HsmsMessage(\n\t\t\t0,\n\t\t\t0,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\tsystemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.SelectReq,\n\t\t);\n\t}\n\n\t/**\n\t * @description Creates a Select Response message.\n\t * @param req The Select Request message.\n\t * @param status The status of the response.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic selectRsp(req: HsmsMessage, status: number): HsmsMessage {\n\t\treturn new HsmsMessage(\n\t\t\t0,\n\t\t\tstatus,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\treq.systemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.SelectRsp,\n\t\t);\n\t}\n\n\t/**\n\t * @description Creates a Deselect Request message.\n\t * @param systemBytes The system bytes of the message.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic deselectReq(systemBytes: number): HsmsMessage {\n\t\treturn new HsmsMessage(\n\t\t\t0,\n\t\t\t0,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\tsystemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.DeselectReq,\n\t\t);\n\t}\n\n\t/**\n\t * @description Creates a Deselect Response message.\n\t * @param req The Deselect Request message.\n\t * @param status The status of the response.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic deselectRsp(req: HsmsMessage, status: number): HsmsMessage {\n\t\treturn new HsmsMessage(\n\t\t\t0,\n\t\t\tstatus,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\treq.systemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.DeselectRsp,\n\t\t);\n\t}\n\n\t/**\n\t * @description Creates a Link Test Request message.\n\t * @param systemBytes The system bytes of the message.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic linkTestReq(systemBytes: number): HsmsMessage {\n\t\treturn new HsmsMessage(\n\t\t\t0,\n\t\t\t0,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\tsystemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.LinkTestReq,\n\t\t);\n\t}\n\n\t/**\n\t * @description Creates a Link Test Response message.\n\t * @param req The Link Test Request message.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic linkTestRsp(req: HsmsMessage): HsmsMessage {\n\t\treturn new HsmsMessage(\n\t\t\t0,\n\t\t\t0,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\treq.systemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.LinkTestRsp,\n\t\t);\n\t}\n\n\t/**\n\t * @description Creates a Reject Request message.\n\t * @param req The message that triggered the reject.\n\t * @param reason The reason for the reject.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic rejectReq(req: HsmsMessage, reason: RejectReason): HsmsMessage {\n\t\t// Byte 2 (Stream) should be the sType of the rejected message if PType is not supported\n\t\t// But typically it's just mirroring or specific logic.\n\t\t// Python: b2 = h10bytes[4] (PType) if reason == NOT_SUPPORT_TYPE_P else h10bytes[5] (SType)\n\t\tconst b2 = reason === RejectReason.NotSupportTypeP ? req.pType : req.sType;\n\t\treturn new HsmsMessage(\n\t\t\tb2,\n\t\t\treason,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\treq.systemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.RejectReq,\n\t\t);\n\t}\n\n\t/**\n\t * @description Creates a Separate Request message.\n\t * @param systemBytes The system bytes of the message.\n\t * @returns The HsmsMessage object.\n\t */\n\tstatic separateReq(systemBytes: number): HsmsMessage {\n\t\treturn new HsmsMessage(\n\t\t\t0,\n\t\t\t0,\n\t\t\tfalse,\n\t\t\tnull,\n\t\t\tsystemBytes,\n\t\t\t0xffff,\n\t\t\t0,\n\t\t\tHsmsControlType.SeparateReq,\n\t\t);\n\t}\n}\n"],"mappings":"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"}