- added function LogicalNode_getDataSet

This commit is contained in:
Michael Zillgith 2015-07-20 10:37:40 +02:00
parent 7eeac08551
commit bbccffb65a
12 changed files with 112 additions and 34 deletions

View file

@ -10,7 +10,7 @@
#define STACK_CONFIG_H_
/* include asserts if set to 1 */
#define DEBUG 1
#define DEBUG 0
/* print debugging information with printf if set to 1 */
#define DEBUG_SOCKET 0
@ -21,7 +21,7 @@
#define DEBUG_IED_CLIENT 0
#define DEBUG_MMS_CLIENT 0
#define DEBUG_MMS_SERVER 0
#define DEBUG_GOOSE_SUBSCRIBER 1
#define DEBUG_GOOSE_SUBSCRIBER 0
#define DEBUG_GOOSE_PUBLISHER 0
/* Maximum MMS PDU SIZE - default is 65000 */
@ -136,7 +136,7 @@
#define CONFIG_IEC61850_SETTING_GROUPS 1
/* default reservation time of a setting group control block in s */
#define CONFIG_IEC61850_SG_RESVTMS 10
#define CONFIG_IEC61850_SG_RESVTMS 300
/* default results for MMS identify service */
#define CONFIG_DEFAULT_MMS_VENDOR_NAME "libiec61850.com"

View file

@ -376,6 +376,11 @@ GoosePublisher_publish(GoosePublisher self, LinkedList dataSet)
if (DEBUG_GOOSE_PUBLISHER)
printf("GOOSE_PUBLISHER: send GOOSE message\n");
struct timeval tv;
gettimeofday(&tv,NULL/*&tz*/);
printf("GOOSE SEND: %ld %ld\n",tv.tv_sec, tv.tv_usec);
Ethernet_sendPacket(self->ethernetSocket, self->buffer, self->payloadStart + payloadLength);
return 0;

View file

@ -612,6 +612,13 @@ exit_with_fault:
static void
parseGooseMessage(GooseReceiver self, int numbytes)
{
struct timeval tv;
gettimeofday(&tv,NULL/*&tz*/);
printf("RCVD GOOSE: %ld %ld\n",tv.tv_sec, tv.tv_usec);
int bufPos;
bool subscriberFound = false;
uint8_t* buffer = self->buffer;

View file

@ -416,6 +416,17 @@ LogicalNode_hasBufferedReports(LogicalNode* node);
bool
LogicalNode_hasUnbufferedReports(LogicalNode* node);
/**
* \brief get a data set instance
*
* \param self the logical node instance of the data set
* \param dataSetName the name of the data set
*
* \return the data set instance or NULL if the data set does not exist
*/
DataSet*
LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName);
bool
DataObject_hasFCData(DataObject* dataObject, FunctionalConstraint fc);

View file

