removed code smells detected by IntelliJ and Error Prone SCA, removed the GUI's jcalendar dependency

pull/19/head
Stefan Feuerhahn 5 years ago
parent 6c89bb3639
commit 792afe0ce8

@ -69,7 +69,6 @@ tasks.register<Tar>("tar") {
dependencies {
implementation("com.beanit:asn1bean:1.12.0")
implementation("com.toedter:jcalendar:1.4")
implementation("org.slf4j:slf4j-api:1.7.25")
runtimeOnly("ch.qos.logback:logback-classic:1.2.3")
}

@ -21,7 +21,6 @@ Besides the IEC61850bean library the folder *build/libs-all/* contains the follo
* *logback-core/logback-classic* - an actual logger implementation of the slf4-api. It is used by the console server application to output log information. It can be replaced by a logger of your choice that supports the slf4j API. Like slf4j it is only needed for server implementations. License: EPLv1.0 and LGPLv2.1, http://logback.qos.ch
* *jcalendar* - a calendar library needed by the client GUI. You don't need this dependency if you don't use the client gui. (C)1999-2011 Kai Toedter, License: LGPLv3, http://toedter.com/jcalendar/
### Console & GUI Applications

@ -0,0 +1,5 @@
#Tue Jun 30 15:11:36 CEST 2020
tselLocal=0,0
serverAddress=127.0.0.1
tselRemote=0,1
serverPort=10002

@ -20,7 +20,6 @@ import com.beanit.iec61850bean.internal.mms.asn1.Unsigned32;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
@ -81,7 +80,7 @@ public final class Array extends FcModelNode {
@Override
public List<BasicDataAttribute> getBasicDataAttributes() {
List<BasicDataAttribute> subBasicDataAttributes = new LinkedList<>();
List<BasicDataAttribute> subBasicDataAttributes = new ArrayList<>();
for (ModelNode item : items) {
subBasicDataAttributes.addAll(item.getBasicDataAttributes());
}

@ -17,7 +17,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public abstract class BasicDataAttribute extends FcModelNode {
@ -34,10 +33,10 @@ public abstract class BasicDataAttribute extends FcModelNode {
boolean qchg;
boolean dupd;
List<Urcb> chgRcbs = null;
List<Urcb> dupdRcbs = null;
final List<Urcb> chgRcbs;
final List<Urcb> dupdRcbs;
BasicDataAttribute(
protected BasicDataAttribute(
ObjectReference objectReference, Fc fc, String sAddr, boolean dchg, boolean dupd) {
this.objectReference = objectReference;
this.fc = fc;
@ -47,9 +46,13 @@ public abstract class BasicDataAttribute extends FcModelNode {
if (dchg) {
chgRcbs = new ArrayList<>();
} else {
chgRcbs = null;
}
if (dupd) {
dupdRcbs = new ArrayList<>();
} else {
dupdRcbs = null;
}
}
@ -97,7 +100,7 @@ public abstract class BasicDataAttribute extends FcModelNode {
@Override
public List<BasicDataAttribute> getBasicDataAttributes() {
List<BasicDataAttribute> subBasicDataAttributes = new LinkedList<>();
List<BasicDataAttribute> subBasicDataAttributes = new ArrayList<>();
subBasicDataAttributes.add(this);
return subBasicDataAttributes;
}

@ -24,7 +24,7 @@ public abstract class BdaBitString extends BasicDataAttribute {
final int maxNumBits;
volatile byte[] value;
public BdaBitString(
protected BdaBitString(
ObjectReference objectReference,
Fc fc,
String sAddr,

@ -50,7 +50,7 @@ public final class BdaEntryTime extends BasicDataAttribute {
(byte) (ms >> 24),
(byte) (ms >> 16),
(byte) (ms >> 8),
(byte) (ms),
(byte) ms,
(byte) (days >> 8),
(byte) days
};

@ -18,6 +18,7 @@ import com.beanit.iec61850bean.internal.mms.asn1.FloatingPoint;
import com.beanit.iec61850bean.internal.mms.asn1.TypeDescription;
import com.beanit.iec61850bean.internal.mms.asn1.Unsigned8;
import java.nio.ByteBuffer;
import java.util.Arrays;
public final class BdaFloat64 extends BasicDataAttribute {
@ -55,14 +56,14 @@ public final class BdaFloat64 extends BasicDataAttribute {
return null;
}
return Double.longBitsToDouble(
((0xffL & (value[1])) << 56)
| ((0xffL & (value[2])) << 48)
| ((0xffL & (value[3])) << 40)
| ((0xffL & (value[4])) << 32)
| ((0xffL & (value[5])) << 24)
| ((0xffL & (value[6])) << 16)
| ((0xffL & (value[7])) << 8)
| ((0xffL & (value[8])) << 0));
((0xffL & value[1]) << 56)
| ((0xffL & value[2]) << 48)
| ((0xffL & value[3]) << 40)
| ((0xffL & value[4]) << 32)
| ((0xffL & value[5]) << 24)
| ((0xffL & value[6]) << 16)
| ((0xffL & value[7]) << 8)
| ((0xffL & value[8]) << 0));
}
public void setDouble(Double value) {
@ -126,6 +127,6 @@ public final class BdaFloat64 extends BasicDataAttribute {
@Override
public String getValueString() {
return "" + value;
return "" + Arrays.toString(value);
}
}

@ -13,17 +13,12 @@
*/
package com.beanit.iec61850bean;
import java.util.ArrayList;
public final class BdaQuality extends BdaBitString {
public BdaQuality(ObjectReference objectReference, Fc fc, String sAddr, boolean qchg) {
super(objectReference, fc, sAddr, 13, false, false);
super(objectReference, fc, sAddr, 13, qchg, false);
this.qchg = qchg;
basicType = BdaType.QUALITY;
if (qchg) {
chgRcbs = new ArrayList<>();
}
setDefault();
}

@ -17,7 +17,7 @@ import com.beanit.asn1bean.ber.types.BerNull;
import com.beanit.iec61850bean.internal.mms.asn1.Data;
import com.beanit.iec61850bean.internal.mms.asn1.TypeDescription;
import com.beanit.iec61850bean.internal.mms.asn1.UtcTime;
import java.util.Calendar;
import java.time.Instant;
import java.util.Date;
public final class BdaTimestamp extends BasicDataAttribute {
@ -65,43 +65,6 @@ public final class BdaTimestamp extends BasicDataAttribute {
return ((0xff & value[4]) << 16 | (0xff & value[5]) << 8 | (0xff & value[6]));
}
public void setDate(
Date date,
boolean leapSecondsKnown,
boolean clockFailure,
boolean clockNotSynchronized,
int timeAccuracy) {
if (value == null) {
value = new byte[8];
}
int secondsSinceEpoch = (int) (date.getTime() / 1000L);
int fractionOfSecond = (int) ((date.getTime() % 1000L) / 1000.0 * (1 << 24));
int timeQuality = timeAccuracy & 0x1f;
if (leapSecondsKnown) {
timeQuality = timeQuality | 0x80;
}
if (clockFailure) {
timeQuality = timeQuality | 0x40;
}
if (clockNotSynchronized) {
timeQuality = timeQuality | 0x20;
}
value =
new byte[] {
(byte) ((secondsSinceEpoch >> 24) & 0xff),
(byte) ((secondsSinceEpoch >> 16) & 0xff),
(byte) ((secondsSinceEpoch >> 8) & 0xff),
(byte) (secondsSinceEpoch & 0xff),
(byte) ((fractionOfSecond >> 16) & 0xff),
(byte) ((fractionOfSecond >> 8) & 0xff),
(byte) (fractionOfSecond & 0xff),
(byte) timeQuality
};
}
@Override
public void setValueFrom(BasicDataAttribute bda) {
byte[] srcValue = ((BdaTimestamp) bda).getValue();
@ -111,26 +74,44 @@ public final class BdaTimestamp extends BasicDataAttribute {
System.arraycopy(srcValue, 0, value, 0, srcValue.length);
}
public Date getDate() {
public Instant getInstant() {
if (value == null || value.length == 0) {
return null;
}
long time =
getSecondsSinceEpoch() * 1000L
+ (long) (((float) getFractionOfSecond()) / (1 << 24) * 1000 + 0.5);
return new Date(time);
return Instant.ofEpochMilli(time);
}
public void setDate(Date date) {
public void setInstant(Instant instant) {
setInstant(instant, true, false, false, 10);
}
public void setInstant(
Instant instant,
boolean leapSecondsKnown,
boolean clockFailure,
boolean clockNotSynchronized,
int timeAccuracy) {
if (value == null) {
value = new byte[8];
}
int secondsSinceEpoch = (int) (date.getTime() / 1000L);
int fractionOfSecond = (int) ((date.getTime() % 1000L) / 1000.0 * (1 << 24));
int secondsSinceEpoch = (int) (instant.toEpochMilli() / 1000L);
int fractionOfSecond = (int) ((instant.toEpochMilli() % 1000L) / 1000.0 * (1 << 24));
int timeQuality = timeAccuracy & 0x1f;
if (leapSecondsKnown) {
timeQuality = timeQuality | 0x80;
}
if (clockFailure) {
timeQuality = timeQuality | 0x40;
}
if (clockNotSynchronized) {
timeQuality = timeQuality | 0x20;
}
// 0x8a = time accuracy of 10 and LeapSecondsKnown = true, ClockFailure
// = false, ClockNotSynchronized = false
value =
new byte[] {
(byte) ((secondsSinceEpoch >> 24) & 0xff),
@ -140,7 +121,7 @@ public final class BdaTimestamp extends BasicDataAttribute {
(byte) ((fractionOfSecond >> 16) & 0xff),
(byte) ((fractionOfSecond >> 8) & 0xff),
(byte) (fractionOfSecond & 0xff),
(byte) 0x8a
(byte) timeQuality
};
}
@ -161,9 +142,6 @@ public final class BdaTimestamp extends BasicDataAttribute {
* does not take into account the leap seconds that occurred before the initialization of the time
* source of the device.
*
* <p>Java {@link Date} and {@link Calendar} objects do handle leap seconds, so this is usually
* true.
*
* @return TRUE of the attribute LeapSecondsKnown shall indicate that the value for
* SecondSinceEpoch takes into account all leap seconds occurred
*/
@ -213,7 +191,7 @@ public final class BdaTimestamp extends BasicDataAttribute {
/** Sets Timestamp to current time */
public void setCurrentTime() {
setDate(new Date());
setInstant(Instant.now());
}
@Override
@ -254,11 +232,11 @@ public final class BdaTimestamp extends BasicDataAttribute {
@Override
public String toString() {
return getReference().toString() + ": " + getDate();
return getReference().toString() + ": " + getInstant();
}
@Override
public String getValueString() {
return getDate().toString();
return getInstant().toString();
}
}

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.iec61850bean.internal.mms.asn1.Data;
import com.beanit.iec61850bean.internal.mms.asn1.Integer32;
import com.beanit.iec61850bean.internal.mms.asn1.MMSString;
@ -108,6 +110,6 @@ public final class BdaUnicodeString extends BasicDataAttribute {
if (value == null) {
return getReference().toString() + ": null";
}
return getReference().toString() + ": " + new String(value);
return getReference().toString() + ": " + new String(value, UTF_8);
}
}

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
import com.beanit.iec61850bean.internal.mms.asn1.Data;
import com.beanit.iec61850bean.internal.mms.asn1.Integer32;
@ -49,7 +51,7 @@ public final class BdaVisibleString extends BasicDataAttribute {
}
public void setValue(String value) {
setValue(value.getBytes());
setValue(value.getBytes(UTF_8));
}
@Override
@ -66,7 +68,7 @@ public final class BdaVisibleString extends BasicDataAttribute {
}
public String getStringValue() {
return new String(value);
return new String(value, UTF_8);
}
@Override
@ -118,11 +120,11 @@ public final class BdaVisibleString extends BasicDataAttribute {
if (value.length == 0 || value[0] == (byte) 0) {
return getReference().toString() + ": ''";
}
return getReference().toString() + ": " + new String(value);
return getReference().toString() + ": " + new String(value, UTF_8);
}
@Override
public String getValueString() {
return new String(value);
return new String(value, UTF_8);
}
}

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import com.beanit.asn1bean.ber.types.BerInteger;
import com.beanit.asn1bean.ber.types.BerNull;
@ -75,12 +77,11 @@ import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.text.ParseException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@ -429,6 +430,7 @@ public final class ClientAssociation {
decodedResponsePdu = incomingResponses.poll(responseTimeout, TimeUnit.MILLISECONDS);
}
} catch (InterruptedException e) {
// TODO can this ever be interrupted?
}
if (decodedResponsePdu == null) {
@ -661,7 +663,7 @@ public final class ClientAssociation {
}
private List<String> retrieveLogicalNodeNames(String ld) throws ServiceError, IOException {
List<String> lns = new LinkedList<>();
List<String> lns = new ArrayList<>();
String continueAfterRef = "";
do {
ConfirmedServiceRequest serviceRequest =
@ -669,7 +671,7 @@ public final class ClientAssociation {
ConfirmedServiceResponse confirmedServiceResponse = encodeWriteReadDecode(serviceRequest);
continueAfterRef = decodeGetDirectoryResponse(confirmedServiceResponse, lns);
} while (continueAfterRef != "");
} while (!continueAfterRef.isEmpty());
return lns;
}
@ -684,16 +686,16 @@ public final class ClientAssociation {
objectClass.setBasicObjectClass(new BerInteger(2));
}
GetNameListRequest getNameListRequest = null;
GetNameListRequest getNameListRequest;
ObjectScope objectScopeChoiceType = new ObjectScope();
objectScopeChoiceType.setDomainSpecific(new Identifier(ldRef.getBytes()));
objectScopeChoiceType.setDomainSpecific(new Identifier(ldRef.getBytes(UTF_8)));
getNameListRequest = new GetNameListRequest();
getNameListRequest.setObjectClass(objectClass);
getNameListRequest.setObjectScope(objectScopeChoiceType);
if (continueAfter != "") {
getNameListRequest.setContinueAfter(new Identifier(continueAfter.getBytes()));
if (!continueAfter.isEmpty()) {
getNameListRequest.setContinueAfter(new Identifier(continueAfter.getBytes(UTF_8)));
}
ConfirmedServiceRequest confirmedServiceRequest = new ConfirmedServiceRequest();
@ -756,8 +758,8 @@ public final class ClientAssociation {
private ConfirmedServiceRequest constructGetDataDefinitionRequest(ObjectReference lnRef) {
ObjectName.DomainSpecific domainSpec = new ObjectName.DomainSpecific();
domainSpec.setDomainID(new Identifier(lnRef.get(0).getBytes()));
domainSpec.setItemID(new Identifier(lnRef.get(1).getBytes()));
domainSpec.setDomainID(new Identifier(lnRef.get(0).getBytes(UTF_8)));
domainSpec.setItemID(new Identifier(lnRef.get(1).getBytes(UTF_8)));
ObjectName objectName = new ObjectName();
objectName.setDomainSpecific(domainSpec);
@ -856,7 +858,7 @@ public final class ClientAssociation {
*/
public List<FileInformation> getFileDirectory(String directoryName)
throws ServiceError, IOException {
List<FileInformation> files = new LinkedList<>();
List<FileInformation> files = new ArrayList<>();
boolean moreFollows = true;
@ -866,7 +868,7 @@ public final class ClientAssociation {
FileDirectoryRequest fileDirectoryRequest = new FileDirectoryRequest();
BerGraphicString berGraphicString = new BerGraphicString(directoryName.getBytes());
BerGraphicString berGraphicString = new BerGraphicString(directoryName.getBytes(UTF_8));
FileName fileSpecification = new FileName();
fileSpecification.getBerGraphicString().add(berGraphicString);
@ -878,7 +880,7 @@ public final class ClientAssociation {
continueAfterSpecification
.getBerGraphicString()
.add(new BerGraphicString(continueAfter.getBytes()));
.add(new BerGraphicString(continueAfter.getBytes(UTF_8)));
fileDirectoryRequest.setContinueAfter(continueAfterSpecification);
}
@ -910,7 +912,7 @@ public final class ClientAssociation {
public void deleteFile(String filename) throws ServiceError, IOException {
FileDeleteRequest fileDeleteRequest = new FileDeleteRequest();
fileDeleteRequest.getBerGraphicString().add(new BerGraphicString(filename.getBytes()));
fileDeleteRequest.getBerGraphicString().add(new BerGraphicString(filename.getBytes(UTF_8)));
ConfirmedServiceRequest confirmedServiceRequest = new ConfirmedServiceRequest();
confirmedServiceRequest.setFileDelete(fileDeleteRequest);
@ -929,7 +931,7 @@ public final class ClientAssociation {
FileOpenRequest fileOpenRequest = new FileOpenRequest();
FileName fileSpecification = new FileName();
fileSpecification.getBerGraphicString().add(new BerGraphicString(filename.getBytes()));
fileSpecification.getBerGraphicString().add(new BerGraphicString(filename.getBytes(UTF_8)));
fileOpenRequest.setFileName(fileSpecification);
fileOpenRequest.setInitialPosition(new Unsigned32(0));
@ -1229,7 +1231,7 @@ public final class ClientAssociation {
private ConfirmedServiceRequest constructGetDataSetDirectoryRequest(
Identifier dsId, LogicalDevice ld) throws ServiceError {
ObjectName.DomainSpecific domainSpecificObjectName = new ObjectName.DomainSpecific();
domainSpecificObjectName.setDomainID(new Identifier(ld.getName().getBytes()));
domainSpecificObjectName.setDomainID(new Identifier(ld.getName().getBytes(UTF_8)));
domainSpecificObjectName.setItemID(dsId);
GetNamedVariableListAttributesRequest dataSetObj = new GetNamedVariableListAttributesRequest();
@ -1720,7 +1722,7 @@ public final class ClientAssociation {
String dataSetRef = null;
if (optFlds.isDataSetName()) {
dataSetRef = (listRes.get(index++).getSuccess().getVisibleString().toString());
dataSetRef = listRes.get(index++).getSuccess().getVisibleString().toString();
} else {
for (Urcb urcb : serverModel.getUrcbs()) {
if ((urcb.getRptId() != null && urcb.getRptId().getStringValue().equals(rptId))
@ -1755,7 +1757,7 @@ public final class ClientAssociation {
Boolean bufOvfl = null;
if (optFlds.isBufferOverflow()) {
bufOvfl = (listRes.get(index++).getSuccess().getBool().value);
bufOvfl = listRes.get(index++).getSuccess().getBool().value;
}
BdaOctetString entryId = null;
@ -1915,7 +1917,7 @@ public final class ClientAssociation {
}
((BdaInt8U) oper.getChild("ctlNum")).setValue((short) 1);
((BdaTimestamp) oper.getChild("T")).setDate(new Date(System.currentTimeMillis()));
((BdaTimestamp) oper.getChild("T")).setInstant(Instant.now());
setDataValues(oper);
}
@ -2008,6 +2010,7 @@ public final class ClientAssociation {
try {
incomingResponses.put(decodedResponsePdu);
} catch (InterruptedException e) {
// TODO can this ever be interrupted?
}
}
}
@ -2025,6 +2028,7 @@ public final class ClientAssociation {
try {
incomingResponses.put(decodedResponsePdu);
} catch (InterruptedException e) {
// TODO can this ever be interrupted?
}
}
}
@ -2043,6 +2047,7 @@ public final class ClientAssociation {
try {
incomingResponses.put(decodedResponsePdu);
} catch (InterruptedException e) {
// TODO can this ever be interrupted?
}
}
}
@ -2082,6 +2087,7 @@ public final class ClientAssociation {
try {
incomingResponses.put(mmsPdu);
} catch (InterruptedException e1) {
// TODO can this ever be interrupted?
}
}
}
@ -2108,6 +2114,7 @@ public final class ClientAssociation {
try {
incomingResponses.put(mmsPdu);
} catch (InterruptedException e1) {
// TODO can this ever be interrupted?
}
}
}

@ -20,7 +20,6 @@ import com.beanit.iec61850bean.internal.mms.asn1.TypeDescription.Structure.Compo
import com.beanit.iec61850bean.internal.mms.asn1.TypeSpecification;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
final class DataDefinitionResParser {
@ -46,7 +45,7 @@ final class DataDefinitionResParser {
Components structure = typeSpec.getStructure().getComponents();
List<FcDataObject> fcDataObjects = new LinkedList<>();
List<FcDataObject> fcDataObjects = new ArrayList<>();
Fc fc;
for (TypeDescription.Structure.Components.SEQUENCE fcComponent : structure.getSEQUENCE()) {

@ -13,13 +13,14 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.iec61850bean.internal.mms.asn1.Identifier;
import com.beanit.iec61850bean.internal.mms.asn1.ObjectName;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -42,7 +43,7 @@ public final class DataSet implements Iterable<FcModelNode> {
+ dataSetReference
+ " is invalid. Must either start with @ or contain a slash.");
}
this.members = new LinkedList<>();
this.members = new ArrayList<>();
this.dataSetReference = dataSetReference;
this.deletable = deletable;
@ -105,7 +106,7 @@ public final class DataSet implements Iterable<FcModelNode> {
}
public List<BasicDataAttribute> getBasicDataAttributes() {
List<BasicDataAttribute> subBasicDataAttributes = new LinkedList<>();
List<BasicDataAttribute> subBasicDataAttributes = new ArrayList<>();
for (ModelNode member : members) {
subBasicDataAttributes.addAll(member.getBasicDataAttributes());
}
@ -120,7 +121,7 @@ public final class DataSet implements Iterable<FcModelNode> {
if (dataSetReference.charAt(0) == '@') {
mmsObjectName = new ObjectName();
mmsObjectName.setAaSpecific(new Identifier(dataSetReference.getBytes()));
mmsObjectName.setAaSpecific(new Identifier(dataSetReference.getBytes(UTF_8)));
return mmsObjectName;
}
@ -129,8 +130,8 @@ public final class DataSet implements Iterable<FcModelNode> {
String itemID = dataSetReference.substring(slash + 1).replace('.', '$');
ObjectName.DomainSpecific domainSpecificObjectName = new ObjectName.DomainSpecific();
domainSpecificObjectName.setDomainID(new Identifier(domainID.getBytes()));
domainSpecificObjectName.setItemID(new Identifier(itemID.getBytes()));
domainSpecificObjectName.setDomainID(new Identifier(domainID.getBytes(UTF_8)));
domainSpecificObjectName.setItemID(new Identifier(itemID.getBytes(UTF_8)));
mmsObjectName = new ObjectName();
mmsObjectName.setDomainSpecific(domainSpecificObjectName);

@ -51,12 +51,6 @@ public enum Fc {
/** Buffered Reporting */
BR;
/*
* * @param fc
*
* @return
*/
public static Fc fromString(String fc) {
try {
return Fc.valueOf(fc);

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.iec61850bean.internal.mms.asn1.AlternateAccess;
import com.beanit.iec61850bean.internal.mms.asn1.AlternateAccessSelection;
import com.beanit.iec61850bean.internal.mms.asn1.AlternateAccessSelection.SelectAccess;
@ -151,7 +153,7 @@ public abstract class FcModelNode extends ModelNode {
}
BasicIdentifier subIndexReference =
new BasicIdentifier(postArrayIndexItemId.toString().getBytes());
new BasicIdentifier(postArrayIndexItemId.toString().getBytes(UTF_8));
AlternateAccessSelection.SelectAccess subIndexReferenceSelectAccess =
new AlternateAccessSelection.SelectAccess();
@ -220,8 +222,9 @@ public abstract class FcModelNode extends ModelNode {
}
ObjectName.DomainSpecific domainSpecificObjectName = new ObjectName.DomainSpecific();
domainSpecificObjectName.setDomainID(new Identifier(objectReference.get(0).getBytes()));
domainSpecificObjectName.setItemID(new Identifier(preArrayIndexItemId.toString().getBytes()));
domainSpecificObjectName.setDomainID(new Identifier(objectReference.get(0).getBytes(UTF_8)));
domainSpecificObjectName.setItemID(
new Identifier(preArrayIndexItemId.toString().getBytes(UTF_8)));
ObjectName objectName = new ObjectName();
objectName.setDomainSpecific(domainSpecificObjectName);

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.iec61850bean.internal.mms.asn1.Data;
import com.beanit.iec61850bean.internal.mms.asn1.Identifier;
import com.beanit.iec61850bean.internal.mms.asn1.TypeDescription;
@ -22,7 +24,6 @@ import com.beanit.iec61850bean.internal.mms.asn1.TypeSpecification;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -111,7 +112,7 @@ public abstract class ModelNode implements Iterable<ModelNode> {
* node.
*/
public List<BasicDataAttribute> getBasicDataAttributes() {
List<BasicDataAttribute> subBasicDataAttributes = new LinkedList<>();
List<BasicDataAttribute> subBasicDataAttributes = new ArrayList<>();
for (ModelNode child : children.values()) {
subBasicDataAttributes.addAll(child.getBasicDataAttributes());
}
@ -160,7 +161,7 @@ public abstract class ModelNode implements Iterable<ModelNode> {
TypeDescription.Structure.Components.SEQUENCE component =
new TypeDescription.Structure.Components.SEQUENCE();
component.setComponentName(new Identifier(child.getName().getBytes()));
component.setComponentName(new Identifier(child.getName().getBytes(UTF_8)));
component.setComponentType(typeSpecification);
structComponents.add(component);

@ -13,8 +13,8 @@
*/
package com.beanit.iec61850bean;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/** ObjectReference syntax: LDName/LNName.DOName[.Name[. ...]] */
@ -34,7 +34,11 @@ public final class ObjectReference implements Iterable<String> {
this.objectReference = objectReference;
}
/** @return Returns name part of the reference. */
/**
* Returns name part of the reference.
*
* @return the name
*/
public String getName() {
if (nodeNames == null) {
parseForNameList();
@ -107,7 +111,7 @@ public final class ObjectReference implements Iterable<String> {
private void parseForNameList() {
nodeNames = new LinkedList<>();
nodeNames = new ArrayList<>();
int lastDelim = -1;
int nextDelim = objectReference.indexOf('/');

@ -19,7 +19,7 @@ public abstract class Rcb extends FcDataObject {
DataSet dataSet;
public Rcb(ObjectReference objectReference, Fc fc, List<FcModelNode> children) {
protected Rcb(ObjectReference objectReference, Fc fc, List<FcModelNode> children) {
super(objectReference, fc, children);
}

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.iec61850bean.internal.scl.AbstractDataAttribute;
import com.beanit.iec61850bean.internal.scl.Bda;
import com.beanit.iec61850bean.internal.scl.Da;
@ -31,7 +33,6 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
@ -175,7 +176,7 @@ public class SclParser {
if (namedItem == null) {
throw new SclParseException("AccessPoint has no name attribute!");
}
String name = namedItem.getNodeValue();
// TODO save this name?
serverSap = new ServerSap(102, 0, null, server, null);
break;
@ -590,7 +591,7 @@ public class SclParser {
new ObjectReference(reportObjRef.toString() + ".RptID"), fc, "", 129, false, false);
attribute = rcbNodeAttributes.getNamedItem("rptID");
if (attribute != null) {
rptId.setValue(attribute.getNodeValue().getBytes());
rptId.setValue(attribute.getNodeValue().getBytes(UTF_8));
} else {
rptId.setValue(reportObjRef.toString());
}
@ -615,7 +616,7 @@ public class SclParser {
if (attribute != null) {
String nodeValue = attribute.getNodeValue();
String dataSetName = parentRef + "$" + nodeValue;
datSet.setValue(dataSetName.getBytes());
datSet.setValue(dataSetName.getBytes(UTF_8));
}
children.add(datSet);
@ -760,14 +761,14 @@ public class SclParser {
Map<Fc, List<FcModelNode>> subFCDataMap = new LinkedHashMap<>();
for (Fc fc : Fc.values()) {
subFCDataMap.put(fc, new LinkedList<FcModelNode>());
subFCDataMap.put(fc, new ArrayList<>());
}
for (ModelNode childNode : childNodes) {
subFCDataMap.get(((FcModelNode) childNode).getFc()).add((FcModelNode) childNode);
}
List<FcDataObject> fcDataObjects = new LinkedList<>();
List<FcDataObject> fcDataObjects = new ArrayList<>();
ObjectReference objectReference = new ObjectReference(ref);
for (Fc fc : Fc.values()) {
@ -1002,7 +1003,7 @@ public class SclParser {
dchg,
dupd);
if (val != null) {
bda.setValue(val.getBytes());
bda.setValue(val.getBytes(UTF_8));
}
return bda;
} else if (bType.startsWith("Unicode")) {
@ -1015,7 +1016,7 @@ public class SclParser {
dchg,
dupd);
if (val != null) {
bda.setValue(val.getBytes());
bda.setValue(val.getBytes(UTF_8));
}
return bda;
} else if (bType.startsWith("Octet")) {
@ -1099,7 +1100,7 @@ public class SclParser {
BdaVisibleString bda =
new BdaVisibleString(new ObjectReference(ref), fc, sAddr, 129, dchg, dupd);
if (val != null) {
bda.setValue(val.getBytes());
bda.setValue(val.getBytes(UTF_8));
}
return bda;
} else {

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import com.beanit.asn1bean.ber.types.BerInteger;
import com.beanit.asn1bean.ber.types.BerNull;
@ -73,7 +75,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.Executors;
@ -286,7 +287,7 @@ final class ServerAssociation {
getNameListRequest.getObjectClass().getBasicObjectClass().longValue();
if (basicObjectClass == 9) {
logger.debug("Got a GetServerDirectory (MMS GetNameList[DOMAIN]) request");
response = handleGetServerDirectoryRequest(getNameListRequest);
response = handleGetServerDirectoryRequest();
} else if (basicObjectClass == 0) {
logger.debug("Got a Get{LD|LN}Directory (MMS GetNameList[NAMED_VARIABLE]) request");
response = handleGetDirectoryRequest(getNameListRequest);
@ -417,7 +418,7 @@ final class ServerAssociation {
private MMSpdu listenForMmsRequest(AcseAssociation acseAssociation) {
while (true) {
MMSpdu mmsRequestPdu = null;
MMSpdu mmsRequestPdu;
byte[] buffer;
pduBuffer.clear();
try {
@ -494,7 +495,7 @@ final class ServerAssociation {
default:
errClass.setOthers(new BerInteger(e.getErrorCode()));
}
com.beanit.iec61850bean.internal.mms.asn1.ServiceError asn1ServiceError = null;
com.beanit.iec61850bean.internal.mms.asn1.ServiceError asn1ServiceError;
asn1ServiceError = new com.beanit.iec61850bean.internal.mms.asn1.ServiceError();
asn1ServiceError.setErrorClass(errClass);
@ -510,14 +511,13 @@ final class ServerAssociation {
return mmsPdu;
}
private GetNameListResponse handleGetServerDirectoryRequest(GetNameListRequest getNameListRequest)
throws ServiceError {
private GetNameListResponse handleGetServerDirectoryRequest() throws ServiceError {
ListOfIdentifier listOfIdentifier = new ListOfIdentifier();
List<Identifier> identifiers = listOfIdentifier.getIdentifier();
for (ModelNode ld : serverModel) {
identifiers.add(new Identifier(ld.getName().getBytes()));
identifiers.add(new Identifier(ld.getName().getBytes(UTF_8)));
}
GetNameListResponse getNameListResponse = new GetNameListResponse();
@ -564,7 +564,7 @@ final class ServerAssociation {
insertRef = false;
}
List<String> mmsReferences = new LinkedList<>();
List<String> mmsReferences = new ArrayList<>();
for (ModelNode logicalNodeMn : logicalDevice) {
LogicalNode logicalNode = (LogicalNode) logicalNodeMn;
@ -598,9 +598,9 @@ final class ServerAssociation {
break;
}
Identifier identifier = null;
Identifier identifier;
identifier = new Identifier(mmsReference.getBytes());
identifier = new Identifier(mmsReference.getBytes(UTF_8));
identifiers.add(identifier);
identifierSize += mmsReference.length() + 2;
@ -773,7 +773,7 @@ final class ServerAssociation {
TypeDescription.Structure.Components.SEQUENCE structComponent =
new TypeDescription.Structure.Components.SEQUENCE();
structComponent.setComponentName(new Identifier(child.getName().getBytes()));
structComponent.setComponentName(new Identifier(child.getName().getBytes(UTF_8)));
structComponent.setComponentType(typeSpecification);
doStructComponents.add(structComponent);
}
@ -825,7 +825,7 @@ final class ServerAssociation {
TypeDescription.Structure.Components.SEQUENCE doStructComponent =
new TypeDescription.Structure.Components.SEQUENCE();
doStructComponent.setComponentName(new Identifier(child.getName().getBytes()));
doStructComponent.setComponentName(new Identifier(child.getName().getBytes(UTF_8)));
doStructComponent.setComponentType(typeSpecification);
doStructComponents.add(doStructComponent);
@ -842,7 +842,7 @@ final class ServerAssociation {
TypeDescription.Structure.Components.SEQUENCE structCom =
new TypeDescription.Structure.Components.SEQUENCE();
structCom.setComponentName(new Identifier(mmsFc.getBytes()));
structCom.setComponentName(new Identifier(mmsFc.getBytes(UTF_8)));
structCom.setComponentType(typeSpecification);
structComponents.add(structCom);
@ -1513,7 +1513,7 @@ final class ServerAssociation {
logger.info("maxMMSPduSize reached");
break;
}
identifiers.add(new Identifier(dsRef.getBytes()));
identifiers.add(new Identifier(dsRef.getBytes(UTF_8)));
identifierSize += dsRef.length() + 2;
} else {
if (dsRef.equals(continueAfter)) {

@ -22,7 +22,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -116,7 +115,7 @@ public final class ServerModel extends ModelNode {
List<String> getDataSetNames(String ldName) {
// TODO make thread save
List<String> dataSetNames = new LinkedList<>();
List<String> dataSetNames = new ArrayList<>();
for (String dataSetRef : dataSets.keySet()) {
if (dataSetRef.startsWith(ldName)) {
dataSetNames.add(dataSetRef.substring(dataSetRef.indexOf('/') + 1).replace('.', '$'));
@ -135,7 +134,7 @@ public final class ServerModel extends ModelNode {
}
/**
* @param dataSetReference
* @param dataSetReference the data set reference
* @return returns the DataSet that was removed, null if no DataSet with the given reference was
* found or the data set is not deletable.
*/
@ -266,9 +265,9 @@ public final class ServerModel extends ModelNode {
* Returns the subModelNode that is referenced by the given VariableDef. Return null in case the
* referenced ModelNode is not found.
*
* @param variableDef
* @param variableDef the variableDef
* @return the subModelNode that is referenced by the given VariableDef
* @throws ServiceError
* @throws ServiceError if an error occurs
*/
FcModelNode getNodeFromVariableDef(VariableDefs.SEQUENCE variableDef) throws ServiceError {

@ -39,10 +39,10 @@ public final class ServerSap {
final ServerModel serverModel;
byte[] servicesSupportedCalled =
new byte[] {(byte) 0xee, 0x1c, 0, 0, 0x04, 0x08, 0, 0, 0x79, (byte) 0xef, 0x18};
byte[] cbbBitString = {(byte) (0xfb), 0x00};
byte[] cbbBitString = {(byte) 0xfb, 0x00};
ServerEventListener serverEventListener;
Timer timer;
List<ServerAssociation> associations = new ArrayList<>();
final List<ServerAssociation> associations = new ArrayList<>();
boolean listening = false;
private int proposedMaxMmsPduSize = 65000;
private int proposedMaxServOutstandingCalling = 5;

@ -44,22 +44,26 @@ public final class ServiceError extends Exception {
private final int errorCode;
public ServiceError(int errorCode) {
super("Error code=" + errorCode);
this.errorCode = errorCode;
this(errorCode, "", null);
}
public ServiceError(int errorCode, String s) {
super(s);
this.errorCode = errorCode;
this(errorCode, s, null);
}
public ServiceError(int errorCode, Throwable cause) {
super(cause);
this.errorCode = errorCode;
this(errorCode, "", cause);
}
public ServiceError(int errorCode, String s, Throwable cause) {
super(s, cause);
super(
"Service error: "
+ getErrorName(errorCode)
+ "("
+ errorCode
+ ")"
+ (s.isEmpty() ? "" : (" " + s)),
cause);
this.errorCode = errorCode;
}
@ -115,14 +119,4 @@ public final class ServiceError extends Exception {
public int getErrorCode() {
return errorCode;
}
@Override
public String toString() {
String message = getLocalizedMessage();
String result = getClass().getName() + ": " + getErrorName(errorCode) + "(" + errorCode + ")";
if (message != null) {
result += ": " + message;
}
return result;
}
}

@ -13,6 +13,8 @@
*/
package com.beanit.iec61850bean;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.types.BerBitString;
import com.beanit.iec61850bean.internal.mms.asn1.AccessResult;
import com.beanit.iec61850bean.internal.mms.asn1.Data;
@ -213,7 +215,7 @@ public class Urcb extends Rcb {
if (integrity || gi) {
for (int i = 0; i < dataSetSize; i++) {
inclusionStringArray[i / 8] |= 1 << (7 - i % 8);
inclusionStringArray[i / 8] = (byte) (inclusionStringArray[i / 8] | 1 << (7 - i % 8));
}
BerBitString inclusionString = new BerBitString(inclusionStringArray, dataSetSize);
@ -251,7 +253,8 @@ public class Urcb extends Rcb {
int index = 0;
for (FcModelNode dataSetMember : dataSet) {
if (membersToBeReported.get(dataSetMember) != null) {
inclusionStringArray[index / 8] |= 1 << (7 - index % 8);
inclusionStringArray[index / 8] =
(byte) (inclusionStringArray[index / 8] | 1 << (7 - index % 8));
}
index++;
}
@ -289,18 +292,14 @@ public class Urcb extends Rcb {
}
ObjectName objectName = new ObjectName();
objectName.setVmdSpecific(new Identifier("RPT".getBytes()));
objectName.setVmdSpecific(new Identifier("RPT".getBytes(UTF_8)));
VariableAccessSpecification varAccSpec = new VariableAccessSpecification();
varAccSpec.setVariableListName(objectName);
// null,
// new ObjectName(new Identifier("RPT".getBytes()), null, null));
InformationReport infoReport = new InformationReport();
infoReport.setVariableAccessSpecification(varAccSpec);
infoReport.setListOfAccessResult(listOfAccessResult);
// varAccSpec,
// new InformationReport.ListOfAccessResult(listOfAccessResult));
UnconfirmedService unconfirmedService = new UnconfirmedService();
unconfirmedService.setInformationReport(infoReport);

@ -342,7 +342,7 @@ public class ConsoleClient {
System.out.print(
"Set the trigger options (data change, data update, quality change, interity, GI):");
String triggerOptionsString = actionProcessor.getReader().readLine();
String[] triggerOptionsStrings = triggerOptionsString.split(",");
String[] triggerOptionsStrings = triggerOptionsString.split(",", -1);
BdaTriggerConditions triggerOptions = urcb.getTrgOps();
triggerOptions.setDataChange(
Boolean.parseBoolean(triggerOptionsStrings[0]));

@ -23,7 +23,7 @@ public abstract class BasicDataBind<E extends BasicDataAttribute> {
private JComponent valueField;
public BasicDataBind(E data, BdaType type) {
protected BasicDataBind(E data, BdaType type) {
if (data.getBasicType() != type) {
throw new IllegalArgumentException(data.getName() + " is no " + type);
}

@ -105,8 +105,8 @@ public class ClientGui extends JFrame implements ActionListener, TreeSelectionLi
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (IOException ignored) {
// there is nothing that can be done if closing fails
}
}
@ -350,6 +350,7 @@ public class ClientGui extends JFrame implements ActionListener, TreeSelectionLi
out.close();
}
} catch (IOException e) {
// nothing meaningful can be done if closing fails
}
}

@ -24,7 +24,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.swing.tree.TreeNode;
@ -85,7 +84,7 @@ public class ServerModelParser {
}
childMap.get(child.getName()).add(((FcModelNode) child).getFc());
}
for (Entry<String, Set<Fc>> childEntry : childMap.entrySet()) {
for (Map.Entry<String, Set<Fc>> childEntry : childMap.entrySet()) {
addFunctionalConstraintObject(treeLN, node, childEntry.getKey(), childEntry.getValue());
}
}
@ -95,7 +94,7 @@ public class ServerModelParser {
parent.add(treeDS);
Collection<FcModelNode> children = node.getMembers();
for (ModelNode child : children) {
addFunctionalConstraintObject(treeDS, node, child);
addFunctionalConstraintObject(treeDS, child);
}
}
@ -110,8 +109,7 @@ public class ServerModelParser {
}
}
private void addFunctionalConstraintObject(
DataSetTreeNode parent, DataSet parentNode, ModelNode node) {
private void addFunctionalConstraintObject(DataSetTreeNode parent, ModelNode node) {
DataObjectTreeNode treeFCDO = new DataObjectTreeNode(node.getReference().toString(), node);
parent.add(treeFCDO);
if (node.getChildren() != null) {

@ -29,7 +29,7 @@ public abstract class TextFieldDataBind<E extends BasicDataAttribute> extends Ba
private final DocumentFilter filter;
protected JTextField inputField;
public TextFieldDataBind(E data, BdaType type, AbstractFilter filter) {
TextFieldDataBind(E data, BdaType type, AbstractFilter filter) {
super(data, type);
this.filter = filter;
}

@ -15,69 +15,36 @@ package com.beanit.iec61850bean.clientgui.databind;
import com.beanit.iec61850bean.BdaTimestamp;
import com.beanit.iec61850bean.BdaType;
import com.beanit.iec61850bean.clientgui.BasicDataBind;
import com.toedter.calendar.JDateChooser;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Date;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import java.time.Instant;
import java.time.format.DateTimeParseException;
public class TimeStampDataBind extends BasicDataBind<BdaTimestamp> {
public class TimeStampDataBind extends TextFieldDataBind<BdaTimestamp> {
private static final Dimension DATECHOOSERDIMENSION = new Dimension(120, 20);
private JDateChooser dateChooser;
private JSpinner timeSpinner;
private static final TimestampFilter FILTER = new TimestampFilter();
public TimeStampDataBind(BdaTimestamp data) {
super(data, BdaType.TIMESTAMP);
}
@Override
protected JComponent init() {
dateChooser = new JDateChooser();
dateChooser.setDateFormatString("dd-MM-yyyy");
dateChooser.setPreferredSize(DATECHOOSERDIMENSION);
timeSpinner = new JSpinner(new SpinnerDateModel());
JSpinner.DateEditor timeEditor = new JSpinner.DateEditor(timeSpinner, "HH:mm:ss");
timeSpinner.setEditor(timeEditor);
Date d = data.getDate();
if (d == null) {
d = new Date(0);
}
dateChooser.setDate(d);
timeSpinner.setValue(d);
JPanel dateTimePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
dateTimePanel.add(dateChooser);
dateTimePanel.add(Box.createRigidArea(new Dimension(5, 0)));
dateTimePanel.add(timeSpinner);
return dateTimePanel;
super(data, BdaType.TIMESTAMP, FILTER);
}
@Override
protected void resetImpl() {
Date d = data.getDate();
if (d == null) {
d = new Date(0);
}
dateChooser.setDate(d);
timeSpinner.setValue(d);
inputField.setText(data.getInstant().toString());
}
@SuppressWarnings("deprecation")
@Override
protected void writeImpl() {
Date newDate = dateChooser.getDate();
Date timeValues = (Date) timeSpinner.getValue();
newDate.setHours(timeValues.getHours());
newDate.setMinutes(timeValues.getMinutes());
newDate.setSeconds(timeValues.getSeconds());
data.setDate(newDate);
data.setInstant(Instant.parse(inputField.getText()));
}
private static class TimestampFilter extends AbstractFilter {
@Override
protected boolean test(String text) {
try {
Instant.parse(text);
return true;
} catch (DateTimeParseException e) {
return false;
}
}
}
}

@ -45,7 +45,7 @@ public class HexString {
* @return the hex string
*/
public static String fromInt(int i) {
byte[] bytes = new byte[] {(byte) (i >> 24), (byte) (i >> 16), (byte) (i >> 8), (byte) (i)};
byte[] bytes = new byte[] {(byte) (i >> 24), (byte) (i >> 16), (byte) (i >> 8), (byte) i};
return fromBytes(bytes);
}
@ -65,7 +65,7 @@ public class HexString {
(byte) (l >> 24),
(byte) (l >> 16),
(byte) (l >> 8),
(byte) (l)
(byte) l
};
return fromBytes(bytes);
}

@ -125,6 +125,7 @@ public class ActionProcessor {
try {
reader.close();
} catch (IOException ignored) {
// if closing fails there is nothing meaningful that can be done
}
}
}

@ -26,17 +26,14 @@ public abstract class CliParameter {
optional = builder.optional;
}
/** @return the name */
public String getName() {
return name;
}
/** @return the description */
public String getDescription() {
return description;
}
/** @return the optional */
public boolean isOptional() {
return optional;
}

@ -41,7 +41,7 @@ public class FlagCliParameter extends CliParameter {
}
@Override
int parse(String[] args, int i) throws CliParseException {
int parse(String[] args, int i) {
selected = true;
return 1;
}

@ -15,7 +15,7 @@ package com.beanit.iec61850bean.internal.cli;
abstract class ValueCliParameter extends CliParameter {
String parameterName;
final String parameterName;
ValueCliParameter(CliParameterBuilder builder, String parameterName) {
super(builder);

@ -28,7 +28,7 @@ public abstract class AbstractDataAttribute extends AbstractElement {
private String type = null; /* conditional - if bType = "Enum" or "Struct" */
private int count = 0; /* optional - number of array elements */
public AbstractDataAttribute(Node xmlNode) throws SclParseException {
AbstractDataAttribute(Node xmlNode) throws SclParseException {
super(xmlNode);
NamedNodeMap attributes = xmlNode.getAttributes();

@ -22,12 +22,12 @@ public abstract class AbstractElement {
private String name = null;
private String desc = null;
public AbstractElement(String name, String desc) {
AbstractElement(String name, String desc) {
this.name = name;
this.desc = desc;
}
public AbstractElement(Node xmlNode) throws SclParseException {
AbstractElement(Node xmlNode) throws SclParseException {
NamedNodeMap attributes = xmlNode.getAttributes();
Node node = attributes.getNamedItem("name");

@ -22,7 +22,7 @@ public abstract class AbstractType {
// attributes not needed: desc
public AbstractType(Node xmlNode) throws SclParseException {
AbstractType(Node xmlNode) throws SclParseException {
Node idNode = xmlNode.getAttributes().getNamedItem("id");
if (idNode == null) {
throw new SclParseException("Required attribute \"id\" not found!");

@ -0,0 +1,47 @@
/*
* Copyright 2019 beanit
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.iec61850bean.internal.util;
public class SequenceNumber {
private final int maxValue;
private final int minValue;
private int value;
public SequenceNumber(int initValue, int minValue, int maxValue) {
assert (initValue >= minValue) && (initValue <= maxValue);
this.minValue = minValue;
this.maxValue = maxValue;
this.value = initValue;
}
public static int getIncrement(int value, int minValue, int maxValue) {
assert (value >= minValue) && (value <= maxValue);
if (value == maxValue) {
return minValue;
} else {
return ++value;
}
}
public int getAndIncrement() {
int oldValue = value;
if (value == maxValue) {
value = minValue;
} else {
++value;
}
return oldValue;
}
}

@ -13,6 +13,8 @@
*/
package com.beanit.josistack;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import com.beanit.asn1bean.ber.types.BerAny;
import com.beanit.asn1bean.ber.types.BerInteger;
@ -55,7 +57,6 @@ import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeoutException;
@ -289,7 +290,9 @@ public final class AcseAssociation {
public void accept(ByteBuffer payload) throws IOException {
BerAny anyPayload =
new BerAny(Arrays.copyOfRange(payload.array(), payload.position(), payload.limit()));
new BerAny(
Arrays.copyOfRange(
payload.array(), payload.arrayOffset() + payload.position(), payload.limit()));
Myexternal.Encoding encoding = new Myexternal.Encoding();
encoding.setSingleASN1Type(anyPayload);
@ -328,9 +331,9 @@ public final class AcseAssociation {
reverseOStream.reset();
cpaPPdu.encode(reverseOStream, true);
List<byte[]> ssduList = new LinkedList<>();
List<Integer> ssduOffsets = new LinkedList<>();
List<Integer> ssduLengths = new LinkedList<>();
List<byte[]> ssduList = new ArrayList<>();
List<Integer> ssduOffsets = new ArrayList<>();
List<Integer> ssduLengths = new ArrayList<>();
ssduList.add(reverseOStream.buffer);
ssduOffsets.add(reverseOStream.index + 1);
@ -405,7 +408,7 @@ public final class AcseAssociation {
sduAcceptHeader[idx++] = (byte) 0xc1;
// Parameter length
sduAcceptHeader[idx++] = (byte) ssduLength;
sduAcceptHeader[idx] = (byte) ssduLength;
ssdu.add(0, sduAcceptHeader);
ssduOffsets.add(0, 0);
@ -420,20 +423,6 @@ public final class AcseAssociation {
return returnBuffer;
}
/**
* Starts an Application Association by sending an association request and waiting for an
* association accept message
*
* @param payload payload that can be sent with the association request
* @param port
* @param address
* @param tSAP
* @param aeQualifierCalling
* @param aeQualifierCalled
* @param apTitleCalling
* @param apTitleCalled
* @throws IOException
*/
void startAssociation(
ByteBuffer payload,
InetAddress address,
@ -450,7 +439,7 @@ public final class AcseAssociation {
int aeQualifierCalled,
int aeQualifierCalling)
throws IOException {
if (connected == true) {
if (connected) {
throw new IOException();
}
@ -466,7 +455,9 @@ public final class AcseAssociation {
Myexternal.Encoding encoding = new Myexternal.Encoding();
encoding.setSingleASN1Type(
new BerAny(Arrays.copyOfRange(payload.array(), payload.position(), payload.limit())));
new BerAny(
Arrays.copyOfRange(
payload.array(), payload.arrayOffset() + payload.position(), payload.limit())));
Myexternal myExternal = new Myexternal();
myExternal.setDirectReference(directReference);
@ -485,7 +476,8 @@ public final class AcseAssociation {
new ACSERequirements(new byte[] {(byte) 0x02, (byte) 0x07, (byte) 0x80});
mechanism_name = default_mechanism_name;
authentication_value = new AuthenticationValue();
authentication_value.setCharstring(new BerGraphicString(authenticationParameter.getBytes()));
authentication_value.setCharstring(
new BerGraphicString(authenticationParameter.getBytes(UTF_8)));
}
AARQApdu aarq = new AARQApdu();
@ -521,16 +513,15 @@ public final class AcseAssociation {
reverseOStream.reset();
cpType.encode(reverseOStream, true);
List<byte[]> ssduList = new LinkedList<>();
List<Integer> ssduOffsets = new LinkedList<>();
List<Integer> ssduLengths = new LinkedList<>();
List<byte[]> ssduList = new ArrayList<>();
List<Integer> ssduOffsets = new ArrayList<>();
List<Integer> ssduLengths = new ArrayList<>();
ssduList.add(reverseOStream.buffer);
ssduOffsets.add(reverseOStream.index + 1);
ssduLengths.add(reverseOStream.buffer.length - (reverseOStream.index + 1));
ByteBuffer res = null;
res =
ByteBuffer res =
startSConnection(
ssduList,
ssduOffsets,
@ -546,12 +537,6 @@ public final class AcseAssociation {
associateResponseAPDU = decodePConResponse(res);
}
/**
* Starts a session layer connection, sends a CONNECT (CN), waits for a ACCEPT (AC) and throws an
* IOException if not successful
*
* @throws IOException
*/
private ByteBuffer startSConnection(
List<byte[]> ssduList,
List<Integer> ssduOffsets,
@ -564,7 +549,7 @@ public final class AcseAssociation {
byte[] sSelRemote,
byte[] sSelLocal)
throws IOException {
if (connected == true) {
if (connected) {
throw new IOException();
}
@ -639,7 +624,7 @@ public final class AcseAssociation {
// Parameter type: Session user data (193)
spduHeader[idx++] = (byte) 0xc1;
// Parameter length
spduHeader[idx++] = (byte) (ssduLength & 0xff);
spduHeader[idx] = (byte) (ssduLength & 0xff);
// write session user data
ssduList.add(0, spduHeader);
@ -658,7 +643,6 @@ public final class AcseAssociation {
} catch (TimeoutException e) {
throw new IOException("ResponseTimeout waiting for connection response.", e);
}
idx = 0;
// read ISO 8327-1 Header
// SPDU Type: ACCEPT (14)
@ -774,8 +758,8 @@ public final class AcseAssociation {
public void send(ByteBuffer payload) throws IOException {
List<byte[]> ssduList = new ArrayList<>();
List<Integer> ssduOffsets = new LinkedList<>();
List<Integer> ssduLengths = new LinkedList<>();
List<Integer> ssduOffsets = new ArrayList<>();
List<Integer> ssduLengths = new ArrayList<>();
encodePresentationLayer(payload, ssduList, ssduOffsets, ssduLengths);
@ -791,11 +775,13 @@ public final class AcseAssociation {
List<Integer> ssduLengths)
throws IOException {
PDVList pdv_list = new PDVList();
pdv_list.setPresentationContextIdentifier(new PresentationContextIdentifier(3l));
pdv_list.setPresentationContextIdentifier(new PresentationContextIdentifier(3L));
PDVList.PresentationDataValues presentationDataValues = new PDVList.PresentationDataValues();
presentationDataValues.setSingleASN1Type(
new BerAny(Arrays.copyOfRange(payload.array(), payload.position(), payload.limit())));
new BerAny(
Arrays.copyOfRange(
payload.array(), payload.arrayOffset() + payload.position(), payload.limit())));
pdv_list.setPresentationDataValues(presentationDataValues);
FullyEncodedData fully_encoded_data = new FullyEncodedData();
@ -814,8 +800,7 @@ public final class AcseAssociation {
}
private void encodeSessionLayer(
List<byte[]> ssduList, List<Integer> ssduOffsets, List<Integer> ssduLengths)
throws IOException {
List<byte[]> ssduList, List<Integer> ssduOffsets, List<Integer> ssduLengths) {
byte[] spduHeader = new byte[4];
// --write iso 8327-1 Header--
@ -847,7 +832,7 @@ public final class AcseAssociation {
*/
public byte[] receive(ByteBuffer pduBuffer)
throws DecodingException, IOException, TimeoutException {
if (connected == false) {
if (!connected) {
throw new IllegalStateException("ACSE Association not connected");
}
tConnection.receive(pduBuffer);
@ -937,7 +922,7 @@ public final class AcseAssociation {
}
ByteBuffer listenForCn(ByteBuffer pduBuffer) throws IOException, TimeoutException {
if (connected == true) {
if (connected) {
throw new IllegalStateException("ACSE Association is already connected");
}
int parameter;

@ -97,16 +97,16 @@ public final class ClientTSap {
/**
* Set the maxTPDUSize. The default maxTPduSize is 65531 (see RFC 1006).
*
* @param maxTPduSizeParam The maximum length is equal to 2^(maxTPduSizeParam) octets. Note that
* @param maxTPDUSizeParam The maximum length is equal to 2^(maxTPDUSizeParam) octets. Note that
* the actual TSDU size that can be transfered is equal to TPduSize-3. Default is 65531 octets
* (see RFC 1006), 7 &lt;= maxTPduSizeParam &lt;= 16, needs to be set before listening or
* (see RFC 1006), 7 &lt;= maxTPDUSizeParam &lt;= 16, needs to be set before listening or
* connecting
*/
public void setMaxTPDUSizeParam(int maxTPduSizeParam) {
if (maxTPduSizeParam < 7 || maxTPduSizeParam > 16) {
public void setMaxTPDUSizeParam(int maxTPDUSizeParam) {
if (maxTPDUSizeParam < 7 || maxTPDUSizeParam > 16) {
throw new IllegalArgumentException("maxTPDUSizeParam is out of bound");
}
this.maxTPDUSizeParam = maxTPduSizeParam;
this.maxTPDUSizeParam = maxTPDUSizeParam;
}
/**

@ -186,19 +186,19 @@ public class ServerTSap {
/**
* Set the maxTPDUSize. The default maxTPduSize is 65531 (see RFC 1006).
*
* @param maxTPduSizeParam The maximum length is equal to 2^(maxTPduSizeParam) octets. Note that
* @param maxTPDUSizeParam The maximum length is equal to 2^(maxTPDUSizeParam) octets. Note that
* the actual TSDU size that can be transfered is equal to TPduSize-3. Default is 65531 octets
* (see RFC 1006), 7 &lt;= maxTPduSizeParam &lt;= 16, needs to be set before listening or
* (see RFC 1006), 7 &lt;= maxTPDUSizeParam &lt;= 16, needs to be set before listening or
* connecting
*/
public void setMaxTPDUSizeParam(int maxTPduSizeParam) {
public void setMaxTPDUSizeParam(int maxTPDUSizeParam) {
if (started == true) {
throw new RuntimeException("Trying to set parameter although server has started.");
}
if (maxTPduSizeParam < 7 || maxTPduSizeParam > 16) {
if (maxTPDUSizeParam < 7 || maxTPDUSizeParam > 16) {
throw new IllegalArgumentException("maxTPDUSizeParam is out of bound");
}
this.maxTPDUSizeParam = maxTPduSizeParam;
this.maxTPDUSizeParam = maxTPDUSizeParam;
}
TConnectionListener getConnectionListener() {

@ -106,6 +106,7 @@ final class ServerThread extends Thread {
try {
serverSocket.close();
} catch (IOException e) {
// there is nothing meaningful to be done when closing fails
}
}
}

@ -13,6 +13,7 @@
*/
package com.beanit.jositransport;
import com.beanit.iec61850bean.internal.util.SequenceNumber;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
@ -28,9 +29,8 @@ import java.util.concurrent.TimeoutException;
public final class TConnection {
// private static final Logger logger = LoggerFactory.getLogger(TConnection.class);
private static Integer connectionCounter = 0;
// some servers do not like srcRef 0
private static final SequenceNumber connectionCounter = new SequenceNumber(1, 1, 65519);
private final Socket socket;
private final DataOutputStream os;
private final DataInputStream is;
@ -59,13 +59,8 @@ public final class TConnection {
os = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
is = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
synchronized (socket) {
connectionCounter++;
connectionCounter %= 65520;
if (connectionCounter == 0) {
connectionCounter = 1; // some servers do not like srcRef 0
}
srcRef = connectionCounter;
synchronized (connectionCounter) {
srcRef = connectionCounter.getAndIncrement();
}
this.messageTimeout = messageTimeout;
@ -82,7 +77,7 @@ public final class TConnection {
* According to the norm a syntax error in the CR should be followed by an ER. This implementation
* does not send an ER because it seems unnecessary.
*
* @throws IOException
* @throws IOException if an error occurs
*/
void listenForCR() throws IOException {
@ -234,7 +229,7 @@ public final class TConnection {
/**
* Starts a connection, sends a CR, waits for a CC and throws an IOException if not successful
*
* @throws IOException
* @throws IOException if an error occurs
*/
void startConnection() throws IOException {
@ -632,7 +627,8 @@ public final class TConnection {
os.write(0x00);
os.flush();
} catch (IOException e) {
} catch (IOException ignored) {
// io exceptions while disconnecting can be ignored
} finally {
close();
}
@ -646,10 +642,12 @@ public final class TConnection {
// will also close socket
os.close();
} catch (Exception e) {
// there is nothing meaningful to be done if closing fails
}
try {
is.close();
} catch (Exception e) {
// there is nothing meaningful to be done if closing fails
}
if (serverThread != null) {
serverThread.connectionClosedSignal();

@ -13,6 +13,7 @@
*/
package com.beanit.iec61850bean.integrationtests;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -150,12 +151,12 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
namePlateVendor =
(BdaVisibleString) serverModel.findModelNode("ied1lDevice1/LLN0.NamPlt.vendor", Fc.DC);
namePlateVendor.setValue("Fraunhofer ISE".getBytes());
namePlateVendor.setValue("beanit".getBytes(UTF_8));
clientAssociation.setDataValues(namePlateVendor);
namePlateVendor.setDefault();
clientAssociation.getDataValues(namePlateVendor);
assertEquals("Fraunhofer ISE", new String(namePlateVendor.getValue()));
assertEquals("beanit", new String(namePlateVendor.getValue(), UTF_8));
// -------------Test DataSets-Start---------------------
@ -197,7 +198,7 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
assertNull(serviceError);
}
assertTrue("Fraunhofer ISE".equals(new String(namePlateVendor.getValue())));
assertTrue("beanit".equals(new String(namePlateVendor.getValue(), UTF_8)));
clientAssociation.deleteDataSet(nonPersistentDataSet);
@ -258,11 +259,7 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
// clientAssociation.close();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.sleep(1000);
clientAssociation2.getDataValues(sbo2);
assertEquals(sbo2.getStringValue(), "success");
@ -274,11 +271,7 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
clientAssociation2.close();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.sleep(100);
clientAssociation.getDataValues(sbo);
assertEquals(sbo.getStringValue(), "success");
@ -448,7 +441,7 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
}
@Override
public void serverStoppedListening(ServerSap serverSAP) {
public void serverStoppedListening(ServerSap serverSap) {
// TODO Auto-generated method stub
}
@ -473,7 +466,7 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
totWBdas.add(q);
totWBdas.add(t);
float totWMagVal = 0.0f;
double totWMagVal = 0.0f;
q.setValidity(BdaQuality.Validity.GOOD);
// for (int i = 0; i < 500000; i++) {
@ -481,7 +474,7 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
totWMagVal += 1.0;
System.out.println("setting totWmag to: " + totWMagVal);
totWMag.setFloat(totWMagVal);
totWMag.setFloat((float) totWMagVal);
t.setCurrentTime();
if (q.getValidity() == Validity.GOOD) {
@ -493,7 +486,9 @@ public class ClientServerITest extends Thread implements ServerEventListener, Cl
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// is not interrupted
}
serverSap.setValues(totWBdas);
// // Run the garbage collector

@ -45,8 +45,6 @@ public class ClientServerITest2 extends Thread implements ServerEventListener, C
// Get the Java runtime
public static Runtime runtime = Runtime.getRuntime();
private static int numReports = 0;
private static int numSuccess = 0;
private static int numAssociationClosed = 0;
int port = 54322;
String host = "127.0.0.1";
ClientSap clientSap = new ClientSap();
@ -154,7 +152,7 @@ public class ClientServerITest2 extends Thread implements ServerEventListener, C
}
@Override
public void serverStoppedListening(ServerSap serverSAP) {
public void serverStoppedListening(ServerSap serverSap) {
// TODO Auto-generated method stub
}
@ -239,13 +237,10 @@ public class ClientServerITest2 extends Thread implements ServerEventListener, C
assertTrue(reasons.get(0).isIntegrity());
assertTrue(reasons.get(1).isIntegrity());
}
numSuccess++;
}
@Override
public void associationClosed(IOException e) {
System.out.println("Association closed!");
numAssociationClosed++;
}
}

@ -47,8 +47,6 @@ public class ReportingTest implements ClientEventListener {
private static final String CREATED_DATASET_REFERENCE = "ied1lDevice1/LLN0$datasetnew";
private static final String CHANGING_SERVER_DA_REFERENCE_1 =
"ied1lDevice1/MMXU1.W.phsA.cVal.mag.f";
private static final String CHANGING_SERVER_DA_REFERENCE_2 =
"ied1lDevice1/DSCH1.SchdAbsTm.sptestval1";
private static final int PORT = 54321;
private static final String ICD_FILE = "src/test/resources/iec61850bean-sample01.icd";
private static final String URCB1_REFERENCE = "ied1lDevice1/LLN0.urcb101";

@ -283,7 +283,7 @@ public class SiemensClientITest {
serverAcseSAP.stopListening();
}
public class SampleServer implements AcseAssociationListener {
public static class SampleServer implements AcseAssociationListener {
@Override
public void serverStoppedListeningIndication(IOException e) {

@ -60,7 +60,7 @@ public class ClientServerITest {
ClientTSap tSAP = new ClientTSap();
tSAP.setMaxTPDUSizeParam(7);
TConnection tConnection = null;
TConnection tConnection;
tConnection = tSAP.connectTo(address, port);
@ -399,7 +399,7 @@ public class ClientServerITest {
return C;
}
public class SampleServer implements TConnectionListener {
public static class SampleServer implements TConnectionListener {
@Override
public void connectionIndication(TConnection tConnection) {

Loading…
Cancel
Save