- added IedServer_setGooseInterfaceId function to set ethernet interface for GOOSE at runtime

This commit is contained in:
Michael Zillgith 2015-02-20 14:31:25 +01:00
parent 4cc0b4fe13
commit d0676ba305
26 changed files with 144 additions and 70 deletions

View file

@ -36,7 +36,7 @@
#define GOOSE_MAX_MESSAGE_SIZE 1518
static void
prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, char* interfaceID);
prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, const char* interfaceID);
struct sGoosePublisher {
uint8_t* buffer;
@ -65,7 +65,7 @@ struct sGoosePublisher {
GoosePublisher
GoosePublisher_create(CommParameters* parameters, char* interfaceID)
GoosePublisher_create(CommParameters* parameters, const char* interfaceID)
{
GoosePublisher self = (GoosePublisher) GLOBAL_CALLOC(1, sizeof(struct sGoosePublisher));
@ -160,7 +160,7 @@ GoosePublisher_setTimeAllowedToLive(GoosePublisher self, uint32_t timeAllowedToL
}
static void
prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, char* interfaceID)
prepareGooseBuffer(GoosePublisher self, CommParameters* parameters, const char* interfaceID)
{
uint8_t srcAddr[6];

View file

@ -41,7 +41,7 @@ typedef struct sCommParameters {
typedef struct sGoosePublisher* GoosePublisher;
GoosePublisher
GoosePublisher_create(CommParameters* parameters, char* interfaceID);
GoosePublisher_create(CommParameters* parameters, const char* interfaceID);
void
GoosePublisher_destroy(GoosePublisher self);

View file

@ -96,7 +96,8 @@ int _Ethernet_setBpfEthertypeFilter(EthernetSocket self, uint16_t etherType)
}
}
void Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr)
void
Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr)
{
struct ifaddrs *ifap, *ifc;
struct sockaddr_dl* link;
@ -131,7 +132,8 @@ void Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr)
freeifaddrs(ifap);
}
EthernetSocket Ethernet_createSocket(char* interfaceId, uint8_t* destAddress)
EthernetSocket
Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress)
{
char bpfFileStringBuffer[11] = { 0 };
int i;

View file

@ -45,7 +45,7 @@ struct sEthernetSocket {
};
static int
getInterfaceIndex(int sock, char* deviceName)
getInterfaceIndex(int sock, const char* deviceName)
{
struct ifreq ifr;
@ -76,7 +76,7 @@ getInterfaceIndex(int sock, char* deviceName)
void
Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr)
Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr)
{
struct ifreq buffer;
@ -100,7 +100,7 @@ Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr)
EthernetSocket
Ethernet_createSocket(char* interfaceId, uint8_t* destAddress)
Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress)
{
EthernetSocket ethernetSocket = GLOBAL_CALLOC(1, sizeof(struct sEthernetSocket));

View file

@ -211,7 +211,7 @@ getAdapterMacAddress(char* pcapAdapterName, uint8_t* macAddress)
void
Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr)
Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr)
{
#ifdef __GNUC__
#ifndef __MINGW64_VERSION_MAJOR
@ -238,7 +238,7 @@ Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr)
EthernetSocket
Ethernet_createSocket(char* interfaceId, uint8_t* destAddress)
Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress)
{
pcap_t *pcapSocket;
char errbuf[PCAP_ERRBUF_SIZE];
@ -332,12 +332,12 @@ Ethernet_isSupported()
}
void
Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr)
Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr)
{
}
EthernetSocket
Ethernet_createSocket(char* interfaceId, uint8_t* destAddress)
Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress)
{
return NULL;
}

View file