@ -960,11 +960,12 @@ IedServer_observeDataAttribute(IedServer self, DataAttribute* dataAttribute,
* \param the data attribute that has been written by an MMS client.
* \param the value the client want to write to the data attribute
* \param connection the connection object of the client connection that invoked the write operation
* \param parameter the user provided parameter
*
* \return true if access is accepted, false if access is denied.
*/
typedef MmsDataAccessError
(*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection);
(*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter);
/**
* \brief Install a WriteAccessHandler for a data attribute.
@ -979,10 +980,11 @@ typedef MmsDataAccessError
* \param dataAttribute the data attribute to monitor
* \param handler the callback function that is invoked if a client tries to write to
* the monitored data attribute.
* \param parameter a user provided parameter that is passed to the WriteAccessHandler when called.
*/
void
IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute,
WriteAccessHandler handler);
WriteAccessHandler handler, void* parameter);
typedef enum {
ACCESS_POLICY_ALLOW,

View file

@ -139,7 +139,7 @@ void
MmsMapping_setConnectionIndicationHandler(MmsMapping* self, IedConnectionIndicationHandler handler, void* parameter);
void
MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler);
MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter);
MmsDataAccessError
Control_writeAccessControlObject(MmsMapping* self, MmsDomain* domain, char* variableIdOrig,

View file

@ -476,7 +476,7 @@ singleThreadedServerThread(void* parameter)
while (running) {
if (IedServer_waitReady(self, 100) > 0) {
if (IedServer_waitReady(self, 25) > 0) {
MmsServer_handleIncomingMessages(self->mmsServer);
IedServer_performPeriodicTasks(self);
}
@ -770,26 +770,26 @@ checkForChangedTriggers(IedServer self, DataAttribute* dataAttribute)
#if (CONFIG_IEC61850_REPORT_SERVICE == 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
if (dataAttribute->triggerOptions & TRG_OPT_DATA_CHANGED) {
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue);
#endif
#if (CONFIG_IEC61850_REPORT_SERVICE == 1)
MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue,
REPORT_CONTROL_VALUE_CHANGED);
#endif
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue);
#endif
}
else if (dataAttribute->triggerOptions & TRG_OPT_QUALITY_CHANGED) {
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue);
#endif
#if (CONFIG_IEC61850_REPORT_SERVICE == 1)
MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue,
REPORT_CONTROL_QUALITY_CHANGED);
#endif
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue);
#endif
}
#endif /* (CONFIG_IEC61850_REPORT_SERVICE== 1) || (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */
@ -916,9 +916,16 @@ IedServer_updateBooleanAttributeValue(IedServer self, DataAttribute* dataAttribu
bool currentValue = MmsValue_getBoolean(dataAttribute->mmsValue);
if (currentValue == value) {
checkForUpdateTrigger(self, dataAttribute);
}
else {
// struct timeval tv;
//
// gettimeofday(&tv,NULL/*&tz*/);
// printf("UPDATE BOOL: %ld %ld\n",tv.tv_sec, tv.tv_usec);
MmsValue_setBoolean(dataAttribute->mmsValue, value);
checkForChangedTriggers(self, dataAttribute);
@ -993,15 +1000,15 @@ IedServer_updateQuality(IedServer self, DataAttribute* dataAttribute, Quality qu
if (oldQuality != (uint32_t) quality) {
MmsValue_setBitStringFromInteger(dataAttribute->mmsValue, (uint32_t) quality);
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue);
#endif
#if (CONFIG_IEC61850_REPORT_SERVICE == 1)
if (dataAttribute->triggerOptions & TRG_OPT_QUALITY_CHANGED)
MmsMapping_triggerReportObservers(self->mmsMapping, dataAttribute->mmsValue,
REPORT_CONTROL_QUALITY_CHANGED);
#endif
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
MmsMapping_triggerGooseObservers(self->mmsMapping, dataAttribute->mmsValue);
#endif
}
@ -1079,12 +1086,12 @@ IedServer_setWriteAccessPolicy(IedServer self, FunctionalConstraint fc, AccessPo
}
void
IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, WriteAccessHandler handler)
IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter)
{
if (dataAttribute == NULL)
*((int*) NULL) = 1;
MmsMapping_installWriteAccessHandler(self->mmsMapping, dataAttribute, handler);
MmsMapping_installWriteAccessHandler(self->mmsMapping, dataAttribute, handler, parameter);
}
void

View file

