secs4js 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -1
- package/lib/core/AbstractSecsCommunicator.d.ts.map +1 -1
- package/lib/core/AbstractSecsCommunicator.js +9 -6
- package/lib/core/AbstractSecsCommunicator.js.map +1 -1
- package/lib/hsms/HsmsCommunicator.d.ts.map +1 -1
- package/lib/hsms/HsmsCommunicator.js +1 -1
- package/lib/hsms/HsmsCommunicator.js.map +1 -1
- package/lib/logging/SecsLogger.d.ts +1 -1
- package/lib/logging/SecsLogger.d.ts.map +1 -1
- package/lib/logging/SecsLogger.js +20 -9
- package/lib/logging/SecsLogger.js.map +1 -1
- package/lib/secs1/Secs1Communicator.js +17 -17
- package/lib/secs1/Secs1Communicator.js.map +1 -1
- package/lib/secs1/Secs1OnTcpIpActiveCommunicator.js +2 -2
- package/lib/secs1/Secs1OnTcpIpActiveCommunicator.js.map +1 -1
- package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.d.ts +7 -1
- package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.d.ts.map +1 -1
- package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.js +111 -25
- package/lib/secs1/Secs1OnTcpIpPassiveCommunicator.js.map +1 -1
- package/lib/secs1/Secs1SerialCommunicator.d.ts.map +1 -1
- package/lib/secs1/Secs1SerialCommunicator.js +1 -0
- package/lib/secs1/Secs1SerialCommunicator.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -51,7 +51,22 @@ pnpm dlx tsx examples/<example_file_name>.ts
|
|
|
51
51
|
I provide a concise, clear, and efficient way to create SECS-II message types. You can use the following code to import the required items:
|
|
52
52
|
|
|
53
53
|
```ts
|
|
54
|
-
import {
|
|
54
|
+
import {
|
|
55
|
+
B,
|
|
56
|
+
BOOLEAN,
|
|
57
|
+
U1,
|
|
58
|
+
U2,
|
|
59
|
+
U4,
|
|
60
|
+
U8,
|
|
61
|
+
I1,
|
|
62
|
+
I2,
|
|
63
|
+
I4,
|
|
64
|
+
I8,
|
|
65
|
+
F4,
|
|
66
|
+
F8,
|
|
67
|
+
A,
|
|
68
|
+
L,
|
|
69
|
+
} from "secs4js";
|
|
55
70
|
```
|
|
56
71
|
|
|
57
72
|
Using these items, you can easily create SECS-II message types. For example, to create a message containing L, A, and U1 items, you can use the following code:
|
|
@@ -159,6 +174,77 @@ const parsedBody = SmlParser.parseBody(smlBody);
|
|
|
159
174
|
console.log(parsedBody?.toSml());
|
|
160
175
|
```
|
|
161
176
|
|
|
177
|
+
### 3. Extracting Data from SECS-II Messages
|
|
178
|
+
|
|
179
|
+
Data extraction is performed using array indexers, and specific values are retrieved through the `.value` property.
|
|
180
|
+
|
|
181
|
+
We implement parsing conventions that align better with user expectations. For instance, `<BOOLEAN TRUE FALSE>` is parsed into a Boolean array `[true, false]`.
|
|
182
|
+
|
|
183
|
+
For single values, we return the value directly rather than wrapping it in an array. For example, `<U1 123>` is parsed as `123`.
|
|
184
|
+
|
|
185
|
+
For detailed usage, please refer to the code example below. Note that type assertions are required for each retrieved node to ensure TypeScript type safety.
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import {
|
|
189
|
+
A,
|
|
190
|
+
L,
|
|
191
|
+
Secs2ItemAscii,
|
|
192
|
+
Secs2ItemList,
|
|
193
|
+
Secs2ItemNumeric,
|
|
194
|
+
SmlParser,
|
|
195
|
+
} from "secs4js";
|
|
196
|
+
|
|
197
|
+
function getItemValue() {
|
|
198
|
+
const body = L(A("MDLN-A"), A("SOFTREV-1"));
|
|
199
|
+
const firstA = body?.[0] as Secs2ItemAscii;
|
|
200
|
+
console.log("MDLN: ", firstA.value);
|
|
201
|
+
|
|
202
|
+
const smlBody = `
|
|
203
|
+
<L
|
|
204
|
+
<A "OK" >
|
|
205
|
+
<U1 20 >
|
|
206
|
+
<U2 1000 2000 >
|
|
207
|
+
<U4 100000000 200000000 >
|
|
208
|
+
<U8 1000000000000000 2000000000000 >
|
|
209
|
+
<I1 10 20 >
|
|
210
|
+
<I2 1000 -2000 >
|
|
211
|
+
<I4 100 >
|
|
212
|
+
<I8 -1234567890123456 9973232131213124 >
|
|
213
|
+
<F4 3.14 -6.18 >
|
|
214
|
+
<F8 1.234567890123456 6.18 >
|
|
215
|
+
<B 0x10 0x20 >
|
|
216
|
+
<Boolean TRUE FALSE >
|
|
217
|
+
<L
|
|
218
|
+
<A "Nested" >
|
|
219
|
+
<F4 3.14 >
|
|
220
|
+
<L
|
|
221
|
+
<A "More Nested">
|
|
222
|
+
<Boolean F>
|
|
223
|
+
>
|
|
224
|
+
>
|
|
225
|
+
>
|
|
226
|
+
`;
|
|
227
|
+
const smlBodySecs2Items = SmlParser.parseBody(smlBody);
|
|
228
|
+
const zeroItem = smlBodySecs2Items?.[0] as Secs2ItemAscii;
|
|
229
|
+
const firstU1 = smlBodySecs2Items?.[1] as Secs2ItemNumeric;
|
|
230
|
+
const secondItem = smlBodySecs2Items?.[2] as Secs2ItemNumeric;
|
|
231
|
+
const eighthItem = smlBodySecs2Items?.[8] as Secs2ItemNumeric;
|
|
232
|
+
const tenthItem = smlBodySecs2Items?.[10] as Secs2ItemNumeric;
|
|
233
|
+
const twelfthItem = smlBodySecs2Items?.[12] as Secs2ItemNumeric;
|
|
234
|
+
const nestedList = smlBodySecs2Items?.[13] as Secs2ItemList;
|
|
235
|
+
const nestedListFirstItem = nestedList?.[0] as Secs2ItemAscii;
|
|
236
|
+
console.log("ASCII value: ", zeroItem.value);
|
|
237
|
+
console.log("U1 value: ", firstU1.value);
|
|
238
|
+
console.log("U2 value: ", secondItem.value);
|
|
239
|
+
console.log("I8 value: ", eighthItem.value);
|
|
240
|
+
console.log("F8 value: ", tenthItem.value);
|
|
241
|
+
console.log("BOOLEAN value: ", twelfthItem.value);
|
|
242
|
+
console.log("NESTED ASCII value: ", nestedListFirstItem.value);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
getItemValue();
|
|
246
|
+
```
|
|
247
|
+
|
|
162
248
|
## Sending and Replying to Messages
|
|
163
249
|
|
|
164
250
|
In this library, you can actively send messages and passively reply to messages.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractSecsCommunicator.d.ts","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAWA;AAoBA;AAeA;;AACgB,UApCC,sBAAA,CAoCD;EAAkC,OAAA,EAAA,CAnCvC,WAmCuC,CAAA;EAChD,KAAA,EAAA,CAnCO,KAmCP,CAAA;EAK0B,SAAA,EAAA,EAAA;EAeV,YAAA,EAAA,EAAA;;;;;;;;;;;;;;;AAoEN,UAzGK,sBAAA,CAyGL;EAAR,QAAA,EAAA,MAAA;
|
|
1
|
+
{"version":3,"file":"AbstractSecsCommunicator.d.ts","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAWA;AAoBA;AAeA;;AACgB,UApCC,sBAAA,CAoCD;EAAkC,OAAA,EAAA,CAnCvC,WAmCuC,CAAA;EAChD,KAAA,EAAA,CAnCO,KAmCP,CAAA;EAK0B,SAAA,EAAA,EAAA;EAeV,YAAA,EAAA,EAAA;;;;;;;;;;;;;;;AAoEN,UAzGK,sBAAA,CAyGL;EAAR,QAAA,EAAA,MAAA;EAmEU,OAAA,EAAA,OAAA;EAGN,IAAA,CAAA,EAAA,MAAA;EACJ,GAAA,CAAA,EA5KG,gBA4KH;EA0C0B,SAAA,CAAA,EAAA,MAAA;EAxMpB,SAAA,CAAA,EAAA,MAAA;EAAY,SAAA,CAAA,EAAA,MAAA;;;;;;;uBAHA,wCACN,aAAa,qBAAqB,yBAChD,gCACQ,YAAA;;;;6BAIkB;;;;;;;;;;2BAYJ;mBAGN;kBACD;WACP,MAAA,CAAO;;sBAII;mBAoBH;oBACC;;wCAgBoB,SAAS;yFAKtC,eACD,0BACL;sFASI,gDAEJ;2DAMI,2BACJ,QAAQ;oBAmEE,kDAGN,2BACJ;;+BA0C0B"}
|
|
@@ -47,7 +47,8 @@ var AbstractSecsCommunicator = class extends EventEmitter {
|
|
|
47
47
|
const systemBytes = this.getNextSystemBytes();
|
|
48
48
|
const msg = this.createMessage(stream, func, wBit, body, systemBytes);
|
|
49
49
|
const sml = msg.toSml();
|
|
50
|
-
|
|
50
|
+
const buffer = msg.toBuffer();
|
|
51
|
+
this.logger.logSecs2("Sent", sml, this.deviceId, systemBytes, buffer);
|
|
51
52
|
this.logger.detail.debug({
|
|
52
53
|
protocol: "SECS",
|
|
53
54
|
dir: "Sent",
|
|
@@ -69,7 +70,7 @@ var AbstractSecsCommunicator = class extends EventEmitter {
|
|
|
69
70
|
reject,
|
|
70
71
|
timer
|
|
71
72
|
});
|
|
72
|
-
this.sendBufferWithLogs("Sent", "SECS",
|
|
73
|
+
this.sendBufferWithLogs("Sent", "SECS", buffer, {
|
|
73
74
|
stream,
|
|
74
75
|
func,
|
|
75
76
|
wBit,
|
|
@@ -88,7 +89,7 @@ var AbstractSecsCommunicator = class extends EventEmitter {
|
|
|
88
89
|
});
|
|
89
90
|
});
|
|
90
91
|
else {
|
|
91
|
-
await this.sendBufferWithLogs("Sent", "SECS",
|
|
92
|
+
await this.sendBufferWithLogs("Sent", "SECS", buffer, {
|
|
92
93
|
stream,
|
|
93
94
|
func,
|
|
94
95
|
wBit,
|
|
@@ -100,7 +101,8 @@ var AbstractSecsCommunicator = class extends EventEmitter {
|
|
|
100
101
|
async reply(primaryMsg, stream, func, body = null) {
|
|
101
102
|
const msg = this.createMessage(stream, func, false, body, primaryMsg.systemBytes);
|
|
102
103
|
const sml = msg.toSml();
|
|
103
|
-
|
|
104
|
+
const buffer = msg.toBuffer();
|
|
105
|
+
this.logger.logSecs2("Sent", sml, this.deviceId, primaryMsg.systemBytes, buffer);
|
|
104
106
|
this.logger.detail.debug({
|
|
105
107
|
protocol: "SECS",
|
|
106
108
|
dir: "Sent",
|
|
@@ -110,7 +112,7 @@ var AbstractSecsCommunicator = class extends EventEmitter {
|
|
|
110
112
|
systemBytes: primaryMsg.systemBytes,
|
|
111
113
|
sml
|
|
112
114
|
}, "sml");
|
|
113
|
-
await this.sendBufferWithLogs("Sent", "SECS",
|
|
115
|
+
await this.sendBufferWithLogs("Sent", "SECS", buffer, {
|
|
114
116
|
stream,
|
|
115
117
|
func,
|
|
116
118
|
wBit: false,
|
|
@@ -123,7 +125,8 @@ var AbstractSecsCommunicator = class extends EventEmitter {
|
|
|
123
125
|
}
|
|
124
126
|
handleMessage(msg) {
|
|
125
127
|
const sml = msg.toSml();
|
|
126
|
-
|
|
128
|
+
const buffer = msg.toBuffer();
|
|
129
|
+
this.logger.logSecs2("Received", sml, this.deviceId, msg.systemBytes, buffer);
|
|
127
130
|
this.logger.detail.debug({
|
|
128
131
|
protocol: "SECS",
|
|
129
132
|
dir: "Received",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractSecsCommunicator.js","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\nimport { SecsMessage } from \"./AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"./secs2item/AbstractSecs2Item.js\";\nimport { SecsLogger, type SecsLoggerConfig } from \"../logging/SecsLogger.js\";\n\n/**\n * @param message The message received.\n * @param error The error occurred.\n * @param connected The connection is established.\n * @param disconnected The connection is closed.\n */\nexport interface SecsCommunicatorEvents {\n\tmessage: [SecsMessage];\n\terror: [Error];\n\tconnected: [];\n\tdisconnected: [];\n}\n\n/**\n * @param deviceId The device ID.\n * @param isEquip Whether the device is an equip.\n * @param name The name of the connection.\n * @param timeoutT1 Only SECS-I supports this parameter, ENQ retransmission interval.\n * @param timeoutT2 Only SECS-I supports this parameter, ENQ wait-for-response timeout.\n * @param timeoutT3 Support SECS-I and SECS-II, W-Bit timeout.\n * @param timeoutT4 Only SECS-I supports this parameter, data block retransmission interval.\n * @param timeoutT5 Support SECS-I and SECS-II, establishment of communication session timeout.\n * @param timeoutT6 Only HSMS supports this parameter, reply control message timeout.\n * @param timeoutT7 Only HSMS supports this parameter, create connection timeout.\n * @param timeoutT8 Only HSMS supports this parameter, the maximum time interval between message bytes when receiving a message\n */\nexport interface SecsCommunicatorConfig {\n\tdeviceId: number;\n\tisEquip: boolean;\n\tname?: string;\n\tlog?: SecsLoggerConfig;\n\ttimeoutT1?: number;\n\ttimeoutT2?: number;\n\ttimeoutT3?: number;\n\ttimeoutT4?: number;\n\ttimeoutT5?: number;\n\ttimeoutT6?: number;\n\ttimeoutT7?: number;\n\ttimeoutT8?: number;\n}\n\nexport abstract class AbstractSecsCommunicator<\n\tEvents extends Record<keyof Events, unknown[]> & SecsCommunicatorEvents =\n\t\tSecsCommunicatorEvents,\n> extends EventEmitter {\n\tpublic readonly deviceId: number;\n\tpublic readonly isEquip: boolean;\n\tpublic readonly name: string;\n\tprotected readonly logger: SecsLogger;\n\n\tpublic timeoutT1 = 1;\n\tpublic timeoutT2 = 15;\n\tpublic timeoutT3 = 45;\n\tpublic timeoutT4 = 45;\n\tpublic timeoutT5 = 10;\n\tpublic timeoutT6 = 5;\n\tpublic timeoutT7 = 10;\n\tpublic timeoutT8 = 5;\n\n\tprotected _systemBytesCounter = 0;\n\tprotected _transactions = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tresolve: (msg: SecsMessage) => void;\n\t\t\treject: (err: Error) => void;\n\t\t\ttimer: NodeJS.Timeout;\n\t\t}\n\t>();\n\n\tconstructor(config: SecsCommunicatorConfig) {\n\t\tsuper();\n\t\tthis.deviceId = config.deviceId;\n\t\tthis.isEquip = config.isEquip;\n\t\tthis.name = config.name ?? \"SecsCommunicator\";\n\t\tif (config.timeoutT1 !== undefined) this.timeoutT1 = config.timeoutT1;\n\t\tif (config.timeoutT2 !== undefined) this.timeoutT2 = config.timeoutT2;\n\t\tif (config.timeoutT3 !== undefined) this.timeoutT3 = config.timeoutT3;\n\t\tif (config.timeoutT4 !== undefined) this.timeoutT4 = config.timeoutT4;\n\t\tif (config.timeoutT5 !== undefined) this.timeoutT5 = config.timeoutT5;\n\t\tif (config.timeoutT6 !== undefined) this.timeoutT6 = config.timeoutT6;\n\t\tif (config.timeoutT7 !== undefined) this.timeoutT7 = config.timeoutT7;\n\t\tif (config.timeoutT8 !== undefined) this.timeoutT8 = config.timeoutT8;\n\t\tthis.logger = SecsLogger.create(config.log, {\n\t\t\tname: this.name,\n\t\t\tdeviceId: this.deviceId,\n\t\t\tisEquip: this.isEquip,\n\t\t});\n\t}\n\n\tabstract open(): Promise<void>;\n\tabstract close(): Promise<void>;\n\n\tprotected emitInternal(\n\t\teventName: string | symbol,\n\t\t...args: unknown[]\n\t): boolean {\n\t\treturn (\n\t\t\tsuper.emit as (\n\t\t\t\tthis: AbstractSecsCommunicator<Events>,\n\t\t\t\teventName: string | symbol,\n\t\t\t\t...args: unknown[]\n\t\t\t) => boolean\n\t\t).call(this, eventName, ...args);\n\t}\n\n\t// This method sends the message bytes. To be implemented by subclasses.\n\tprotected abstract sendBuffer(buffer: Buffer): Promise<void>;\n\n\tprotected async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tthis.logger.logBytes(direction, protocol, buffer, meta);\n\t\tawait this.sendBuffer(buffer);\n\t}\n\n\tprotected abstract 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\n\tasync 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\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = this.createMessage(stream, func, wBit, body, systemBytes);\n\t\tconst sml = msg.toSml();\n\t\tthis.logger.logSecs2(\"Sent\", sml);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\n\t\tif (wBit) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst timer = setTimeout(() => {\n\t\t\t\t\tif (this._transactions.has(systemBytes)) {\n\t\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`T3 Timeout waiting for reply to S${String(stream)}F${String(func)} [SysBytes=${String(systemBytes)}]`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}, this.timeoutT3 * 1000);\n\n\t\t\t\tthis._transactions.set(systemBytes, { resolve, reject, timer });\n\n\t\t\t\tthis.sendBufferWithLogs(\"Sent\", \"SECS\", msg.toBuffer(), {\n\t\t\t\t\tstream,\n\t\t\t\t\tfunc,\n\t\t\t\t\twBit,\n\t\t\t\t\tsystemBytes,\n\t\t\t\t}).catch((err: unknown) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\tthis.logger.detail.error(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terr: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\t\t\tstream,\n\t\t\t\t\t\t\tfunc,\n\t\t\t\t\t\t\twBit,\n\t\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"send failed\",\n\t\t\t\t\t);\n\t\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", msg.toBuffer(), {\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync reply(\n\t\tprimaryMsg: SecsMessage,\n\t\tstream: number,\n\t\tfunc: number,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<void> {\n\t\tconst msg = this.createMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\tfalse,\n\t\t\tbody,\n\t\t\tprimaryMsg.systemBytes,\n\t\t);\n\t\tconst sml = msg.toSml();\n\t\tthis.logger.logSecs2(\"Sent\", sml);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit: false,\n\t\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", msg.toBuffer(), {\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit: false,\n\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t});\n\t}\n\n\tprotected getNextSystemBytes(): number {\n\t\tthis._systemBytesCounter = (this._systemBytesCounter + 1) >>> 0; // Ensure 32-bit unsigned\n\t\treturn this._systemBytesCounter;\n\t}\n\n\tprotected handleMessage(msg: SecsMessage) {\n\t\tconst sml = msg.toSml();\n\t\tthis.logger.logSecs2(\"Received\", sml);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Received\",\n\t\t\t\tstream: msg.stream,\n\t\t\t\tfunc: msg.func,\n\t\t\t\twBit: msg.wBit,\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"message\",\n\t\t);\n\t\t// Check if it's a reply\n\t\t// Usually, if we have a transaction waiting for this SystemBytes, we treat it as a reply.\n\t\t// However, Stream 0 (HSMS Control) messages are never replies to SECS-II messages.\n\t\t// SECS-II replies usually have the same SystemBytes as the primary.\n\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\treturn;\n\t\t}\n\n\t\t// If not a reply, emit event\n\t\tthis.emitInternal(\"message\", msg);\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AbstractSecsCommunicator.js","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\nimport { SecsMessage } from \"./AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"./secs2item/AbstractSecs2Item.js\";\nimport { SecsLogger, type SecsLoggerConfig } from \"../logging/SecsLogger.js\";\n\n/**\n * @param message The message received.\n * @param error The error occurred.\n * @param connected The connection is established.\n * @param disconnected The connection is closed.\n */\nexport interface SecsCommunicatorEvents {\n\tmessage: [SecsMessage];\n\terror: [Error];\n\tconnected: [];\n\tdisconnected: [];\n}\n\n/**\n * @param deviceId The device ID.\n * @param isEquip Whether the device is an equip.\n * @param name The name of the connection.\n * @param timeoutT1 Only SECS-I supports this parameter, ENQ retransmission interval.\n * @param timeoutT2 Only SECS-I supports this parameter, ENQ wait-for-response timeout.\n * @param timeoutT3 Support SECS-I and SECS-II, W-Bit timeout.\n * @param timeoutT4 Only SECS-I supports this parameter, data block retransmission interval.\n * @param timeoutT5 Support SECS-I and SECS-II, establishment of communication session timeout.\n * @param timeoutT6 Only HSMS supports this parameter, reply control message timeout.\n * @param timeoutT7 Only HSMS supports this parameter, create connection timeout.\n * @param timeoutT8 Only HSMS supports this parameter, the maximum time interval between message bytes when receiving a message\n */\nexport interface SecsCommunicatorConfig {\n\tdeviceId: number;\n\tisEquip: boolean;\n\tname?: string;\n\tlog?: SecsLoggerConfig;\n\ttimeoutT1?: number;\n\ttimeoutT2?: number;\n\ttimeoutT3?: number;\n\ttimeoutT4?: number;\n\ttimeoutT5?: number;\n\ttimeoutT6?: number;\n\ttimeoutT7?: number;\n\ttimeoutT8?: number;\n}\n\nexport abstract class AbstractSecsCommunicator<\n\tEvents extends Record<keyof Events, unknown[]> & SecsCommunicatorEvents =\n\t\tSecsCommunicatorEvents,\n> extends EventEmitter {\n\tpublic readonly deviceId: number;\n\tpublic readonly isEquip: boolean;\n\tpublic readonly name: string;\n\tprotected readonly logger: SecsLogger;\n\n\tpublic timeoutT1 = 1;\n\tpublic timeoutT2 = 15;\n\tpublic timeoutT3 = 45;\n\tpublic timeoutT4 = 45;\n\tpublic timeoutT5 = 10;\n\tpublic timeoutT6 = 5;\n\tpublic timeoutT7 = 10;\n\tpublic timeoutT8 = 5;\n\n\tprotected _systemBytesCounter = 0;\n\tprotected _transactions = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tresolve: (msg: SecsMessage) => void;\n\t\t\treject: (err: Error) => void;\n\t\t\ttimer: NodeJS.Timeout;\n\t\t}\n\t>();\n\n\tconstructor(config: SecsCommunicatorConfig) {\n\t\tsuper();\n\t\tthis.deviceId = config.deviceId;\n\t\tthis.isEquip = config.isEquip;\n\t\tthis.name = config.name ?? \"SecsCommunicator\";\n\t\tif (config.timeoutT1 !== undefined) this.timeoutT1 = config.timeoutT1;\n\t\tif (config.timeoutT2 !== undefined) this.timeoutT2 = config.timeoutT2;\n\t\tif (config.timeoutT3 !== undefined) this.timeoutT3 = config.timeoutT3;\n\t\tif (config.timeoutT4 !== undefined) this.timeoutT4 = config.timeoutT4;\n\t\tif (config.timeoutT5 !== undefined) this.timeoutT5 = config.timeoutT5;\n\t\tif (config.timeoutT6 !== undefined) this.timeoutT6 = config.timeoutT6;\n\t\tif (config.timeoutT7 !== undefined) this.timeoutT7 = config.timeoutT7;\n\t\tif (config.timeoutT8 !== undefined) this.timeoutT8 = config.timeoutT8;\n\t\tthis.logger = SecsLogger.create(config.log, {\n\t\t\tname: this.name,\n\t\t\tdeviceId: this.deviceId,\n\t\t\tisEquip: this.isEquip,\n\t\t});\n\t}\n\n\tabstract open(): Promise<void>;\n\tabstract close(): Promise<void>;\n\n\tprotected emitInternal(\n\t\teventName: string | symbol,\n\t\t...args: unknown[]\n\t): boolean {\n\t\treturn (\n\t\t\tsuper.emit as (\n\t\t\t\tthis: AbstractSecsCommunicator<Events>,\n\t\t\t\teventName: string | symbol,\n\t\t\t\t...args: unknown[]\n\t\t\t) => boolean\n\t\t).call(this, eventName, ...args);\n\t}\n\n\t// This method sends the message bytes. To be implemented by subclasses.\n\tprotected abstract sendBuffer(buffer: Buffer): Promise<void>;\n\n\tprotected async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tthis.logger.logBytes(direction, protocol, buffer, meta);\n\t\tawait this.sendBuffer(buffer);\n\t}\n\n\tprotected abstract 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\n\tasync 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\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = this.createMessage(stream, func, wBit, body, systemBytes);\n\t\tconst sml = msg.toSml();\n\t\tconst buffer = msg.toBuffer();\n\t\tthis.logger.logSecs2(\"Sent\", sml, this.deviceId, systemBytes, buffer);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\n\t\tif (wBit) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst timer = setTimeout(() => {\n\t\t\t\t\tif (this._transactions.has(systemBytes)) {\n\t\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`T3 Timeout waiting for reply to S${String(stream)}F${String(func)} [SysBytes=${String(systemBytes)}]`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}, this.timeoutT3 * 1000);\n\n\t\t\t\tthis._transactions.set(systemBytes, { resolve, reject, timer });\n\n\t\t\t\tthis.sendBufferWithLogs(\"Sent\", \"SECS\", buffer, {\n\t\t\t\t\tstream,\n\t\t\t\t\tfunc,\n\t\t\t\t\twBit,\n\t\t\t\t\tsystemBytes,\n\t\t\t\t}).catch((err: unknown) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\tthis.logger.detail.error(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terr: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\t\t\tstream,\n\t\t\t\t\t\t\tfunc,\n\t\t\t\t\t\t\twBit,\n\t\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"send failed\",\n\t\t\t\t\t);\n\t\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", buffer, {\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync reply(\n\t\tprimaryMsg: SecsMessage,\n\t\tstream: number,\n\t\tfunc: number,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<void> {\n\t\tconst msg = this.createMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\tfalse,\n\t\t\tbody,\n\t\t\tprimaryMsg.systemBytes,\n\t\t);\n\t\tconst sml = msg.toSml();\n\t\tconst buffer = msg.toBuffer();\n\t\tthis.logger.logSecs2(\n\t\t\t\"Sent\",\n\t\t\tsml,\n\t\t\tthis.deviceId,\n\t\t\tprimaryMsg.systemBytes,\n\t\t\tbuffer,\n\t\t);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit: false,\n\t\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", buffer, {\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit: false,\n\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t});\n\t}\n\n\tprotected getNextSystemBytes(): number {\n\t\tthis._systemBytesCounter = (this._systemBytesCounter + 1) >>> 0; // Ensure 32-bit unsigned\n\t\treturn this._systemBytesCounter;\n\t}\n\n\tprotected handleMessage(msg: SecsMessage) {\n\t\tconst sml = msg.toSml();\n\t\tconst buffer = msg.toBuffer();\n\t\tthis.logger.logSecs2(\n\t\t\t\"Received\",\n\t\t\tsml,\n\t\t\tthis.deviceId,\n\t\t\tmsg.systemBytes,\n\t\t\tbuffer,\n\t\t);\n\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Received\",\n\t\t\t\tstream: msg.stream,\n\t\t\t\tfunc: msg.func,\n\t\t\t\twBit: msg.wBit,\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"message\",\n\t\t);\n\t\t// Check if it's a reply\n\t\t// Usually, if we have a transaction waiting for this SystemBytes, we treat it as a reply.\n\t\t// However, Stream 0 (HSMS Control) messages are never replies to SECS-II messages.\n\t\t// SECS-II replies usually have the same SystemBytes as the primary.\n\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\treturn;\n\t\t}\n\n\t\t// If not a reply, emit event\n\t\tthis.emitInternal(\"message\", msg);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HsmsCommunicator.d.ts","names":[],"sources":["../../src/hsms/HsmsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;aAaY,SAAA;;EAAA,SAAA,GAAS,WAAA;EAAA;EAYJ,QAAA,GAAA,UAAA;AAMjB;AAKA;;;;;;AA0BU,UArCO,sBAAA,SAA+B,sBAqCtC,CAAA;EACD,EAAA,EAAA,MAAA;EACL,IAAA,EAAA,MAAA;EAYgC,gBAAA,CAAA,EAAA,MAAA;;AAiB5B,UA9DS,sBAAA,SAA+B,sBA8DxC,CAAA;EAEJ,QAAA,EAAA,EAAA;EAckC,UAAA,EAAA,EAAA;;
|
|
1
|
+
{"version":3,"file":"HsmsCommunicator.d.ts","names":[],"sources":["../../src/hsms/HsmsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;aAaY,SAAA;;EAAA,SAAA,GAAS,WAAA;EAAA;EAYJ,QAAA,GAAA,UAAA;AAMjB;AAKA;;;;;;AA0BU,UArCO,sBAAA,SAA+B,sBAqCtC,CAAA;EACD,EAAA,EAAA,MAAA;EACL,IAAA,EAAA,MAAA;EAYgC,gBAAA,CAAA,EAAA,MAAA;;AAiB5B,UA9DS,sBAAA,SAA+B,sBA8DxC,CAAA;EAEJ,QAAA,EAAA,EAAA;EAckC,UAAA,EAAA,EAAA;;AAgON,uBAzSV,gBAAA,SAAyB,wBAySf,CAzSwC,sBAySxC,CAAA,CAAA;EA0BE,EAAA,EAAA,MAAA;EAIA,IAAA,EAAA,MAAA;EAWA,UAAA,MAAA,EA9Uf,MA8Ue,GAAA,IAAA;EAcA,UAAA,KAAA,EA3VhB,SA2VgB;EAoBC,QAAA,MAAA;EAYC,QAAA,OAAA;EAA2B,QAAA,OAAA;EASzB,IAAA,eAAA,CAAA,CAAA,EA5XP,SA4XO;EAA2B,WAAA,CAAA,MAAA,EAxX5C,sBAwX4C;EAS3B,UAAA,kBAAA,CAAA,SAAA,EAAA,MAAA,GAAA,UAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,EAxX5B,MAwX4B,EAAA,IAAA,CAAA,EAvX7B,MAuX6B,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,EAtXlC,OAsXkC,CAAA,IAAA,CAAA;EAAW,UAAA,UAAA,CAAA,MAAA,EA1Wb,MA0Wa,CAAA,EA1WJ,OA0WI,CAAA,IAAA,CAAA;EAQhB,UAAA,aAAA,CAAA,MAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,OAAA,EAAA,IAAA,EAjWzB,iBAiWyB,GAAA,IAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EA/V7B,WA+V6B;EAAqB,UAAA,kBAAA,CAAA,MAAA,EAjVhB,MAiVgB,CAAA,EAAA,IAAA;EAAY,QAAA,YAAA;EAa1D,QAAA,YAAA;EACI,QAAA,YAAA;EAAR,QAAA,YAAA;EAQmC,QAAA,aAAA;EAAR,QAAA,kBAAA;EA+BE,QAAA,oBAAA;EA+BA,UAAA,eAAA,CAAA,GAAA,EAxND,WAwNC,CAAA,EAAA,IAAA;EA9ec,UAAA,eAAA,CAAA,GAAA,EAySf,WAzSe,CAAA,EAAA,IAAA;EAAwB,UAAA,iBAAA,CAAA,GAAA,EAmUrC,WAnUqC,CAAA,EAAA,IAAA;mCAuUrC;mCAWA;mCAcA;oCAoBC;+BAYC,8BAA2B;iCASzB,8BAA2B;iCAS3B,cAAW;4BAQhB,qBAAqB,eAAY;2DAa1D,2BACJ,QAAQ;mBAQmB,QAAQ;qBA+BN;qBA+BA"}
|
|
@@ -163,7 +163,7 @@ var HsmsCommunicator = class extends AbstractSecsCommunicator {
|
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
165
|
if (this.state !== HsmsState.Selected) {
|
|
166
|
-
this.logger.logSecs2("Received", msg.toSml());
|
|
166
|
+
this.logger.logSecs2("Received", msg.toSml(), this.deviceId, msg.systemBytes, msg.toBuffer());
|
|
167
167
|
this.sendReject(msg, RejectReason.NotSelected);
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
@@ -1 +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 override async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tawait super.sendBufferWithLogs(\n\t\t\tdirection,\n\t\t\tprotocol === \"SECS\" ? \"HSMS\" : protocol,\n\t\t\tbuffer,\n\t\t\t{\n\t\t\t\thsmsState: this.state,\n\t\t\t\t...meta,\n\t\t\t},\n\t\t);\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\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, {\n\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\tremotePort: socket.remotePort,\n\t\t});\n\t\tthis.resetT7Timer();\n\t\tthis.emit(\"connected\");\n\n\t\tsocket.on(\"data\", (data) => {\n\t\t\tthis.logger.logBytes(\"Received\", \"HSMS\", data, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t\tchunkLength: data.length,\n\t\t\t});\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\tconst prevState = this.state;\n\t\t\tthis.state = HsmsState.NotConnected;\n\t\t\tthis.logger.logState(\"HSMS\", prevState, this.state, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t});\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\tthis.logger.logBytes(\"Received\", \"HSMS\", msgBuffer, {\n\t\t\t\t\tframeLength: length,\n\t\t\t\t});\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.logger.detail.debug(\n\t\t\t\t{\n\t\t\t\t\tprotocol: \"HSMS\",\n\t\t\t\t\tcontrolType: msg.sType,\n\t\t\t\t\tpType: msg.pType,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\t},\n\t\t\t\t\"control\",\n\t\t\t);\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\tthis.logger.logSecs2(\"Received\", msg.toSml());\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.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\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.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\t\tselectStatus: status,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\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.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\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.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\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\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state);\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.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SelectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendDeselectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.deselectRsp(req, status);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.DeselectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendLinkTestRsp(req: HsmsMessage) {\n\t\tconst rsp = HsmsMessage.linkTestRsp(req);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.LinkTestRsp,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendReject(req: HsmsMessage, reason: RejectReason) {\n\t\tconst rsp = HsmsMessage.rejectReq(req, reason);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.RejectReq,\n\t\t\treason,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\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.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.SelectReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).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.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.LinkTestReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).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.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SeparateReq,\n\t\t\tsystemBytes,\n\t\t});\n\t\tconst socket = this.socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, { systemBytes });\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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"}
|
|
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 override async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tawait super.sendBufferWithLogs(\n\t\t\tdirection,\n\t\t\tprotocol === \"SECS\" ? \"HSMS\" : protocol,\n\t\t\tbuffer,\n\t\t\t{\n\t\t\t\thsmsState: this.state,\n\t\t\t\t...meta,\n\t\t\t},\n\t\t);\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\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, {\n\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\tremotePort: socket.remotePort,\n\t\t});\n\t\tthis.resetT7Timer();\n\t\tthis.emit(\"connected\");\n\n\t\tsocket.on(\"data\", (data) => {\n\t\t\tthis.logger.logBytes(\"Received\", \"HSMS\", data, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t\tchunkLength: data.length,\n\t\t\t});\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\tconst prevState = this.state;\n\t\t\tthis.state = HsmsState.NotConnected;\n\t\t\tthis.logger.logState(\"HSMS\", prevState, this.state, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t});\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\tthis.logger.logBytes(\"Received\", \"HSMS\", msgBuffer, {\n\t\t\t\t\tframeLength: length,\n\t\t\t\t});\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.logger.detail.debug(\n\t\t\t\t{\n\t\t\t\t\tprotocol: \"HSMS\",\n\t\t\t\t\tcontrolType: msg.sType,\n\t\t\t\t\tpType: msg.pType,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\t},\n\t\t\t\t\"control\",\n\t\t\t);\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\tthis.logger.logSecs2(\n\t\t\t\t\"Received\",\n\t\t\t\tmsg.toSml(),\n\t\t\t\tthis.deviceId,\n\t\t\t\tmsg.systemBytes,\n\t\t\t\tmsg.toBuffer(),\n\t\t\t);\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.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\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.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\t\tselectStatus: status,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\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.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\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.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\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\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state);\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.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SelectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendDeselectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.deselectRsp(req, status);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.DeselectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendLinkTestRsp(req: HsmsMessage) {\n\t\tconst rsp = HsmsMessage.linkTestRsp(req);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.LinkTestRsp,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendReject(req: HsmsMessage, reason: RejectReason) {\n\t\tconst rsp = HsmsMessage.rejectReq(req, reason);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.RejectReq,\n\t\t\treason,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\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.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.SelectReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).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.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.LinkTestReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).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.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SeparateReq,\n\t\t\tsystemBytes,\n\t\t});\n\t\tconst socket = this.socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, { systemBytes });\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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"}
|
|
@@ -26,7 +26,7 @@ declare class SecsLogger {
|
|
|
26
26
|
private readonly secs2Stream;
|
|
27
27
|
private readonly maxHexBytes;
|
|
28
28
|
private constructor();
|
|
29
|
-
logSecs2(direction: SecsLogDirection, sml: string): void;
|
|
29
|
+
logSecs2(direction: SecsLogDirection, sml: string, deviceId: number, systemBytes: number, buffer?: Buffer): void;
|
|
30
30
|
logBytes(direction: SecsLogDirection, protocol: string, buffer: Buffer, meta?: Record<string, unknown>): void;
|
|
31
31
|
logState(protocol: string, prev: string, next: string, meta?: Record<string, unknown>): void;
|
|
32
32
|
close(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecsLogger.d.ts","names":[],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":[],"mappings":";;;KAKY,gBAAA;UAEK,gBAAA;EAFL,OAAA,CAAA,EAAA,OAAA;EAEK,OAAA,CAAA,EAAA,OAAA;EAUA,OAAA,CAAA,EAAA,MAAA;
|
|
1
|
+
{"version":3,"file":"SecsLogger.d.ts","names":[],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":[],"mappings":";;;KAKY,gBAAA;UAEK,gBAAA;EAFL,OAAA,CAAA,EAAA,OAAA;EAEK,OAAA,CAAA,EAAA,OAAA;EAUA,OAAA,CAAA,EAAA,MAAA;EA6bJ,aAAU,CAAA,EAAA,MAAA;EACH,WAAA,CAAA,EAncL,eAmcK;EAKV,UAAA,CAAA,EAvcI,eAucJ;EACH,WAAA,CAAA,EAAA,MAAA;;AAiFkB,UArhBR,iBAAA,CAqhBQ;EAwBZ,IAAA,EAAA,MAAA;EAIF,QAAA,EAAA,MAAA;EAeE,OAAA,EAAA,OAAA;;AAGJ,cAtII,UAAA,CAsIJ;EAkBA,OAAA,QAAA,CAAA,CAAA,EAvJW,UAuJX;EAAM,OAAA,MAAA,CAAA,MAAA,EAlJL,gBAkJK,GAAA,SAAA,EAAA,GAAA,EAjJR,iBAiJQ,CAAA,EAhJX,UAgJW;mBAhEU;;;;;;;sBAwBZ,+EAIF;sBAeE,4CAEH,eACD;gEAkBA"}
|
|
@@ -277,6 +277,8 @@ var Secs2LineTransformStream = class extends Writable {
|
|
|
277
277
|
const timeValue = rec.time;
|
|
278
278
|
const dirValue = rec.dir;
|
|
279
279
|
const smlValue = rec.sml;
|
|
280
|
+
const deviceIdValue = rec.deviceId;
|
|
281
|
+
const systemBytesValue = rec.systemBytes;
|
|
280
282
|
const dir = dirValue === "Sent" || dirValue === "Received" ? dirValue : null;
|
|
281
283
|
const sml = typeof smlValue === "string" ? smlValue : null;
|
|
282
284
|
if (!dir || !sml) return;
|
|
@@ -284,7 +286,9 @@ var Secs2LineTransformStream = class extends Writable {
|
|
|
284
286
|
if (typeof timeValue === "number") date = new Date(timeValue);
|
|
285
287
|
else if (typeof timeValue === "string") date = new Date(timeValue);
|
|
286
288
|
else date = /* @__PURE__ */ new Date();
|
|
287
|
-
const
|
|
289
|
+
const deviceId = typeof deviceIdValue === "number" ? deviceIdValue : 0;
|
|
290
|
+
const systemBytes = typeof systemBytesValue === "number" ? systemBytesValue : 0;
|
|
291
|
+
const out = `${formatDateTime(date)} ${dir} DeviceID: ${deviceId} SystemBytes: ${systemBytes} \n${normalizeSmlForSingleLine(sml)}\n`;
|
|
288
292
|
this.target.write(out);
|
|
289
293
|
}
|
|
290
294
|
};
|
|
@@ -328,12 +332,14 @@ var SecsLogger = class SecsLogger {
|
|
|
328
332
|
deviceId: ctx.deviceId,
|
|
329
333
|
isEquip: ctx.isEquip
|
|
330
334
|
};
|
|
331
|
-
const
|
|
335
|
+
const detailPrettyStream = new PrettyPrintTransformStream();
|
|
336
|
+
detailPrettyStream.pipe(detailStream);
|
|
337
|
+
const detailStreams = [{ stream: detailPrettyStream }];
|
|
332
338
|
if (consoleEnabled) {
|
|
333
|
-
const
|
|
334
|
-
|
|
339
|
+
const consolePrettyStream = new PrettyPrintTransformStream();
|
|
340
|
+
consolePrettyStream.pipe(process.stdout);
|
|
335
341
|
detailStreams.push({
|
|
336
|
-
stream:
|
|
342
|
+
stream: consolePrettyStream,
|
|
337
343
|
level: detailLevel
|
|
338
344
|
});
|
|
339
345
|
}
|
|
@@ -341,14 +347,16 @@ var SecsLogger = class SecsLogger {
|
|
|
341
347
|
level: detailLevel,
|
|
342
348
|
base: bindings
|
|
343
349
|
}, pino.multistream(detailStreams));
|
|
344
|
-
const
|
|
350
|
+
const secs2ToDetailPrettyStream = new PrettyPrintTransformStream();
|
|
351
|
+
secs2ToDetailPrettyStream.pipe(detailStream);
|
|
352
|
+
const secs2Streams = [{ stream: secs2Stream }, { stream: secs2ToDetailPrettyStream }];
|
|
345
353
|
if (consoleEnabled) secs2Streams.push({
|
|
346
354
|
stream: process.stdout,
|
|
347
355
|
level: secs2Level
|
|
348
356
|
});
|
|
349
357
|
const secs2 = pino({
|
|
350
358
|
level: secs2Level,
|
|
351
|
-
base:
|
|
359
|
+
base: bindings,
|
|
352
360
|
messageKey: "msg"
|
|
353
361
|
}, pino.multistream(secs2Streams));
|
|
354
362
|
return new SecsLogger({
|
|
@@ -378,10 +386,13 @@ var SecsLogger = class SecsLogger {
|
|
|
378
386
|
this.secs2Stream = params.secs2Stream;
|
|
379
387
|
this.maxHexBytes = params.config.maxHexBytes ?? 64 * 1024;
|
|
380
388
|
}
|
|
381
|
-
logSecs2(direction, sml) {
|
|
389
|
+
logSecs2(direction, sml, deviceId, systemBytes, buffer) {
|
|
382
390
|
this.secs2.info({
|
|
383
391
|
dir: direction,
|
|
384
|
-
sml: normalizeSmlForSingleLine(sml)
|
|
392
|
+
sml: normalizeSmlForSingleLine(sml),
|
|
393
|
+
deviceId,
|
|
394
|
+
systemBytes,
|
|
395
|
+
hex: buffer ? bufferToHex(buffer, this.maxHexBytes) : void 0
|
|
385
396
|
}, "");
|
|
386
397
|
}
|
|
387
398
|
logBytes(direction, protocol, buffer, meta) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecsLogger.js","names":["parts: string[]","pairs: string[]","entries: fs.Dirent[]","obj: unknown","date: Date","detailStreams: pino.StreamEntry[]","secs2Streams: pino.StreamEntry[]"],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { Writable, Transform } from \"stream\";\nimport pino, { type LevelWithSilent, type Logger } from \"pino\";\n\nexport type SecsLogDirection = \"Received\" | \"Sent\";\n\nexport interface SecsLoggerConfig {\n\tenabled?: boolean;\n\tconsole?: boolean;\n\tbaseDir?: string;\n\tretentionDays?: number;\n\tdetailLevel?: LevelWithSilent;\n\tsecs2Level?: LevelWithSilent;\n\tmaxHexBytes?: number;\n}\n\nexport interface SecsLoggerContext {\n\tname: string;\n\tdeviceId: number;\n\tisEquip: boolean;\n}\n\nfunction formatDate(date: Date): string {\n\tconst y = date.getFullYear();\n\tconst m = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst d = String(date.getDate()).padStart(2, \"0\");\n\treturn `${String(y)}-${m}-${d}`;\n}\n\nfunction formatDateTime(date: Date): string {\n\tconst ymd = formatDate(date);\n\tconst hh = String(date.getHours()).padStart(2, \"0\");\n\tconst mm = String(date.getMinutes()).padStart(2, \"0\");\n\tconst ss = String(date.getSeconds()).padStart(2, \"0\");\n\tconst ms = String(date.getMilliseconds()).padStart(3, \"0\");\n\treturn `${ymd} ${hh}:${mm}:${ss}.${ms}`;\n}\n\nfunction tryParseYmdDirName(dirName: string): Date | null {\n\tconst m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(dirName);\n\tif (!m) return null;\n\tconst year = Number(m[1]);\n\tconst month = Number(m[2]);\n\tconst day = Number(m[3]);\n\tif (\n\t\t!Number.isFinite(year) ||\n\t\t!Number.isFinite(month) ||\n\t\t!Number.isFinite(day)\n\t)\n\t\treturn null;\n\tconst dt = new Date(year, month - 1, day);\n\tif (dt.getFullYear() !== year) return null;\n\tif (dt.getMonth() !== month - 1) return null;\n\tif (dt.getDate() !== day) return null;\n\treturn dt;\n}\n\nfunction normalizeSmlForSingleLine(sml: string): string {\n\treturn sml.trim();\n}\n\nfunction bufferToHex(buffer: Buffer, maxHexBytes: number): string {\n\tconst len = buffer.length;\n\tconst max = Math.max(0, maxHexBytes);\n\tconst slice = len <= max ? buffer : buffer.subarray(0, max);\n\tconst hex = slice.toString(\"hex\");\n\tconst suffix = len <= max ? \"\" : `…(+${String(len - max)} bytes)`;\n\treturn `${hex}${suffix}`;\n}\n\nclass PrettyPrintTransformStream extends Transform {\n\tprivate pending = \"\";\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\toverride _transform(\n\t\tchunk: Buffer | string,\n\t\t_encoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _flush(callback: (error?: Error | null) => void): void {\n\t\tcallback();\n\t}\n\n\tprivate flush(): void {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tconst obj = JSON.parse(line) as Record<string, unknown>;\n\t\t\tconst formatted = this.formatLine(obj);\n\t\t\tthis.push(formatted);\n\t\t}\n\t}\n\n\tprivate formatLine(obj: Record<string, unknown>): string {\n\t\tconst time = this.formatTime(obj.time);\n\t\tconst level = this.formatLevel(obj.level as number);\n\t\tconst extra = this.formatExtra(obj);\n\t\tconst msg = this.formatMessage(obj);\n\n\t\treturn `${time} ${level} ${extra} | ${msg}\\n`;\n\t}\n\n\tprivate formatTime(timeValue: unknown): string {\n\t\tif (typeof timeValue === \"number\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\tif (typeof timeValue === \"string\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\treturn formatDateTime(new Date());\n\t}\n\n\tprivate formatLevel(level: number): string {\n\t\tconst levels: Record<number, string> = {\n\t\t\t10: \"TRACE\",\n\t\t\t20: \"DEBUG\",\n\t\t\t30: \"INFO \",\n\t\t\t40: \"WARN \",\n\t\t\t50: \"ERROR\",\n\t\t\t60: \"FATAL\",\n\t\t};\n\t\treturn levels[level] ?? \"UNKNOWN\";\n\t}\n\n\tprivate formatExtra(obj: Record<string, unknown>): string {\n\t\tconst parts: string[] = [];\n\n\t\tif (typeof obj.protocol === \"string\") {\n\t\t\tparts.push(obj.protocol);\n\t\t}\n\t\tif (typeof obj.dir === \"string\") {\n\t\t\tparts.push(obj.dir);\n\t\t}\n\t\tif (typeof obj.prev === \"string\" && typeof obj.next === \"string\") {\n\t\t\tparts.push(`${obj.prev} -> ${obj.next}`);\n\t\t}\n\n\t\treturn parts.join(\" \");\n\t}\n\n\tprivate formatMessage(obj: Record<string, unknown>): string {\n\t\tconst msgValue = obj.msg;\n\t\tif (typeof msgValue === \"string\" && msgValue.trim().length > 0) {\n\t\t\treturn msgValue;\n\t\t}\n\n\t\tconst excludeKeys = new Set([\n\t\t\t\"time\",\n\t\t\t\"level\",\n\t\t\t\"msg\",\n\t\t\t\"name\",\n\t\t\t\"deviceId\",\n\t\t\t\"isEquip\",\n\t\t\t\"protocol\",\n\t\t\t\"dir\",\n\t\t\t\"prev\",\n\t\t\t\"next\",\n\t\t]);\n\n\t\tconst pairs: string[] = [];\n\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\tif (excludeKeys.has(key)) continue;\n\t\t\tif (Buffer.isBuffer(value)) {\n\t\t\t\tpairs.push(`${key}=${value.toString(\"hex\")}`);\n\t\t\t} else if (typeof value === \"string\") {\n\t\t\t\tpairs.push(`${key}=${value}`);\n\t\t\t} else if (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\t\tpairs.push(`${key}=${String(value)}`);\n\t\t\t} else {\n\t\t\t\tpairs.push(`${key}=${this.formatValue(value)}`);\n\t\t\t}\n\t\t}\n\n\t\treturn pairs.join(\" \");\n\t}\n\n\tprivate formatValue(value: unknown): string {\n\t\tif (value === null) return \"null\";\n\t\tif (value === undefined) return \"undefined\";\n\t\tif (typeof value === \"string\") return value;\n\t\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\treturn String(value);\n\t\t}\n\t\tif (Buffer.isBuffer(value)) {\n\t\t\treturn value.toString(\"hex\");\n\t\t}\n\t\tif (typeof value === \"object\") {\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn \"[object]\";\n\t\t\t}\n\t\t}\n\t\treturn String(value as string | number | bigint | boolean);\n\t}\n}\n\nclass DailyRotatingFileStream extends Writable {\n\tprivate readonly baseDir: string;\n\tprivate readonly fileNameForDate: (ymd: string) => string;\n\tprivate readonly retentionDays: number;\n\tprivate currentYmd: string | null = null;\n\tprivate currentStream: fs.WriteStream | null = null;\n\tprivate cleanupYmd: string | null = null;\n\tprivate pending = \"\";\n\n\tconstructor(params: {\n\t\tbaseDir: string;\n\t\tfileNameForDate: (ymd: string) => string;\n\t\tretentionDays: number;\n\t}) {\n\t\tsuper();\n\t\tthis.baseDir = params.baseDir;\n\t\tthis.fileNameForDate = params.fileNameForDate;\n\t\tthis.retentionDays = params.retentionDays;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flushCompleteLines();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tif (this.pending.length > 0) {\n\t\t\t\tthis.ensureStreamForNow();\n\t\t\t\tthis.currentStream?.write(this.pending);\n\t\t\t\tthis.pending = \"\";\n\t\t\t}\n\t\t\tthis.currentStream?.end(() => callback());\n\t\t\tthis.currentStream = null;\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flushCompleteLines() {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx + 1);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tthis.ensureStreamForNow();\n\t\t\tthis.currentStream?.write(line);\n\t\t}\n\t}\n\n\tprivate ensureStreamForNow() {\n\t\tconst now = new Date();\n\t\tconst ymd = formatDate(now);\n\t\tif (this.currentYmd === ymd && this.currentStream) return;\n\n\t\tif (this.currentStream) {\n\t\t\tthis.currentStream.end();\n\t\t\tthis.currentStream = null;\n\t\t}\n\n\t\tconst dir = path.join(this.baseDir, ymd);\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t\tconst filePath = path.join(dir, this.fileNameForDate(ymd));\n\t\tthis.currentStream = fs.createWriteStream(filePath, { flags: \"a\" });\n\t\tthis.currentYmd = ymd;\n\n\t\tif (this.retentionDays > 0 && this.cleanupYmd !== ymd) {\n\t\t\tthis.cleanupYmd = ymd;\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tthis.cleanupOldDirs(now).catch(() => undefined);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async cleanupOldDirs(now: Date): Promise<void> {\n\t\tconst retentionDays = this.retentionDays;\n\t\tif (retentionDays <= 0) return;\n\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = await fs.promises.readdir(this.baseDir, {\n\t\t\t\twithFileTypes: true,\n\t\t\t});\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tconst cutoff = new Date(\n\t\t\tnow.getFullYear(),\n\t\t\tnow.getMonth(),\n\t\t\tnow.getDate(),\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t\tcutoff.setDate(cutoff.getDate() - retentionDays);\n\n\t\tfor (const ent of entries) {\n\t\t\tif (!ent.isDirectory()) continue;\n\t\t\tconst dirName = ent.name;\n\t\t\tconst dirDate = tryParseYmdDirName(dirName);\n\t\t\tif (!dirDate) continue;\n\t\t\tif (dirDate >= cutoff) continue;\n\t\t\tconst full = path.join(this.baseDir, dirName);\n\t\t\ttry {\n\t\t\t\tawait fs.promises.rm(full, { recursive: true, force: true });\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass Secs2LineTransformStream extends Writable {\n\tprivate readonly target: DailyRotatingFileStream;\n\tprivate pending = \"\";\n\n\tconstructor(target: DailyRotatingFileStream) {\n\t\tsuper();\n\t\tthis.target = target;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tthis.flush(true);\n\t\t\tthis.target.end(() => callback());\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flush(flushAll = false) {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) {\n\t\t\t\tif (flushAll && this.pending.length > 0) {\n\t\t\t\t\tthis.handleLine(this.pending);\n\t\t\t\t\tthis.pending = \"\";\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tthis.handleLine(line);\n\t\t}\n\t}\n\n\tprivate handleLine(jsonLine: string) {\n\t\tlet obj: unknown;\n\t\ttry {\n\t\t\tobj = JSON.parse(jsonLine);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!obj || typeof obj !== \"object\") return;\n\t\tconst rec = obj as Record<string, unknown>;\n\t\tconst timeValue = rec.time;\n\t\tconst dirValue = rec.dir;\n\t\tconst smlValue = rec.sml;\n\n\t\tconst dir =\n\t\t\tdirValue === \"Sent\" || dirValue === \"Received\" ? dirValue : null;\n\t\tconst sml = typeof smlValue === \"string\" ? smlValue : null;\n\t\tif (!dir || !sml) return;\n\n\t\tlet date: Date;\n\t\tif (typeof timeValue === \"number\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else if (typeof timeValue === \"string\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t}\n\n\t\tconst out = `${formatDateTime(date)} ${dir} \\n${normalizeSmlForSingleLine(sml)}\\n`;\n\t\tthis.target.write(out);\n\t}\n}\n\nclass DisabledSecsLogger {\n\tdetail: Logger;\n\tsecs2: Logger;\n\tconstructor() {\n\t\tthis.detail = pino({ enabled: false });\n\t\tthis.secs2 = pino({ enabled: false });\n\t}\n\n\tlogSecs2(_direction: SecsLogDirection, _sml: string): void {\n\t\treturn;\n\t}\n\n\tlogBytes(\n\t\t_direction: SecsLogDirection,\n\t\t_protocol: string,\n\t\t_buffer: Buffer,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tlogState(\n\t\t_protocol: string,\n\t\t_prev: string,\n\t\t_next: string,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tclose(): void {\n\t\treturn;\n\t}\n}\n\nexport class SecsLogger {\n\tstatic disabled(): SecsLogger {\n\t\treturn new DisabledSecsLogger() as unknown as SecsLogger;\n\t}\n\n\tstatic create(\n\t\tconfig: SecsLoggerConfig | undefined,\n\t\tctx: SecsLoggerContext,\n\t): SecsLogger {\n\t\tconst enabled = config?.enabled ?? false;\n\t\tconst consoleEnabled = config?.console ?? false;\n\t\tif (!enabled) return SecsLogger.disabled();\n\n\t\tconst baseDir = config?.baseDir\n\t\t\t? path.resolve(config.baseDir)\n\t\t\t: path.resolve(process.cwd(), \"logs\");\n\t\tconst retentionDays = config?.retentionDays ?? 7;\n\t\tconst detailLevel = config?.detailLevel ?? \"debug\";\n\t\tconst secs2Level = config?.secs2Level ?? \"info\";\n\n\t\tconst detailStream = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-DETAIL.log`,\n\t\t\tretentionDays,\n\t\t});\n\n\t\tconst secs2Target = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-SECS-II.log`,\n\t\t\tretentionDays,\n\t\t});\n\t\tconst secs2Stream = new Secs2LineTransformStream(secs2Target);\n\n\t\tconst bindings = {\n\t\t\tname: ctx.name,\n\t\t\tdeviceId: ctx.deviceId,\n\t\t\tisEquip: ctx.isEquip,\n\t\t};\n\n\t\tconst detailStreams: pino.StreamEntry[] = [\n\t\t\t{ stream: detailStream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tconst prettyStream = new PrettyPrintTransformStream();\n\t\t\tprettyStream.pipe(process.stdout);\n\t\t\tdetailStreams.push({\n\t\t\t\tstream: prettyStream,\n\t\t\t\tlevel: detailLevel as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst detail = pino(\n\t\t\t{ level: detailLevel, base: bindings },\n\t\t\tpino.multistream(detailStreams),\n\t\t);\n\n\t\tconst secs2Streams: pino.StreamEntry[] = [\n\t\t\t{ stream: secs2Stream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tsecs2Streams.push({\n\t\t\t\tstream: process.stdout,\n\t\t\t\tlevel: secs2Level as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst secs2 = pino(\n\t\t\t{\n\t\t\t\tlevel: secs2Level,\n\t\t\t\tbase: null,\n\t\t\t\tmessageKey: \"msg\",\n\t\t\t},\n\t\t\tpino.multistream(secs2Streams),\n\t\t);\n\n\t\treturn new SecsLogger({\n\t\t\tconfig: { ...config, baseDir, retentionDays },\n\t\t\tdetail,\n\t\t\tsecs2,\n\t\t\tdetailStream,\n\t\t\tsecs2Target,\n\t\t\tsecs2Stream,\n\t\t});\n\t}\n\n\tpublic readonly detail: Logger;\n\tprivate readonly secs2: Logger;\n\tprivate readonly detailStream: DailyRotatingFileStream;\n\tprivate readonly secs2Target: DailyRotatingFileStream;\n\tprivate readonly secs2Stream: Secs2LineTransformStream;\n\tprivate readonly maxHexBytes: number;\n\n\tprivate constructor(params: {\n\t\tconfig: SecsLoggerConfig;\n\t\tdetail: Logger;\n\t\tsecs2: Logger;\n\t\tdetailStream: DailyRotatingFileStream;\n\t\tsecs2Target: DailyRotatingFileStream;\n\t\tsecs2Stream: Secs2LineTransformStream;\n\t}) {\n\t\tthis.detail = params.detail;\n\t\tthis.secs2 = params.secs2;\n\t\tthis.detailStream = params.detailStream;\n\t\tthis.secs2Target = params.secs2Target;\n\t\tthis.secs2Stream = params.secs2Stream;\n\t\tthis.maxHexBytes = params.config.maxHexBytes ?? 64 * 1024;\n\t}\n\n\tlogSecs2(direction: SecsLogDirection, sml: string): void {\n\t\tthis.secs2.info(\n\t\t\t{ dir: direction, sml: normalizeSmlForSingleLine(sml) },\n\t\t\t\"\",\n\t\t);\n\t}\n\n\tlogBytes(\n\t\tdirection: SecsLogDirection,\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.trace(\n\t\t\t{\n\t\t\t\tprotocol,\n\t\t\t\tdir: direction,\n\t\t\t\tbyteLength: buffer.length,\n\t\t\t\thex: bufferToHex(buffer, this.maxHexBytes),\n\t\t\t\t...meta,\n\t\t\t},\n\t\t\t\"bytes\",\n\t\t);\n\t}\n\n\tlogState(\n\t\tprotocol: string,\n\t\tprev: string,\n\t\tnext: string,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.info({ protocol, prev, next, ...meta }, \"state\");\n\t}\n\n\tclose(): void {\n\t\tthis.secs2.flush();\n\t\tthis.detail.flush();\n\t\tthis.secs2Stream.end();\n\t\tthis.secs2Target.end();\n\t\tthis.detailStream.end();\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SecsLogger.js","names":["parts: string[]","pairs: string[]","entries: fs.Dirent[]","obj: unknown","date: Date","detailStreams: pino.StreamEntry[]","secs2Streams: pino.StreamEntry[]"],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { Writable, Transform } from \"stream\";\nimport pino, { type LevelWithSilent, type Logger } from \"pino\";\n\nexport type SecsLogDirection = \"Received\" | \"Sent\";\n\nexport interface SecsLoggerConfig {\n\tenabled?: boolean;\n\tconsole?: boolean;\n\tbaseDir?: string;\n\tretentionDays?: number;\n\tdetailLevel?: LevelWithSilent;\n\tsecs2Level?: LevelWithSilent;\n\tmaxHexBytes?: number;\n}\n\nexport interface SecsLoggerContext {\n\tname: string;\n\tdeviceId: number;\n\tisEquip: boolean;\n}\n\nfunction formatDate(date: Date): string {\n\tconst y = date.getFullYear();\n\tconst m = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst d = String(date.getDate()).padStart(2, \"0\");\n\treturn `${String(y)}-${m}-${d}`;\n}\n\nfunction formatDateTime(date: Date): string {\n\tconst ymd = formatDate(date);\n\tconst hh = String(date.getHours()).padStart(2, \"0\");\n\tconst mm = String(date.getMinutes()).padStart(2, \"0\");\n\tconst ss = String(date.getSeconds()).padStart(2, \"0\");\n\tconst ms = String(date.getMilliseconds()).padStart(3, \"0\");\n\treturn `${ymd} ${hh}:${mm}:${ss}.${ms}`;\n}\n\nfunction tryParseYmdDirName(dirName: string): Date | null {\n\tconst m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(dirName);\n\tif (!m) return null;\n\tconst year = Number(m[1]);\n\tconst month = Number(m[2]);\n\tconst day = Number(m[3]);\n\tif (\n\t\t!Number.isFinite(year) ||\n\t\t!Number.isFinite(month) ||\n\t\t!Number.isFinite(day)\n\t)\n\t\treturn null;\n\tconst dt = new Date(year, month - 1, day);\n\tif (dt.getFullYear() !== year) return null;\n\tif (dt.getMonth() !== month - 1) return null;\n\tif (dt.getDate() !== day) return null;\n\treturn dt;\n}\n\nfunction normalizeSmlForSingleLine(sml: string): string {\n\treturn sml.trim();\n}\n\nfunction bufferToHex(buffer: Buffer, maxHexBytes: number): string {\n\tconst len = buffer.length;\n\tconst max = Math.max(0, maxHexBytes);\n\tconst slice = len <= max ? buffer : buffer.subarray(0, max);\n\tconst hex = slice.toString(\"hex\");\n\tconst suffix = len <= max ? \"\" : `…(+${String(len - max)} bytes)`;\n\treturn `${hex}${suffix}`;\n}\n\nclass PrettyPrintTransformStream extends Transform {\n\tprivate pending = \"\";\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\toverride _transform(\n\t\tchunk: Buffer | string,\n\t\t_encoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _flush(callback: (error?: Error | null) => void): void {\n\t\tcallback();\n\t}\n\n\tprivate flush(): void {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tconst obj = JSON.parse(line) as Record<string, unknown>;\n\t\t\tconst formatted = this.formatLine(obj);\n\t\t\tthis.push(formatted);\n\t\t}\n\t}\n\n\tprivate formatLine(obj: Record<string, unknown>): string {\n\t\tconst time = this.formatTime(obj.time);\n\t\tconst level = this.formatLevel(obj.level as number);\n\t\tconst extra = this.formatExtra(obj);\n\t\tconst msg = this.formatMessage(obj);\n\n\t\treturn `${time} ${level} ${extra} | ${msg}\\n`;\n\t}\n\n\tprivate formatTime(timeValue: unknown): string {\n\t\tif (typeof timeValue === \"number\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\tif (typeof timeValue === \"string\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\treturn formatDateTime(new Date());\n\t}\n\n\tprivate formatLevel(level: number): string {\n\t\tconst levels: Record<number, string> = {\n\t\t\t10: \"TRACE\",\n\t\t\t20: \"DEBUG\",\n\t\t\t30: \"INFO \",\n\t\t\t40: \"WARN \",\n\t\t\t50: \"ERROR\",\n\t\t\t60: \"FATAL\",\n\t\t};\n\t\treturn levels[level] ?? \"UNKNOWN\";\n\t}\n\n\tprivate formatExtra(obj: Record<string, unknown>): string {\n\t\tconst parts: string[] = [];\n\n\t\tif (typeof obj.protocol === \"string\") {\n\t\t\tparts.push(obj.protocol);\n\t\t}\n\t\tif (typeof obj.dir === \"string\") {\n\t\t\tparts.push(obj.dir);\n\t\t}\n\t\tif (typeof obj.prev === \"string\" && typeof obj.next === \"string\") {\n\t\t\tparts.push(`${obj.prev} -> ${obj.next}`);\n\t\t}\n\n\t\treturn parts.join(\" \");\n\t}\n\n\tprivate formatMessage(obj: Record<string, unknown>): string {\n\t\tconst msgValue = obj.msg;\n\t\tif (typeof msgValue === \"string\" && msgValue.trim().length > 0) {\n\t\t\treturn msgValue;\n\t\t}\n\n\t\tconst excludeKeys = new Set([\n\t\t\t\"time\",\n\t\t\t\"level\",\n\t\t\t\"msg\",\n\t\t\t\"name\",\n\t\t\t\"deviceId\",\n\t\t\t\"isEquip\",\n\t\t\t\"protocol\",\n\t\t\t\"dir\",\n\t\t\t\"prev\",\n\t\t\t\"next\",\n\t\t]);\n\n\t\tconst pairs: string[] = [];\n\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\tif (excludeKeys.has(key)) continue;\n\t\t\tif (Buffer.isBuffer(value)) {\n\t\t\t\tpairs.push(`${key}=${value.toString(\"hex\")}`);\n\t\t\t} else if (typeof value === \"string\") {\n\t\t\t\tpairs.push(`${key}=${value}`);\n\t\t\t} else if (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\t\tpairs.push(`${key}=${String(value)}`);\n\t\t\t} else {\n\t\t\t\tpairs.push(`${key}=${this.formatValue(value)}`);\n\t\t\t}\n\t\t}\n\n\t\treturn pairs.join(\" \");\n\t}\n\n\tprivate formatValue(value: unknown): string {\n\t\tif (value === null) return \"null\";\n\t\tif (value === undefined) return \"undefined\";\n\t\tif (typeof value === \"string\") return value;\n\t\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\treturn String(value);\n\t\t}\n\t\tif (Buffer.isBuffer(value)) {\n\t\t\treturn value.toString(\"hex\");\n\t\t}\n\t\tif (typeof value === \"object\") {\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn \"[object]\";\n\t\t\t}\n\t\t}\n\t\treturn String(value as string | number | bigint | boolean);\n\t}\n}\n\nclass DailyRotatingFileStream extends Writable {\n\tprivate readonly baseDir: string;\n\tprivate readonly fileNameForDate: (ymd: string) => string;\n\tprivate readonly retentionDays: number;\n\tprivate currentYmd: string | null = null;\n\tprivate currentStream: fs.WriteStream | null = null;\n\tprivate cleanupYmd: string | null = null;\n\tprivate pending = \"\";\n\n\tconstructor(params: {\n\t\tbaseDir: string;\n\t\tfileNameForDate: (ymd: string) => string;\n\t\tretentionDays: number;\n\t}) {\n\t\tsuper();\n\t\tthis.baseDir = params.baseDir;\n\t\tthis.fileNameForDate = params.fileNameForDate;\n\t\tthis.retentionDays = params.retentionDays;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flushCompleteLines();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tif (this.pending.length > 0) {\n\t\t\t\tthis.ensureStreamForNow();\n\t\t\t\tthis.currentStream?.write(this.pending);\n\t\t\t\tthis.pending = \"\";\n\t\t\t}\n\t\t\tthis.currentStream?.end(() => callback());\n\t\t\tthis.currentStream = null;\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flushCompleteLines() {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx + 1);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tthis.ensureStreamForNow();\n\t\t\tthis.currentStream?.write(line);\n\t\t}\n\t}\n\n\tprivate ensureStreamForNow() {\n\t\tconst now = new Date();\n\t\tconst ymd = formatDate(now);\n\t\tif (this.currentYmd === ymd && this.currentStream) return;\n\n\t\tif (this.currentStream) {\n\t\t\tthis.currentStream.end();\n\t\t\tthis.currentStream = null;\n\t\t}\n\n\t\tconst dir = path.join(this.baseDir, ymd);\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t\tconst filePath = path.join(dir, this.fileNameForDate(ymd));\n\t\tthis.currentStream = fs.createWriteStream(filePath, { flags: \"a\" });\n\t\tthis.currentYmd = ymd;\n\n\t\tif (this.retentionDays > 0 && this.cleanupYmd !== ymd) {\n\t\t\tthis.cleanupYmd = ymd;\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tthis.cleanupOldDirs(now).catch(() => undefined);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async cleanupOldDirs(now: Date): Promise<void> {\n\t\tconst retentionDays = this.retentionDays;\n\t\tif (retentionDays <= 0) return;\n\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = await fs.promises.readdir(this.baseDir, {\n\t\t\t\twithFileTypes: true,\n\t\t\t});\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tconst cutoff = new Date(\n\t\t\tnow.getFullYear(),\n\t\t\tnow.getMonth(),\n\t\t\tnow.getDate(),\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t\tcutoff.setDate(cutoff.getDate() - retentionDays);\n\n\t\tfor (const ent of entries) {\n\t\t\tif (!ent.isDirectory()) continue;\n\t\t\tconst dirName = ent.name;\n\t\t\tconst dirDate = tryParseYmdDirName(dirName);\n\t\t\tif (!dirDate) continue;\n\t\t\tif (dirDate >= cutoff) continue;\n\t\t\tconst full = path.join(this.baseDir, dirName);\n\t\t\ttry {\n\t\t\t\tawait fs.promises.rm(full, { recursive: true, force: true });\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass Secs2LineTransformStream extends Writable {\n\tprivate readonly target: DailyRotatingFileStream;\n\tprivate pending = \"\";\n\n\tconstructor(target: DailyRotatingFileStream) {\n\t\tsuper();\n\t\tthis.target = target;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tthis.flush(true);\n\t\t\tthis.target.end(() => callback());\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flush(flushAll = false) {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) {\n\t\t\t\tif (flushAll && this.pending.length > 0) {\n\t\t\t\t\tthis.handleLine(this.pending);\n\t\t\t\t\tthis.pending = \"\";\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tthis.handleLine(line);\n\t\t}\n\t}\n\n\tprivate handleLine(jsonLine: string) {\n\t\tlet obj: unknown;\n\t\ttry {\n\t\t\tobj = JSON.parse(jsonLine);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!obj || typeof obj !== \"object\") return;\n\t\tconst rec = obj as Record<string, unknown>;\n\t\tconst timeValue = rec.time;\n\t\tconst dirValue = rec.dir;\n\t\tconst smlValue = rec.sml;\n\t\tconst deviceIdValue = rec.deviceId;\n\t\tconst systemBytesValue = rec.systemBytes;\n\n\t\tconst dir =\n\t\t\tdirValue === \"Sent\" || dirValue === \"Received\" ? dirValue : null;\n\t\tconst sml = typeof smlValue === \"string\" ? smlValue : null;\n\t\tif (!dir || !sml) return;\n\n\t\tlet date: Date;\n\t\tif (typeof timeValue === \"number\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else if (typeof timeValue === \"string\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t}\n\n\t\tconst deviceId = typeof deviceIdValue === \"number\" ? deviceIdValue : 0;\n\t\tconst systemBytes =\n\t\t\ttypeof systemBytesValue === \"number\" ? systemBytesValue : 0;\n\n\t\tconst out = `${formatDateTime(date)} ${dir} DeviceID: ${deviceId} SystemBytes: ${systemBytes} \\n${normalizeSmlForSingleLine(sml)}\\n`;\n\t\tthis.target.write(out);\n\t}\n}\n\nclass DisabledSecsLogger {\n\tdetail: Logger;\n\tsecs2: Logger;\n\tconstructor() {\n\t\tthis.detail = pino({ enabled: false });\n\t\tthis.secs2 = pino({ enabled: false });\n\t}\n\n\tlogSecs2(_direction: SecsLogDirection, _sml: string): void {\n\t\treturn;\n\t}\n\n\tlogBytes(\n\t\t_direction: SecsLogDirection,\n\t\t_protocol: string,\n\t\t_buffer: Buffer,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tlogState(\n\t\t_protocol: string,\n\t\t_prev: string,\n\t\t_next: string,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tclose(): void {\n\t\treturn;\n\t}\n}\n\nexport class SecsLogger {\n\tstatic disabled(): SecsLogger {\n\t\treturn new DisabledSecsLogger() as unknown as SecsLogger;\n\t}\n\n\tstatic create(\n\t\tconfig: SecsLoggerConfig | undefined,\n\t\tctx: SecsLoggerContext,\n\t): SecsLogger {\n\t\tconst enabled = config?.enabled ?? false;\n\t\tconst consoleEnabled = config?.console ?? false;\n\t\tif (!enabled) return SecsLogger.disabled();\n\n\t\tconst baseDir = config?.baseDir\n\t\t\t? path.resolve(config.baseDir)\n\t\t\t: path.resolve(process.cwd(), \"logs\");\n\t\tconst retentionDays = config?.retentionDays ?? 7;\n\t\tconst detailLevel = config?.detailLevel ?? \"debug\";\n\t\tconst secs2Level = config?.secs2Level ?? \"info\";\n\n\t\tconst detailStream = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-DETAIL.log`,\n\t\t\tretentionDays,\n\t\t});\n\n\t\tconst secs2Target = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-SECS-II.log`,\n\t\t\tretentionDays,\n\t\t});\n\t\tconst secs2Stream = new Secs2LineTransformStream(secs2Target);\n\n\t\tconst bindings = {\n\t\t\tname: ctx.name,\n\t\t\tdeviceId: ctx.deviceId,\n\t\t\tisEquip: ctx.isEquip,\n\t\t};\n\n\t\tconst detailPrettyStream = new PrettyPrintTransformStream();\n\t\tdetailPrettyStream.pipe(detailStream);\n\t\tconst detailStreams: pino.StreamEntry[] = [\n\t\t\t{ stream: detailPrettyStream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tconst consolePrettyStream = new PrettyPrintTransformStream();\n\t\t\tconsolePrettyStream.pipe(process.stdout);\n\t\t\tdetailStreams.push({\n\t\t\t\tstream: consolePrettyStream,\n\t\t\t\tlevel: detailLevel as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst detail = pino(\n\t\t\t{ level: detailLevel, base: bindings },\n\t\t\tpino.multistream(detailStreams),\n\t\t);\n\n\t\tconst secs2ToDetailPrettyStream = new PrettyPrintTransformStream();\n\t\tsecs2ToDetailPrettyStream.pipe(detailStream);\n\t\tconst secs2Streams: pino.StreamEntry[] = [\n\t\t\t{ stream: secs2Stream as pino.DestinationStream },\n\t\t\t{ stream: secs2ToDetailPrettyStream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tsecs2Streams.push({\n\t\t\t\tstream: process.stdout,\n\t\t\t\tlevel: secs2Level as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst secs2 = pino(\n\t\t\t{\n\t\t\t\tlevel: secs2Level,\n\t\t\t\tbase: bindings,\n\t\t\t\tmessageKey: \"msg\",\n\t\t\t},\n\t\t\tpino.multistream(secs2Streams),\n\t\t);\n\n\t\treturn new SecsLogger({\n\t\t\tconfig: { ...config, baseDir, retentionDays },\n\t\t\tdetail,\n\t\t\tsecs2,\n\t\t\tdetailStream,\n\t\t\tsecs2Target,\n\t\t\tsecs2Stream,\n\t\t});\n\t}\n\n\tpublic readonly detail: Logger;\n\tprivate readonly secs2: Logger;\n\tprivate readonly detailStream: DailyRotatingFileStream;\n\tprivate readonly secs2Target: DailyRotatingFileStream;\n\tprivate readonly secs2Stream: Secs2LineTransformStream;\n\tprivate readonly maxHexBytes: number;\n\n\tprivate constructor(params: {\n\t\tconfig: SecsLoggerConfig;\n\t\tdetail: Logger;\n\t\tsecs2: Logger;\n\t\tdetailStream: DailyRotatingFileStream;\n\t\tsecs2Target: DailyRotatingFileStream;\n\t\tsecs2Stream: Secs2LineTransformStream;\n\t}) {\n\t\tthis.detail = params.detail;\n\t\tthis.secs2 = params.secs2;\n\t\tthis.detailStream = params.detailStream;\n\t\tthis.secs2Target = params.secs2Target;\n\t\tthis.secs2Stream = params.secs2Stream;\n\t\tthis.maxHexBytes = params.config.maxHexBytes ?? 64 * 1024;\n\t}\n\n\tlogSecs2(\n\t\tdirection: SecsLogDirection,\n\t\tsml: string,\n\t\tdeviceId: number,\n\t\tsystemBytes: number,\n\t\tbuffer?: Buffer,\n\t): void {\n\t\tthis.secs2.info(\n\t\t\t{\n\t\t\t\tdir: direction,\n\t\t\t\tsml: normalizeSmlForSingleLine(sml),\n\t\t\t\tdeviceId,\n\t\t\t\tsystemBytes,\n\t\t\t\thex: buffer ? bufferToHex(buffer, this.maxHexBytes) : undefined,\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\t}\n\n\tlogBytes(\n\t\tdirection: SecsLogDirection,\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.trace(\n\t\t\t{\n\t\t\t\tprotocol,\n\t\t\t\tdir: direction,\n\t\t\t\tbyteLength: buffer.length,\n\t\t\t\thex: bufferToHex(buffer, this.maxHexBytes),\n\t\t\t\t...meta,\n\t\t\t},\n\t\t\t\"bytes\",\n\t\t);\n\t}\n\n\tlogState(\n\t\tprotocol: string,\n\t\tprev: string,\n\t\tnext: string,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.info({ protocol, prev, next, ...meta }, \"state\");\n\t}\n\n\tclose(): void {\n\t\tthis.secs2.flush();\n\t\tthis.detail.flush();\n\t\tthis.secs2Stream.end();\n\t\tthis.secs2Target.end();\n\t\tthis.detailStream.end();\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -40,9 +40,9 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
40
40
|
this.stream = stream;
|
|
41
41
|
this.resetState();
|
|
42
42
|
this.buffer = Buffer.alloc(0);
|
|
43
|
-
this.logger.logState("
|
|
43
|
+
this.logger.logState("SECS-I", "NotConnected", "Connected");
|
|
44
44
|
stream.on("data", (data) => {
|
|
45
|
-
this.logger.logBytes("Received", "
|
|
45
|
+
this.logger.logBytes("Received", "SECS-I", data, { chunkLength: data.length });
|
|
46
46
|
this.buffer = Buffer.concat([this.buffer, data]);
|
|
47
47
|
if (this.state === CommState.WAIT_BLOCK_LENGTH || this.state === CommState.WAIT_BLOCK_DATA) this.startT1();
|
|
48
48
|
this.processBuffer();
|
|
@@ -51,7 +51,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
51
51
|
this.rejectAllTransactions(/* @__PURE__ */ new Error("Stream closed"));
|
|
52
52
|
this.stream = null;
|
|
53
53
|
this.emit("disconnected");
|
|
54
|
-
this.logger.logState("
|
|
54
|
+
this.logger.logState("SECS-I", "Connected", "NotConnected");
|
|
55
55
|
this.stopAllTimers();
|
|
56
56
|
this.resetState();
|
|
57
57
|
});
|
|
@@ -129,13 +129,13 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
129
129
|
}, timeout);
|
|
130
130
|
}
|
|
131
131
|
handleT1Timeout() {
|
|
132
|
-
this.logger.detail.warn({ protocol: "
|
|
132
|
+
this.logger.detail.warn({ protocol: "SECS-I" }, "t1 timeout");
|
|
133
133
|
this.t1Timer = null;
|
|
134
134
|
this.emit("error", /* @__PURE__ */ new Error("T1 Timeout"));
|
|
135
135
|
this.resetState();
|
|
136
136
|
}
|
|
137
137
|
handleT2Timeout() {
|
|
138
|
-
this.logger.detail.warn({ protocol: "
|
|
138
|
+
this.logger.detail.warn({ protocol: "SECS-I" }, "t2 timeout");
|
|
139
139
|
this.t2Timer = null;
|
|
140
140
|
if (this.state === CommState.WAIT_EOT) {
|
|
141
141
|
this.retryCount++;
|
|
@@ -144,7 +144,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
144
144
|
this.resetState();
|
|
145
145
|
} else {
|
|
146
146
|
this.logger.detail.info({
|
|
147
|
-
protocol: "
|
|
147
|
+
protocol: "SECS-I",
|
|
148
148
|
retryCount: this.retryCount,
|
|
149
149
|
retry: this.retry
|
|
150
150
|
}, "retrying ENQ");
|
|
@@ -160,7 +160,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
160
160
|
this.resetState();
|
|
161
161
|
} else {
|
|
162
162
|
this.logger.detail.info({
|
|
163
|
-
protocol: "
|
|
163
|
+
protocol: "SECS-I",
|
|
164
164
|
retryCount: this.retryCount,
|
|
165
165
|
retry: this.retry
|
|
166
166
|
}, "retrying block");
|
|
@@ -171,7 +171,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
171
171
|
this.resetState();
|
|
172
172
|
}
|
|
173
173
|
handleT4Timeout() {
|
|
174
|
-
this.logger.detail.warn({ protocol: "
|
|
174
|
+
this.logger.detail.warn({ protocol: "SECS-I" }, "t4 timeout");
|
|
175
175
|
this.t4Timer = null;
|
|
176
176
|
this.resetState();
|
|
177
177
|
}
|
|
@@ -186,7 +186,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
186
186
|
const stream = this.stream;
|
|
187
187
|
if (stream && !stream.destroyed) {
|
|
188
188
|
const buf = Buffer.from([byte]);
|
|
189
|
-
this.logger.logBytes("Sent", "
|
|
189
|
+
this.logger.logBytes("Sent", "SECS-I", buf);
|
|
190
190
|
stream.write(buf);
|
|
191
191
|
}
|
|
192
192
|
}
|
|
@@ -196,7 +196,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
196
196
|
const byte = this.buffer[0];
|
|
197
197
|
this.buffer = this.buffer.subarray(1);
|
|
198
198
|
if (byte === ENQ) {
|
|
199
|
-
this.logger.detail.debug({ protocol: "
|
|
199
|
+
this.logger.detail.debug({ protocol: "SECS-I" }, "rx ENQ");
|
|
200
200
|
this.sendByte(EOT);
|
|
201
201
|
this.state = CommState.WAIT_BLOCK_LENGTH;
|
|
202
202
|
this.receivedBlocks = [];
|
|
@@ -209,13 +209,13 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
209
209
|
const byte = this.buffer[0];
|
|
210
210
|
this.buffer = this.buffer.subarray(1);
|
|
211
211
|
if (byte === EOT) {
|
|
212
|
-
this.logger.detail.debug({ protocol: "
|
|
212
|
+
this.logger.detail.debug({ protocol: "SECS-I" }, "rx EOT");
|
|
213
213
|
this.clearT2();
|
|
214
214
|
this.currentBlockIndex = 0;
|
|
215
215
|
this.sendCurrentBlock();
|
|
216
216
|
} else if (byte === ENQ) {
|
|
217
217
|
if (!this.isMaster) {
|
|
218
|
-
this.logger.detail.debug({ protocol: "
|
|
218
|
+
this.logger.detail.debug({ protocol: "SECS-I" }, "rx ENQ while waiting EOT");
|
|
219
219
|
this.clearT2();
|
|
220
220
|
this.sendByte(EOT);
|
|
221
221
|
this.state = CommState.WAIT_BLOCK_LENGTH;
|
|
@@ -230,7 +230,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
230
230
|
const byte = this.buffer[0];
|
|
231
231
|
this.buffer = this.buffer.subarray(1);
|
|
232
232
|
if (byte === ACK) {
|
|
233
|
-
this.logger.detail.debug({ protocol: "
|
|
233
|
+
this.logger.detail.debug({ protocol: "SECS-I" }, "rx ACK");
|
|
234
234
|
this.clearT2();
|
|
235
235
|
if (this.currentBlocks[this.currentBlockIndex].eBit) {
|
|
236
236
|
this.currentBlocks = [];
|
|
@@ -242,7 +242,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
242
242
|
this.sendCurrentBlock();
|
|
243
243
|
}
|
|
244
244
|
} else if (byte === NAK) {
|
|
245
|
-
this.logger.detail.warn({ protocol: "
|
|
245
|
+
this.logger.detail.warn({ protocol: "SECS-I" }, "rx NAK");
|
|
246
246
|
this.clearT2();
|
|
247
247
|
this.handleT2Timeout();
|
|
248
248
|
}
|
|
@@ -274,7 +274,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
274
274
|
const block = new Secs1MessageBlock(fullBlockBuffer);
|
|
275
275
|
if (block.isValid()) if (block.blockNumber !== this.expectedBlockNum) {
|
|
276
276
|
this.logger.detail.warn({
|
|
277
|
-
protocol: "
|
|
277
|
+
protocol: "SECS-I",
|
|
278
278
|
expected: this.expectedBlockNum,
|
|
279
279
|
got: block.blockNumber
|
|
280
280
|
}, "wrong block number");
|
|
@@ -300,7 +300,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
else {
|
|
303
|
-
this.logger.detail.warn({ protocol: "
|
|
303
|
+
this.logger.detail.warn({ protocol: "SECS-I" }, "invalid checksum");
|
|
304
304
|
this.sendByte(NAK);
|
|
305
305
|
this.state = CommState.IDLE;
|
|
306
306
|
this.resetState();
|
|
@@ -315,7 +315,7 @@ var Secs1Communicator = class extends AbstractSecsCommunicator {
|
|
|
315
315
|
const stream = this.stream;
|
|
316
316
|
const block = this.currentBlocks[this.currentBlockIndex];
|
|
317
317
|
if (stream && !stream.destroyed) {
|
|
318
|
-
this.logger.logBytes("Sent", "
|
|
318
|
+
this.logger.logBytes("Sent", "SECS-I", block.buffer, {
|
|
319
319
|
blockNumber: block.blockNumber,
|
|
320
320
|
eBit: block.eBit,
|
|
321
321
|
systemBytes: block.systemBytes,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secs1Communicator.js","names":[],"sources":["../../src/secs1/Secs1Communicator.ts"],"sourcesContent":["import { Duplex } from \"stream\";\nimport {\n\tAbstractSecsCommunicator,\n\tSecsCommunicatorConfig,\n} from \"../core/AbstractSecsCommunicator.js\";\nimport { SecsMessage } from \"../core/AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"../core/secs2item/AbstractSecs2Item.js\";\nimport { Secs1Message } from \"./Secs1Message.js\";\nimport { Secs1MessageBlock } from \"./Secs1MessageBlock.js\";\n\nexport interface Secs1CommunicatorConfig extends SecsCommunicatorConfig {\n\tretry?: number;\n\tisMaster?: boolean;\n}\n\nconst ENQ = 0x05;\nconst EOT = 0x04;\nconst ACK = 0x06;\nconst NAK = 0x15;\n\nenum CommState {\n\tIDLE,\n\tWAIT_EOT,\n\tWAIT_ACK,\n\tWAIT_BLOCK_LENGTH,\n\tWAIT_BLOCK_DATA,\n}\n\nexport abstract class Secs1Communicator extends AbstractSecsCommunicator {\n\tpublic retry: number;\n\tpublic isMaster: boolean;\n\n\tprotected stream: Duplex | null = null;\n\n\tprivate state: CommState = CommState.IDLE;\n\tprivate buffer: Buffer = Buffer.alloc(0);\n\n\tprivate sendQueue: Buffer[] = [];\n\tprivate currentBlocks: Secs1MessageBlock[] = [];\n\tprivate currentBlockIndex = 0;\n\tprivate retryCount = 0;\n\n\tprivate receivedBlocks: Secs1MessageBlock[] = [];\n\tprivate expectedBlockNum = 1;\n\tprivate currentBlockLength = 0;\n\n\tprivate t1Timer: NodeJS.Timeout | null = null;\n\tprivate t2Timer: NodeJS.Timeout | null = null;\n\tprivate t4Timer: NodeJS.Timeout | null = null;\n\n\tconstructor(config: Secs1CommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.retry = config.retry ?? 3;\n\t\tthis.isMaster = config.isMaster ?? false;\n\t}\n\n\tprotected attachStream(stream: Duplex) {\n\t\tthis.stream = stream;\n\t\tthis.resetState();\n\t\tthis.buffer = Buffer.alloc(0);\n\t\tthis.logger.logState(\"SECS1\", \"NotConnected\", \"Connected\");\n\n\t\tstream.on(\"data\", (data: Buffer) => {\n\t\t\tthis.logger.logBytes(\"Received\", \"SECS1\", data, {\n\t\t\t\tchunkLength: data.length,\n\t\t\t});\n\t\t\tthis.buffer = Buffer.concat([this.buffer, data]);\n\t\t\tif (\n\t\t\t\tthis.state === CommState.WAIT_BLOCK_LENGTH ||\n\t\t\t\tthis.state === CommState.WAIT_BLOCK_DATA\n\t\t\t) {\n\t\t\t\tthis.startT1();\n\t\t\t}\n\t\t\tthis.processBuffer();\n\t\t});\n\n\t\tstream.on(\"close\", () => {\n\t\t\tthis.rejectAllTransactions(new Error(\"Stream closed\"));\n\t\t\tthis.stream = null;\n\t\t\tthis.emit(\"disconnected\");\n\t\t\tthis.logger.logState(\"SECS1\", \"Connected\", \"NotConnected\");\n\t\t\tthis.stopAllTimers();\n\t\t\tthis.resetState();\n\t\t});\n\n\t\tstream.on(\"error\", (err: Error) => {\n\t\t\tthis.emit(\"error\", err);\n\t\t});\n\n\t\tthis.emit(\"connected\");\n\t\tthis.processSendQueue();\n\t}\n\n\tprotected stop() {\n\t\tconst stream = this.stream;\n\t\tif (stream && !stream.destroyed) {\n\t\t\tstream.destroy();\n\t\t}\n\t\tthis.stream = null;\n\t\tthis.stopAllTimers();\n\t\tthis.resetState();\n\t}\n\n\tprotected override async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tawait super.sendBufferWithLogs(\n\t\t\tdirection,\n\t\t\tprotocol === \"SECS\" ? \"SECS1\" : protocol,\n\t\t\tbuffer,\n\t\t\t{\n\t\t\t\tcommState: CommState[this.state],\n\t\t\t\t...meta,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override sendBuffer(buffer: Buffer): Promise<void> {\n\t\tthis.sendQueue.push(buffer);\n\t\tprocess.nextTick(() => this.processSendQueue());\n\t\treturn Promise.resolve();\n\t}\n\n\tprotected override 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\treturn new Secs1Message(\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);\n\t}\n\n\tprivate clearT1() {\n\t\tif (this.t1Timer) {\n\t\t\tclearTimeout(this.t1Timer);\n\t\t\tthis.t1Timer = null;\n\t\t}\n\t}\n\n\tprivate clearT2() {\n\t\tif (this.t2Timer) {\n\t\t\tclearTimeout(this.t2Timer);\n\t\t\tthis.t2Timer = null;\n\t\t}\n\t}\n\n\tprivate clearT4() {\n\t\tif (this.t4Timer) {\n\t\t\tclearTimeout(this.t4Timer);\n\t\t\tthis.t4Timer = null;\n\t\t}\n\t}\n\n\tprivate stopAllTimers() {\n\t\tthis.clearT1();\n\t\tthis.clearT2();\n\t\tthis.clearT4();\n\t}\n\n\tprivate startT1() {\n\t\tthis.clearT1();\n\t\tif (this.timeoutT1 <= 0) return;\n\t\tthis.t1Timer = setTimeout(() => {\n\t\t\tthis.handleT1Timeout();\n\t\t}, this.timeoutT1 * 1000);\n\t}\n\n\tprivate startT2() {\n\t\tthis.clearT2();\n\t\tif (this.timeoutT2 <= 0) return;\n\t\tconst timeout = this.timeoutT2 * 1000;\n\t\tthis.t2Timer = setTimeout(() => {\n\t\t\tthis.handleT2Timeout();\n\t\t}, timeout);\n\t}\n\n\tprivate startT4() {\n\t\tthis.clearT4();\n\t\tif (this.timeoutT4 <= 0) return;\n\t\tconst timeout = this.timeoutT4 * 1000;\n\t\tthis.t4Timer = setTimeout(() => {\n\t\t\tthis.handleT4Timeout();\n\t\t}, timeout);\n\t}\n\n\tprivate handleT1Timeout() {\n\t\tthis.logger.detail.warn({ protocol: \"SECS1\" }, \"t1 timeout\");\n\t\tthis.t1Timer = null;\n\t\tthis.emit(\"error\", new Error(\"T1 Timeout\"));\n\t\tthis.resetState();\n\t}\n\n\tprivate handleT2Timeout() {\n\t\tthis.logger.detail.warn({ protocol: \"SECS1\" }, \"t2 timeout\");\n\t\tthis.t2Timer = null;\n\t\tif (this.state === CommState.WAIT_EOT) {\n\t\t\tthis.retryCount++;\n\t\t\tif (this.retryCount > this.retry) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Retry limit exceeded waiting for EOT\"));\n\t\t\t\tthis.resetState();\n\t\t\t} else {\n\t\t\t\tthis.logger.detail.info(\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol: \"SECS1\",\n\t\t\t\t\t\tretryCount: this.retryCount,\n\t\t\t\t\t\tretry: this.retry,\n\t\t\t\t\t},\n\t\t\t\t\t\"retrying ENQ\",\n\t\t\t\t);\n\t\t\t\tthis.sendByte(ENQ);\n\t\t\t\tthis.startT2();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.state === CommState.WAIT_ACK) {\n\t\t\tthis.retryCount++;\n\t\t\tif (this.retryCount > this.retry) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Retry limit exceeded waiting for ACK\"));\n\t\t\t\tthis.resetState();\n\t\t\t} else {\n\t\t\t\tthis.logger.detail.info(\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol: \"SECS1\",\n\t\t\t\t\t\tretryCount: this.retryCount,\n\t\t\t\t\t\tretry: this.retry,\n\t\t\t\t\t},\n\t\t\t\t\t\"retrying block\",\n\t\t\t\t);\n\t\t\t\tthis.sendCurrentBlock();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.resetState();\n\t}\n\n\tprivate handleT4Timeout() {\n\t\tthis.logger.detail.warn({ protocol: \"SECS1\" }, \"t4 timeout\");\n\t\tthis.t4Timer = null;\n\t\tthis.resetState();\n\t}\n\n\tprivate resetState() {\n\t\tthis.state = CommState.IDLE;\n\t\tthis.receivedBlocks = [];\n\t\tthis.expectedBlockNum = 1;\n\t\tthis.currentBlockLength = 0;\n\t\tthis.stopAllTimers();\n\t}\n\n\tprivate sendByte(byte: number) {\n\t\tconst stream = this.stream;\n\t\tif (stream && !stream.destroyed) {\n\t\t\tconst buf = Buffer.from([byte]);\n\t\t\tthis.logger.logBytes(\"Sent\", \"SECS1\", buf);\n\t\t\tstream.write(buf);\n\t\t}\n\t}\n\n\tprivate processBuffer() {\n\t\twhile (this.buffer.length > 0) {\n\t\t\tswitch (this.state) {\n\t\t\t\tcase CommState.IDLE: {\n\t\t\t\t\tconst byte = this.buffer[0];\n\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\tif (byte === ENQ) {\n\t\t\t\t\t\tthis.logger.detail.debug({ protocol: \"SECS1\" }, \"rx ENQ\");\n\t\t\t\t\t\tthis.sendByte(EOT);\n\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_LENGTH;\n\t\t\t\t\t\tthis.receivedBlocks = [];\n\t\t\t\t\t\tthis.expectedBlockNum = 1;\n\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_EOT: {\n\t\t\t\t\tconst byte = this.buffer[0];\n\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\tif (byte === EOT) {\n\t\t\t\t\t\tthis.logger.detail.debug({ protocol: \"SECS1\" }, \"rx EOT\");\n\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\tthis.currentBlockIndex = 0;\n\t\t\t\t\t\tthis.sendCurrentBlock();\n\t\t\t\t\t} else if (byte === ENQ) {\n\t\t\t\t\t\tif (!this.isMaster) {\n\t\t\t\t\t\t\tthis.logger.detail.debug(\n\t\t\t\t\t\t\t\t{ protocol: \"SECS1\" },\n\t\t\t\t\t\t\t\t\"rx ENQ while waiting EOT\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\t\tthis.sendByte(EOT);\n\t\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_LENGTH;\n\t\t\t\t\t\t\tthis.receivedBlocks = [];\n\t\t\t\t\t\t\tthis.expectedBlockNum = 1;\n\t\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_ACK: {\n\t\t\t\t\tconst byte = this.buffer[0];\n\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\tif (byte === ACK) {\n\t\t\t\t\t\tthis.logger.detail.debug({ protocol: \"SECS1\" }, \"rx ACK\");\n\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\tconst currentBlock = this.currentBlocks[this.currentBlockIndex];\n\t\t\t\t\t\tif (currentBlock.eBit) {\n\t\t\t\t\t\t\tthis.currentBlocks = [];\n\t\t\t\t\t\t\tthis.retryCount = 0;\n\t\t\t\t\t\t\tthis.state = CommState.IDLE;\n\t\t\t\t\t\t\tthis.processSendQueue();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.currentBlockIndex++;\n\t\t\t\t\t\t\tthis.sendCurrentBlock();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (byte === NAK) {\n\t\t\t\t\t\tthis.logger.detail.warn({ protocol: \"SECS1\" }, \"rx NAK\");\n\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\tthis.handleT2Timeout();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_BLOCK_LENGTH: {\n\t\t\t\t\tif (this.t4Timer) {\n\t\t\t\t\t\tthis.clearT4();\n\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t}\n\t\t\t\t\tconst len = this.buffer[0];\n\t\t\t\t\tif (len < 10) {\n\t\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.currentBlockLength = len;\n\t\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_DATA;\n\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_BLOCK_DATA: {\n\t\t\t\t\tif (this.buffer.length >= this.currentBlockLength + 2) {\n\t\t\t\t\t\tconst blockData = this.buffer.subarray(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tthis.currentBlockLength + 2,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.buffer = this.buffer.subarray(this.currentBlockLength + 2);\n\t\t\t\t\t\tthis.stopAllTimers();\n\n\t\t\t\t\t\tconst fullBlockBuffer = Buffer.alloc(1 + blockData.length);\n\t\t\t\t\t\tfullBlockBuffer[0] = this.currentBlockLength;\n\t\t\t\t\t\tblockData.copy(fullBlockBuffer, 1);\n\n\t\t\t\t\t\tconst block = new Secs1MessageBlock(fullBlockBuffer);\n\t\t\t\t\t\tif (block.isValid()) {\n\t\t\t\t\t\t\tif (block.blockNumber !== this.expectedBlockNum) {\n\t\t\t\t\t\t\t\tthis.logger.detail.warn(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tprotocol: \"SECS1\",\n\t\t\t\t\t\t\t\t\t\texpected: this.expectedBlockNum,\n\t\t\t\t\t\t\t\t\t\tgot: block.blockNumber,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"wrong block number\",\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthis.sendByte(NAK);\n\t\t\t\t\t\t\t\tthis.state = CommState.IDLE;\n\t\t\t\t\t\t\t\tthis.resetState();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.sendByte(ACK);\n\t\t\t\t\t\t\t\tthis.receivedBlocks.push(block);\n\t\t\t\t\t\t\t\tif (block.eBit) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tconst msg = Secs1Message.fromBlocks(this.receivedBlocks);\n\t\t\t\t\t\t\t\t\t\tthis.handleMessage(msg);\n\t\t\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t\t\t\t\te instanceof Error ? e : new Error(String(e)),\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.resetState();\n\t\t\t\t\t\t\t\t\tthis.processSendQueue();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tthis.expectedBlockNum++;\n\t\t\t\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_LENGTH;\n\t\t\t\t\t\t\t\t\tthis.startT4();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.logger.detail.warn(\n\t\t\t\t\t\t\t\t{ protocol: \"SECS1\" },\n\t\t\t\t\t\t\t\t\"invalid checksum\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthis.sendByte(NAK);\n\t\t\t\t\t\t\tthis.state = CommState.IDLE;\n\t\t\t\t\t\t\tthis.resetState();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendCurrentBlock() {\n\t\tif (this.currentBlockIndex >= this.currentBlocks.length) return;\n\t\tconst stream = this.stream;\n\t\tconst block = this.currentBlocks[this.currentBlockIndex];\n\t\tif (stream && !stream.destroyed) {\n\t\t\tthis.logger.logBytes(\"Sent\", \"SECS1\", block.buffer, {\n\t\t\t\tblockNumber: block.blockNumber,\n\t\t\t\teBit: block.eBit,\n\t\t\t\tsystemBytes: block.systemBytes,\n\t\t\t\tstream: block.stream,\n\t\t\t\tfunc: block.func,\n\t\t\t});\n\t\t\tstream.write(block.buffer);\n\t\t\tthis.state = CommState.WAIT_ACK;\n\t\t\tthis.startT2();\n\t\t}\n\t}\n\n\tprivate processSendQueue() {\n\t\tif (this.state !== CommState.IDLE) return;\n\t\tconst stream = this.stream;\n\t\tif (!stream || stream.destroyed) return;\n\t\tif (this.sendQueue.length === 0) return;\n\n\t\tconst buffer = this.sendQueue.shift();\n\t\tif (!buffer) return;\n\n\t\ttry {\n\t\t\tconst rBit = (buffer[0] & 0x80) === 0x80;\n\t\t\tconst deviceId = ((buffer[0] & 0x7f) << 8) | buffer[1];\n\t\t\tconst streamId = buffer[2] & 0x7f;\n\t\t\tconst wBit = (buffer[2] & 0x80) === 0x80;\n\t\t\tconst func = buffer[3];\n\t\t\tconst systemBytes = buffer.readUInt32BE(6);\n\t\t\tconst bodyBuffer = buffer.subarray(10);\n\n\t\t\tthis.currentBlocks = [];\n\t\t\tlet pos = 0;\n\t\t\tlet blockNum = 1;\n\n\t\t\tif (bodyBuffer.length === 0) {\n\t\t\t\tthis.currentBlocks.push(\n\t\t\t\t\tSecs1MessageBlock.fromParts(\n\t\t\t\t\t\tdeviceId,\n\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\tfunc,\n\t\t\t\t\t\twBit,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tblockNum,\n\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\tBuffer.alloc(0),\n\t\t\t\t\t\trBit,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\twhile (pos < bodyBuffer.length) {\n\t\t\t\t\tconst remaining = bodyBuffer.length - pos;\n\t\t\t\t\tconst chunkSize = remaining > 244 ? 244 : remaining;\n\t\t\t\t\tconst chunk = bodyBuffer.subarray(pos, pos + chunkSize);\n\t\t\t\t\tconst isLast = pos + chunkSize >= bodyBuffer.length;\n\n\t\t\t\t\tthis.currentBlocks.push(\n\t\t\t\t\t\tSecs1MessageBlock.fromParts(\n\t\t\t\t\t\t\tdeviceId,\n\t\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\t\tfunc,\n\t\t\t\t\t\t\twBit,\n\t\t\t\t\t\t\tisLast,\n\t\t\t\t\t\t\tblockNum,\n\t\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\trBit,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tpos += chunkSize;\n\t\t\t\t\tblockNum++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.currentBlockIndex = 0;\n\t\t\tthis.retryCount = 0;\n\n\t\t\tthis.sendByte(ENQ);\n\t\t\tthis.state = CommState.WAIT_EOT;\n\t\t\tthis.startT2();\n\t\t} catch (e) {\n\t\t\tthis.emit(\"error\", e instanceof Error ? e : new Error(String(e)));\n\t\t\tthis.processSendQueue();\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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"}
|
|
1
|
+
{"version":3,"file":"Secs1Communicator.js","names":[],"sources":["../../src/secs1/Secs1Communicator.ts"],"sourcesContent":["import { Duplex } from \"stream\";\nimport {\n\tAbstractSecsCommunicator,\n\tSecsCommunicatorConfig,\n} from \"../core/AbstractSecsCommunicator.js\";\nimport { SecsMessage } from \"../core/AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"../core/secs2item/AbstractSecs2Item.js\";\nimport { Secs1Message } from \"./Secs1Message.js\";\nimport { Secs1MessageBlock } from \"./Secs1MessageBlock.js\";\n\nexport interface Secs1CommunicatorConfig extends SecsCommunicatorConfig {\n\tretry?: number;\n\tisMaster?: boolean;\n}\n\nconst ENQ = 0x05;\nconst EOT = 0x04;\nconst ACK = 0x06;\nconst NAK = 0x15;\n\nenum CommState {\n\tIDLE,\n\tWAIT_EOT,\n\tWAIT_ACK,\n\tWAIT_BLOCK_LENGTH,\n\tWAIT_BLOCK_DATA,\n}\n\nexport abstract class Secs1Communicator extends AbstractSecsCommunicator {\n\tpublic retry: number;\n\tpublic isMaster: boolean;\n\n\tprotected stream: Duplex | null = null;\n\n\tprivate state: CommState = CommState.IDLE;\n\tprivate buffer: Buffer = Buffer.alloc(0);\n\n\tprivate sendQueue: Buffer[] = [];\n\tprivate currentBlocks: Secs1MessageBlock[] = [];\n\tprivate currentBlockIndex = 0;\n\tprivate retryCount = 0;\n\n\tprivate receivedBlocks: Secs1MessageBlock[] = [];\n\tprivate expectedBlockNum = 1;\n\tprivate currentBlockLength = 0;\n\n\tprivate t1Timer: NodeJS.Timeout | null = null;\n\tprivate t2Timer: NodeJS.Timeout | null = null;\n\tprivate t4Timer: NodeJS.Timeout | null = null;\n\n\tconstructor(config: Secs1CommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.retry = config.retry ?? 3;\n\t\tthis.isMaster = config.isMaster ?? false;\n\t}\n\n\tprotected attachStream(stream: Duplex) {\n\t\tthis.stream = stream;\n\t\tthis.resetState();\n\t\tthis.buffer = Buffer.alloc(0);\n\t\tthis.logger.logState(\"SECS-I\", \"NotConnected\", \"Connected\");\n\n\t\tstream.on(\"data\", (data: Buffer) => {\n\t\t\tthis.logger.logBytes(\"Received\", \"SECS-I\", data, {\n\t\t\t\tchunkLength: data.length,\n\t\t\t});\n\t\t\tthis.buffer = Buffer.concat([this.buffer, data]);\n\t\t\tif (\n\t\t\t\tthis.state === CommState.WAIT_BLOCK_LENGTH ||\n\t\t\t\tthis.state === CommState.WAIT_BLOCK_DATA\n\t\t\t) {\n\t\t\t\tthis.startT1();\n\t\t\t}\n\t\t\tthis.processBuffer();\n\t\t});\n\n\t\tstream.on(\"close\", () => {\n\t\t\tthis.rejectAllTransactions(new Error(\"Stream closed\"));\n\t\t\tthis.stream = null;\n\t\t\tthis.emit(\"disconnected\");\n\t\t\tthis.logger.logState(\"SECS-I\", \"Connected\", \"NotConnected\");\n\t\t\tthis.stopAllTimers();\n\t\t\tthis.resetState();\n\t\t});\n\n\t\tstream.on(\"error\", (err: Error) => {\n\t\t\tthis.emit(\"error\", err);\n\t\t});\n\n\t\tthis.emit(\"connected\");\n\t\tthis.processSendQueue();\n\t}\n\n\tprotected stop() {\n\t\tconst stream = this.stream;\n\t\tif (stream && !stream.destroyed) {\n\t\t\tstream.destroy();\n\t\t}\n\t\tthis.stream = null;\n\t\tthis.stopAllTimers();\n\t\tthis.resetState();\n\t}\n\n\tprotected override async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tawait super.sendBufferWithLogs(\n\t\t\tdirection,\n\t\t\tprotocol === \"SECS\" ? \"SECS1\" : protocol,\n\t\t\tbuffer,\n\t\t\t{\n\t\t\t\tcommState: CommState[this.state],\n\t\t\t\t...meta,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected override sendBuffer(buffer: Buffer): Promise<void> {\n\t\tthis.sendQueue.push(buffer);\n\t\tprocess.nextTick(() => this.processSendQueue());\n\t\treturn Promise.resolve();\n\t}\n\n\tprotected override 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\treturn new Secs1Message(\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);\n\t}\n\n\tprivate clearT1() {\n\t\tif (this.t1Timer) {\n\t\t\tclearTimeout(this.t1Timer);\n\t\t\tthis.t1Timer = null;\n\t\t}\n\t}\n\n\tprivate clearT2() {\n\t\tif (this.t2Timer) {\n\t\t\tclearTimeout(this.t2Timer);\n\t\t\tthis.t2Timer = null;\n\t\t}\n\t}\n\n\tprivate clearT4() {\n\t\tif (this.t4Timer) {\n\t\t\tclearTimeout(this.t4Timer);\n\t\t\tthis.t4Timer = null;\n\t\t}\n\t}\n\n\tprivate stopAllTimers() {\n\t\tthis.clearT1();\n\t\tthis.clearT2();\n\t\tthis.clearT4();\n\t}\n\n\tprivate startT1() {\n\t\tthis.clearT1();\n\t\tif (this.timeoutT1 <= 0) return;\n\t\tthis.t1Timer = setTimeout(() => {\n\t\t\tthis.handleT1Timeout();\n\t\t}, this.timeoutT1 * 1000);\n\t}\n\n\tprivate startT2() {\n\t\tthis.clearT2();\n\t\tif (this.timeoutT2 <= 0) return;\n\t\tconst timeout = this.timeoutT2 * 1000;\n\t\tthis.t2Timer = setTimeout(() => {\n\t\t\tthis.handleT2Timeout();\n\t\t}, timeout);\n\t}\n\n\tprivate startT4() {\n\t\tthis.clearT4();\n\t\tif (this.timeoutT4 <= 0) return;\n\t\tconst timeout = this.timeoutT4 * 1000;\n\t\tthis.t4Timer = setTimeout(() => {\n\t\t\tthis.handleT4Timeout();\n\t\t}, timeout);\n\t}\n\n\tprivate handleT1Timeout() {\n\t\tthis.logger.detail.warn({ protocol: \"SECS-I\" }, \"t1 timeout\");\n\t\tthis.t1Timer = null;\n\t\tthis.emit(\"error\", new Error(\"T1 Timeout\"));\n\t\tthis.resetState();\n\t}\n\n\tprivate handleT2Timeout() {\n\t\tthis.logger.detail.warn({ protocol: \"SECS-I\" }, \"t2 timeout\");\n\t\tthis.t2Timer = null;\n\t\tif (this.state === CommState.WAIT_EOT) {\n\t\t\tthis.retryCount++;\n\t\t\tif (this.retryCount > this.retry) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Retry limit exceeded waiting for EOT\"));\n\t\t\t\tthis.resetState();\n\t\t\t} else {\n\t\t\t\tthis.logger.detail.info(\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol: \"SECS-I\",\n\t\t\t\t\t\tretryCount: this.retryCount,\n\t\t\t\t\t\tretry: this.retry,\n\t\t\t\t\t},\n\t\t\t\t\t\"retrying ENQ\",\n\t\t\t\t);\n\t\t\t\tthis.sendByte(ENQ);\n\t\t\t\tthis.startT2();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.state === CommState.WAIT_ACK) {\n\t\t\tthis.retryCount++;\n\t\t\tif (this.retryCount > this.retry) {\n\t\t\t\tthis.emit(\"error\", new Error(\"Retry limit exceeded waiting for ACK\"));\n\t\t\t\tthis.resetState();\n\t\t\t} else {\n\t\t\t\tthis.logger.detail.info(\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol: \"SECS-I\",\n\t\t\t\t\t\tretryCount: this.retryCount,\n\t\t\t\t\t\tretry: this.retry,\n\t\t\t\t\t},\n\t\t\t\t\t\"retrying block\",\n\t\t\t\t);\n\t\t\t\tthis.sendCurrentBlock();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.resetState();\n\t}\n\n\tprivate handleT4Timeout() {\n\t\tthis.logger.detail.warn({ protocol: \"SECS-I\" }, \"t4 timeout\");\n\t\tthis.t4Timer = null;\n\t\tthis.resetState();\n\t}\n\n\tprivate resetState() {\n\t\tthis.state = CommState.IDLE;\n\t\tthis.receivedBlocks = [];\n\t\tthis.expectedBlockNum = 1;\n\t\tthis.currentBlockLength = 0;\n\t\tthis.stopAllTimers();\n\t}\n\n\tprivate sendByte(byte: number) {\n\t\tconst stream = this.stream;\n\t\tif (stream && !stream.destroyed) {\n\t\t\tconst buf = Buffer.from([byte]);\n\t\t\tthis.logger.logBytes(\"Sent\", \"SECS-I\", buf);\n\t\t\tstream.write(buf);\n\t\t}\n\t}\n\n\tprivate processBuffer() {\n\t\twhile (this.buffer.length > 0) {\n\t\t\tswitch (this.state) {\n\t\t\t\tcase CommState.IDLE: {\n\t\t\t\t\tconst byte = this.buffer[0];\n\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\tif (byte === ENQ) {\n\t\t\t\t\t\tthis.logger.detail.debug({ protocol: \"SECS-I\" }, \"rx ENQ\");\n\t\t\t\t\t\tthis.sendByte(EOT);\n\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_LENGTH;\n\t\t\t\t\t\tthis.receivedBlocks = [];\n\t\t\t\t\t\tthis.expectedBlockNum = 1;\n\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_EOT: {\n\t\t\t\t\tconst byte = this.buffer[0];\n\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\tif (byte === EOT) {\n\t\t\t\t\t\tthis.logger.detail.debug({ protocol: \"SECS-I\" }, \"rx EOT\");\n\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\tthis.currentBlockIndex = 0;\n\t\t\t\t\t\tthis.sendCurrentBlock();\n\t\t\t\t\t} else if (byte === ENQ) {\n\t\t\t\t\t\tif (!this.isMaster) {\n\t\t\t\t\t\t\tthis.logger.detail.debug(\n\t\t\t\t\t\t\t\t{ protocol: \"SECS-I\" },\n\t\t\t\t\t\t\t\t\"rx ENQ while waiting EOT\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\t\tthis.sendByte(EOT);\n\t\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_LENGTH;\n\t\t\t\t\t\t\tthis.receivedBlocks = [];\n\t\t\t\t\t\t\tthis.expectedBlockNum = 1;\n\t\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_ACK: {\n\t\t\t\t\tconst byte = this.buffer[0];\n\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\tif (byte === ACK) {\n\t\t\t\t\t\tthis.logger.detail.debug({ protocol: \"SECS-I\" }, \"rx ACK\");\n\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\tconst currentBlock = this.currentBlocks[this.currentBlockIndex];\n\t\t\t\t\t\tif (currentBlock.eBit) {\n\t\t\t\t\t\t\tthis.currentBlocks = [];\n\t\t\t\t\t\t\tthis.retryCount = 0;\n\t\t\t\t\t\t\tthis.state = CommState.IDLE;\n\t\t\t\t\t\t\tthis.processSendQueue();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.currentBlockIndex++;\n\t\t\t\t\t\t\tthis.sendCurrentBlock();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (byte === NAK) {\n\t\t\t\t\t\tthis.logger.detail.warn({ protocol: \"SECS-I\" }, \"rx NAK\");\n\t\t\t\t\t\tthis.clearT2();\n\t\t\t\t\t\tthis.handleT2Timeout();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_BLOCK_LENGTH: {\n\t\t\t\t\tif (this.t4Timer) {\n\t\t\t\t\t\tthis.clearT4();\n\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t}\n\t\t\t\t\tconst len = this.buffer[0];\n\t\t\t\t\tif (len < 10) {\n\t\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.currentBlockLength = len;\n\t\t\t\t\t\tthis.buffer = this.buffer.subarray(1);\n\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_DATA;\n\t\t\t\t\t\tthis.startT1();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase CommState.WAIT_BLOCK_DATA: {\n\t\t\t\t\tif (this.buffer.length >= this.currentBlockLength + 2) {\n\t\t\t\t\t\tconst blockData = this.buffer.subarray(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tthis.currentBlockLength + 2,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.buffer = this.buffer.subarray(this.currentBlockLength + 2);\n\t\t\t\t\t\tthis.stopAllTimers();\n\n\t\t\t\t\t\tconst fullBlockBuffer = Buffer.alloc(1 + blockData.length);\n\t\t\t\t\t\tfullBlockBuffer[0] = this.currentBlockLength;\n\t\t\t\t\t\tblockData.copy(fullBlockBuffer, 1);\n\n\t\t\t\t\t\tconst block = new Secs1MessageBlock(fullBlockBuffer);\n\t\t\t\t\t\tif (block.isValid()) {\n\t\t\t\t\t\t\tif (block.blockNumber !== this.expectedBlockNum) {\n\t\t\t\t\t\t\t\tthis.logger.detail.warn(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tprotocol: \"SECS-I\",\n\t\t\t\t\t\t\t\t\t\texpected: this.expectedBlockNum,\n\t\t\t\t\t\t\t\t\t\tgot: block.blockNumber,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"wrong block number\",\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tthis.sendByte(NAK);\n\t\t\t\t\t\t\t\tthis.state = CommState.IDLE;\n\t\t\t\t\t\t\t\tthis.resetState();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.sendByte(ACK);\n\t\t\t\t\t\t\t\tthis.receivedBlocks.push(block);\n\t\t\t\t\t\t\t\tif (block.eBit) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tconst msg = Secs1Message.fromBlocks(this.receivedBlocks);\n\t\t\t\t\t\t\t\t\t\tthis.handleMessage(msg);\n\t\t\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t\t\t\t\te instanceof Error ? e : new Error(String(e)),\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tthis.resetState();\n\t\t\t\t\t\t\t\t\tthis.processSendQueue();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tthis.expectedBlockNum++;\n\t\t\t\t\t\t\t\t\tthis.state = CommState.WAIT_BLOCK_LENGTH;\n\t\t\t\t\t\t\t\t\tthis.startT4();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.logger.detail.warn(\n\t\t\t\t\t\t\t\t{ protocol: \"SECS-I\" },\n\t\t\t\t\t\t\t\t\"invalid checksum\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthis.sendByte(NAK);\n\t\t\t\t\t\t\tthis.state = CommState.IDLE;\n\t\t\t\t\t\t\tthis.resetState();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendCurrentBlock() {\n\t\tif (this.currentBlockIndex >= this.currentBlocks.length) return;\n\t\tconst stream = this.stream;\n\t\tconst block = this.currentBlocks[this.currentBlockIndex];\n\t\tif (stream && !stream.destroyed) {\n\t\t\tthis.logger.logBytes(\"Sent\", \"SECS-I\", block.buffer, {\n\t\t\t\tblockNumber: block.blockNumber,\n\t\t\t\teBit: block.eBit,\n\t\t\t\tsystemBytes: block.systemBytes,\n\t\t\t\tstream: block.stream,\n\t\t\t\tfunc: block.func,\n\t\t\t});\n\t\t\tstream.write(block.buffer);\n\t\t\tthis.state = CommState.WAIT_ACK;\n\t\t\tthis.startT2();\n\t\t}\n\t}\n\n\tprivate processSendQueue() {\n\t\tif (this.state !== CommState.IDLE) return;\n\t\tconst stream = this.stream;\n\t\tif (!stream || stream.destroyed) return;\n\t\tif (this.sendQueue.length === 0) return;\n\n\t\tconst buffer = this.sendQueue.shift();\n\t\tif (!buffer) return;\n\n\t\ttry {\n\t\t\tconst rBit = (buffer[0] & 0x80) === 0x80;\n\t\t\tconst deviceId = ((buffer[0] & 0x7f) << 8) | buffer[1];\n\t\t\tconst streamId = buffer[2] & 0x7f;\n\t\t\tconst wBit = (buffer[2] & 0x80) === 0x80;\n\t\t\tconst func = buffer[3];\n\t\t\tconst systemBytes = buffer.readUInt32BE(6);\n\t\t\tconst bodyBuffer = buffer.subarray(10);\n\n\t\t\tthis.currentBlocks = [];\n\t\t\tlet pos = 0;\n\t\t\tlet blockNum = 1;\n\n\t\t\tif (bodyBuffer.length === 0) {\n\t\t\t\tthis.currentBlocks.push(\n\t\t\t\t\tSecs1MessageBlock.fromParts(\n\t\t\t\t\t\tdeviceId,\n\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\tfunc,\n\t\t\t\t\t\twBit,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tblockNum,\n\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\tBuffer.alloc(0),\n\t\t\t\t\t\trBit,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\twhile (pos < bodyBuffer.length) {\n\t\t\t\t\tconst remaining = bodyBuffer.length - pos;\n\t\t\t\t\tconst chunkSize = remaining > 244 ? 244 : remaining;\n\t\t\t\t\tconst chunk = bodyBuffer.subarray(pos, pos + chunkSize);\n\t\t\t\t\tconst isLast = pos + chunkSize >= bodyBuffer.length;\n\n\t\t\t\t\tthis.currentBlocks.push(\n\t\t\t\t\t\tSecs1MessageBlock.fromParts(\n\t\t\t\t\t\t\tdeviceId,\n\t\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\t\tfunc,\n\t\t\t\t\t\t\twBit,\n\t\t\t\t\t\t\tisLast,\n\t\t\t\t\t\t\tblockNum,\n\t\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\trBit,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\tpos += chunkSize;\n\t\t\t\t\tblockNum++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.currentBlockIndex = 0;\n\t\t\tthis.retryCount = 0;\n\n\t\t\tthis.sendByte(ENQ);\n\t\t\tthis.state = CommState.WAIT_EOT;\n\t\t\tthis.startT2();\n\t\t} catch (e) {\n\t\t\tthis.emit(\"error\", e instanceof Error ? e : new Error(String(e)));\n\t\t\tthis.processSendQueue();\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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"}
|
|
@@ -16,7 +16,7 @@ var Secs1OnTcpIpActiveCommunicator = class extends Secs1Communicator {
|
|
|
16
16
|
this.on("disconnected", () => {
|
|
17
17
|
if (!this.shouldStop) {
|
|
18
18
|
this.logger.detail.warn({
|
|
19
|
-
protocol: "
|
|
19
|
+
protocol: "SECS-I-TCP/IP",
|
|
20
20
|
ip: this.ip,
|
|
21
21
|
port: this.port,
|
|
22
22
|
timeoutT5: this.timeoutT5
|
|
@@ -44,7 +44,7 @@ var Secs1OnTcpIpActiveCommunicator = class extends Secs1Communicator {
|
|
|
44
44
|
const onError = (err) => {
|
|
45
45
|
socket.destroy();
|
|
46
46
|
this.logger.detail.warn({
|
|
47
|
-
protocol: "
|
|
47
|
+
protocol: "SECS-I-TCP/IP",
|
|
48
48
|
ip: this.ip,
|
|
49
49
|
port: this.port,
|
|
50
50
|
timeoutT5: this.timeoutT5,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secs1OnTcpIpActiveCommunicator.js","names":[],"sources":["../../src/secs1/Secs1OnTcpIpActiveCommunicator.ts"],"sourcesContent":["import { Socket } from \"net\";\nimport {\n\tSecs1Communicator,\n\tSecs1CommunicatorConfig,\n} from \"./Secs1Communicator.js\";\n\nexport interface Secs1OnTcpIpActiveCommunicatorConfig extends Secs1CommunicatorConfig {\n\tip: string;\n\tport: number;\n}\n\nexport class Secs1OnTcpIpActiveCommunicator extends Secs1Communicator {\n\tpublic ip: string;\n\tpublic port: number;\n\n\tprivate shouldStop = false;\n\tprivate reconnectTimer: NodeJS.Timeout | null = null;\n\tprivate connectionPromiseResolver: (() => void) | null = null;\n\tprivate pendingSocket: Socket | null = null;\n\n\tconstructor(config: Secs1OnTcpIpActiveCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.ip = config.ip;\n\t\tthis.port = config.port;\n\t\tthis.on(\"disconnected\", () => {\n\t\t\tif (!this.shouldStop) {\n\t\t\t\tthis.logger.detail.warn(\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol: \"
|
|
1
|
+
{"version":3,"file":"Secs1OnTcpIpActiveCommunicator.js","names":[],"sources":["../../src/secs1/Secs1OnTcpIpActiveCommunicator.ts"],"sourcesContent":["import { Socket } from \"net\";\nimport {\n\tSecs1Communicator,\n\tSecs1CommunicatorConfig,\n} from \"./Secs1Communicator.js\";\n\nexport interface Secs1OnTcpIpActiveCommunicatorConfig extends Secs1CommunicatorConfig {\n\tip: string;\n\tport: number;\n}\n\nexport class Secs1OnTcpIpActiveCommunicator extends Secs1Communicator {\n\tpublic ip: string;\n\tpublic port: number;\n\n\tprivate shouldStop = false;\n\tprivate reconnectTimer: NodeJS.Timeout | null = null;\n\tprivate connectionPromiseResolver: (() => void) | null = null;\n\tprivate pendingSocket: Socket | null = null;\n\n\tconstructor(config: Secs1OnTcpIpActiveCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.ip = config.ip;\n\t\tthis.port = config.port;\n\t\tthis.on(\"disconnected\", () => {\n\t\t\tif (!this.shouldStop) {\n\t\t\t\tthis.logger.detail.warn(\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol: \"SECS-I-TCP/IP\",\n\t\t\t\t\t\tip: this.ip,\n\t\t\t\t\t\tport: this.port,\n\t\t\t\t\t\ttimeoutT5: this.timeoutT5,\n\t\t\t\t\t},\n\t\t\t\t\t\"connection lost; scheduling reconnect\",\n\t\t\t\t);\n\t\t\t\tthis.scheduleReconnect();\n\t\t\t}\n\t\t});\n\t}\n\n\tasync open(): Promise<void> {\n\t\tif (this.stream && !this.stream.destroyed) return;\n\t\tif (this.pendingSocket && !this.pendingSocket.destroyed) return;\n\n\t\tthis.shouldStop = false;\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.connectionPromiseResolver = resolve;\n\t\t\tthis.connect();\n\t\t});\n\t}\n\n\tprivate connect() {\n\t\tif (this.shouldStop) return;\n\t\tif (this.stream && !this.stream.destroyed) return;\n\t\tif (this.pendingSocket && !this.pendingSocket.destroyed) return;\n\n\t\tconst socket = new Socket();\n\t\tsocket.setNoDelay(true);\n\t\tthis.pendingSocket = socket;\n\n\t\tconst onError = (err: Error) => {\n\t\t\tsocket.destroy();\n\t\t\tthis.logger.detail.warn(\n\t\t\t\t{\n\t\t\t\t\tprotocol: \"SECS-I-TCP/IP\",\n\t\t\t\t\tip: this.ip,\n\t\t\t\t\tport: this.port,\n\t\t\t\t\ttimeoutT5: this.timeoutT5,\n\t\t\t\t\terr,\n\t\t\t\t},\n\t\t\t\t\"connection failed; scheduling reconnect\",\n\t\t\t);\n\t\t\tif (!this.shouldStop) {\n\t\t\t\tthis.scheduleReconnect();\n\t\t\t}\n\t\t};\n\n\t\tsocket.once(\"error\", onError);\n\n\t\tsocket.once(\"close\", () => {\n\t\t\tif (this.pendingSocket === socket) {\n\t\t\t\tthis.pendingSocket = null;\n\t\t\t}\n\t\t});\n\n\t\tsocket.connect(this.port, this.ip, () => {\n\t\t\tsocket.removeListener(\"error\", onError);\n\t\t\tif (this.pendingSocket === socket) {\n\t\t\t\tthis.pendingSocket = null;\n\t\t\t}\n\t\t\tthis.attachStream(socket);\n\n\t\t\tif (this.connectionPromiseResolver) {\n\t\t\t\tthis.connectionPromiseResolver();\n\t\t\t\tthis.connectionPromiseResolver = null;\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate scheduleReconnect() {\n\t\tif (this.reconnectTimer) {\n\t\t\tclearTimeout(this.reconnectTimer);\n\t\t}\n\t\tthis.reconnectTimer = setTimeout(() => {\n\t\t\tthis.reconnectTimer = null;\n\t\t\tthis.connect();\n\t\t}, this.timeoutT5 * 1000);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.shouldStop = true;\n\t\tif (this.reconnectTimer) {\n\t\t\tclearTimeout(this.reconnectTimer);\n\t\t\tthis.reconnectTimer = null;\n\t\t}\n\t\tif (this.pendingSocket) {\n\t\t\tthis.pendingSocket.destroy();\n\t\t\tthis.pendingSocket = null;\n\t\t}\n\t\tthis.stop();\n\t\tawait Promise.resolve();\n\t}\n}\n"],"mappings":";;;;AAWA,IAAa,iCAAb,cAAoD,kBAAkB;CACrE,AAAO;CACP,AAAO;CAEP,AAAQ,aAAa;CACrB,AAAQ,iBAAwC;CAChD,AAAQ,4BAAiD;CACzD,AAAQ,gBAA+B;CAEvC,YAAY,QAA8C;AACzD,QAAM,OAAO;AACb,OAAK,KAAK,OAAO;AACjB,OAAK,OAAO,OAAO;AACnB,OAAK,GAAG,sBAAsB;AAC7B,OAAI,CAAC,KAAK,YAAY;AACrB,SAAK,OAAO,OAAO,KAClB;KACC,UAAU;KACV,IAAI,KAAK;KACT,MAAM,KAAK;KACX,WAAW,KAAK;KAChB,EACD,wCACA;AACD,SAAK,mBAAmB;;IAExB;;CAGH,MAAM,OAAsB;AAC3B,MAAI,KAAK,UAAU,CAAC,KAAK,OAAO,UAAW;AAC3C,MAAI,KAAK,iBAAiB,CAAC,KAAK,cAAc,UAAW;AAEzD,OAAK,aAAa;AAElB,SAAO,IAAI,SAAS,YAAY;AAC/B,QAAK,4BAA4B;AACjC,QAAK,SAAS;IACb;;CAGH,AAAQ,UAAU;AACjB,MAAI,KAAK,WAAY;AACrB,MAAI,KAAK,UAAU,CAAC,KAAK,OAAO,UAAW;AAC3C,MAAI,KAAK,iBAAiB,CAAC,KAAK,cAAc,UAAW;EAEzD,MAAM,SAAS,IAAI,QAAQ;AAC3B,SAAO,WAAW,KAAK;AACvB,OAAK,gBAAgB;EAErB,MAAM,WAAW,QAAe;AAC/B,UAAO,SAAS;AAChB,QAAK,OAAO,OAAO,KAClB;IACC,UAAU;IACV,IAAI,KAAK;IACT,MAAM,KAAK;IACX,WAAW,KAAK;IAChB;IACA,EACD,0CACA;AACD,OAAI,CAAC,KAAK,WACT,MAAK,mBAAmB;;AAI1B,SAAO,KAAK,SAAS,QAAQ;AAE7B,SAAO,KAAK,eAAe;AAC1B,OAAI,KAAK,kBAAkB,OAC1B,MAAK,gBAAgB;IAErB;AAEF,SAAO,QAAQ,KAAK,MAAM,KAAK,UAAU;AACxC,UAAO,eAAe,SAAS,QAAQ;AACvC,OAAI,KAAK,kBAAkB,OAC1B,MAAK,gBAAgB;AAEtB,QAAK,aAAa,OAAO;AAEzB,OAAI,KAAK,2BAA2B;AACnC,SAAK,2BAA2B;AAChC,SAAK,4BAA4B;;IAEjC;;CAGH,AAAQ,oBAAoB;AAC3B,MAAI,KAAK,eACR,cAAa,KAAK,eAAe;AAElC,OAAK,iBAAiB,iBAAiB;AACtC,QAAK,iBAAiB;AACtB,QAAK,SAAS;KACZ,KAAK,YAAY,IAAK;;CAG1B,MAAM,QAAuB;AAC5B,OAAK,aAAa;AAClB,MAAI,KAAK,gBAAgB;AACxB,gBAAa,KAAK,eAAe;AACjC,QAAK,iBAAiB;;AAEvB,MAAI,KAAK,eAAe;AACvB,QAAK,cAAc,SAAS;AAC5B,QAAK,gBAAgB;;AAEtB,OAAK,MAAM;AACX,QAAM,QAAQ,SAAS"}
|
|
@@ -4,15 +4,21 @@ import { Secs1Communicator, Secs1CommunicatorConfig } from "./Secs1Communicator.
|
|
|
4
4
|
interface Secs1OnTcpIpPassiveCommunicatorConfig extends Secs1CommunicatorConfig {
|
|
5
5
|
ip: string;
|
|
6
6
|
port: number;
|
|
7
|
+
timeoutRebind?: number;
|
|
7
8
|
}
|
|
8
9
|
declare class Secs1OnTcpIpPassiveCommunicator extends Secs1Communicator {
|
|
9
10
|
ip: string;
|
|
10
11
|
port: number;
|
|
11
12
|
private server;
|
|
13
|
+
private shouldStop;
|
|
14
|
+
private serverLoopPromise;
|
|
15
|
+
private timeoutRebind;
|
|
12
16
|
constructor(config: Secs1OnTcpIpPassiveCommunicatorConfig);
|
|
13
17
|
open(): Promise<void>;
|
|
14
|
-
|
|
18
|
+
private runServerLoop;
|
|
19
|
+
private listenOnce;
|
|
15
20
|
private handleIncomingSocket;
|
|
21
|
+
close(): Promise<void>;
|
|
16
22
|
}
|
|
17
23
|
//#endregion
|
|
18
24
|
export { Secs1OnTcpIpPassiveCommunicator, Secs1OnTcpIpPassiveCommunicatorConfig };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secs1OnTcpIpPassiveCommunicator.d.ts","names":[],"sources":["../../src/secs1/Secs1OnTcpIpPassiveCommunicator.ts"],"sourcesContent":[],"mappings":";;;UAMiB,qCAAA,SAA8C;;EAA9C,IAAA,EAAA,MAAA;
|
|
1
|
+
{"version":3,"file":"Secs1OnTcpIpPassiveCommunicator.d.ts","names":[],"sources":["../../src/secs1/Secs1OnTcpIpPassiveCommunicator.ts"],"sourcesContent":[],"mappings":";;;UAMiB,qCAAA,SAA8C;;EAA9C,IAAA,EAAA,MAAA;EAMJ,aAAA,CAAA,EAAA,MAAA;;AAkBE,cAlBF,+BAAA,SAAwC,iBAAA,CAkBtC;EA6IL,EAAA,EAAA,MAAA;EA/J2C,IAAA,EAAA,MAAA;EAAiB,QAAA,MAAA;;;;sBASjD;UASN;;;;WA6IL"}
|
|
@@ -6,50 +6,136 @@ var Secs1OnTcpIpPassiveCommunicator = class extends Secs1Communicator {
|
|
|
6
6
|
ip;
|
|
7
7
|
port;
|
|
8
8
|
server = null;
|
|
9
|
+
shouldStop = false;
|
|
10
|
+
serverLoopPromise = null;
|
|
11
|
+
timeoutRebind = 5;
|
|
9
12
|
constructor(config) {
|
|
10
13
|
super(config);
|
|
11
14
|
this.ip = config.ip;
|
|
12
15
|
this.port = config.port;
|
|
16
|
+
if (config.timeoutRebind !== void 0) this.timeoutRebind = config.timeoutRebind;
|
|
13
17
|
}
|
|
14
18
|
async open() {
|
|
15
|
-
if (this.
|
|
19
|
+
if (this.serverLoopPromise) return;
|
|
20
|
+
this.shouldStop = false;
|
|
21
|
+
let resolveFirstListen = null;
|
|
22
|
+
const firstListen = new Promise((resolve) => {
|
|
23
|
+
resolveFirstListen = resolve;
|
|
24
|
+
});
|
|
25
|
+
this.serverLoopPromise = this.runServerLoop(() => {
|
|
26
|
+
resolveFirstListen?.();
|
|
27
|
+
resolveFirstListen = null;
|
|
28
|
+
}).catch((err) => {
|
|
29
|
+
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
30
|
+
});
|
|
31
|
+
await firstListen;
|
|
32
|
+
}
|
|
33
|
+
async runServerLoop(onFirstListening) {
|
|
34
|
+
let first = true;
|
|
35
|
+
while (!this.shouldStop) {
|
|
36
|
+
try {
|
|
37
|
+
await this.listenOnce(first ? onFirstListening : null);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
if (!this.shouldStop) this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
40
|
+
if (!this.shouldStop) await new Promise((resolve) => setTimeout(resolve, this.timeoutRebind * 1e3));
|
|
41
|
+
}
|
|
42
|
+
first = false;
|
|
43
|
+
if (this.shouldStop) return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async listenOnce(onListening) {
|
|
16
47
|
return new Promise((resolve, reject) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
48
|
+
const server = createServer((socket) => {
|
|
49
|
+
this.handleIncomingSocket(socket);
|
|
50
|
+
});
|
|
51
|
+
this.server = server;
|
|
52
|
+
let hasConnected = false;
|
|
53
|
+
let settled = false;
|
|
54
|
+
const cleanup = () => {
|
|
55
|
+
server.removeListener("error", onServerError);
|
|
56
|
+
server.removeListener("close", onServerClose);
|
|
57
|
+
this.removeListener("connected", onConnected);
|
|
58
|
+
this.removeListener("disconnected", onDisconnected);
|
|
59
|
+
};
|
|
60
|
+
const finish = (err) => {
|
|
61
|
+
if (settled) return;
|
|
62
|
+
settled = true;
|
|
63
|
+
if (this.server === server) this.server = null;
|
|
64
|
+
cleanup();
|
|
65
|
+
if (err) reject(err);
|
|
66
|
+
else resolve();
|
|
67
|
+
};
|
|
68
|
+
const closeServer = () => {
|
|
69
|
+
if (settled) return;
|
|
70
|
+
if (!server.listening) {
|
|
71
|
+
finish();
|
|
25
72
|
return;
|
|
26
73
|
}
|
|
27
|
-
|
|
28
|
-
|
|
74
|
+
server.close((closeErr) => {
|
|
75
|
+
if (closeErr) finish(closeErr);
|
|
76
|
+
else finish();
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const onServerError = (_err) => {
|
|
80
|
+
closeServer();
|
|
81
|
+
};
|
|
82
|
+
const onServerClose = () => {
|
|
83
|
+
finish();
|
|
84
|
+
};
|
|
85
|
+
const onConnected = () => {
|
|
86
|
+
hasConnected = true;
|
|
87
|
+
};
|
|
88
|
+
const onDisconnected = () => {
|
|
89
|
+
if (!hasConnected) return;
|
|
90
|
+
closeServer();
|
|
91
|
+
};
|
|
92
|
+
server.on("error", onServerError);
|
|
93
|
+
server.on("close", onServerClose);
|
|
94
|
+
this.on("connected", onConnected);
|
|
95
|
+
this.on("disconnected", onDisconnected);
|
|
96
|
+
server.listen(this.port, this.ip, () => {
|
|
97
|
+
onListening?.();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
handleIncomingSocket(socket) {
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
if (this.stream && !this.stream.destroyed) {
|
|
104
|
+
this.logger.detail.warn({
|
|
105
|
+
protocol: "SECS-I-TCP/IP",
|
|
29
106
|
remoteAddress: socket.remoteAddress,
|
|
30
107
|
remotePort: socket.remotePort
|
|
31
|
-
}, "
|
|
32
|
-
|
|
33
|
-
});
|
|
34
|
-
this.server.on("error", (err) => {
|
|
35
|
-
reject(err);
|
|
36
|
-
});
|
|
37
|
-
this.server.listen(this.port, this.ip, () => {
|
|
108
|
+
}, "rejecting new connection (single session)");
|
|
109
|
+
socket.destroy();
|
|
38
110
|
resolve();
|
|
39
|
-
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.logger.detail.info({
|
|
114
|
+
protocol: "SECS-I-TCP/IP",
|
|
115
|
+
remoteAddress: socket.remoteAddress,
|
|
116
|
+
remotePort: socket.remotePort
|
|
117
|
+
}, "accepted connection");
|
|
118
|
+
this.attachStream(socket);
|
|
119
|
+
resolve();
|
|
40
120
|
});
|
|
41
121
|
}
|
|
42
122
|
close() {
|
|
123
|
+
this.shouldStop = true;
|
|
43
124
|
this.stop();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
125
|
+
const server = this.server;
|
|
126
|
+
if (server) return new Promise((resolve) => {
|
|
127
|
+
server.close(() => {
|
|
128
|
+
this.server = null;
|
|
129
|
+
resolve();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
if (this.serverLoopPromise) {
|
|
133
|
+
const loop = this.serverLoopPromise;
|
|
134
|
+
this.serverLoopPromise = null;
|
|
135
|
+
return loop;
|
|
47
136
|
}
|
|
48
137
|
return Promise.resolve();
|
|
49
138
|
}
|
|
50
|
-
handleIncomingSocket(socket) {
|
|
51
|
-
this.attachStream(socket);
|
|
52
|
-
}
|
|
53
139
|
};
|
|
54
140
|
|
|
55
141
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secs1OnTcpIpPassiveCommunicator.js","names":[],"sources":["../../src/secs1/Secs1OnTcpIpPassiveCommunicator.ts"],"sourcesContent":["import { Server, Socket, createServer } from \"net\";\nimport {\n\tSecs1Communicator,\n\tSecs1CommunicatorConfig,\n} from \"./Secs1Communicator.js\";\n\nexport interface Secs1OnTcpIpPassiveCommunicatorConfig extends Secs1CommunicatorConfig {\n\tip: string;\n\tport: number;\n}\n\nexport class Secs1OnTcpIpPassiveCommunicator extends Secs1Communicator {\n\tpublic ip: string;\n\tpublic port: number;\n\n\tprivate server: Server | null = null;\n\n\tconstructor(config: Secs1OnTcpIpPassiveCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.ip = config.ip;\n\t\tthis.port = config.port;\n\t}\n\n\tasync open(): Promise<void> {\n\t\tif (this.
|
|
1
|
+
{"version":3,"file":"Secs1OnTcpIpPassiveCommunicator.js","names":["resolveFirstListen: (() => void) | null"],"sources":["../../src/secs1/Secs1OnTcpIpPassiveCommunicator.ts"],"sourcesContent":["import { Server, Socket, createServer } from \"net\";\nimport {\n\tSecs1Communicator,\n\tSecs1CommunicatorConfig,\n} from \"./Secs1Communicator.js\";\n\nexport interface Secs1OnTcpIpPassiveCommunicatorConfig extends Secs1CommunicatorConfig {\n\tip: string;\n\tport: number;\n\ttimeoutRebind?: number;\n}\n\nexport class Secs1OnTcpIpPassiveCommunicator extends Secs1Communicator {\n\tpublic ip: string;\n\tpublic port: number;\n\n\tprivate server: Server | null = null;\n\tprivate shouldStop = false;\n\tprivate serverLoopPromise: Promise<void> | null = null;\n\tprivate timeoutRebind = 5;\n\n\tconstructor(config: Secs1OnTcpIpPassiveCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.ip = config.ip;\n\t\tthis.port = config.port;\n\t\tif (config.timeoutRebind !== undefined) {\n\t\t\tthis.timeoutRebind = config.timeoutRebind;\n\t\t}\n\t}\n\n\tasync open(): Promise<void> {\n\t\tif (this.serverLoopPromise) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.shouldStop = false;\n\n\t\tlet resolveFirstListen: (() => void) | null = null;\n\t\tconst firstListen = new Promise<void>((resolve) => {\n\t\t\tresolveFirstListen = resolve;\n\t\t});\n\n\t\tthis.serverLoopPromise = this.runServerLoop(() => {\n\t\t\tresolveFirstListen?.();\n\t\t\tresolveFirstListen = null;\n\t\t}).catch((err: unknown) => {\n\t\t\tthis.emit(\"error\", err instanceof Error ? err : new Error(String(err)));\n\t\t});\n\n\t\tawait firstListen;\n\t}\n\n\tprivate async runServerLoop(onFirstListening: () => void): Promise<void> {\n\t\tlet first = true;\n\t\twhile (!this.shouldStop) {\n\t\t\ttry {\n\t\t\t\tawait this.listenOnce(first ? onFirstListening : null);\n\t\t\t} catch (err) {\n\t\t\t\tif (!this.shouldStop) {\n\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\terr instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!this.shouldStop) {\n\t\t\t\t\tawait new Promise((resolve) =>\n\t\t\t\t\t\tsetTimeout(resolve, this.timeoutRebind * 1000),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfirst = false;\n\t\t\tif (this.shouldStop) return;\n\t\t}\n\t}\n\n\tprivate async listenOnce(onListening: (() => void) | null): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst server = createServer((socket) => {\n\t\t\t\tvoid this.handleIncomingSocket(socket);\n\t\t\t});\n\t\t\tthis.server = server;\n\n\t\t\tlet hasConnected = false;\n\t\t\tlet settled = false;\n\n\t\t\tconst cleanup = () => {\n\t\t\t\tserver.removeListener(\"error\", onServerError);\n\t\t\t\tserver.removeListener(\"close\", onServerClose);\n\t\t\t\tthis.removeListener(\"connected\", onConnected);\n\t\t\t\tthis.removeListener(\"disconnected\", onDisconnected);\n\t\t\t};\n\n\t\t\tconst finish = (err?: Error) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tif (this.server === server) {\n\t\t\t\t\tthis.server = null;\n\t\t\t\t}\n\t\t\t\tcleanup();\n\t\t\t\tif (err) reject(err);\n\t\t\t\telse resolve();\n\t\t\t};\n\n\t\t\tconst closeServer = () => {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (!server.listening) {\n\t\t\t\t\tfinish();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tserver.close((closeErr) => {\n\t\t\t\t\tif (closeErr) finish(closeErr);\n\t\t\t\t\telse finish();\n\t\t\t\t});\n\t\t\t};\n\n\t\t\tconst onServerError = (_err: Error) => {\n\t\t\t\tcloseServer();\n\t\t\t};\n\n\t\t\tconst onServerClose = () => {\n\t\t\t\tfinish();\n\t\t\t};\n\n\t\t\tconst onConnected = () => {\n\t\t\t\thasConnected = true;\n\t\t\t};\n\n\t\t\tconst onDisconnected = () => {\n\t\t\t\tif (!hasConnected) return;\n\t\t\t\tcloseServer();\n\t\t\t};\n\n\t\t\tserver.on(\"error\", onServerError);\n\t\t\tserver.on(\"close\", onServerClose);\n\t\t\tthis.on(\"connected\", onConnected);\n\t\t\tthis.on(\"disconnected\", onDisconnected);\n\n\t\t\tserver.listen(this.port, this.ip, () => {\n\t\t\t\tonListening?.();\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate handleIncomingSocket(socket: Socket): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tif (this.stream && !this.stream.destroyed) {\n\t\t\t\tthis.logger.detail.warn(\n\t\t\t\t\t{\n\t\t\t\t\t\tprotocol: \"SECS-I-TCP/IP\",\n\t\t\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\t\t\tremotePort: socket.remotePort,\n\t\t\t\t\t},\n\t\t\t\t\t\"rejecting new connection (single session)\",\n\t\t\t\t);\n\t\t\t\tsocket.destroy();\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.logger.detail.info(\n\t\t\t\t{\n\t\t\t\t\tprotocol: \"SECS-I-TCP/IP\",\n\t\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\t\tremotePort: socket.remotePort,\n\t\t\t\t},\n\t\t\t\t\"accepted connection\",\n\t\t\t);\n\t\t\tthis.attachStream(socket);\n\t\t\tresolve();\n\t\t});\n\t}\n\n\tclose(): Promise<void> {\n\t\tthis.shouldStop = true;\n\t\tthis.stop();\n\t\tconst server = this.server;\n\t\tif (server) {\n\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\tserver.close(() => {\n\t\t\t\t\tthis.server = null;\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\tif (this.serverLoopPromise) {\n\t\t\tconst loop = this.serverLoopPromise;\n\t\t\tthis.serverLoopPromise = null;\n\t\t\treturn loop;\n\t\t}\n\t\treturn Promise.resolve();\n\t}\n}\n"],"mappings":";;;;AAYA,IAAa,kCAAb,cAAqD,kBAAkB;CACtE,AAAO;CACP,AAAO;CAEP,AAAQ,SAAwB;CAChC,AAAQ,aAAa;CACrB,AAAQ,oBAA0C;CAClD,AAAQ,gBAAgB;CAExB,YAAY,QAA+C;AAC1D,QAAM,OAAO;AACb,OAAK,KAAK,OAAO;AACjB,OAAK,OAAO,OAAO;AACnB,MAAI,OAAO,kBAAkB,OAC5B,MAAK,gBAAgB,OAAO;;CAI9B,MAAM,OAAsB;AAC3B,MAAI,KAAK,kBACR;AAGD,OAAK,aAAa;EAElB,IAAIA,qBAA0C;EAC9C,MAAM,cAAc,IAAI,SAAe,YAAY;AAClD,wBAAqB;IACpB;AAEF,OAAK,oBAAoB,KAAK,oBAAoB;AACjD,yBAAsB;AACtB,wBAAqB;IACpB,CAAC,OAAO,QAAiB;AAC1B,QAAK,KAAK,SAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;IACtE;AAEF,QAAM;;CAGP,MAAc,cAAc,kBAA6C;EACxE,IAAI,QAAQ;AACZ,SAAO,CAAC,KAAK,YAAY;AACxB,OAAI;AACH,UAAM,KAAK,WAAW,QAAQ,mBAAmB,KAAK;YAC9C,KAAK;AACb,QAAI,CAAC,KAAK,WACT,MAAK,KACJ,SACA,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CACnD;AAEF,QAAI,CAAC,KAAK,WACT,OAAM,IAAI,SAAS,YAClB,WAAW,SAAS,KAAK,gBAAgB,IAAK,CAC9C;;AAGH,WAAQ;AACR,OAAI,KAAK,WAAY;;;CAIvB,MAAc,WAAW,aAAiD;AACzE,SAAO,IAAI,SAAS,SAAS,WAAW;GACvC,MAAM,SAAS,cAAc,WAAW;AACvC,IAAK,KAAK,qBAAqB,OAAO;KACrC;AACF,QAAK,SAAS;GAEd,IAAI,eAAe;GACnB,IAAI,UAAU;GAEd,MAAM,gBAAgB;AACrB,WAAO,eAAe,SAAS,cAAc;AAC7C,WAAO,eAAe,SAAS,cAAc;AAC7C,SAAK,eAAe,aAAa,YAAY;AAC7C,SAAK,eAAe,gBAAgB,eAAe;;GAGpD,MAAM,UAAU,QAAgB;AAC/B,QAAI,QAAS;AACb,cAAU;AACV,QAAI,KAAK,WAAW,OACnB,MAAK,SAAS;AAEf,aAAS;AACT,QAAI,IAAK,QAAO,IAAI;QACf,UAAS;;GAGf,MAAM,oBAAoB;AACzB,QAAI,QAAS;AACb,QAAI,CAAC,OAAO,WAAW;AACtB,aAAQ;AACR;;AAED,WAAO,OAAO,aAAa;AAC1B,SAAI,SAAU,QAAO,SAAS;SACzB,SAAQ;MACZ;;GAGH,MAAM,iBAAiB,SAAgB;AACtC,iBAAa;;GAGd,MAAM,sBAAsB;AAC3B,YAAQ;;GAGT,MAAM,oBAAoB;AACzB,mBAAe;;GAGhB,MAAM,uBAAuB;AAC5B,QAAI,CAAC,aAAc;AACnB,iBAAa;;AAGd,UAAO,GAAG,SAAS,cAAc;AACjC,UAAO,GAAG,SAAS,cAAc;AACjC,QAAK,GAAG,aAAa,YAAY;AACjC,QAAK,GAAG,gBAAgB,eAAe;AAEvC,UAAO,OAAO,KAAK,MAAM,KAAK,UAAU;AACvC,mBAAe;KACd;IACD;;CAGH,AAAQ,qBAAqB,QAA+B;AAC3D,SAAO,IAAI,SAAS,YAAY;AAC/B,OAAI,KAAK,UAAU,CAAC,KAAK,OAAO,WAAW;AAC1C,SAAK,OAAO,OAAO,KAClB;KACC,UAAU;KACV,eAAe,OAAO;KACtB,YAAY,OAAO;KACnB,EACD,4CACA;AACD,WAAO,SAAS;AAChB,aAAS;AACT;;AAED,QAAK,OAAO,OAAO,KAClB;IACC,UAAU;IACV,eAAe,OAAO;IACtB,YAAY,OAAO;IACnB,EACD,sBACA;AACD,QAAK,aAAa,OAAO;AACzB,YAAS;IACR;;CAGH,QAAuB;AACtB,OAAK,aAAa;AAClB,OAAK,MAAM;EACX,MAAM,SAAS,KAAK;AACpB,MAAI,OACH,QAAO,IAAI,SAAe,YAAY;AACrC,UAAO,YAAY;AAClB,SAAK,SAAS;AACd,aAAS;KACR;IACD;AAEH,MAAI,KAAK,mBAAmB;GAC3B,MAAM,OAAO,KAAK;AAClB,QAAK,oBAAoB;AACzB,UAAO;;AAER,SAAO,QAAQ,SAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secs1SerialCommunicator.d.ts","names":[],"sources":["../../src/secs1/Secs1SerialCommunicator.ts"],"sourcesContent":[],"mappings":";;;UAMiB,6BAAA,SAAsC;;EAAtC,QAAA,EAAA,MAAA;AAKjB;AAMqB,cANR,uBAAA,SAAgC,iBAAA,CAMxB;
|
|
1
|
+
{"version":3,"file":"Secs1SerialCommunicator.d.ts","names":[],"sources":["../../src/secs1/Secs1SerialCommunicator.ts"],"sourcesContent":[],"mappings":";;;UAMiB,6BAAA,SAAsC;;EAAtC,QAAA,EAAA,MAAA;AAKjB;AAMqB,cANR,uBAAA,SAAgC,iBAAA,CAMxB;EAON,QAAA,IAAA;EA4BC,IAAA,EAAA,MAAA;EAzC6B,QAAA,EAAA,MAAA;EAAiB,WAAA,CAAA,MAAA,EAMzC,6BANyC;UAa/C;WA4BC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Secs1SerialCommunicator.js","names":[],"sources":["../../src/secs1/Secs1SerialCommunicator.ts"],"sourcesContent":["import { SerialPort } from \"serialport\";\nimport {\n\tSecs1Communicator,\n\tSecs1CommunicatorConfig,\n} from \"./Secs1Communicator.js\";\n\nexport interface Secs1SerialCommunicatorConfig extends Secs1CommunicatorConfig {\n\tpath: string;\n\tbaudRate: number;\n}\n\nexport class Secs1SerialCommunicator extends Secs1Communicator {\n\tprivate port: SerialPort | null = null;\n\n\tpublic path: string;\n\tpublic baudRate: number;\n\n\tconstructor(config: Secs1SerialCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.path = config.path;\n\t\tthis.baudRate = config.baudRate;\n\t}\n\n\tasync open(): Promise<void> {\n\t\tif (this.port?.isOpen) return;\n\n\t\tconst port = new SerialPort({\n\t\t\tpath: this.path,\n\t\t\tbaudRate: this.baudRate,\n\t\t\tautoOpen: false,\n\t\t});\n\t\tthis.port = port;\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst onError = (err: Error) => {\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\tport.once(\"error\", onError);\n\t\t\tport.open((err) => {\n\t\t\t\tport.removeListener(\"error\", onError);\n\t\t\t\tif (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.attachStream(port);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.stop();\n\n\t\tconst port = this.port;\n\t\tthis.port = null;\n\t\tif (!port) return;\n\n\t\tif (!port.isOpen) {\n\t\t\tport.destroy();\n\t\t\treturn;\n\t\t}\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tport.close((err) => {\n\t\t\t\tif (err) reject(err);\n\t\t\t\telse resolve();\n\t\t\t});\n\t\t});\n\n\t\tport.destroy();\n\t}\n}\n"],"mappings":";;;;AAWA,IAAa,0BAAb,cAA6C,kBAAkB;CAC9D,AAAQ,OAA0B;CAElC,AAAO;CACP,AAAO;CAEP,YAAY,QAAuC;AAClD,QAAM,OAAO;AACb,OAAK,OAAO,OAAO;AACnB,OAAK,WAAW,OAAO;;CAGxB,MAAM,OAAsB;AAC3B,MAAI,KAAK,MAAM,OAAQ;EAEvB,MAAM,OAAO,IAAI,WAAW;GAC3B,MAAM,KAAK;GACX,UAAU,KAAK;GACf,UAAU;GACV,CAAC;AACF,OAAK,OAAO;AAEZ,SAAO,IAAI,SAAS,SAAS,WAAW;GACvC,MAAM,WAAW,QAAe;AAC/B,WAAO,IAAI;;AAGZ,QAAK,KAAK,SAAS,QAAQ;AAC3B,QAAK,MAAM,QAAQ;AAClB,SAAK,eAAe,SAAS,QAAQ;AACrC,QAAI,KAAK;AACR,YAAO,IAAI;AACX;;AAED,SAAK,aAAa,KAAK;AACvB,aAAS;KACR;IACD;;CAGH,MAAM,QAAuB;AAC5B,OAAK,MAAM;EAEX,MAAM,OAAO,KAAK;AAClB,OAAK,OAAO;AACZ,MAAI,CAAC,KAAM;AAEX,MAAI,CAAC,KAAK,QAAQ;AACjB,QAAK,SAAS;AACd;;AAGD,QAAM,IAAI,SAAe,SAAS,WAAW;AAC5C,QAAK,OAAO,QAAQ;AACnB,QAAI,IAAK,QAAO,IAAI;QACf,UAAS;KACb;IACD;AAEF,OAAK,SAAS"}
|
|
1
|
+
{"version":3,"file":"Secs1SerialCommunicator.js","names":[],"sources":["../../src/secs1/Secs1SerialCommunicator.ts"],"sourcesContent":["import { SerialPort } from \"serialport\";\nimport {\n\tSecs1Communicator,\n\tSecs1CommunicatorConfig,\n} from \"./Secs1Communicator.js\";\n\nexport interface Secs1SerialCommunicatorConfig extends Secs1CommunicatorConfig {\n\tpath: string;\n\tbaudRate: number;\n}\n\nexport class Secs1SerialCommunicator extends Secs1Communicator {\n\tprivate port: SerialPort | null = null;\n\n\tpublic path: string;\n\tpublic baudRate: number;\n\n\tconstructor(config: Secs1SerialCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.isMaster = config.isEquip;\n\t\tthis.path = config.path;\n\t\tthis.baudRate = config.baudRate;\n\t}\n\n\tasync open(): Promise<void> {\n\t\tif (this.port?.isOpen) return;\n\n\t\tconst port = new SerialPort({\n\t\t\tpath: this.path,\n\t\t\tbaudRate: this.baudRate,\n\t\t\tautoOpen: false,\n\t\t});\n\t\tthis.port = port;\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst onError = (err: Error) => {\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\tport.once(\"error\", onError);\n\t\t\tport.open((err) => {\n\t\t\t\tport.removeListener(\"error\", onError);\n\t\t\t\tif (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.attachStream(port);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.stop();\n\n\t\tconst port = this.port;\n\t\tthis.port = null;\n\t\tif (!port) return;\n\n\t\tif (!port.isOpen) {\n\t\t\tport.destroy();\n\t\t\treturn;\n\t\t}\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tport.close((err) => {\n\t\t\t\tif (err) reject(err);\n\t\t\t\telse resolve();\n\t\t\t});\n\t\t});\n\n\t\tport.destroy();\n\t}\n}\n"],"mappings":";;;;AAWA,IAAa,0BAAb,cAA6C,kBAAkB;CAC9D,AAAQ,OAA0B;CAElC,AAAO;CACP,AAAO;CAEP,YAAY,QAAuC;AAClD,QAAM,OAAO;AACb,OAAK,WAAW,OAAO;AACvB,OAAK,OAAO,OAAO;AACnB,OAAK,WAAW,OAAO;;CAGxB,MAAM,OAAsB;AAC3B,MAAI,KAAK,MAAM,OAAQ;EAEvB,MAAM,OAAO,IAAI,WAAW;GAC3B,MAAM,KAAK;GACX,UAAU,KAAK;GACf,UAAU;GACV,CAAC;AACF,OAAK,OAAO;AAEZ,SAAO,IAAI,SAAS,SAAS,WAAW;GACvC,MAAM,WAAW,QAAe;AAC/B,WAAO,IAAI;;AAGZ,QAAK,KAAK,SAAS,QAAQ;AAC3B,QAAK,MAAM,QAAQ;AAClB,SAAK,eAAe,SAAS,QAAQ;AACrC,QAAI,KAAK;AACR,YAAO,IAAI;AACX;;AAED,SAAK,aAAa,KAAK;AACvB,aAAS;KACR;IACD;;CAGH,MAAM,QAAuB;AAC5B,OAAK,MAAM;EAEX,MAAM,OAAO,KAAK;AAClB,OAAK,OAAO;AACZ,MAAI,CAAC,KAAM;AAEX,MAAI,CAAC,KAAK,QAAQ;AACjB,QAAK,SAAS;AACd;;AAGD,QAAM,IAAI,SAAe,SAAS,WAAW;AAC5C,QAAK,OAAO,QAAQ;AACnB,QAAI,IAAK,QAAO,IAAI;QACf,UAAS;KACb;IACD;AAEF,OAAK,SAAS"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "secs4js",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "A simple, efficient, and user-friendly SECS/GEM protocol library implemented in TypeScript.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"author": {
|
|
24
24
|
"name": "Ran Qian",
|
|
25
|
-
"email": "
|
|
25
|
+
"email": "fizzdog.rq@foxmail.com"
|
|
26
26
|
},
|
|
27
27
|
"type": "module",
|
|
28
28
|
"main": "./lib/index.js",
|