Skip to content

Commit d6e6d39

Browse files
committed
Added CIPAttribute.Get(), fixed CIPMultiServiceRequest, CIPRequest data handler can be another CIPRequest, updated Changelog
1 parent e5b5abb commit d6e6d39

14 files changed

Lines changed: 195 additions & 62 deletions

File tree

CHANGELOG.md

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,48 @@
11
# Changelog
22

3+
## 2.0.0-beta.8 (2020-01-23)
4+
- Added CIPAttribute.Get() as a helper method for creating a GetAttributeSingle service CIPRequest
5+
```javascript
6+
/**
7+
* Creates a GetAttributeSingle service CIPRequest for retrieving the device
8+
* type of Identity object instance 1
9+
*/
10+
const request = CIP.Core.Objects.Identity.InstanceAttribute.DeviceType.Get(1);
11+
```
12+
- Improved CIPRequest and CIPMultiServiceRequest
13+
- A CIPRequest can be specified as the data handler for another CIPRequest (see ConnectionManager's UnconnectedSend method)
14+
- CIPMultiServiceRequest (CIPRequest.Multi) now works
15+
- Here is an example of two requests inside of a multi service request inside of an unconnected send
16+
```javascript
17+
const { TCP, CIP } = require('../../src');
18+
19+
const tcpLayer = new TCP('1.2.3.4');
20+
const cipLayer = new CIP(tcpLayer);
21+
22+
/** Create an Unconnected Send request */
23+
const request = CIP.Core.Objects.ConnectionManager.UnconnectedSend(
24+
/** multi service request */
25+
new CIP.Core.Request.Multi([
26+
/** two different GetAttributeSingle requests */
27+
CIP.Core.Objects.MessageRouter.InstanceAttribute.ObjectList.Get(1),
28+
CIP.Core.Objects.Port.InstanceAttribute.Name.Get(1)
29+
]),
30+
/** routing out of port 1 to address 0 */
31+
CIP.Core.EPath.Encode(true, [
32+
new CIP.Core.EPath.Segments.Port(1, 0)
33+
])
34+
);
35+
36+
/** Use the CIP layer to send the unconnected message */
37+
const res = await cipLayer.sendRequest(false, request);
38+
39+
/** res.value is an array of response objects (2 responses in this case) */
40+
console.log(res.value);
41+
42+
await tcpLayer.close();
43+
```
44+
- Fixed CIP Layer sendRequest not propagating errors
45+
346
## 2.0.0-beta.7 (2020-01-22)
447
- The Layers object exported by the package has been removed.
548
```javascript
@@ -77,9 +120,13 @@
77120
```javascript
78121
let i = 0;
79122
logix.listTags(function(tag) {
80-
i++;
81-
console.log(i, tag);
82-
return i < 10; // return true to continue listing tags
123+
if (tag != null) {
124+
i++;
125+
console.log(i, tag);
126+
return i < 10; // return true to continue listing tags
127+
} else {
128+
// tag is null so listing is finished
129+
}
83130
});
84131
```
85132
- Improved EIP Layer listIdentities timeout handling, it should be much faster to resolve

src/layers/cip/core/attribute.js

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
'use strict';
22

3+
const { Decode } = require('./datatypes/decoding');
4+
const { CommonServiceCodes } = require('./constants/services');
5+
const EPath = require('./epath');
6+
const LogicalSegment = EPath.Segments.Logical;
7+
8+
const CIPRequest = require('./request');
39
const CIPFeature = require('./feature');
410

511
class CIPAttribute extends CIPFeature {
@@ -9,9 +15,49 @@ class CIPAttribute extends CIPFeature {
915
this.getable = getable;
1016
this.setable = setable;
1117
}
18+
19+
Get(instance) {
20+
return new CIPRequest(
21+
CommonServiceCodes.GetAttributeSingle,
22+
EPath.Encode(true, [
23+
new LogicalSegment.ClassID(this.classCode),
24+
new LogicalSegment.InstanceID(instance),
25+
new LogicalSegment.AttributeID(this.code)
26+
]),
27+
null,
28+
(buffer, offset, cb) => {
29+
Decode(this.dataType, buffer, offset, cb);
30+
}
31+
);
32+
}
1233
}
1334

14-
CIPAttribute.Class = class CIPClassAttribute extends CIPAttribute {}
15-
CIPAttribute.Instance = class CIPInstanceAttribute extends CIPAttribute {}
35+
CIPAttribute.Class = class CIPClassAttribute extends CIPAttribute { }
36+
CIPAttribute.Instance = class CIPInstanceAttribute extends CIPAttribute { }
37+
38+
module.exports = CIPAttribute;
39+
40+
41+
42+
// 'use strict';
43+
44+
// const CIPRequest
45+
// const CIPFeature = require('./feature');
46+
47+
// class CIPAttribute extends CIPFeature {
48+
// constructor(code, name, dataType, getable = true, setable = false) {
49+
// super(code, name);
50+
// this.dataType = dataType;
51+
// this.getable = getable;
52+
// this.setable = setable;
53+
// }
54+
55+
// request() {
56+
57+
// }
58+
// }
59+
60+
// CIPAttribute.Class = class CIPClassAttribute extends CIPAttribute {}
61+
// CIPAttribute.Instance = class CIPInstanceAttribute extends CIPAttribute {}
1662

17-
module.exports = CIPAttribute;
63+
// module.exports = CIPAttribute;

src/layers/cip/core/feature.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use strict';
22

33
class CIPFeature {
4-
constructor(code, name) {
4+
constructor(code, name, classCode) {
55
this.code = code;
66
this.name = name;
7+
this.classCode = classCode;
78
}
89
}
910

src/layers/cip/core/object.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,17 @@ const CommonServices = Object.freeze({
6969

7070
function CIPMetaObject(classCode, options) {
7171
options = options || {};
72-
const ClassAttributeGroup = options.ClassAttributeGroup || new CIPFeatureGroup([]);
73-
const InstanceAttributeGroup = options.InstanceAttributeGroup || new CIPFeatureGroup([]);
72+
// const ClassAttributeGroup = options.ClassAttributeGroup || new CIPFeatureGroup([]);
73+
// const InstanceAttributeGroup = options.InstanceAttributeGroup || new CIPFeatureGroup([]);
74+
75+
const ClassAttributes = Array.isArray(options.ClassAttributes) ? options.ClassAttributes : Object.values(options.ClassAttributes || {});
76+
const InstanceAttributes = Array.isArray(options.InstanceAttributes) ? options.InstanceAttributes : Object.values(options.InstanceAttributes || {});
77+
78+
ClassAttributes.forEach(attribute => attribute.classCode = classCode);
79+
InstanceAttributes.forEach(attribute => attribute.classCode = classCode);
80+
81+
const ClassAttributeGroup = new CIPFeatureGroup(ClassAttributes);
82+
const InstanceAttributeGroup = new CIPFeatureGroup(InstanceAttributes);
7483
const GetAttributesAllInstanceAttributes = options.GetAttributesAllInstanceAttributes || [];
7584

7685
class CIPObject {

src/layers/cip/core/objects/ConnectionManager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class ConnectionManager {
5454
ServiceCodes.UnconnectedSend,
5555
ConnectionManager_EPath,
5656
buffer,
57-
request.handler,
57+
request,
5858
{
5959
acceptedServiceCodes: [ServiceCodes.UnconnectedSend, request.service],
6060
statusHandler: function(statusCode, extendedBuffer, cb) {

src/layers/cip/core/objects/EthernetLink.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
const CIPMetaObject = require('../object');
44
const CIPAttribute = require('../attribute');
5-
const CIPFeatureGroup = require('../featuregroup');
65
const { ClassCodes } = require('../constants');
76
const { DataType } = require('../datatypes');
87
const { getBits } = require('../../../../utils');
@@ -169,9 +168,6 @@ const InstanceAttribute = Object.freeze({
169168
// PortTrafficOverloadAlarm: new CIPAttribute.Instance(107, 'Port Traffic Overload Alarm', DataType.USINT)
170169
});
171170

172-
const ClassAttributeGroup = new CIPFeatureGroup(Object.values(ClassAttribute));
173-
const InstanceAttributeGroup = new CIPFeatureGroup(Object.values(InstanceAttribute));
174-
175171

176172
const GetAttributesAllInstanceAttributes = Object.freeze([
177173
InstanceAttribute.InterfaceSpeed,
@@ -184,8 +180,8 @@ const GetAttributesAllInstanceAttributes = Object.freeze([
184180

185181

186182
const CIPObject = CIPMetaObject(ClassCodes.EthernetLink, {
187-
ClassAttributeGroup,
188-
InstanceAttributeGroup,
183+
ClassAttributes: ClassAttribute,
184+
InstanceAttributes: InstanceAttribute,
189185
GetAttributesAllInstanceAttributes
190186
});
191187

src/layers/cip/core/objects/Identity.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
const CIPMetaObject = require('../object');
44
const CIPAttribute = require('../attribute');
5-
const CIPFeatureGroup = require('../featuregroup');
65

76
const {
87
ClassCodes,
@@ -83,12 +82,10 @@ const GetAttributesAllInstanceAttributes = [
8382
InstanceAttribute.ProductName
8483
];
8584

86-
const ClassAttributeGroup = new CIPFeatureGroup(Object.values(ClassAttribute))
87-
const InstanceAttributeGroup = new CIPFeatureGroup(Object.values(InstanceAttribute));
8885

8986
const CIPObject = CIPMetaObject(ClassCodes.Identity, {
90-
ClassAttributeGroup,
91-
InstanceAttributeGroup,
87+
ClassAttributes: ClassAttribute,
88+
InstanceAttributes: InstanceAttribute,
9289
GetAttributesAllInstanceAttributes
9390
});
9491

src/layers/cip/core/objects/MessageRouter.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
const CIPMetaObject = require('../object');
44
const CIPAttribute = require('../attribute');
5-
const CIPFeatureGroup = require('../featuregroup');
65

76
const {
87
ClassCodes,
@@ -43,12 +42,9 @@ const InstanceAttribute = Object.freeze({
4342
});
4443

4544

46-
const ClassAttributeGroup = new CIPFeatureGroup(Object.values(ClassAttribute))
47-
const InstanceAttributeGroup = new CIPFeatureGroup(Object.values(InstanceAttribute));
48-
4945
const CIPObject = CIPMetaObject(ClassCodes.MessageRouter, {
50-
ClassAttributeGroup,
51-
InstanceAttributeGroup
46+
ClassAttributes: ClassAttribute,
47+
InstanceAttributes: InstanceAttribute
5248
});
5349

5450
class MessageRouter extends CIPObject {}

src/layers/cip/core/objects/Port.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
const CIPMetaObject = require('../object');
2626
const CIPAttribute = require('../attribute');
27-
const CIPFeatureGroup = require('../featuregroup');
2827
const { ClassCodes } = require('../constants');
2928
const { DataType } = require('../datatypes');
3029

@@ -101,10 +100,6 @@ const InstanceAttribute = Object.freeze({
101100
});
102101

103102

104-
const ClassAttributeGroup = new CIPFeatureGroup(Object.values(ClassAttribute))
105-
const InstanceAttributeGroup = new CIPFeatureGroup(Object.values(InstanceAttribute));
106-
107-
108103
const GetAttributesAllInstanceAttributes = Object.freeze([
109104
InstanceAttribute.Type,
110105
InstanceAttribute.Number,
@@ -115,8 +110,8 @@ const GetAttributesAllInstanceAttributes = Object.freeze([
115110

116111

117112
const CIPObject = CIPMetaObject(ClassCodes.Port, {
118-
ClassAttributeGroup,
119-
InstanceAttributeGroup,
113+
ClassAttributes: ClassAttribute,
114+
InstanceAttributes: InstanceAttribute,
120115
GetAttributesAllInstanceAttributes
121116
});
122117

src/layers/cip/core/objects/TCPIPInterface.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
const CIPMetaObject = require('../object');
44
const CIPAttribute = require('../attribute');
5-
const CIPFeatureGroup = require('../featuregroup');
65
const { ClassCodes } = require('../constants');
76
const { DataType } = require('../datatypes');
87

8+
99
const ClassAttribute = Object.freeze({});
1010

1111

@@ -69,10 +69,6 @@ const InstanceAttribute = Object.freeze({
6969
});
7070

7171

72-
const ClassAttributeGroup = new CIPFeatureGroup(Object.values(ClassAttribute))
73-
const InstanceAttributeGroup = new CIPFeatureGroup(Object.values(InstanceAttribute));
74-
75-
7672
const GetAttributesAllInstanceAttributes = Object.freeze([
7773
InstanceAttribute.Status,
7874
InstanceAttribute.ConfigurationCapability,
@@ -84,8 +80,8 @@ const GetAttributesAllInstanceAttributes = Object.freeze([
8480

8581

8682
const CIPObject = CIPMetaObject(ClassCodes.TCPIPInterface, {
87-
ClassAttributeGroup,
88-
InstanceAttributeGroup,
83+
ClassAttributes: ClassAttribute,
84+
InstanceAttributes: InstanceAttribute,
8985
GetAttributesAllInstanceAttributes
9086
});
9187

0 commit comments

Comments
 (0)