@ -169,7 +169,6 @@ MmsGooseControlBlock_enable(MmsGooseControlBlock self)
if (!MmsGooseControlBlock_isEnabled(self)) {
if (self->dataSetRef != NULL) {
GLOBAL_FREEMEM(self->dataSetRef);

View file

@ -50,6 +50,7 @@ typedef struct
{
DataAttribute* attribute;
WriteAccessHandler handler;
void* parameter;
} AttributeAccessHandler;
@ -1759,6 +1760,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
sg->editSgConfirmedHandler(sg->editSgConfirmedHandlerParameter, sg->sgcb,
sg->sgcb->editSG);
unselectSettingGroup(sg);
return DATA_ACCESS_ERROR_SUCCESS;
}
else
@ -1826,7 +1829,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
if (matchingValue != NULL) {
MmsDataAccessError handlerResult =
accessHandler->handler(dataAttribute, matchingValue, (ClientConnection) connection);
accessHandler->handler(dataAttribute, matchingValue, (ClientConnection) connection,
accessHandler->parameter);
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS)
handlerFound = true;
@ -1838,8 +1842,8 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
else { /* if ACCESS_POLICY_DENY only allow direct access to handled data attribute */
if (dataAttribute->mmsValue == cachedValue) {
MmsDataAccessError handlerResult =
accessHandler->handler(dataAttribute, value, (ClientConnection) connection);
accessHandler->handler(dataAttribute, value, (ClientConnection) connection,
accessHandler->parameter);
if (handlerResult == DATA_ACCESS_ERROR_SUCCESS) {
handlerFound = true;
@ -1923,7 +1927,7 @@ getAccessHandlerForAttribute(MmsMapping* self, DataAttribute* dataAttribute)
}
void
MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler)
MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttribute, WriteAccessHandler handler, void* parameter)
{
AttributeAccessHandler* accessHandler = getAccessHandlerForAttribute(self, dataAttribute);
@ -1931,6 +1935,7 @@ MmsMapping_installWriteAccessHandler(MmsMapping* self, DataAttribute* dataAttrib
accessHandler = (AttributeAccessHandler*) GLOBAL_MALLOC(sizeof(AttributeAccessHandler));
accessHandler->attribute = dataAttribute;
accessHandler->parameter = parameter;
LinkedList_add(self->attributeAccessHandlers, (void*) accessHandler);
}

View file

@ -345,6 +345,46 @@ LogicalNode_hasFCData(LogicalNode* node, FunctionalConstraint fc)
return false;
}
DataSet*
LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName)
{
assert(self->modelType == LogicalNodeModelType);
assert(dataSetName != NULL);
char dsName[66];
LogicalDevice* ld = (LogicalDevice*) self->parent;
if (strlen(dataSetName) > 32) {
if (DEBUG_IED_SERVER) {
printf("IED_SERVER: LogicalNode_getDataSet - data set name %s too long!\n", dataSetName);
}
goto exit_error;
}
StringUtils_createStringInBuffer(dsName, 3, self->name, "$", dataSetName);
IedModel* iedModel = (IedModel*) ld->parent;
DataSet* ds = iedModel->dataSets;
while (ds != NULL) {
if (strcmp(ds->logicalDeviceName, ld->name) == 0) {
if (strcmp(ds->name, dsName) == 0) {
return ds;
}
}
ds = ds->sibling;
}
exit_error:
return NULL;
}
int
LogicalDevice_getLogicalNodeCount(LogicalDevice* logicalDevice)
{

View file

@ -103,12 +103,19 @@ encodeStructuredAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool
int
mmsServer_encodeAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool encode)
{
if (value == NULL) // TODO report internal error
return 0;
// if (value == NULL) // TODO report internal error
// return 0;
int size;
switch (value->type) {
case MMS_BOOLEAN:
if (encode)
bufPos = BerEncoder_encodeBoolean(0x83, value->value.boolean, buffer, bufPos);
else
size = 3;
break;
case MMS_STRUCTURE:
if (encode)
bufPos = encodeStructuredAccessResult(value, buffer, bufPos, true);
@ -166,12 +173,7 @@ mmsServer_encodeAccessResult(MmsValue* value, uint8_t* buffer, int bufPos, bool
else
size = BerEncoder_determineEncodedBitStringSize(value->value.bitString.size);
break;
case MMS_BOOLEAN:
if (encode)
bufPos = BerEncoder_encodeBoolean(0x83, value->value.boolean, buffer, bufPos);
else
size = 3;
break;
case MMS_BINARY_TIME:
if (encode)
bufPos = BerEncoder_encodeOctetString(0x8c, value->value.binaryTime.buf,

Binary file not shown.