Skip to content

Commit 8a28088

Browse files
committed
fix(service): correct atomicWriteFile service functionality
1 parent 0e34f9f commit 8a28088

5 files changed

Lines changed: 35 additions & 55 deletions

File tree

lib/asn1.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ const decodeDoubleSafe = (buffer, offset, lenValue) => {
864864
}
865865
};
866866

867-
const decodeOctetString = (buffer, offset, maxLength, octetStringOffset, octetStringLength) => {
867+
const decodeOctetString = module.exports.decodeOctetString = (buffer, offset, maxLength, octetStringOffset, octetStringLength) => {
868868
const octetString = [];
869869
for (let i = octetStringOffset; i < (octetStringOffset + octetStringLength); i++) {
870870
octetString.push(buffer[offset + i]);

lib/client.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ class Client extends EventEmitter {
725725
});
726726
}
727727

728-
writeFile(address, objectId, position, count, fileBuffer, options, next) {
728+
writeFile(address, objectId, position, fileBuffer, options, next) {
729729
next = next || options;
730730
const settings = {
731731
maxSegments: options.maxSegments || baEnum.MaxSegments.MAX_SEG65,
@@ -735,7 +735,7 @@ class Client extends EventEmitter {
735735
const buffer = this._getBuffer();
736736
baNpdu.encode(buffer, baEnum.NpduControls.PRIORITY_NORMAL_MESSAGE | baEnum.NpduControls.EXPECTING_REPLY, address);
737737
baAdpu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.PDU_TYPE_CONFIRMED_SERVICE_REQUEST, baEnum.ConfirmedServices.SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, settings.maxSegments, settings.maxAdpu, settings.invokeId, 0, 0);
738-
baServices.encodeAtomicWriteFile(buffer, true, objectId, position, 1, fileBuffer, count);
738+
baServices.encodeAtomicWriteFile(buffer, false, objectId, position, fileBuffer);
739739
baBvlc.encode(buffer.buffer, baEnum.BvlcFunctions.BVLC_ORIGINAL_UNICAST_NPDU, buffer.offset);
740740
this._transport.send(buffer.buffer, buffer.offset, address);
741741
this._addCallback(settings.invokeId, (err, data) => {

lib/services.js

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -270,19 +270,19 @@ module.exports.decodeAtomicReadFileAcknowledge = (buffer, offset) => {
270270
};
271271
};
272272

273-
module.exports.encodeAtomicWriteFile = (buffer, isStream, objectId, position, blockCount, blocks, counts) => {
273+
module.exports.encodeAtomicWriteFile = (buffer, isStream, objectId, position, blocks) => {
274274
baAsn1.encodeApplicationObjectId(buffer, objectId.type, objectId.instance);
275275
if (isStream) {
276276
baAsn1.encodeOpeningTag(buffer, 0);
277277
baAsn1.encodeApplicationSigned(buffer, position);
278-
baAsn1.encodeApplicationOctetString(buffer, blocks[0], 0, counts[0]);
278+
baAsn1.encodeApplicationOctetString(buffer, blocks[0], 0, blocks[0].length);
279279
baAsn1.encodeClosingTag(buffer, 0);
280280
} else {
281281
baAsn1.encodeOpeningTag(buffer, 1);
282282
baAsn1.encodeApplicationSigned(buffer, position);
283-
baAsn1.encodeApplicationUnsigned(buffer, blockCount);
284-
for (let i = 0; i < blockCount; i++) {
285-
baAsn1.encodeApplicationOctetString(buffer, blocks[i], 0, counts[i]);
283+
baAsn1.encodeApplicationUnsigned(buffer, blocks.length);
284+
for (let i = 0; i < blocks.length; i++) {
285+
baAsn1.encodeApplicationOctetString(buffer, blocks[i], 0, blocks[i].length);
286286
}
287287
baAsn1.encodeClosingTag(buffer, 1);
288288
}
@@ -292,13 +292,12 @@ module.exports.decodeAtomicWriteFile = (buffer, offset, apduLen) => {
292292
let len = 0;
293293
let result;
294294
let decodedValue;
295-
let isStream = true;
296-
let position = -1;
297-
let blockCount = 0;
298-
let blocks = null;
299-
let counts = null;
295+
let isStream;
296+
let position;
297+
let blocks = [];
298+
let blockCount;
300299
result = baAsn1.decodeTagNumberAndValue(buffer, offset + len);
301-
len += result.length;
300+
len += result.len;
302301
if (result.tagNumber !== baEnum.ApplicationTags.BACNET_APPLICATION_TAG_OBJECT_ID) return;
303302
decodedValue = baAsn1.decodeObjectId(buffer, offset + len);
304303
len += decodedValue.len;
@@ -307,55 +306,41 @@ module.exports.decodeAtomicWriteFile = (buffer, offset, apduLen) => {
307306
isStream = true;
308307
len++;
309308
result = baAsn1.decodeTagNumberAndValue(buffer, offset + len);
310-
len += result.length;
309+
len += result.len;
311310
if (result.tagNumber !== baEnum.ApplicationTags.BACNET_APPLICATION_TAG_SIGNED_INT) return;
312311
decodedValue = baAsn1.decodeSigned(buffer, offset + len, result.value);
313312
len += decodedValue.len;
314313
position = decodedValue.value;
315314
result = baAsn1.decodeTagNumberAndValue(buffer, offset + len);
316-
len += result.length;
315+
len += result.len;
317316
if (result.tagNumber !== baEnum.ApplicationTags.BACNET_APPLICATION_TAG_OCTET_STRING) return;
318-
blockCount = 1;
319-
320-
// TODO: Implement
321-
322-
/*
323-
blocks = new byte[1][];
324-
blocks[0] = new byte[len_value_type];
325-
counts = new int[] { len_value_type };*/
326-
327-
len += baAsn1.decodeOctetString(buffer, offset + len, apduLen, blocks[0], 0, result.value);
328-
317+
decodedValue = baAsn1.decodeOctetString(buffer, offset + len, apduLen, 0, result.value);
318+
len += decodedValue.len;
319+
blocks.push(decodedValue.value);
329320
if (!baAsn1.decodeIsClosingTagNumber(buffer, offset + len, 0)) return;
330321
len++;
331322
} else if (baAsn1.decodeIsOpeningTagNumber(buffer, offset + len, 1)) {
332323
isStream = false;
333324
len++;
334325
result = baAsn1.decodeTagNumberAndValue(buffer, offset + len);
335-
len += result.length;
326+
len += result.len;
336327
if (result.tagNumber !== baEnum.ApplicationTags.BACNET_APPLICATION_TAG_SIGNED_INT) return;
337328
decodedValue = baAsn1.decodeSigned(buffer, offset + len, result.value);
338329
len += decodedValue.len;
339330
position = decodedValue.value;
340331
result = baAsn1.decodeTagNumberAndValue(buffer, offset + len);
341-
len += result.length;
332+
len += result.len;
342333
if (result.tagNumber !== baEnum.ApplicationTags.BACNET_APPLICATION_TAG_UNSIGNED_INT) return;
343334
decodedValue = baAsn1.decodeUnsigned(buffer, offset + len, result.value);
344335
len += decodedValue.len;
345336
blockCount = decodedValue.value;
346-
347-
// TODO: Implement
348-
/*blocks = new byte[block_count][];
349-
counts = new int[block_count];*/
350-
351337
for (let i = 0; i < blockCount; i++) {
352338
result = baAsn1.decodeTagNumberAndValue(buffer, offset + len);
353339
len += result.len;
354-
/*blocks[i] = new byte[len_value_type];
355-
counts[i] = len_value_type;*/
356340
if (result.tagNumber !== baEnum.ApplicationTags.BACNET_APPLICATION_TAG_OCTET_STRING) return;
357-
len += baAsn1.decodeOctetString(buffer, offset + len, apduLen, blocks[i], 0, result.value);
358-
341+
decodedValue = baAsn1.decodeOctetString(buffer, offset + len, apduLen, 0, result.value);
342+
len += decodedValue.len;
343+
blocks.push(decodedValue.value);
359344
}
360345
if (!baAsn1.decodeIsClosingTagNumber(buffer, offset + len, 1)) return;
361346
len++;
@@ -367,9 +352,7 @@ module.exports.decodeAtomicWriteFile = (buffer, offset, apduLen) => {
367352
isStream: isStream,
368353
objectId: objectId,
369354
position: position,
370-
blockCount: blockCount,
371-
blocks: blocks,
372-
counts: counts
355+
blocks: blocks
373356
};
374357
};
375358

test/integration/write-file.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const utils = require('./utils');
66
describe('bacstack - writeFile integration', () => {
77
it('should return a timeout error if no device is available', (next) => {
88
const client = new utils.bacnetClient({adpuTimeout: 200});
9-
client.writeFile('127.0.0.1', {type: 10, instance: 2}, 0, 4, [5, 6, 7 , 8], (err, value) => {
9+
client.writeFile('127.0.0.1', {type: 10, instance: 2}, 0, [[5, 6, 7, 8], [5, 6, 7, 8]], (err, value) => {
1010
expect(err.message).to.eql('ERR_TIMEOUT');
1111
expect(value).to.eql(undefined);
1212
client.close();

test/unit/bacnet-services.spec.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,33 +1243,30 @@ describe('bacstack - Services layer', () => {
12431243
});
12441244
});
12451245

1246-
// TODO: Correct test behaviour
1247-
describe.skip('AtomicWriteFile', () => {
1246+
describe('AtomicWriteFile', () => {
12481247
it('should successfully encode and decode as stream', () => {
12491248
const buffer = utils.getBuffer();
1250-
// (buffer, isStream, objectId, position, blockCount, blocks, counts);
1251-
baServices.encodeAtomicWriteFile(buffer, true, {type: 51, instance: 2}, 0, 100, [12, 12], 2);
1249+
baServices.encodeAtomicWriteFile(buffer, true, {type: 12, instance: 51}, 5, [[12, 12]]);
12521250
const result = baServices.decodeAtomicWriteFile(buffer.buffer, 0, buffer.offset);
12531251
delete result.len;
12541252
expect(result).to.deep.equal({
1255-
objectId: {type: 51, instance: 2},
1256-
count: 12,
1253+
objectId: {type: 12, instance: 51},
12571254
isStream: true,
1258-
position: -50
1255+
position: 5,
1256+
blocks: [[12, 12]]
12591257
});
12601258
});
12611259

12621260
it('should successfully encode and decode as non-stream', () => {
12631261
const buffer = utils.getBuffer();
1264-
// (buffer, isStream, objectId, position, blockCount, blocks, counts);
1265-
baServices.encodeAtomicWriteFile(buffer, false, {type: 51, instance: 2}, 0, 100, [12, 12], 2);
1262+
baServices.encodeAtomicWriteFile(buffer, false, {type: 12, instance: 88}, 10, [[12, 12], [12, 12]]);
12661263
const result = baServices.decodeAtomicWriteFile(buffer.buffer, 0, buffer.offset);
12671264
delete result.len;
12681265
expect(result).to.deep.equal({
1269-
objectId: {type: 51, instance: 2},
1270-
count: 12,
1271-
isStream: true,
1272-
position: -50
1266+
objectId: {type: 12, instance: 88},
1267+
isStream: false,
1268+
position: 10,
1269+
blocks: [[12, 12], [12, 12]]
12731270
});
12741271
});
12751272
});

0 commit comments

Comments
 (0)