diff --git a/examples/iec61850_9_2_LE_example/CMakeLists.txt b/examples/iec61850_9_2_LE_example/CMakeLists.txt
index 994caae3..fdaa929f 100644
--- a/examples/iec61850_9_2_LE_example/CMakeLists.txt
+++ b/examples/iec61850_9_2_LE_example/CMakeLists.txt
@@ -2,20 +2,20 @@ include_directories(
.
)
-set(server_example2_SRCS
+set(sv_9_2_LE_example_SRCS
server_example2.c
static_model.c
)
IF(WIN32)
-set_source_files_properties(${server_example2_SRCS}
+set_source_files_properties(${sv_9_2_LE_example_SRCS}
PROPERTIES LANGUAGE CXX)
ENDIF(WIN32)
-add_executable(server_example2
- ${server_example2_SRCS}
+add_executable(sv_9_2_LE_example
+ ${sv_9_2_LE_example_SRCS}
)
-target_link_libraries(server_example2
+target_link_libraries(sv_9_2_LE_example
iec61850
)
diff --git a/examples/iec61850_9_2_LE_example/Makefile b/examples/iec61850_9_2_LE_example/Makefile
index 3781758b..8437cf31 100644
--- a/examples/iec61850_9_2_LE_example/Makefile
+++ b/examples/iec61850_9_2_LE_example/Makefile
@@ -1,7 +1,7 @@
LIBIEC_HOME=../..
-PROJECT_BINARY_NAME = server_example2
-PROJECT_SOURCES = server_example2.c
+PROJECT_BINARY_NAME = sv_9_2LE_example
+PROJECT_SOURCES = iec61850_9_2_LE_example.c
PROJECT_SOURCES += static_model.c
PROJECT_ICD_FILE = complexModel.icd
diff --git a/examples/iec61850_9_2_LE_example/iec61850_9_2_LE_example.c b/examples/iec61850_9_2_LE_example/iec61850_9_2_LE_example.c
new file mode 100644
index 00000000..86c1cdbc
--- /dev/null
+++ b/examples/iec61850_9_2_LE_example/iec61850_9_2_LE_example.c
@@ -0,0 +1,152 @@
+/*
+ * iec61850_9_2_LE_example.c
+ *
+ * Copyright 2016 Michael Zillgith
+ *
+ * This file is part of libIEC61850.
+ *
+ * libIEC61850 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libIEC61850 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with libIEC61850. If not, see .
+ *
+ * See COPYING file for the complete license text.
+ */
+
+#include "iec61850_server.h"
+#include "sv_publisher.h"
+#include "hal_thread.h"
+#include
+#include
+#include
+
+
+/* Include the generated header with the model access handles */
+#include "static_model.h"
+
+/* import IEC 61850 device model created from SCL-File */
+extern IedModel iedModel;
+
+static int running = 0;
+
+void sigint_handler(int signalId)
+{
+ running = 0;
+}
+
+static int amp1;
+static int amp2;
+static int amp3;
+static int amp4;
+
+static int vol1;
+static int vol2;
+static int vol3;
+static int vol4;
+
+static SampledValuesPublisher svPublisher;
+static SV_ASDU asdu;
+
+static void
+setupSVPublisher()
+{
+ svPublisher = SampledValuesPublisher_create("eth1");
+
+ asdu = SampledValuesPublisher_addASDU(svPublisher, "xxxxMUnn01", NULL, 1);
+
+ amp1 = SV_ASDU_addINT32(asdu);
+ amp2 = SV_ASDU_addINT32(asdu);
+ amp3 = SV_ASDU_addINT32(asdu);
+ amp4 = SV_ASDU_addINT32(asdu);
+
+ vol1 = SV_ASDU_addINT32(asdu);
+ vol2 = SV_ASDU_addINT32(asdu);
+ vol3 = SV_ASDU_addINT32(asdu);
+ vol4 = SV_ASDU_addINT32(asdu);
+
+ SampledValuesPublisher_setupComplete(svPublisher);
+}
+
+int
+main(int argc, char** argv)
+{
+ IedServer iedServer = IedServer_create(&iedModel);
+
+ // TODO set initial measurement and status values from process
+
+ /* MMS server will be instructed to start listening to client connections. */
+ IedServer_start(iedServer, 102);
+
+ if (!IedServer_isRunning(iedServer)) {
+ printf("Starting server failed! Exit.\n");
+ IedServer_destroy(iedServer);
+ exit(-1);
+ }
+
+ running = 1;
+
+ signal(SIGINT, sigint_handler);
+
+ setupSVPublisher();
+
+ int voltage = 1;
+ int current = 1;
+
+ while (running) {
+
+ uint64_t timeval = Hal_getTimeInMs();
+
+ IedServer_lockDataModel(iedServer);
+
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TCTR1_Amp_instMag_i, current);
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TCTR2_Amp_instMag_i, current);
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TCTR3_Amp_instMag_i, current);
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TCTR3_Amp_instMag_i, current);
+
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TVTR1_Vol_instMag_i, voltage);
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TVTR2_Vol_instMag_i, voltage);
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TVTR3_Vol_instMag_i, voltage);
+ IedServer_updateInt32AttributeValue(iedServer, IEDMODEL_MUnn_TVTR4_Vol_instMag_i, voltage);
+
+ IedServer_unlockDataModel(iedServer);
+
+ if (1) {
+
+ SV_ASDU_setINT32(asdu, amp1, current);
+ SV_ASDU_setINT32(asdu, amp2, current);
+ SV_ASDU_setINT32(asdu, amp3, current);
+ SV_ASDU_setINT32(asdu, amp4, current);
+
+ SV_ASDU_setINT32(asdu, vol1, voltage);
+ SV_ASDU_setINT32(asdu, vol2, voltage);
+ SV_ASDU_setINT32(asdu, vol3, voltage);
+ SV_ASDU_setINT32(asdu, vol4, voltage);
+
+ SV_ASDU_increaseSmpCnt(asdu);
+
+ SampledValuesPublisher_publish(svPublisher);
+ }
+
+ voltage++;
+ current++;
+
+ Thread_sleep(500);
+ }
+
+ /* stop MMS server - close TCP server socket and all client sockets */
+ IedServer_stop(iedServer);
+
+ /* Cleanup - free all resources */
+ SampledValuesPublisher_destroy(svPublisher);
+ IedServer_destroy(iedServer);
+
+ return 0;
+} /* main() */
diff --git a/examples/iec61850_9_2_LE_example/server_example2.c b/examples/iec61850_9_2_LE_example/server_example2.c
deleted file mode 100644
index 662cf501..00000000
--- a/examples/iec61850_9_2_LE_example/server_example2.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * server_example2.c
- *
- * Copyright 2013 Michael Zillgith
- *
- * This file is part of libIEC61850.
- *
- * libIEC61850 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * libIEC61850 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with libIEC61850. If not, see .
- *
- * See COPYING file for the complete license text.
- */
-
-#include "iec61850_server.h"
-#include "hal_thread.h"
-#include
-#include
-#include
-
-
-/* Include the generated header with the model access handles */
-#include "static_model.h"
-
-/* import IEC 61850 device model created from SCL-File */
-extern IedModel iedModel;
-
-static int running = 0;
-
-void sigint_handler(int signalId)
-{
- running = 0;
-}
-
-int
-main(int argc, char** argv)
-{
- IedServer iedServer = IedServer_create(&iedModel);
-
- // TODO get stored values from persistent storage
-
- // TODO set initial measurement and status values from process
-
- /* MMS server will be instructed to start listening to client connections. */
- IedServer_start(iedServer, 102);
-
- if (!IedServer_isRunning(iedServer)) {
- printf("Starting server failed! Exit.\n");
- IedServer_destroy(iedServer);
- exit(-1);
- }
-
- running = 1;
-
- signal(SIGINT, sigint_handler);
-
- float power = 500.f;
-
- while (running) {
-
- uint64_t timeval = Hal_getTimeInMs();
-
- IedServer_unlockDataModel(iedServer);
-
- power += 0.1f;
-
- Thread_sleep(500);
- }
-
- /* stop MMS server - close TCP server socket and all client sockets */
- IedServer_stop(iedServer);
-
- /* Cleanup - free all resources */
- IedServer_destroy(iedServer);
-
- return 0;
-} /* main() */
diff --git a/examples/iec61850_9_2_LE_example/static_model.c b/examples/iec61850_9_2_LE_example/static_model.c
index 06c58685..5962f83d 100644
--- a/examples/iec61850_9_2_LE_example/static_model.c
+++ b/examples/iec61850_9_2_LE_example/static_model.c
@@ -22,7 +22,7 @@ extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda7;
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda0 = {
"MUnn",
false,
- "TCTR1$MX$Amp",
+ "TCTR1$MX$Amp$instMag$i",
-1,
NULL,
NULL,
@@ -32,7 +32,7 @@ DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda0 = {
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda1 = {
"MUnn",
false,
- "TCTR2$MX$Amp",
+ "TCTR2$MX$Amp$instMag$i",
-1,
NULL,
NULL,
@@ -42,7 +42,7 @@ DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda1 = {
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda2 = {
"MUnn",
false,
- "TCTR3$MX$Amp",
+ "TCTR3$MX$Amp$instMag$i",
-1,
NULL,
NULL,
@@ -52,7 +52,7 @@ DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda2 = {
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda3 = {
"MUnn",
false,
- "TCTR4$MX$Amp",
+ "TCTR4$MX$Amp$instMag$i",
-1,
NULL,
NULL,
@@ -62,7 +62,7 @@ DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda3 = {
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda4 = {
"MUnn",
false,
- "TVTR1$MX$Vol",
+ "TVTR1$MX$Vol$instMag$i",
-1,
NULL,
NULL,
@@ -72,7 +72,7 @@ DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda4 = {
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda5 = {
"MUnn",
false,
- "TVTR2$MX$Vol",
+ "TVTR2$MX$Vol$instMag$i",
-1,
NULL,
NULL,
@@ -82,7 +82,7 @@ DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda5 = {
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda6 = {
"MUnn",
false,
- "TVTR3$MX$Vol",
+ "TVTR3$MX$Vol$instMag$i",
-1,
NULL,
NULL,
@@ -92,7 +92,7 @@ DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda6 = {
DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda7 = {
"MUnn",
false,
- "TVTR4$MX$Vol",
+ "TVTR4$MX$Vol$instMag$i",
-1,
NULL,
NULL,
diff --git a/examples/iec61850_9_2_LE_example/sv.icd b/examples/iec61850_9_2_LE_example/sv.icd
index b52f8d92..9ef2d1a1 100644
--- a/examples/iec61850_9_2_LE_example/sv.icd
+++ b/examples/iec61850_9_2_LE_example/sv.icd
@@ -74,21 +74,21 @@ SCL.xsd">
+ doName="Amp" daName="instMag.i"/>
+ doName="Amp" daName="instMag.i"/>
+ doName="Amp" daName="instMag.i"/>
+ doName="Amp" daName="instMag.i"/>
+ doName="Vol" daName="instMag.i"/>
+ doName="Vol" daName="instMag.i"/>
+ doName="Vol" daName="instMag.i"/>
+ doName="Vol" daName="instMag.i"/>
diff --git a/src/sampled_values/sv_publisher.c b/src/sampled_values/sv_publisher.c
index ccf1bc8d..67e65f88 100644
--- a/src/sampled_values/sv_publisher.c
+++ b/src/sampled_values/sv_publisher.c
@@ -24,7 +24,11 @@
#include "stack_config.h"
#include "libiec61850_platform_includes.h"
+
+#include "sv_publisher.h"
+
#include "hal_ethernet.h"
+#include "ber_encoder.h"
#define DEBUG_SV_PUBLISHER 1
@@ -36,14 +40,6 @@
#define SV_MAX_MESSAGE_SIZE 1518
-#define IEC61850_SV_SMPSYNC_NOT_SYNCHRONIZED 0
-#define IEC61850_SV_SMPSYNC_SYNCED_UNSPEC_LOCAL_CLOCK 1
-#define IEC61850_SV_SMPSYNC_SYNCED_GLOBAL_CLOCK 2
-
-#define IEC61850_SV_SMPMOD_PER_NOMINAL_PERIOD 0
-#define IEC61850_SV_SMPMOD_SAMPLES_PER_SECOND 1
-#define IEC61850_SV_SMPMOD_SECONDS_PER_SAMPLE 2
-
typedef struct sCommParameters {
uint8_t vlanPriority;
uint16_t vlanId;
@@ -51,7 +47,7 @@ typedef struct sCommParameters {
uint8_t dstAddress[6];
} CommParameters;
-typedef struct sSV_ASDU* SV_ASDU;
+
struct sSV_ASDU {
char* svID;
@@ -73,7 +69,7 @@ struct sSV_ASDU {
SV_ASDU _next;
};
-typedef struct sSampledValuesPublisher* SampledValuesPublisher;
+
struct sSampledValuesPublisher {
uint8_t* buffer;
@@ -93,7 +89,7 @@ struct sSampledValuesPublisher {
static void
-preparePacketBuffer(SampledValuesPublisher self, CommParameters* parameters, char* interfaceID)
+preparePacketBuffer(SampledValuesPublisher self, CommParameters* parameters, const char* interfaceID)
{
uint8_t srcAddr[6];
@@ -208,6 +204,26 @@ encodeUInt32FixedSize(uint32_t value, uint8_t* buffer, int bufPos)
return bufPos;
}
+static int
+encodeInt32FixedSize(int32_t value, uint8_t* buffer, int bufPos)
+{
+ uint8_t* valueArray = (uint8_t*) &value;
+
+#if (ORDER_LITTLE_ENDIAN == 1)
+ buffer[bufPos++] = valueArray[3];
+ buffer[bufPos++] = valueArray[2];
+ buffer[bufPos++] = valueArray[1];
+ buffer[bufPos++] = valueArray[0];
+#else
+ buffer[bufPos++] = valueArray[0];
+ buffer[bufPos++] = valueArray[1];
+ buffer[bufPos++] = valueArray[2];
+ buffer[bufPos++] = valueArray[3];
+#endif
+
+ return bufPos;
+}
+
SampledValuesPublisher
SampledValuesPublisher_create(const char* interfaceId)
@@ -302,7 +318,7 @@ SV_ASDU_encodeToBuffer(SV_ASDU self, uint8_t* buffer, int bufPos)
if (self->datset != NULL)
bufPos = BerEncoder_encodeStringWithTag(0x81, self->datset, buffer, bufPos);
- uint8_t octetString[4];
+ //uint8_t octetString[4];
/* SmpCnt */
bufPos = BerEncoder_encodeTL(0x82, 2, buffer, bufPos);
@@ -447,6 +463,12 @@ SV_ASDU_addINT32(SV_ASDU self)
return index;
}
+void
+SV_ASDU_setINT32(SV_ASDU self, int index, int32_t value)
+{
+ encodeInt32FixedSize(value, self->_dataBuffer, index);
+}
+
int
SV_ASDU_addFLOAT(SV_ASDU self)
{
@@ -480,7 +502,9 @@ SV_ASDU_setFLOAT(SV_ASDU self, int index, float value)
void
SV_ASDU_setSmpCnt(SV_ASDU self, uint16_t value)
{
- //TODO write value to correct field in buffer
+ self->smpCnt = value;
+
+ encodeUInt16FixedSize(self->smpCnt, self->smpCntBuf, 0);
}
void
@@ -498,45 +522,7 @@ SV_ASDU_setRefrTm(SV_ASDU self, Timestamp refrTm)
}
#endif
-
-int
-main(int argc, char** argv)
-{
- SampledValuesPublisher svPublisher = SampledValuesPublisher_create("eth1");
-
- SV_ASDU asdu1 = SampledValuesPublisher_addASDU(svPublisher, "svpub1", NULL, 1);
-
- int float1 = SV_ASDU_addFLOAT(asdu1);
- int float2 = SV_ASDU_addFLOAT(asdu1);
-
- SV_ASDU asdu2 = SampledValuesPublisher_addASDU(svPublisher, "svpub2", NULL, 1);
-
- int float3 = SV_ASDU_addFLOAT(asdu2);
- int float4 = SV_ASDU_addFLOAT(asdu2);
-
- SampledValuesPublisher_setupComplete(svPublisher);
-
- float fVal1 = 1234.5678f;
- float fVal2 = 0.12345f;
-
- int i;
-
- for (i = 0; i < 10; i++) {
- SV_ASDU_setFLOAT(asdu1, float1, fVal1);
- SV_ASDU_setFLOAT(asdu1, float2, fVal2);
-
- SV_ASDU_increaseSmpCnt(asdu1);
- SV_ASDU_increaseSmpCnt(asdu2);
-
- fVal1 += 1.1f;
- fVal2 += 0.1f;
-
- SampledValuesPublisher_publish(svPublisher);
- }
-
- SampledValuesPublisher_destroy(svPublisher);
-}
-
+#if 0
int
main1(int argc, char** argv)
{
@@ -568,4 +554,4 @@ main1(int argc, char** argv)
SampledValuesPublisher_destroy(svPublisher);
}
-
+#endif