diff --git a/src/tag/index.ts b/src/tag/index.ts index 46d48ab..8a21524 100644 --- a/src/tag/index.ts +++ b/src/tag/index.ts @@ -494,7 +494,7 @@ export class Tag extends EventEmitter { * @param Data - Returned from Successful Read Tag Request */ parseReadMessageResponseValueForAtomic(data: Buffer) { - const { SINT, INT, DINT, REAL, BOOL, LINT, BIT_STRING, UINT } = Types; + const { SINT, INT, DINT, REAL, BOOL, LINT, BIT_STRING, UINT, SHORT_STRING, USINT } = Types; const { read_size } = this.state; @@ -512,6 +512,17 @@ export class Tag extends EventEmitter { this.controller_value = data.readInt8(2); } break; + case USINT: + if (data.length > 3) { + const array = []; + for (let i = 0; i < data.length - 2; i++) { + array.push(data.readUInt8(i + 2)); + } + this.controller_value = array; + } else { + this.controller_value = data.readUInt8(2); + } + break; case UINT: if (data.length > 4) { const array = []; @@ -583,9 +594,23 @@ export class Tag extends EventEmitter { this.controller_value = data.readBigInt64LE(2); } break; + case SHORT_STRING: // single byte character string + if (data.length > 3) { + const len = data.readUInt8(2); + this.controller_value = data.toString('utf8', 3); // use latin1 encoding? + if (len !== this.controller_value.length) { + throw new Error(` Read from Controller: Short string length mismatch`); + } + } else { + //empty string, data[2] will be 0 as well, as it is the string length + //return empty string instead of null + this.controller_value = '';//null; + } + break; default: + const ttt = CIP.DataTypes.getTypeCodeString(this.state.tag.type); throw new Error( - `Unrecognized Type Passed Read from Controller: ${this.state.tag.type}` + `Unrecognized Type Passed Read from Controller: ${this.state.tag.type} ${ttt}` ); } /* eslint-enable indent */ @@ -600,7 +625,9 @@ export class Tag extends EventEmitter { * @memberof Tag */ generateWriteMessageRequest(value: any = null, size: number = 0x01): Buffer { - if (value !== null) this.state.tag.value = value; + if (value !== null) { + this.state.tag.value = value; + } const { tag } = this.state; @@ -668,7 +695,7 @@ export class Tag extends EventEmitter { */ generateWriteMessageRequestForAtomic(value: any, size: number) { const { tag } = this.state; - const { SINT, INT, DINT, REAL, BOOL, LINT } = Types; + const { SINT, INT, DINT, REAL, BOOL, LINT, SHORT_STRING, USINT } = Types; // Build Message Router to Embed in UCMM let buf = Buffer.alloc(4); let valBuf = null; @@ -687,7 +714,7 @@ export class Tag extends EventEmitter { if (Array.isArray(value)) { valBuf = Buffer.alloc(value.length); for (var i = 0; i < value.length; i++) { - valBuf.writeUInt8(value[i], i); + valBuf.writeInt8(value[i], i); } } else { valBuf = Buffer.alloc(1); @@ -695,6 +722,18 @@ export class Tag extends EventEmitter { } buf = Buffer.concat([buf, valBuf]); break; + case USINT: + if (Array.isArray(value)) { + valBuf = Buffer.alloc(value.length); + for (var i = 0; i < value.length; i++) { + valBuf.writeUInt8(value[i], i); + } + } else { + valBuf = Buffer.alloc(1); + valBuf.writeUInt8(tag.value); + } + buf = Buffer.concat([buf, valBuf]); + break; case INT: if (Array.isArray(value)) { valBuf = Buffer.alloc(2 * value.length); @@ -754,6 +793,22 @@ export class Tag extends EventEmitter { } buf = Buffer.concat([buf, valBuf]); break; + case SHORT_STRING: + valBuf = Buffer.alloc(1); + if (!tag.value || tag.value.length === 0) + valBuf.writeInt8(0x00); + else { + const strBuf = Buffer.from(tag.value, 'latin1'); + const strlen = strBuf.length; + if ( strlen > 255) { + throw new Error(`String too long to Write to Controller: ${tag.type}, limit 255 bytes, length ${strlen}`); + } + valBuf = Buffer.alloc(1 + strlen); // 1+ for length byte + valBuf.writeUInt8(strlen);//write the length + strBuf.copy(valBuf,1,); + } + buf = Buffer.concat([buf, valBuf]); + break; default: throw new Error(`Unrecognized Type to Write to Controller: ${tag.type}`); }