You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
backend/src/main/java/com/beanit/iec61850bean/FcModelNode.java

253 lines
8.5 KiB
Java

/*
* Copyright 2011 The IEC61850bean Authors
*
* 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;
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;
import com.beanit.iec61850bean.internal.mms.asn1.AlternateAccessSelection.SelectAccess.Component;
import com.beanit.iec61850bean.internal.mms.asn1.BasicIdentifier;
import com.beanit.iec61850bean.internal.mms.asn1.Identifier;
import com.beanit.iec61850bean.internal.mms.asn1.ObjectName;
import com.beanit.iec61850bean.internal.mms.asn1.Unsigned32;
import com.beanit.iec61850bean.internal.mms.asn1.VariableDefs;
import com.beanit.iec61850bean.internal.mms.asn1.VariableSpecification;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public abstract class FcModelNode extends ModelNode {
Fc fc;
private VariableDefs.SEQUENCE variableDef = null;
private ServerAssociation selected = null;
private TimerTask task = null;
public Fc getFc() {
return fc;
}
boolean select(ServerAssociation association, Timer timer) {
if (selected != null) {
if (selected != association) {
return false;
}
} else {
selected = association;
association.selects.add(this);
}
ModelNode sboTimeoutNode =
association.serverModel.findModelNode(objectReference, Fc.CF).getChild("sboTimeout");
if (sboTimeoutNode == null) {
return true;
}
long sboTimeout = ((BdaInt32U) sboTimeoutNode).getValue();
if (sboTimeout == 0) {
return true;
}
class SelectResetTask extends TimerTask {
ServerAssociation association;
SelectResetTask(ServerAssociation association) {
this.association = association;
}
@Override
public void run() {
synchronized (association.serverModel) {
if (task == this) {
task = null;
deselectAndRemove(association);
}
}
}
}
if (task != null) {
task.cancel();
}
task = new SelectResetTask(association);
timer.schedule(task, sboTimeout);
return true;
}
void deselectAndRemove(ServerAssociation association) {
selected = null;
if (task != null) {
task.cancel();
task = null;
}
association.selects.remove(this);
}
void deselect() {
selected = null;
if (task != null) {
task.cancel();
task = null;
}
}
boolean isSelected() {
return selected != null;
}
boolean isSelectedBy(ServerAssociation association) {
return selected == association;
}
VariableDefs.SEQUENCE getMmsVariableDef() {
if (variableDef != null) {
return variableDef;
}
AlternateAccess alternateAccess = null;
StringBuilder preArrayIndexItemId = new StringBuilder(objectReference.get(1));
preArrayIndexItemId.append("$");
preArrayIndexItemId.append(fc);
int arrayIndexPosition = objectReference.getArrayIndexPosition();
if (arrayIndexPosition != -1) {
for (int i = 2; i < arrayIndexPosition; i++) {
preArrayIndexItemId.append("$");
preArrayIndexItemId.append(objectReference.get(i));
}
alternateAccess = new AlternateAccess();
List<AlternateAccess.CHOICE> subSeqOfAlternateAccess = alternateAccess.getCHOICE();
Unsigned32 indexBerInteger =
new Unsigned32(Integer.parseInt(objectReference.get(arrayIndexPosition)));
if (arrayIndexPosition < (objectReference.size() - 1)) {
// this reference points to a sub-node of an array element
StringBuilder postArrayIndexItemId =
new StringBuilder(objectReference.get(arrayIndexPosition + 1));
for (int i = (arrayIndexPosition + 2); i < objectReference.size(); i++) {
postArrayIndexItemId.append("$");
postArrayIndexItemId.append(objectReference.get(i));
}
BasicIdentifier subIndexReference =
new BasicIdentifier(postArrayIndexItemId.toString().getBytes(UTF_8));
AlternateAccessSelection.SelectAccess subIndexReferenceSelectAccess =
new AlternateAccessSelection.SelectAccess();
Component component = new Component();
component.setBasic(subIndexReference);
subIndexReferenceSelectAccess.setComponent(component);
AlternateAccessSelection subIndexReferenceAlternateAccessSelection =
new AlternateAccessSelection();
subIndexReferenceAlternateAccessSelection.setSelectAccess(subIndexReferenceSelectAccess);
AlternateAccess.CHOICE subIndexReferenceAlternateAccessSubChoice =
new AlternateAccess.CHOICE();
subIndexReferenceAlternateAccessSubChoice.setUnnamed(
subIndexReferenceAlternateAccessSelection);
AlternateAccess subIndexReferenceAlternateAccess = new AlternateAccess();
List<AlternateAccess.CHOICE> subIndexReferenceAlternateAccessSubSeqOf =
subIndexReferenceAlternateAccess.getCHOICE();
subIndexReferenceAlternateAccessSubSeqOf.add(subIndexReferenceAlternateAccessSubChoice);
// set array index:
AlternateAccessSelection.SelectAlternateAccess.AccessSelection indexAccessSelectionChoice =
new AlternateAccessSelection.SelectAlternateAccess.AccessSelection();
indexAccessSelectionChoice.setIndex(indexBerInteger);
AlternateAccessSelection.SelectAlternateAccess indexAndLowerReferenceSelectAlternateAccess =
new AlternateAccessSelection.SelectAlternateAccess();
indexAndLowerReferenceSelectAlternateAccess.setAccessSelection(indexAccessSelectionChoice);
indexAndLowerReferenceSelectAlternateAccess.setAlternateAccess(
subIndexReferenceAlternateAccess);
AlternateAccessSelection indexAndLowerReferenceAlternateAccessSelection =
new AlternateAccessSelection();
indexAndLowerReferenceAlternateAccessSelection.setSelectAlternateAccess(
indexAndLowerReferenceSelectAlternateAccess);
AlternateAccess.CHOICE indexAndLowerReferenceAlternateAccessChoice =
new AlternateAccess.CHOICE();
indexAndLowerReferenceAlternateAccessChoice.setUnnamed(
indexAndLowerReferenceAlternateAccessSelection);
subSeqOfAlternateAccess.add(indexAndLowerReferenceAlternateAccessChoice);
} else {
SelectAccess selectAccess = new SelectAccess();
selectAccess.setIndex(indexBerInteger);
AlternateAccessSelection alternateAccessSelection = new AlternateAccessSelection();
alternateAccessSelection.setSelectAccess(selectAccess);
AlternateAccess.CHOICE alternateAccessChoice = new AlternateAccess.CHOICE();
alternateAccessChoice.setUnnamed(alternateAccessSelection);
subSeqOfAlternateAccess.add(alternateAccessChoice);
}
} else {
for (int i = 2; i < objectReference.size(); i++) {
preArrayIndexItemId.append("$");
preArrayIndexItemId.append(objectReference.get(i));
}
}
ObjectName.DomainSpecific domainSpecificObjectName = new ObjectName.DomainSpecific();
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);
VariableSpecification varSpec = new VariableSpecification();
varSpec.setName(objectName);
variableDef = new VariableDefs.SEQUENCE();
variableDef.setAlternateAccess(alternateAccess);
variableDef.setVariableSpecification(varSpec);
return variableDef;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getReference().toString()).append(" [").append(fc).append("]");
for (ModelNode childNode : children.values()) {
sb.append("\n");
sb.append(childNode.toString());
}
return sb.toString();
}
}