@ -57,7 +57,7 @@ typedef struct sEthernetSocket* EthernetSocket;
* \param addr pointer to a buffer to store the MAC address
*/
void
Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr);
Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr);
/**
* \brief Create an Ethernet socket using the specified interface and
@ -67,7 +67,7 @@ Ethernet_getInterfaceMACAddress(char* interfaceId, uint8_t* addr);
* \param destAddress byte array that contains the Ethernet MAC address
*/
EthernetSocket
Ethernet_createSocket(char* interfaceId, uint8_t* destAddress);
Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress);
/**
* \brief destroy the ethernet socket

View file

@ -28,9 +28,6 @@
#include "iec61850_client.h"
#include "mms_client_connection.h"
#include "ied_connection_private.h"
#include "mms_mapping.h"
#include <stdio.h>
#if _MSC_VER
#define snprintf _snprintf
@ -121,7 +118,9 @@ ControlObjectClient_create(const char* objectReference, IedConnection connection
convertToMmsAndInsertFC(itemId, objectReference + strlen(domainId) + 1, "CF");
strncat(itemId, "$ctlModel", 128);
int controlObjectItemIdLen = strlen(itemId);
strncat(itemId, "$ctlModel", 64 - controlObjectItemIdLen);
MmsError mmsError;
@ -403,7 +402,9 @@ ControlObjectClient_operate(ControlObjectClient self, MmsValue* ctlVal, uint64_t
convertToMmsAndInsertFC(itemId, self->objectReference + strlen(domainId) + 1, "CO");
strncat(itemId, "$Oper", 129);
int controlObjectItemIdLen = strlen(itemId);
strncat(itemId, "$Oper", 64 - controlObjectItemIdLen);
if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: operate: %s/%s\n", domainId, itemId);

View file

@ -29,7 +29,8 @@
#include "ied_connection_private.h"
#include "mms_mapping.h"
#include "lib_memory.h"
#include "string_utilities.h"
struct sClientGooseControlBlock {
char* objectReference;

View file

@ -29,7 +29,8 @@
#include "ied_connection_private.h"
#include "mms_mapping.h"
#include "lib_memory.h"
#include "string_utilities.h"
struct sClientReport
{
@ -54,7 +55,6 @@ struct sClientReport
uint64_t timestamp;
uint16_t seqNum;
uint32_t confRev;
bool bufOverflow;
};
char*
@ -393,7 +393,7 @@ private_IedConnection_handleReport(IedConnection self, MmsValue* value)
/* skip bufOvfl */
if (MmsValue_getBitStringBit(optFlds, 6) == true) {
matchingReport->hasBufOverflow = false;
matchingReport->hasBufOverflow = true;
inclusionIndex++;
}

View file

@ -29,7 +29,8 @@
#include "ied_connection_private.h"
#include "mms_mapping.h"
#include "lib_memory.h"
#include "string_utilities.h"
static bool
isBufferedRcb(const char* objectReference)

View file

@ -28,7 +28,6 @@
#include "stack_config.h"
#include "mms_client_connection.h"
#include "mms_mapping.h"
#include "ied_connection_private.h"
#include "mms_value_internal.h"

View file

@ -207,6 +207,19 @@ IedServer_enableGoosePublishing(IedServer self);
void
IedServer_disableGoosePublishing(IedServer self);
/**
* \brief Set the ethernet interface to be used by GOOSE publishing
*
* This function can be used to set the GOOSE interface ID. If not used or set to NULL the
* default interface ID from stack_config.h is used. Note the interface ID is operating system
* specific!
*
* \param self the instance of IedServer to operate on.
* \param interfaceId the ID of the ethernet interface to be used for GOOSE publishing
*/
void
IedServer_setGooseInterfaceId(IedServer self, const char* interfaceId);
/**@}*/
/**

View file

@ -101,4 +101,19 @@ ClientReport_destroy(ClientReport self);
void
private_ControlObjectClient_invokeCommandTerminationHandler(ControlObjectClient self);
/* some declarations that are shared with server side ! */
char*
MmsMapping_getMmsDomainFromObjectReference(const char* objectReference, char* buffer);
char*
MmsMapping_createMmsVariableNameFromObjectReference(const char* objectReference, FunctionalConstraint fc, char* buffer);
char*
MmsMapping_varAccessSpecToObjectReference(MmsVariableAccessSpecification* varAccessSpec);
MmsVariableAccessSpecification*
MmsMapping_ObjectReferenceToVariableAccessSpec(char* objectReference);
#endif /* IED_CONNECTION_PRIVATE_H_ */

View file

@ -25,7 +25,7 @@
#define MMS_MAPPING_H_
#include "iec61850_model.h"
#include "mms_server_connection.h"
//#include "mms_server_connection.h"
#include "mms_device_model.h"
#include "control.h"

View file

