- extended 9-2LE example

pull/6/head
Michael Zillgith 10 years ago
parent 3081fcd935
commit 43d99ad438

@ -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
)

@ -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

@ -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 <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include "iec61850_server.h"
#include "sv_publisher.h"
#include "hal_thread.h"
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
/* 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() */

@ -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 <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include "iec61850_server.h"
#include "hal_thread.h"
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
/* 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() */

@ -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,

@ -74,21 +74,21 @@ SCL.xsd">
<DataSet name="PhsMeas1">
<FCDA ldInst="MUnn" lnClass="TCTR" lnInst="1" fc="MX"
doName="Amp" />
doName="Amp" daName="instMag.i"/>
<FCDA ldInst="MUnn" lnClass="TCTR" lnInst="2" fc="MX"
doName="Amp" />
doName="Amp" daName="instMag.i"/>
<FCDA ldInst="MUnn" lnClass="TCTR" lnInst="3" fc="MX"
doName="Amp" />
doName="Amp" daName="instMag.i"/>
<FCDA ldInst="MUnn" lnClass="TCTR" lnInst="4" fc="MX"
doName="Amp" />
doName="Amp" daName="instMag.i"/>
<FCDA ldInst="MUnn" lnClass="TVTR" lnInst="1" fc="MX"
doName="Vol" />
doName="Vol" daName="instMag.i"/>
<FCDA ldInst="MUnn" lnClass="TVTR" lnInst="2" fc="MX"
doName="Vol" />
doName="Vol" daName="instMag.i"/>
<FCDA ldInst="MUnn" lnClass="TVTR" lnInst="3" fc="MX"
doName="Vol" />
doName="Vol" daName="instMag.i"/>
<FCDA ldInst="MUnn" lnClass="TVTR" lnInst="4" fc="MX"
doName="Vol" />
doName="Vol" daName="instMag.i"/>
</DataSet>

@ -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

Loading…
Cancel
Save