From 3831b8cd5f85e5af50378ab7d01e65b691f61973 Mon Sep 17 00:00:00 2001 From: Mudrekh Goderya Date: Thu, 18 Nov 2021 19:05:12 -0600 Subject: [PATCH 1/5] Handle cases when data has multiple responses Issue writes after listener has been attached. --- src/controller/index.js | 10 ++++------ src/enip/index.js | 5 +++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/controller/index.js b/src/controller/index.js index a56dd7c..aeb5841 100644 --- a/src/controller/index.js +++ b/src/controller/index.js @@ -476,7 +476,6 @@ class Controller extends ENIP { async _readTag(tag, size = null) { const MR = tag.generateReadMessageRequest(size); - this.write_cip(MR); const readTagErr = new Error(`TIMEOUT occurred while writing Reading Tag: ${tag.name}.`); @@ -487,6 +486,7 @@ class Controller extends ENIP { if (err) reject(err); resolve(data); }); + this.write_cip(MR); }), 10000, readTagErr @@ -509,14 +509,11 @@ class Controller extends ENIP { async _writeTag(tag, value = null, size = 0x01) { const MR = tag.generateWriteMessageRequest(value, size); - this.write_cip(MR); - const writeTagErr = new Error(`TIMEOUT occurred while writing Writing Tag: ${tag.name}.`); // Wait for Response await promiseTimeout( new Promise((resolve, reject) => { - // Full Tag Writing this.on("Write Tag", (err, data) => { if (err) reject(err); @@ -532,6 +529,7 @@ class Controller extends ENIP { tag.unstageWriteRequest(); resolve(data); }); + this.write_cip(MR); }), 10000, writeTagErr @@ -555,7 +553,6 @@ class Controller extends ENIP { // Send Each Multi Service Message for (let msg of messages) { - this.write_cip(msg.data); // Wait for Controller to Respond const data = await promiseTimeout( @@ -565,6 +562,7 @@ class Controller extends ENIP { resolve(data); }); + this.write_cip(msg.data); }), 10000, readTagGroupErr @@ -591,7 +589,6 @@ class Controller extends ENIP { // Send Each Multi Service Message for (let msg of messages) { - this.write_cip(msg.data); // Wait for Controller to Respond const data = await promiseTimeout( @@ -601,6 +598,7 @@ class Controller extends ENIP { resolve(data); }); + this.write_cip(msg.data); }), 10000, writeTagGroupErr diff --git a/src/enip/index.js b/src/enip/index.js index 6bdc7c5..9880608 100644 --- a/src/enip/index.js +++ b/src/enip/index.js @@ -240,6 +240,11 @@ class ENIP extends Socket { const encapsulatedData = header.parse(data); const { statusCode, status, commandCode } = encapsulatedData; + // Handle buffers with multiple responses + if(data.length > 24 + encapsulatedData.length) { + setImmediate(() => this._handleDataEvent(Buffer.subarray(data, 24 + encapsulatedData.length))) + } + if (statusCode !== 0) { console.log(`Error <${statusCode}>:`.red, status.red); From c77d61cc96d0312138a1acdff1f7c8123136671e Mon Sep 17 00:00:00 2001 From: Mudrekh Goderya Date: Thu, 18 Nov 2021 19:08:24 -0600 Subject: [PATCH 2/5] Always remove listeners after commands --- src/controller/index.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/controller/index.js b/src/controller/index.js index aeb5841..1bfe715 100644 --- a/src/controller/index.js +++ b/src/controller/index.js @@ -490,9 +490,7 @@ class Controller extends ENIP { }), 10000, readTagErr - ); - - this.removeAllListeners("Read Tag"); + ).finally(() => this.removeAllListeners("Read Tag")); tag.parseReadMessageResponse(data); } @@ -533,10 +531,11 @@ class Controller extends ENIP { }), 10000, writeTagErr - ); + ).finally(() => { + this.removeAllListeners("Write Tag"); + this.removeAllListeners("Read Modify Write Tag"); + }); - this.removeAllListeners("Write Tag"); - this.removeAllListeners("Read Modify Write Tag"); } /** @@ -566,9 +565,7 @@ class Controller extends ENIP { }), 10000, readTagGroupErr - ); - - this.removeAllListeners("Multiple Service Packet"); + ).finally(() => this.removeAllListeners("Multiple Service Packet")); // Parse Messages group.parseReadMessageResponses(data, msg.tag_ids); @@ -602,9 +599,7 @@ class Controller extends ENIP { }), 10000, writeTagGroupErr - ); - - this.removeAllListeners("Multiple Service Packet"); + ).finally(() => this.removeAllListeners("Multiple Service Packet")); group.parseWriteMessageRequests(data, msg.tag_ids); } From 79db7bbd148724ac71add9e7177c02c266026fc8 Mon Sep 17 00:00:00 2001 From: Mudrekh Goderya Date: Fri, 19 Nov 2021 15:43:34 -0600 Subject: [PATCH 3/5] Missing semicolon --- src/enip/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/enip/index.js b/src/enip/index.js index 9880608..55d019a 100644 --- a/src/enip/index.js +++ b/src/enip/index.js @@ -242,7 +242,7 @@ class ENIP extends Socket { // Handle buffers with multiple responses if(data.length > 24 + encapsulatedData.length) { - setImmediate(() => this._handleDataEvent(Buffer.subarray(data, 24 + encapsulatedData.length))) + setImmediate(() => this._handleDataEvent(Buffer.subarray(data, 24 + encapsulatedData.length))); } if (statusCode !== 0) { From 8f60311124482979dd275757b55af7d0db0f5fc3 Mon Sep 17 00:00:00 2001 From: Mudrekh Date: Mon, 22 Nov 2021 10:57:24 -0600 Subject: [PATCH 4/5] Use proper buffer subarray syntax --- src/enip/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/enip/index.js b/src/enip/index.js index 55d019a..ef15394 100644 --- a/src/enip/index.js +++ b/src/enip/index.js @@ -242,7 +242,7 @@ class ENIP extends Socket { // Handle buffers with multiple responses if(data.length > 24 + encapsulatedData.length) { - setImmediate(() => this._handleDataEvent(Buffer.subarray(data, 24 + encapsulatedData.length))); + setImmediate(() => this._handleDataEvent(data.subarray(24 + encapsulatedData.length))); } if (statusCode !== 0) { From 4db71a6c0dd4ee9c8d2b4e3ce54c23f04c5e738e Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 16 Jun 2022 13:40:48 -0500 Subject: [PATCH 5/5] merge read and write queues Sometimes with high volumes of reads and writes, the values will start swapping around if the queues remain separate --- src/controller/index.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/controller/index.js b/src/controller/index.js index 1bfe715..228df57 100644 --- a/src/controller/index.js +++ b/src/controller/index.js @@ -37,8 +37,7 @@ class Controller extends ENIP { }; this.workers = { - read: new Queue(compare, queue_max_size), - write: new Queue(compare, queue_max_size), + readWrite: new Queue(compare, queue_max_size), group: new Queue(compare, queue_max_size) }; } @@ -336,7 +335,7 @@ class Controller extends ENIP { * @memberof Controller */ readTag(tag, size = null) { - return this.workers.read.schedule(this._readTag.bind(this), [tag, size], { + return this.workers.readWrite.schedule(this._readTag.bind(this), [tag, size], { priority: 1, timestamp: new Date() }); @@ -352,7 +351,7 @@ class Controller extends ENIP { * @memberof Controller */ writeTag(tag, value = null, size = 0x01) { - return this.workers.write.schedule(this._writeTag.bind(this), [tag, value, size], { + return this.workers.readWrite.schedule(this._writeTag.bind(this), [tag, value, size], { priority: 1, timestamp: new Date() });