First commit. OpenPLC v3 beta 1

This commit is contained in:
thiagoralves
2018-06-14 10:43:52 -07:00
parent cb922e153c
commit 1b10e97e5e
2742 changed files with 568737 additions and 2 deletions
+16
View File
@@ -0,0 +1,16 @@
Copyright 2013-2016 Automatak, LLC
Licensed to Automatak, LLC (www.automatak.com) under one or more
contributor license agreements. See the NOTICE file distributed with this
work for additional information regarding copyright ownership. Automatak, LLC
licenses this file to you 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.html
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.
+40
View File
@@ -0,0 +1,40 @@
# Java bindings
The opendnp3 Java bindings are built as two separate pieces: a normal Java JAR file and a native shared library
built from the companion C++ source.
The JNI C++ code uses a code generator (in the 'codegen' folder) to create accessors for manipulating java objects
from C++. The entry point for this program is in 'Generator.scala':
https://github.com/automatak/dnp3/blob/2.0.x/java/codegen/src/main/scala/com/automatak/dnp3/codegen/Generator.scala
The POM imports nicely into IntelliJ. The generator is hardwired to spit out the C++ files to the correct location
when run from the project root (this directory where the POM is located). This is the default for IntelliJ.
I use Intellij to run this program. It should just work when you import the pom into IntelliJ. Maven will also build it.
The program is configured to generate only what's required for the objects needed. The configuration is in "Classes.scala":
https://github.com/automatak/dnp3/blob/2.0.x/java/codegen/src/main/scala/com/automatak/dnp3/codegen/Classes.scala
The generator uses reflection to product the C++ wrappers.
The wrappers all looks like this example:
https://github.com/automatak/dnp3/blob/2.0.x/java/cpp/jni/JNIAnalogOutputInt16.h
https://github.com/automatak/dnp3/blob/2.0.x/java/cpp/jni/JNIAnalogOutputInt16.cpp
Each wrapper is a static class that gets initialized here:
https://github.com/automatak/dnp3/blob/2.0.x/java/cpp/jni/JCache.cpp#L110
This invoked when the library is loaded:
https://github.com/automatak/dnp3/blob/2.0.x/java/cpp/adapters/JNI.cpp#L31
This approach has a few benefits:
1. The hand-written code never has to deal with strings or variable length function signatures.
2. All of the jclass, jmethodid, and jfieldid stuff is optimally cached.
3. Changes to java classes usually result in compile-time errors.
4. Management types like LocalRef<jobject> are returned to ensure there are no resource leaks.
+14
View File
@@ -0,0 +1,14 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.automatak.dnp3</groupId>
<artifactId>opendnp3-parent</artifactId>
<version>2.2.1-SNAPSHOT</version>
</parent>
<artifactId>opendnp3-bindings</artifactId>
<packaging>jar</packaging>
</project>
@@ -0,0 +1,59 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import java.util.function.Consumer;
/// <summary>
/// Concrete implementation of ICommandHeader
/// </summary>
public class ActionCommandHeader implements CommandHeaders {
private final Consumer<CommandBuilder> action;
@Override
public void build(CommandBuilder builder) {
action.accept(builder);
}
private ActionCommandHeader(Consumer<CommandBuilder> action) {
this.action = action;
}
public static CommandHeaders fromCROB(Iterable<IndexedValue<ControlRelayOutputBlock>> commands) {
return new ActionCommandHeader((CommandBuilder builder) -> builder.addCrob(commands));
}
public static CommandHeaders fromAO16(Iterable<IndexedValue<AnalogOutputInt16>> commands) {
return new ActionCommandHeader((CommandBuilder builder) -> builder.addAO16(commands));
}
public static CommandHeaders fromAO32(Iterable<IndexedValue<AnalogOutputInt32>> commands) {
return new ActionCommandHeader((CommandBuilder builder) -> builder.addAO32(commands));
}
public static CommandHeaders fromAOFloat(Iterable<IndexedValue<AnalogOutputFloat32>> commands) {
return new ActionCommandHeader((CommandBuilder builder) -> builder.addAOFloat32(commands));
}
public static CommandHeaders fromAODouble(Iterable<IndexedValue<AnalogOutputDouble64>> commands) {
return new ActionCommandHeader((CommandBuilder builder) -> builder.addAODouble64(commands));
}
}
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventAnalogVariation;
import com.automatak.dnp3.enums.StaticAnalogVariation;
public class AnalogConfig extends EventConfig {
public AnalogConfig(int index) {
super(index);
}
public double deadband = 0;
public EventAnalogVariation eventVariation = EventAnalogVariation.Group32Var1;
public StaticAnalogVariation staticVariation = StaticAnalogVariation.Group30Var1;
}
@@ -0,0 +1,44 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* A discrete or continuous analog value
*/
public class AnalogInput extends Measurement
{
public final double value;
/**
* Primary constructor
* @param value double precision value type
* @param quality bit-field representing quality values
* @param timestamp milliseconds since unix epoch UTC
*/
public AnalogInput(double value, byte quality, long timestamp)
{
super(quality, timestamp);
this.value = value;
}
@Override
public String toString() {
return String.format("Analog(%f, 0x%x, %d)", value, quality, timestamp);
}
}
@@ -0,0 +1,38 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.CommandStatus;
/**
* A set-point command request with double precision floating point representation.
* The underlying DNP3 serialization is Group41, Variation 4
*/
public class AnalogOutputDouble64 {
public final double value;
public final CommandStatus status;
public AnalogOutputDouble64(double value, CommandStatus status)
{
this.value = value;
this.status = status;
}
}
@@ -0,0 +1,38 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.CommandStatus;
/**
* A set-point command request with single precision floating point representation.
* The underlying DNP3 serialization is Group41, Variation 3
*/
public class AnalogOutputFloat32 {
public final float value;
public final CommandStatus status;
public AnalogOutputFloat32(float value, CommandStatus status)
{
this.value = value;
this.status = status;
}
}
@@ -0,0 +1,38 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.CommandStatus;
/**
* A set-point command request with short integer representation.
* The underlying DNP3 serialization is Group41, Variation 2
*/
public class AnalogOutputInt16 {
public final short value;
public final CommandStatus status;
public AnalogOutputInt16(short value, CommandStatus status)
{
this.value = value;
this.status = status;
}
}
@@ -0,0 +1,38 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.CommandStatus;
/**
* A set-point command request with short integer representation.
* The underlying DNP3 serialization is Group41, Variation 1
*/
public class AnalogOutputInt32 {
public final int value;
public final CommandStatus status;
public AnalogOutputInt32(int value, CommandStatus status)
{
this.value = value;
this.status = status;
}
}
@@ -0,0 +1,39 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* Represents the status of analog output on an outstation.
*/
public class AnalogOutputStatus extends Measurement
{
public final double value;
public AnalogOutputStatus(double value, byte quality, long timestamp)
{
super(quality, timestamp);
this.value = value;
}
@Override
public String toString() {
return String.format("AnalogOutputStatus(%f, 0x%x, %d)", value, quality, timestamp);
}
}
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventAnalogOutputStatusVariation;
import com.automatak.dnp3.enums.StaticAnalogOutputStatusVariation;
public class AnalogOutputStatusConfig extends EventConfig {
public AnalogOutputStatusConfig(int index) {
super(index);
}
public double deadband = 0;
public EventAnalogOutputStatusVariation eventVariation = EventAnalogOutputStatusVariation.Group42Var1;
public StaticAnalogOutputStatusVariation staticVariation = StaticAnalogOutputStatusVariation.Group40Var1;
}
@@ -0,0 +1,46 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* Represents the set of IIN bits that can be controlled by the application
*/
public class ApplicationIIN
{
public ApplicationIIN(
boolean needTime,
boolean localControl,
boolean deviceTrouble,
boolean configCorrupt)
{
this.needTime = needTime;
this.localControl = localControl;
this.deviceTrouble = deviceTrouble;
this.configCorrupt = configCorrupt;
}
public static ApplicationIIN none(){
return new ApplicationIIN(false, false, false, false);
}
public final boolean needTime;
public final boolean localControl;
public final boolean deviceTrouble;
public final boolean configCorrupt;
}
@@ -0,0 +1,38 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventBinaryVariation;
import com.automatak.dnp3.enums.StaticBinaryVariation;
public class BinaryConfig extends EventConfig {
/**
*
* @param index
*/
public BinaryConfig(int index) {
super(index);
this.eventVariation = EventBinaryVariation.Group2Var1;
this.staticVariation = StaticBinaryVariation.Group1Var2;
}
public EventBinaryVariation eventVariation;
public StaticBinaryVariation staticVariation;
}
@@ -0,0 +1,40 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* A boolean measurement type (i.e. whether a switch is open/closed)
*/
public class BinaryInput extends Measurement
{
public final boolean value;
public BinaryInput(boolean value, byte quality, long timestamp)
{
super(quality, timestamp);
this.value = value;
}
@Override
public String toString() {
return String.format("BinaryInput(%b, 0x%x, %d)", value, quality, timestamp);
}
}
@@ -0,0 +1,39 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* Represents the state of a digital output
*/
public class BinaryOutputStatus extends Measurement
{
public final boolean value;
public BinaryOutputStatus(boolean value, byte quality, long timestamp)
{
super(quality, timestamp);
this.value = value;
}
@Override
public String toString() {
return String.format("BinaryOutputStatus(%b, 0x%x, %d)", value, quality, timestamp);
}
}
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventBinaryOutputStatusVariation;
import com.automatak.dnp3.enums.StaticBinaryOutputStatusVariation;
public class BinaryOutputStatusConfig extends EventConfig {
public BinaryOutputStatusConfig(int index) {
super(index);
this.eventVariation = EventBinaryOutputStatusVariation.Group11Var1;
this.staticVariation = StaticBinaryOutputStatusVariation.Group10Var2;
}
public EventBinaryOutputStatusVariation eventVariation;
public StaticBinaryOutputStatusVariation staticVariation;
}
@@ -0,0 +1,31 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* A set of measurement changes that can be applied to a database
*/
public interface ChangeSet
{
/**
* Apply the change set
* @param database The database to which to apply the changes
*/
void apply(Database database);
}
@@ -0,0 +1,67 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* A communication channel to which DNP3 masters / outstation can be attached
*/
public interface Channel {
/**
* Shutdown the channel and all stacks that have been added. Calling shutdown more than once or
* continuing to use child objects (masters/outstations) after calling shutdown can cause a failure.
*/
void shutdown();
/**
* Set the active log levels for the channel's logger
* @param levels
*/
void setLogLevel(int levels);
/**
* Get statistics for the channel
* @return the statistics object
*/
LinkStatistics getStatistics();
/**
* Adds a master to the channel
*
* @param loggerId name of the logger that will be assigned to this stack
* @param handler where measurements will be sent as they are received from the outstation
* @param application master application instance
* @param config configuration information for the master stack
* @return reference to the created master
* @throws DNP3Exception if any error occurs while creating the master
*/
Master addMaster(String loggerId, SOEHandler handler, MasterApplication application, MasterStackConfig config) throws DNP3Exception;
/**
* Adds an outstation to the channel
*
* @param id name of the logger that will be assigned to this stack
* @param commandHandler where command requests are sent to be handled in application code
* @param application outstation application instance
* @param config configuration information for the outstation stack
* @return reference to the created outstation
* @throws DNP3Exception if any error occurs while creating the outstation
*/
Outstation addOutstation(String id, CommandHandler commandHandler, OutstationApplication application, OutstationStackConfig config) throws DNP3Exception;
}
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.ChannelState;
/**
* Callback interface invoked when the state of a communication channel changes
*/
public interface ChannelListener {
/**
* Invoked when the state changes
* @param state State enumeration
*/
void onStateChange(ChannelState state);
}
@@ -0,0 +1,50 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import java.time.Duration;
/**
* Constrains the time range used for exponential backoff from some minimum to a maximum
*/
public class ChannelRetry
{
/**
* Construct a channel retry class
* @param minRetryDelay minimum retry delay
* @param maxRetryDelay maximum retry delay
*/
public ChannelRetry(Duration minRetryDelay, Duration maxRetryDelay)
{
this.minRetryDelay = minRetryDelay;
this.maxRetryDelay = maxRetryDelay;
}
/// <summary>
/// Default configuration from 1 second to 1 minute
/// </summary>
public static ChannelRetry getDefault()
{
return new ChannelRetry(Duration.ofSeconds(1), Duration.ofMinutes(1));
}
public final Duration minRetryDelay;
public final Duration maxRetryDelay;
}
@@ -0,0 +1,39 @@
package com.automatak.dnp3;
public class ChannelStatistics
{
public ChannelStatistics(
long numOpen,
long numOpenFail,
long numClose,
long numBytesRx,
long numBytesTx,
long numLinkFrameTx
)
{
this.numOpen = numOpen;
this.numOpenFail = numOpenFail;
this.numClose = numClose;
this.numBytesRx = numBytesRx;
this.numBytesTx = numBytesTx;
this.numLinkFrameTx = numLinkFrameTx;
}
/// The number of times the channel has successfully opened
public final long numOpen;
/// The number of times the channel has failed to open
public final long numOpenFail;
/// The number of times the channel has closed either due to user intervention or an error
public final long numClose;
/// The number of bytes received
public final long numBytesRx;
/// The number of bytes transmitted
public final long numBytesTx;
/// Number of frames transmitted
public final long numLinkFrameTx;
}
@@ -0,0 +1,39 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.PointClass;
public class ClassAssignment {
public ClassAssignment(byte group, byte variation, PointClass clazz, Range range) {
this.group = group;
this.variation = variation;
this.clazz = clazz;
this.range = range;
}
public final byte group;
public final byte variation;
public final PointClass clazz;
// if range is full, this implies 0x06
public final Range range;
}
@@ -0,0 +1,72 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.PointClass;
/**
* Structure that records which events are scanned / evented
*/
public class ClassField {
public int bitfield;
private ClassField(int mask) {
this.bitfield = mask;
}
public static ClassField from(PointClass... classes) {
byte mask = 0;
for (PointClass pc : classes) {
mask |= pc.toType();
}
return new ClassField(mask);
}
public boolean isSet(PointClass pc)
{
return (pc.toType() & bitfield) != 0;
}
public void set(PointClass pc, boolean value)
{
if(value)
{
this.bitfield |= pc.toType();
}
else
{
this.bitfield &= ~pc.toType();
}
}
public static ClassField none() {
return new ClassField(0);
}
public static ClassField allClasses() {
return new ClassField(PointClassMasks.ALL_CLASSES);
}
public static ClassField allEventClasses() {
return new ClassField(PointClassMasks.ALL_EVENTS);
}
}
@@ -0,0 +1,31 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* An interface that can have any command type collection added to it
*/
public interface CommandBuilder
{
void addCrob(Iterable<IndexedValue<ControlRelayOutputBlock>> commands);
void addAO16(Iterable<IndexedValue<AnalogOutputInt16>> commands);
void addAO32(Iterable<IndexedValue<AnalogOutputInt32>> commands);
void addAOFloat32(Iterable<IndexedValue<AnalogOutputFloat32>> commands);
void addAODouble64(Iterable<IndexedValue<AnalogOutputDouble64>> commands);
};
@@ -0,0 +1,124 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.CommandStatus;
import com.automatak.dnp3.enums.OperateType;
/**
* Outstation application code implements this interface to handle command requests from a master
*/
public interface CommandHandler {
/**
* Called when an ASDU containing commands begins
*/
void start();
/**
* Called when an ASDU containing commands begins
*/
void end();
/**
* Select a ControlRelayOutputBlock (Group12Var1)
* @param command command object
* @param index request index
* @return Enumeration representing the result of the request
*/
CommandStatus selectCROB(ControlRelayOutputBlock command, int index);
/**
* Select a 32-bit integer AnalogOutput (Group41Var1)
* @param command command object
* @param index request index
* @return Enumeration representing the result of the request
*/
CommandStatus selectAOI32(AnalogOutputInt32 command, int index);
/**
* Select a 16-bit integer AnalogOutput (Group41Var2)
* @param command command object
* @param index request index
* @return Enumeration representing the result of the request
*/
CommandStatus selectAOI16(AnalogOutputInt16 command, int index);
/**
* Select a single precision AnalogOutput (Group41Var3)
* @param command command object
* @param index request index
* @return Enumeration representing the result of the request
*/
CommandStatus selectAOF32(AnalogOutputFloat32 command, int index);
/**
* Select a double precision AnalogOutput (Group41Var4)
* @param command command object
* @param index request index
* @return Enumeration representing the result of the request
*/
CommandStatus selectAOD64(AnalogOutputDouble64 command, int index);
/**
* Operate a ControlRelayOutputBlock (Group12Var1)
* @param command command object
* @param index request index
* @param opType The type of the operation (SBO, DO, DONoAck)
* @return Enumeration representing the result of the request
*/
CommandStatus operateCROB(ControlRelayOutputBlock command, int index, OperateType opType);
/**
* Operate a 32-bit integer AnalogOutput (Group41Var1)
* @param command command object
* @param index request index
* @param opType The type of the operation (SBO, DO, DONoAck)
* @return Enumeration representing the result of the request
*/
CommandStatus operateAOI32(AnalogOutputInt32 command, int index, OperateType opType);
/**
* Operate a 16-bit integer AnalogOutput (Group41Var2)
* @param command command object
* @param index request index
* @param opType The type of the operation (SBO, DO, DONoAck)
* @return Enumeration representing the result of the request
*/
CommandStatus operateAOI16(AnalogOutputInt16 command, int index, OperateType opType);
/**
* Operate a single precision AnalogOutput (Group41Var3)
* @param command command object
* @param index request index
* @param opType The type of the operation (SBO, DO, DONoAck)
* @return Enumeration representing the result of the request
*/
CommandStatus operateAOF32(AnalogOutputFloat32 command, int index, OperateType opType);
/**
* Operate a double precision AnalogOutput (Group41Var4)
* @param command command object
* @param index request index
* @param opType The type of the operation (SBO, DO, DONoAck)
* @return Enumeration representing the result of the request
*/
CommandStatus operateAOD64(AnalogOutputDouble64 command, int index, OperateType opType);
}
@@ -0,0 +1,98 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import java.util.ArrayList;
import java.util.function.Consumer;
/**
* A CommandHeaders is something that can send some info to a CommandBuilder
*/
public class CommandHeader implements CommandHeaders
{
private final Consumer<CommandBuilder> action;
private CommandHeader(Consumer<CommandBuilder> action)
{
this.action = action;
}
public static CommandHeaders fromCROB(Iterable<IndexedValue<ControlRelayOutputBlock>> commands)
{
return new CommandHeader((CommandBuilder b) -> b.addCrob(commands));
}
public static CommandHeaders fromAO16(Iterable<IndexedValue<AnalogOutputInt16>> commands)
{
return new CommandHeader((CommandBuilder b) -> b.addAO16(commands));
}
public static CommandHeader fromAO32(Iterable<IndexedValue<AnalogOutputInt32>> commands)
{
return new CommandHeader((CommandBuilder b) -> b.addAO32(commands));
}
public static CommandHeader fromAOFloat32(Iterable<IndexedValue<AnalogOutputFloat32>> commands)
{
return new CommandHeader((CommandBuilder b) -> b.addAOFloat32(commands));
}
public static CommandHeader fromAODouble64(Iterable<IndexedValue<AnalogOutputDouble64>> commands)
{
return new CommandHeader((CommandBuilder b) -> b.addAODouble64(commands));
}
public static CommandHeaders fromSingleCROB(ControlRelayOutputBlock command, int index)
{
return fromCROB(wrap(command, index));
}
public static CommandHeaders fromSingleAO16(AnalogOutputInt16 command, int index)
{
return fromAO16(wrap(command, index));
}
public static CommandHeader fromSingleAO32(AnalogOutputInt32 command, int index)
{
return fromAO32(wrap(command, index));
}
public static CommandHeader fromSingleAOFloat32(AnalogOutputFloat32 command, int index)
{
return fromAOFloat32(wrap(command, index));
}
public static CommandHeader fromSingleAODouble64(AnalogOutputDouble64 command, int index)
{
return fromAODouble64(wrap(command, index));
}
private static <T> Iterable<IndexedValue<T>> wrap(T meas, int index)
{
ArrayList<IndexedValue<T>> list = new ArrayList<>(1);
list.add(new IndexedValue<>(meas, index));
return list;
}
@Override
public void build(CommandBuilder builder)
{
action.accept(builder);
}
};
@@ -0,0 +1,27 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* A CommandHeaders is something that can send some info to a CommandBuilder
*/
public interface CommandHeaders
{
void build(CommandBuilder builder);
};
@@ -0,0 +1,49 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.CommandPointState;
import com.automatak.dnp3.enums.CommandStatus;
/**
* Aggregate result of command operation. Check the Result before checking the status.
* Status is only valid when Result == RESPONSE_OK
*/
public class CommandPointResult
{
public CommandPointResult(int headerIndex, int requestIndex, CommandPointState state, CommandStatus status)
{
this.headerIndex = headerIndex;
this.requestIndex = requestIndex;
this.state = state;
this.status = status;
}
@Override
public String toString()
{
return String.format("Result(header: %d index: %d State: %s Status: %s)", headerIndex, requestIndex, state, status);
}
public final int headerIndex;
public final int requestIndex;
public final CommandPointState state;
public final CommandStatus status;
}
@@ -0,0 +1,121 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import java.util.concurrent.CompletableFuture;
/**
* Interface for dispatching command requests from a master to an outstation
*/
public interface CommandProcessor {
/**
* Select and operate a set of headers
* @param headers A collection of command headers
* @return value representing the future completion of the commands
*/
CompletableFuture<CommandTaskResult> selectAndOperate(CommandHeaders headers);
/**
* Direct operate a set of headers
* @param headers A collection of command headers
* @return value representing the future completion of the commands
*/
CompletableFuture<CommandTaskResult> directOperate(CommandHeaders headers);
/**
* Select and operate a ControlRelayOutputBlock (Group12Variation1)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> selectAndOperateCROB(ControlRelayOutputBlock command, int index);
/**
* Select and operate a 32-bit integer AnalogOutput (Group41Variation1)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> selectAndOperateAOInt32(AnalogOutputInt32 command, int index);
/**
* Select and operate a 16-bit integer AnalogOutput (Group41Variation2)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> selectAndOperateAOInt16(AnalogOutputInt16 command, int index);
/**
* Select and operate single precision AnalogOutput (Group41Variation3)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> selectAndOperateAOFloat32(AnalogOutputFloat32 command, int index);
/**
* Select and operate double precision AnalogOutput (Group41Variation4)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> selectAndOperateAODouble64(AnalogOutputDouble64 command, int index);
/**
* Direct operate a ControlRelayOutputBlock (Group12Variation1)
* @param command command data
* @param index index of request
* @return future to the result of the operation
*/
CompletableFuture<CommandTaskResult> directOperateCROB(ControlRelayOutputBlock command, int index);
/**
* Direct operate a 32-bit integer AnalogOutput (Group41Variation1)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> directOperateAOInt32(AnalogOutputInt32 command, int index);
/**
* Direct operate a 16-bit integer AnalogOutput (Group41Variation2)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> directOperateAOInt16(AnalogOutputInt16 command, int index);
/**
* Direct operate a single precision AnalogOutput (Group41Variation3)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> directOperateAOFloat32(AnalogOutputFloat32 command, int index);
/**
* Direct operate a double precision AnalogOutput (Group41Variation4)
* @param command command data
* @param index index of request
* @return value representing the future completion of the command
*/
CompletableFuture<CommandTaskResult> directOperateAODouble64(AnalogOutputDouble64 command, int index);
}
@@ -0,0 +1,48 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import java.util.ArrayList;
/// <summary>
/// A command set collects headers and can replay their values back to a builder
/// </summary>
public class CommandSet implements CommandHeaders
{
private final ArrayList<CommandHeaders> headers = new ArrayList<>();
public CommandSet(Iterable<CommandHeaders> headers)
{
headers.forEach((h) -> this.headers.add(h));
}
public static CommandHeaders from(Iterable<CommandHeaders> headers)
{
return new CommandSet(headers);
}
@Override
public void build(CommandBuilder builder)
{
for(CommandHeaders header : headers)
{
header.build(builder);
}
}
}
@@ -0,0 +1,53 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.TaskCompletion;
import java.util.Iterator;
/**
* Result type returned for CommandSet based command requests
*/
public class CommandTaskResult
{
public CommandTaskResult(TaskCompletion summary, Iterable<CommandPointResult> results)
{
this.summary = summary;
this.results = results;
}
@Override
public String toString()
{
Iterator<CommandPointResult> iter = results.iterator();
StringBuilder sb = new StringBuilder();
while (iter.hasNext())
{
sb.append(iter.next());
sb.append(iter.hasNext() ? ", " : "");
}
return String.format("Summary: %s Results: { %s }", summary, sb.toString());
}
public final TaskCompletion summary;
public final Iterable<CommandPointResult> results;
}
@@ -0,0 +1,52 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.CommandStatus;
import com.automatak.dnp3.enums.ControlCode;
/**
* Command request for control a relay output
*/
public class ControlRelayOutputBlock {
public final ControlCode function;
public final short count;
public final long onTimeMs;
public final long offTimeMs;
public final CommandStatus status;
/**
* Primary constructor
* @param function Enumeration that controls that behavior of the command
* @param count How many times to repeat the operation
* @param onTimeMs How long to set the output active
* @param offTimeMs How long to set the output inactive
* @param status Status code received from an outstation
*/
public ControlRelayOutputBlock(ControlCode function, short count, long onTimeMs, long offTimeMs, CommandStatus status)
{
this.function = function;
this.count = count;
this.onTimeMs = onTimeMs;
this.offTimeMs = offTimeMs;
this.status = status;
}
}
@@ -0,0 +1,39 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* An increasing count of some event
*/
public class Counter extends Measurement
{
public final long value;
public Counter(long value, byte quality, long timestamp)
{
super(quality, timestamp);
this.value = value;
}
@Override
public String toString() {
return String.format("Counter(%d, 0x%x, %d)", value, quality, timestamp);
}
}
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventCounterVariation;
import com.automatak.dnp3.enums.StaticCounterVariation;
public class CounterConfig extends EventConfig {
public CounterConfig(int index) {
super(index);
}
public int deadband = 0;
public EventCounterVariation eventVariation = EventCounterVariation.Group22Var1;
public StaticCounterVariation staticVariation = StaticCounterVariation.Group20Var1;
}
@@ -0,0 +1,26 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
public class DNP3Exception extends Exception {
public DNP3Exception(String message)
{
super(message);
}
}
@@ -0,0 +1,104 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* The main entry point for all dnp3 applications. Use this object to create communication channels to which
* you can then add masters and outstations.
*
* To obtain a concrete implementation of this interface, use the DNP3ManagerFactory class in the impl package.
*
*/
public interface DNP3Manager {
/**
* Add a TCP client channel. The channel does not try to connect until you add a stack.
* @param id An id used for logging purposes
* @param levels The starting level for logging output
* @param retry Retry configuration for the channel
* @param address The address of remote host as a INET address i.e. "127.0.0.1" or name "www.google.com"
* @param adapter The local adapter to use. "0.0.0.0* means "any adapter'.
* @param port The port to make the connection on. Note that only the range 0 to 65535 is valid
* @param listener Optional listener (can be null) for monitoring the state of the channel
* @return A channel interface
* @throws DNP3Exception if an error occurs creating the channel
*/
Channel addTCPClient(String id, int levels, ChannelRetry retry, String address, String adapter, int port, ChannelListener listener) throws DNP3Exception;
/**
* Add a TCP client channel. The channel does not try to connect until you add a stack.
* @param id An id used for logging purposes
* @param levels The starting level for logging output
* @param retry Retry configuration for the channel
* @param endpoint TThe address that identifies the network adapter to bind i.e. "127.0.0.1" or "0.0.0.0"
* @param port The port to make the connection on. Note that only the range 0 to 65535 is valid
* @param listener Optional listener (can be null) for monitoring the state of the channel
* @return A channel interface
* @throws DNP3Exception if an error occurs creating the channel
*/
Channel addTCPServer(String id, int levels, ChannelRetry retry, String endpoint, int port, ChannelListener listener) throws DNP3Exception;
/**
* Add a TCP client channel. The channel does not try to connect until you add a stack.
* @param id An id used for logging purposes
* @param levels The starting level for logging output
* @param retry Retry configuration for the channel
* @param address The address of remote host as a INET address i.e. "127.0.0.1" or name "www.google.com"
* @param adapter The local adapter to use. "0.0.0.0* means "any adapter'.
* @param port The port to make the connection on. Note that only the range 0 to 65535 is valid
* @param config TLS configuration
* @param listener Optional listener (can be null) for monitoring the state of the channel
* @return A channel interface
* @throws DNP3Exception if an error occurs creating the channel
*/
Channel addTLSClient(String id, int levels, ChannelRetry retry, String address, String adapter, int port, TLSConfig config, ChannelListener listener) throws DNP3Exception;
/**
* Add a TCP client channel. The channel does not try to connect until you add a stack.
* @param id An id used for logging purposes
* @param levels The starting level for logging output
* @param retry Retry configuration for the channel
* @param endpoint TThe address that identifies the network adapter to bind i.e. "127.0.0.1" or "0.0.0.0"
* @param port The port to make the connection on. Note that only the range 0 to 65535 is valid
* @param config TLS configuration
* @param listener Optional listener (can be null) for monitoring the state of the channel
* @return A channel interface
* @throws DNP3Exception if an error occurs creating the channel
*/
Channel addTLSServer(String id, int levels, ChannelRetry retry, String endpoint, int port, TLSConfig config, ChannelListener listener) throws DNP3Exception;
/**
* Add a serial channel. The port does not try to open until you add a stack.
*
* @param id An id used for logging purposes
* @param levels The starting level for logging output
* @param retry Retry configuration for the channel
* @param settings Configuration for the serial port
* @param listener Optional listener (can be null) for monitoring the state of the channel
* @throws DNP3Exception if an error occurs creating the channel
* @return a channel interface
*/
Channel addSerial(String id, int levels, ChannelRetry retry, SerialSettings settings, ChannelListener listener) throws DNP3Exception;
/**
* Permanently shutdown all channels and any associated stacks
*/
void shutdown();
}
@@ -0,0 +1,20 @@
package com.automatak.dnp3;
/**
* Maps to g50v1
*/
public class DNPTime {
public DNPTime(long msSinceEpoch)
{
this.msSinceEpoch = msSinceEpoch;
}
public final long msSinceEpoch;
@Override
public String toString()
{
return String.format("DNPTime(%d)", msSinceEpoch);
}
}
@@ -0,0 +1,133 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventMode;
/**
* Interface used to load measurement changes into an outstation
*/
public interface Database
{
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
*/
void update(BinaryInput value, int index);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
*/
void update(DoubleBitBinaryInput value, int index);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
*/
void update(AnalogInput value, int index);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
*/
void update(Counter value, int index);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
*/
void update(FrozenCounter value, int index);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
*/
void update(BinaryOutputStatus value, int index);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
*/
void update(AnalogOutputStatus value, int index);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
* @param mode EventMode to use
*/
void update(BinaryInput value, int index, EventMode mode);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
* @param mode EventMode to use
*/
void update(DoubleBitBinaryInput value, int index, EventMode mode);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
* @param mode EventMode to use
*/
void update(AnalogInput value, int index, EventMode mode);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
* @param mode EventMode to use
*/
void update(Counter value, int index, EventMode mode);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
* @param mode EventMode to use
*/
void update(FrozenCounter value, int index, EventMode mode);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
* @param mode EventMode to use
*/
void update(BinaryOutputStatus value, int index, EventMode mode);
/**
* Update a value in the database
* @param value measurement to update
* @param index index of measurement
* @param mode EventMode to use
*/
void update(AnalogOutputStatus value, int index, EventMode mode);
}
@@ -0,0 +1,58 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
/**
* Configuration class for the outstation database
*/
public class DatabaseConfig {
public final List<BinaryConfig> binary;
public final List<DoubleBinaryConfig> doubleBinary;
public final List<AnalogConfig> analog;
public final List<CounterConfig> counter;
public final List<FrozenCounterConfig> frozenCounter;
public final List<BinaryOutputStatusConfig> boStatus;
public final List<AnalogOutputStatusConfig> aoStatus;
private static <T> List<T> initialize(int num, Function<Integer, T> factory) {
ArrayList<T> list = new ArrayList<>(num);
for (int i = 0; i < num; ++i) list.add(factory.apply(i));
return list;
}
public static DatabaseConfig allValues(int num) {
return new DatabaseConfig(num, num, num, num, num, num, num);
}
public DatabaseConfig(int numBinary, int numDoubleBinary, int numAnalog, int numCounter, int numFrozenCounter, int numBOStatus, int numAOStatus) {
this.binary = initialize(numBinary, BinaryConfig::new);
this.doubleBinary = initialize(numDoubleBinary, DoubleBinaryConfig::new);
this.analog = initialize(numAnalog, AnalogConfig::new);
this.counter = initialize(numCounter, CounterConfig::new);
this.frozenCounter = initialize(numFrozenCounter, FrozenCounterConfig::new);
this.boStatus = initialize(numBOStatus, BinaryOutputStatusConfig::new);
this.aoStatus = initialize(numAOStatus, AnalogOutputStatusConfig::new);
}
}
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventDoubleBinaryVariation;
import com.automatak.dnp3.enums.StaticDoubleBinaryVariation;
public class DoubleBinaryConfig extends EventConfig {
public DoubleBinaryConfig(int index) {
super(index);
this.eventVariation = EventDoubleBinaryVariation.Group4Var1;
this.staticVariation = StaticDoubleBinaryVariation.Group3Var2;
}
public EventDoubleBinaryVariation eventVariation;
public StaticDoubleBinaryVariation staticVariation;
}
@@ -0,0 +1,41 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.DoubleBit;
/**
* A boolean measurement type (i.e. whether a switch is open/closed)
*/
public class DoubleBitBinaryInput extends Measurement
{
public final DoubleBit value;
public DoubleBitBinaryInput(DoubleBit value, byte quality, long timestamp)
{
super(quality, timestamp);
this.value = value;
}
@Override
public String toString() {
return String.format("DoubleBitBinaryInput(%s, 0x%x, %d)", value, quality, timestamp);
}
}
@@ -0,0 +1,95 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* Configuration of maximum event counts per event type.
* <p>
* The underlying implementation uses a *preallocated* heap buffer to store events
* until they are transmitted to the master. The size of this buffer is proportional
* to the TotalEvents() method, i.e. the sum of the maximum events for each type.
* <p>
* Implementations should configure the buffers to store a reasonable number events
* given the polling frequency and memory restrictions of the target platform.
*/
public class EventBufferConfig {
/**
* Construct the class using the same maximum for all types. This is mainly used for demo purposes.
* You probably don't want to use this method unless your implementation actually reports every type.
*
* @param num size parameter for every type
* @return a new EventBufferConfig instance
*/
public static EventBufferConfig allTypes(int num) {
return new EventBufferConfig(num, num, num, num, num, num, num);
}
/**
* Construct the class specifying the maximum number of events for each type individually
* @param maxBinaryEvents maximum number of event for this type
* @param maxDoubleBinaryEvents maximum number of event for this type
* @param maxAnalogEvents maximum number of event for this type
* @param maxCounterEvents maximum number of event for this type
* @param maxFrozenCounterEvents maximum number of event for this type
* @param maxBinaryOutputStatusEvents maximum number of event for this type
* @param maxAnalogOutputStatusEvents maximum number of event for this type
*/
public EventBufferConfig(
int maxBinaryEvents,
int maxDoubleBinaryEvents,
int maxAnalogEvents,
int maxCounterEvents,
int maxFrozenCounterEvents,
int maxBinaryOutputStatusEvents,
int maxAnalogOutputStatusEvents)
{
this.maxBinaryEvents = maxBinaryEvents;
this.maxDoubleBinaryEvents = maxDoubleBinaryEvents;
this.maxAnalogEvents = maxAnalogEvents;
this.maxCounterEvents = maxCounterEvents;
this.maxFrozenCounterEvents = maxFrozenCounterEvents;
this.maxBinaryOutputStatusEvents = maxBinaryOutputStatusEvents;
this.maxAnalogOutputStatusEvents = maxAnalogOutputStatusEvents;
}
/// The number of binary events the outstation will buffer before overflowing
public int maxBinaryEvents;
/// The number of double bit binary events the outstation will buffer before overflowing
public int maxDoubleBinaryEvents;
/// The number of analog events the outstation will buffer before overflowing
public int maxAnalogEvents;
/// The number of counter events the outstation will buffer before overflowing
public int maxCounterEvents;
/// The number of frozen counter events the outstation will buffer before overflowing
public int maxFrozenCounterEvents;
/// The number of binary output status events the outstation will buffer before overflowing
public int maxBinaryOutputStatusEvents;
/// The number of analog output status events the outstation will buffer before overflowing
public int maxAnalogOutputStatusEvents;
};
@@ -0,0 +1,32 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.PointClass;
public class EventConfig {
public EventConfig(int vIndex) {
this.vIndex = vIndex;
this.clazz = PointClass.Class1;
}
public int vIndex;
public PointClass clazz;
}
@@ -0,0 +1,50 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* Defines a periodic class based scan (Class 0,1,2,3)
*/
public class ExceptionScan
{
public int classMask;
public long scanRateMs;
/**
* Scan all events every 5 seconds
*/
public ExceptionScan()
{
this.classMask = PointClassMasks.ALL_EVENTS;
this.scanRateMs = 5000;
}
/**
*
* Constructor that sets all values
*
* @param classMask Bit-field that determines which classes are scanned. Use PointClass.getMask to create a mask.
* @param scanRateMs Periodic scan rate in milliseconds
*/
public ExceptionScan(int classMask, long scanRateMs)
{
this.classMask = classMask;
this.scanRateMs = scanRateMs;
}
}
@@ -0,0 +1,39 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
/**
* An increasing count of some event
*/
public class FrozenCounter extends Measurement
{
public final long value;
public FrozenCounter(long value, byte quality, long timestamp)
{
super(quality, timestamp);
this.value = value;
}
@Override
public String toString() {
return String.format("FrozenCounter(%d, 0x%x, %d)", value, quality, timestamp);
}
}
@@ -0,0 +1,33 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.EventFrozenCounterVariation;
import com.automatak.dnp3.enums.StaticFrozenCounterVariation;
public class FrozenCounterConfig extends EventConfig {
public FrozenCounterConfig(int index) {
super(index);
}
public int deadband = 0;
public EventFrozenCounterVariation eventVariation = EventFrozenCounterVariation.Group23Var1;
public StaticFrozenCounterVariation staticVariation = StaticFrozenCounterVariation.Group21Var1;
}
@@ -0,0 +1,139 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.QualifierCode;
import java.util.Arrays;
/**
* Represents a header that can be used to specify various types of master tasks
*/
public class Header
{
public final byte group;
public final byte variation;
public final QualifierCode qualifier;
public final int count;
public final int start;
public final int stop;
private Header(byte group, byte variation, QualifierCode qualifier, int count, int start, int stop)
{
this.group = group;
this.variation = variation;
this.qualifier = qualifier;
this.count = count;
this.start = start;
this.stop = stop;
}
@Override
public String toString()
{
return String.format("g{%d}v{%d} - {%s}", group, variation, qualifier);
}
public static Iterable<Header> getIntegrity()
{
return Arrays.asList(
Header.allObjects((byte)60,(byte)1),
Header.allObjects((byte)60,(byte)2),
Header.allObjects((byte)60,(byte)3),
Header.allObjects((byte)60,(byte)4)
);
}
public static Iterable<Header> getEventClasses()
{
return Arrays.asList(
Header.allObjects((byte)60,(byte)2),
Header.allObjects((byte)60,(byte)3),
Header.allObjects((byte)60,(byte)4)
);
}
/**
* Header requesting all objects of the given type or class (in the case of Group 60 objects) are returned.
*
* @param group Group to request
* @param variation Variation to request
* @return A Header with Qualifier 0x06
*/
public static Header allObjects(Byte group, Byte variation)
{
return new Header(group, variation, QualifierCode.ALL_OBJECTS, 0, 0, 0);
}
/**
* Header requesting that the first "x" indexes are returned, where x is the quantity.
*
* @param group Group to request
* @param variation Variation to request
* @param quantity The number of objects to return
* @return A Header with Qualifier 0x07
*/
public static Header count8(Byte group, Byte variation, short quantity)
{
return new Header(group, variation, QualifierCode.UINT8_CNT, quantity, 0, 0);
}
/**
* Header requesting that the first "x" indexes are returned, where x is the quantity.
*
* @param group Group to request
* @param variation Variation to request
* @param quantity The number of objects to return
* @return A Header with Qualifier 0x08
*/
public static Header count16(Byte group, Byte variation, int quantity)
{
return new Header(group, variation, QualifierCode.UINT16_CNT, quantity, 0, 0);
}
/**
* Header requesting that a range of indices
*
* @param group Group to request
* @param variation Variation to request
* @param startIndex beginning of index range
* @param stopIndex end of index range
* @return A Header with Qualifier 0x00
*/
public static Header Range8(Byte group, Byte variation, short startIndex, short stopIndex)
{
return new Header(group, variation, QualifierCode.UINT8_START_STOP, 0, startIndex, stopIndex);
}
/**
* Header requesting that a range of indices
*
* @param group Group to request
* @param variation Variation to request
* @param startIndex beginning of index range
* @param stopIndex end of index range
* @return A Header with Qualifier 0x01
*/
public static Header Range16(Byte group, Byte variation, int startIndex, int stopIndex)
{
return new Header(group, variation, QualifierCode.UINT16_START_STOP, 0, startIndex, stopIndex);
}
}
@@ -0,0 +1,71 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
import com.automatak.dnp3.enums.GroupVariation;
import com.automatak.dnp3.enums.QualifierCode;
import com.automatak.dnp3.enums.TimestampMode;
public class HeaderInfo
{
public HeaderInfo(GroupVariation variation, QualifierCode qualifier, TimestampMode tsmode, boolean isEvent, boolean flagsValid, int headerIndex)
{
this.variation = variation;
this.qualifier = qualifier;
this.tsmode = tsmode;
this.isEvent = isEvent;
this.flagsValid = flagsValid;
this.headerIndex = headerIndex;
}
@Override
public String toString() {
return String.format("HeaderInfo(%s, %s, timestamp: %s, isEvent: %b, flagsValid: %b, #: %d)", variation, qualifier, tsmode, isEvent, flagsValid, headerIndex);
}
/**
* An enum representing the group and variation for this header
*/
public final GroupVariation variation;
/**
* The qualifier code used for this header
*/
public final QualifierCode qualifier;
/**
* An enumeration describing the validity of the timestamp on the measurements
*/
public final TimestampMode tsmode;
/**
* True if this qualifier is an event type
*/
public final boolean isEvent;
/**
* True if the flags/quality on the measurements are valid
*/
public final boolean flagsValid;
/**
* The index of the header (0-based) within the ASDU
*/
public final int headerIndex;
}
@@ -0,0 +1,91 @@
/**
* Copyright 2013-2016 Automatak, LLC
*
* Licensed to Automatak, LLC (www.automatak.com) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. Automatak, LLC
* licenses this file to you 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.html
*
* 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.automatak.dnp3;
public class IINField
{
public enum LSB
{
ALL_STATIONS(1 << 0),
CLASS1_EVENTS(1 << 1),
CLASS2_EVENTS(1 << 2),
CLASS3_EVENTS(1 << 3),
NEED_TIME(1 << 4),
LOCAL_CONTROL(1 << 5),
DEVICE_TROUBLE(1 << 6),
DEVICE_RESTART(1 << 7);
public final int id;
public boolean isSet(byte value)
{
return (value & id) != 0;
}
LSB(int id)
{
this.id = id;
}
}
public enum MSB
{
FUNC_NOT_SUPPORTED(1 << 0),
OBJECT_UNKNOWN(1 << 1),
PARAM_ERROR(1 << 2),
EVENT_BUFFER_OVERFLOW(1 << 3),
ALREADY_EXECUTING(1 << 4),
CONFIG_CORRUPT(1 << 5),
RESERVED1(1 << 6),
RESERVED2(1 << 7);
public final int id;
public boolean isSet(byte value)
{
return (value & id) != 0;
}
MSB(int id)
{
this.id = id;
}
}
public final byte lsb;
public final byte msb;
public IINField(byte lsb, byte msb)
{
this.lsb = lsb;
this.msb = msb;
}
public boolean isSet(LSB bit)
{
return bit.isSet(lsb);
}
public boolean isSet(MSB bit)
{
return bit.isSet(msb);
}
}

Some files were not shown because too many files have changed in this diff Show More