@ -1,7 +1,7 @@
/*
* mms_mapping_internal.h
*
* Copyright 2013 Michael Zillgith
* Copyright 2013, 2015 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -24,6 +24,8 @@
#ifndef MMS_MAPPING_INTERNAL_H_
#define MMS_MAPPING_INTERNAL_H_
#include "stack_config.h"
#include "hal_thread.h"
#include "linked_list.h"
@ -32,7 +34,12 @@ struct sMmsMapping {
MmsDevice* mmsDevice;
MmsServer mmsServer;
LinkedList reportControls;
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
LinkedList gseControls;
const char* gooseInterfaceId;
#endif
LinkedList controlObjects;
LinkedList observedObjects;
LinkedList attributeAccessHandlers;

View file

@ -29,7 +29,7 @@
#include "hal_thread.h"
#include "ied_server_private.h"
#include "mms_server.h"
//#include "mms_server.h"
struct sClientConnection {

View file

@ -345,36 +345,41 @@ updateDataSetsWithCachedValues(IedServer self)
{
DataSet* dataSet = self->model->dataSets;
while (dataSet != NULL) {
int iedNameLength = strlen(self->model->name);
DataSetEntry* dataSetEntry = dataSet->fcdas;
if (iedNameLength <= 64) {
while (dataSetEntry != NULL) {
while (dataSet != NULL) {
char domainName[65];
DataSetEntry* dataSetEntry = dataSet->fcdas;
strncpy(domainName, self->model->name, 64);
strncat(domainName, dataSetEntry->logicalDeviceName, 64);
while (dataSetEntry != NULL) {
MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, domainName);
char domainName[65];
MmsValue* value = MmsServer_getValueFromCache(self->mmsServer, domain, dataSetEntry->variableName);
strncpy(domainName, self->model->name, 64);
strncat(domainName, dataSetEntry->logicalDeviceName, 64 - iedNameLength);
if (value == NULL) {
if (DEBUG_IED_SERVER) {
printf("LD: %s dataset: %s : error cannot get value from cache for %s -> %s!\n",
dataSet->logicalDeviceName, dataSet->name,
dataSetEntry->logicalDeviceName,
dataSetEntry->variableName);
MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, domainName);
MmsValue* value = MmsServer_getValueFromCache(self->mmsServer, domain, dataSetEntry->variableName);
if (value == NULL) {
if (DEBUG_IED_SERVER) {
printf("LD: %s dataset: %s : error cannot get value from cache for %s -> %s!\n",
dataSet->logicalDeviceName, dataSet->name,
dataSetEntry->logicalDeviceName,
dataSetEntry->variableName);
}
}
else
dataSetEntry->value = value;
dataSetEntry = dataSetEntry->sibling;
}
else
dataSetEntry->value = value;
dataSetEntry = dataSetEntry->sibling;
dataSet = dataSet->sibling;
}
dataSet = dataSet->sibling;
}
}
@ -1094,6 +1099,7 @@ IedServer_getFunctionalConstrainedData(IedServer self, DataObject* dataObject, F
char buffer[128]; /* buffer for variable name string */
char* currentStart = buffer + 127;
currentStart[0] = 0;
MmsValue* value = NULL;
int nameLen;
@ -1130,13 +1136,20 @@ IedServer_getFunctionalConstrainedData(IedServer self, DataObject* dataObject, F
char domainName[65];
if ((strlen(self->model->name) + strlen(ld->name)) > 64)
goto exit_function; // TODO call exception handler!
strncpy(domainName, self->model->name, 64);
strncat(domainName, ld->name, 64);
MmsDomain* domain = MmsDevice_getDomain(self->mmsDevice, domainName);
MmsValue* value = MmsServer_getValueFromCache(self->mmsServer, domain, currentStart);
if (domain == NULL)
goto exit_function; // TODO call exception handler!
value = MmsServer_getValueFromCache(self->mmsServer, domain, currentStart);
exit_function:
return value;
}
@ -1214,3 +1227,10 @@ private_IedServer_removeClientConnection(IedServer self, ClientConnection client
}
void
IedServer_setGooseInterfaceId(IedServer self, const char* interfaceId)
{
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
self->mmsMapping->gooseInterfaceId = interfaceId;
#endif
}

View file

@ -23,7 +23,7 @@
#include "stack_config.h"
#if CONFIG_INCLUDE_GOOSE_SUPPORT == 1
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
#include "libiec61850_platform_includes.h"
#include "mms_mapping.h"
@ -221,7 +221,7 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self)
memcpy(commParameters.dstAddress, MmsValue_getOctetStringBuffer(macAddress), 6);
self->publisher = GoosePublisher_create(&commParameters, NULL);
self->publisher = GoosePublisher_create(&commParameters, self->mmsMapping->gooseInterfaceId);
GoosePublisher_setTimeAllowedToLive(self->publisher, CONFIG_GOOSE_STABLE_STATE_TRANSMISSION_INTERVAL * 3);

View file

@ -990,12 +990,21 @@ createNamedVariableFromLogicalNode(MmsMapping* self, MmsDomain* domain,
static MmsDomain*
createMmsDomainFromIedDevice(MmsMapping* self, LogicalDevice* logicalDevice)
{
MmsDomain* domain = NULL;
char domainName[65];
strncpy(domainName, self->model->name, 64);
strncat(domainName, logicalDevice->name, 64);
int modelNameLength = strlen(self->model->name);
MmsDomain* domain = MmsDomain_create(domainName);
if (modelNameLength > 64)
goto exit_function;
strncpy(domainName, self->model->name, 64);
strncat(domainName, logicalDevice->name, 64 - modelNameLength);
domain = MmsDomain_create(domainName);
if (domain == NULL)
goto exit_function;
int nodesCount = LogicalDevice_getLogicalNodeCount(logicalDevice);
@ -1014,6 +1023,7 @@ createMmsDomainFromIedDevice(MmsMapping* self, LogicalDevice* logicalDevice)
i++;
}
exit_function:
return domain;
}
@ -1042,12 +1052,20 @@ createDataSets(MmsDevice* mmsDevice, IedModel* iedModel)
char domainName[65];
int iedModelNameLength = strlen(iedModel->name);
if (iedModelNameLength > 64)
goto exit_function; //TODO call exception handler!
while (dataset != NULL) {
strncpy(domainName, iedModel->name, 64);
strncat(domainName, dataset->logicalDeviceName, 64);
strncat(domainName, dataset->logicalDeviceName, 64 - iedModelNameLength);
MmsDomain* dataSetDomain = MmsDevice_getDomain(mmsDevice, domainName);
if (dataSetDomain == NULL)
goto exit_function; //TODO call exception handler!
MmsNamedVariableList varList = MmsNamedVariableList_create(dataSetDomain, dataset->name, false);
DataSetEntry* dataSetEntry = dataset->fcdas;
@ -1057,7 +1075,7 @@ createDataSets(MmsDevice* mmsDevice, IedModel* iedModel)
MmsAccessSpecifier accessSpecifier;
strncpy(domainName, iedModel->name, 64);
strncat(domainName, dataSetEntry->logicalDeviceName, 64);
strncat(domainName, dataSetEntry->logicalDeviceName, 64 - iedModelNameLength);
accessSpecifier.domain = MmsDevice_getDomain(mmsDevice, domainName);
@ -1077,6 +1095,9 @@ createDataSets(MmsDevice* mmsDevice, IedModel* iedModel)
dataset = dataset->sibling;
}
exit_function:
return;
}
static MmsDevice*
@ -1111,6 +1132,7 @@ MmsMapping_create(IedModel* model)
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
self->gseControls = LinkedList_create();
self->gooseInterfaceId = NULL;
#endif
#if (CONFIG_IEC61850_CONTROL_SERVICE == 1)

View file

@ -29,14 +29,7 @@
#include "mms_access_result.h"
#include "conversions.h"
#define DEFAULT_MAX_SERV_OUTSTANDING_CALLING 5
#define DEFAULT_MAX_SERV_OUTSTANDING_CALLED 5
#define DEFAULT_DATA_STRUCTURE_NESTING_LEVEL 10
typedef enum
{
MMS_ERROR, MMS_INITIATE, MMS_CONFIRMED_REQUEST, MMS_OK, MMS_CONCLUDE
} MmsIndication;
MmsValue*

View file

@ -31,7 +31,7 @@
#include "libiec61850_platform_includes.h"
#include "mms_common.h"
#include "mms_common_internal.h"
#include "mms_indication.h"
#include "mms_device_model.h"
#include "mms_value.h"
#include "mms_server.h"

View file

@ -28,12 +28,14 @@
#include <MmsPdu.h>
#include "mms_common.h"
#include "mms_indication.h"
#include "mms_server_connection.h"
#include "mms_device_model.h"
#include "mms_common_internal.h"
#include "stack_config.h"
#include "mms_server.h"
#include "byte_buffer.h"
#include "string_utilities.h"
#include "map.h"

View file

@ -282,10 +282,7 @@ IsoClientConnection_associate(IsoClientConnection self, IsoConnectionParameters
AcseConnection_init(&(self->acseConnection), NULL, NULL);
AcseAuthenticationParameter authParameter = NULL;
if (params != NULL)
authParameter = params->acseAuthParameter;
AcseAuthenticationParameter authParameter = params->acseAuthParameter;
struct sBufferChain sAcseBuffer;
BufferChain acseBuffer = &sAcseBuffer;

View file

@ -24,6 +24,7 @@
#include <MmsPdu.h>
#include "mms_common.h"
#include "mms_common_internal.h"
#include "mms_indication.h"
#include "mms_client_connection.h"
#include "byte_buffer.h"

View file

@ -485,4 +485,4 @@ EXPORTS
IedServer_updateTimestampAttributeValue
MmsValue_getUtcTimeBuffer
Timestamp_clearFlags
IedServer_setGooseInterfaceId

View file

@ -509,4 +509,4 @@ EXPORTS
IedServer_updateTimestampAttributeValue
MmsValue_getUtcTimeBuffer
Timestamp_clearFlags
IedServer_setGooseInterfaceId