- code format changes

- IED server: added function IedServer_ignoreReadAccess
pull/515/head
Michael Zillgith 1 year ago
parent 569c4a5c20
commit 5c3fd679a8

@ -528,39 +528,44 @@ readObjectHandlerInternal(uint32_t invokeId, void* parameter, MmsError err, MmsV
IedConnectionOutstandingCall call = iedConnection_lookupOutstandingCall(self, invokeId); IedConnectionOutstandingCall call = iedConnection_lookupOutstandingCall(self, invokeId);
if (call) { if (call)
{
IedConnection_GetRCBValuesHandler handler = (IedConnection_GetRCBValuesHandler) call->callback; IedConnection_GetRCBValuesHandler handler = (IedConnection_GetRCBValuesHandler) call->callback;
ClientReportControlBlock updateRcb = (ClientReportControlBlock) call->specificParameter; ClientReportControlBlock updateRcb = (ClientReportControlBlock) call->specificParameter;
char* rcbReference = (char*) call->specificParameter2.pointer; char* rcbReference = (char*) call->specificParameter2.pointer;
if (err != MMS_ERROR_NONE)
if (err != MMS_ERROR_NONE) { {
handler(invokeId, call->callbackParameter, iedConnection_mapMmsErrorToIedError(err), NULL); handler(invokeId, call->callbackParameter, iedConnection_mapMmsErrorToIedError(err), NULL);
} }
else { else
{
if (value == NULL) { if (value == NULL)
{
handler(invokeId, call->callbackParameter, IED_ERROR_OBJECT_DOES_NOT_EXIST, NULL); handler(invokeId, call->callbackParameter, IED_ERROR_OBJECT_DOES_NOT_EXIST, NULL);
} }
else { else
if (MmsValue_getType(value) == MMS_DATA_ACCESS_ERROR) { {
if (MmsValue_getType(value) == MMS_DATA_ACCESS_ERROR)
{
if (DEBUG_IED_CLIENT) if (DEBUG_IED_CLIENT)
printf("DEBUG_IED_CLIENT: getRCBValues returned data-access-error!\n"); printf("DEBUG_IED_CLIENT: getRCBValues returned data-access-error!\n");
handler(invokeId, call->callbackParameter, iedConnection_mapDataAccessErrorToIedError(MmsValue_getDataAccessError(value)), NULL); handler(invokeId, call->callbackParameter, iedConnection_mapDataAccessErrorToIedError(MmsValue_getDataAccessError(value)), NULL);
} }
else { else
{
ClientReportControlBlock returnRcb = updateRcb; ClientReportControlBlock returnRcb = updateRcb;
if (returnRcb == NULL) if (returnRcb == NULL)
returnRcb = ClientReportControlBlock_create(rcbReference); returnRcb = ClientReportControlBlock_create(rcbReference);
if (clientReportControlBlock_updateValues(returnRcb, value)) { if (clientReportControlBlock_updateValues(returnRcb, value))
{
handler(invokeId, call->callbackParameter, IED_ERROR_OK, returnRcb); handler(invokeId, call->callbackParameter, IED_ERROR_OK, returnRcb);
} }
else { else
{
if (DEBUG_IED_CLIENT) if (DEBUG_IED_CLIENT)
printf("DEBUG_IED_CLIENT: getRCBValues returned wrong type!\n"); printf("DEBUG_IED_CLIENT: getRCBValues returned wrong type!\n");
@ -569,19 +574,18 @@ readObjectHandlerInternal(uint32_t invokeId, void* parameter, MmsError err, MmsV
if (updateRcb == NULL) if (updateRcb == NULL)
ClientReportControlBlock_destroy(returnRcb); ClientReportControlBlock_destroy(returnRcb);
} }
} }
MmsValue_delete(value); MmsValue_delete(value);
} }
} }
GLOBAL_FREEMEM(rcbReference); GLOBAL_FREEMEM(rcbReference);
iedConnection_releaseOutstandingCall(self, call); iedConnection_releaseOutstandingCall(self, call);
} }
else { else
{
if (DEBUG_IED_CLIENT) if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: internal error - no matching outstanding call!\n"); printf("IED_CLIENT: internal error - no matching outstanding call!\n");
} }
@ -598,7 +602,8 @@ IedConnection_getRCBValuesAsync(IedConnection self, IedClientError* error, const
char* domainName = MmsMapping_getMmsDomainFromObjectReference(rcbReference, domainId); char* domainName = MmsMapping_getMmsDomainFromObjectReference(rcbReference, domainId);
if (domainName == NULL) { if (domainName == NULL)
{
*error = IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT; *error = IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT;
return 0; return 0;
} }
@ -608,7 +613,8 @@ IedConnection_getRCBValuesAsync(IedConnection self, IedClientError* error, const
IedConnectionOutstandingCall call = iedConnection_allocateOutstandingCall(self); IedConnectionOutstandingCall call = iedConnection_allocateOutstandingCall(self);
if (call == NULL) { if (call == NULL)
{
*error = IED_ERROR_OUTSTANDING_CALL_LIMIT_REACHED; *error = IED_ERROR_OUTSTANDING_CALL_LIMIT_REACHED;
return 0; return 0;
} }
@ -627,7 +633,8 @@ IedConnection_getRCBValuesAsync(IedConnection self, IedClientError* error, const
*error = iedConnection_mapMmsErrorToIedError(err); *error = iedConnection_mapMmsErrorToIedError(err);
if (err != MMS_ERROR_NONE) { if (err != MMS_ERROR_NONE)
{
GLOBAL_FREEMEM(call->specificParameter2.pointer); GLOBAL_FREEMEM(call->specificParameter2.pointer);
iedConnection_releaseOutstandingCall(self, call); iedConnection_releaseOutstandingCall(self, call);
return 0; return 0;

File diff suppressed because it is too large Load Diff

@ -2010,6 +2010,15 @@ typedef bool
LIB61850_API void LIB61850_API void
IedServer_setControlBlockAccessHandler(IedServer self, IedServer_ControlBlockAccessHandler handler, void* parameter); IedServer_setControlBlockAccessHandler(IedServer self, IedServer_ControlBlockAccessHandler handler, void* parameter);
/**
* \brief Temporarily ignore read requests (for testing purposes)
*
* \param self the instance of IedServer to operate on.
* \param ignore true to ignore read requests, false to handle read requests.
*/
LIB61850_API void
IedServer_ingoreReadAccess(IedServer self, bool ignore);
/**@}*/ /**@}*/
/**@}*/ /**@}*/

@ -1,7 +1,7 @@
/* /*
* ied_connection_private.h * ied_connection_private.h
* *
* Copyright 2013-2022 Michael Zillgith * Copyright 2013-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -34,14 +34,16 @@
typedef struct sIedConnectionOutstandingCall* IedConnectionOutstandingCall; typedef struct sIedConnectionOutstandingCall* IedConnectionOutstandingCall;
struct sIedConnectionOutstandingCall { struct sIedConnectionOutstandingCall
{
bool used; bool used;
uint32_t invokeId; uint32_t invokeId;
void* callback; void* callback;
void* callbackParameter; void* callbackParameter;
void* specificParameter; /* function/service specific parameter */ void* specificParameter; /* function/service specific parameter */
union { union
{
void* pointer; void* pointer;
struct { struct {
uint32_t originalInvokeId; uint32_t originalInvokeId;
@ -81,7 +83,8 @@ struct sIedConnection
uint8_t timeQuality; uint8_t timeQuality;
}; };
struct sClientReportControlBlock { struct sClientReportControlBlock
{
char* objectReference; char* objectReference;
bool isBuffered; bool isBuffered;

@ -81,10 +81,11 @@ struct sIedServer
uint8_t timeQuality; /* user settable time quality for internally updated times */ uint8_t timeQuality; /* user settable time quality for internally updated times */
bool ignoreReadAccess; /* when true don't answer read request (for test purposes) */
bool running; bool running;
}; };
LIB61850_INTERNAL IEC61850_ServiceError LIB61850_INTERNAL IEC61850_ServiceError
private_IedServer_convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError); private_IedServer_convertMmsDataAccessErrorToServiceError(MmsDataAccessError mmsError);

@ -1,7 +1,7 @@
/* /*
* client_connection.c * client_connection.c
* *
* Copyright 2013-2022 Michael Zillgith * Copyright 2013-2024 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -32,8 +32,8 @@
#include "libiec61850_platform_includes.h" #include "libiec61850_platform_includes.h"
struct sClientConnection { struct sClientConnection
{
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore tasksCountMutex; Semaphore tasksCountMutex;
#endif #endif
@ -47,7 +47,8 @@ private_ClientConnection_create(void* serverConnectionHandle)
{ {
ClientConnection self = (ClientConnection) GLOBAL_MALLOC(sizeof(struct sClientConnection)); ClientConnection self = (ClientConnection) GLOBAL_MALLOC(sizeof(struct sClientConnection));
if (self) { if (self)
{
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
self->tasksCountMutex = Semaphore_create(1); self->tasksCountMutex = Semaphore_create(1);
#endif #endif
@ -62,7 +63,8 @@ private_ClientConnection_create(void* serverConnectionHandle)
void void
private_ClientConnection_destroy(ClientConnection self) private_ClientConnection_destroy(ClientConnection self)
{ {
if (self) { if (self)
{
#if (CONFIG_MMS_THREADLESS_STACK != 1) #if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore_destroy(self->tasksCountMutex); Semaphore_destroy(self->tasksCountMutex);
#endif #endif
@ -123,7 +125,6 @@ private_ClientConnection_getServerConnectionHandle(ClientConnection self)
return self->serverConnectionHandle; return self->serverConnectionHandle;
} }
const char* const char*
ClientConnection_getPeerAddress(ClientConnection self) ClientConnection_getPeerAddress(ClientConnection self)
{ {

@ -540,17 +540,18 @@ updateDataSetsWithCachedValues(IedServer self)
} }
} }
IedServer IedServer
IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguration, IedServerConfig serverConfiguration) IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguration, IedServerConfig serverConfiguration)
{ {
IedServer self = (IedServer) GLOBAL_CALLOC(1, sizeof(struct sIedServer)); IedServer self = (IedServer) GLOBAL_CALLOC(1, sizeof(struct sIedServer));
if (self) { if (self)
{
self->model = dataModel; self->model = dataModel;
self->running = false; self->running = false;
self->localIpAddress = NULL; self->localIpAddress = NULL;
self->ignoreReadAccess = false;
#if (CONFIG_IEC61850_EDITION_1 == 1) #if (CONFIG_IEC61850_EDITION_1 == 1)
self->edition = IEC_61850_EDITION_1; self->edition = IEC_61850_EDITION_1;
@ -561,7 +562,8 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
self->logServiceEnabled = true; self->logServiceEnabled = true;
if (serverConfiguration) { if (serverConfiguration)
{
self->logServiceEnabled = serverConfiguration->enableLogService; self->logServiceEnabled = serverConfiguration->enableLogService;
self->edition = serverConfiguration->edition; self->edition = serverConfiguration->edition;
} }
@ -574,7 +576,8 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
#endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */ #endif /* (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) */
#if (CONFIG_IEC61850_REPORT_SERVICE == 1) #if (CONFIG_IEC61850_REPORT_SERVICE == 1)
if (serverConfiguration) { if (serverConfiguration)
{
self->reportBufferSizeBRCBs = serverConfiguration->reportBufferSize; self->reportBufferSizeBRCBs = serverConfiguration->reportBufferSize;
self->reportBufferSizeURCBs = serverConfiguration->reportBufferSizeURCBs; self->reportBufferSizeURCBs = serverConfiguration->reportBufferSizeURCBs;
self->enableBRCBResvTms = serverConfiguration->enableResvTmsForBRCB; self->enableBRCBResvTms = serverConfiguration->enableResvTmsForBRCB;
@ -582,7 +585,8 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
self->syncIntegrityReportTimes = serverConfiguration->syncIntegrityReportTimes; self->syncIntegrityReportTimes = serverConfiguration->syncIntegrityReportTimes;
self->rcbSettingsWritable = serverConfiguration->reportSettingsWritable; self->rcbSettingsWritable = serverConfiguration->reportSettingsWritable;
} }
else { else
{
self->reportBufferSizeBRCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE; self->reportBufferSizeBRCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->reportBufferSizeURCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE; self->reportBufferSizeURCBs = CONFIG_REPORTING_DEFAULT_REPORT_BUFFER_SIZE;
self->enableOwnerForRCB = false; self->enableOwnerForRCB = false;
@ -602,11 +606,13 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
#endif #endif
#if (CONFIG_IEC61850_SETTING_GROUPS == 1) #if (CONFIG_IEC61850_SETTING_GROUPS == 1)
if (serverConfiguration) { if (serverConfiguration)
{
self->enableEditSG = serverConfiguration->enableEditSG; self->enableEditSG = serverConfiguration->enableEditSG;
self->hasSGCBResvTms = serverConfiguration->enableResvTmsForSGCB; self->hasSGCBResvTms = serverConfiguration->enableResvTmsForSGCB;
} }
else { else
{
self->enableEditSG = true; self->enableEditSG = true;
self->hasSGCBResvTms = true; self->hasSGCBResvTms = true;
} }
@ -614,14 +620,15 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
self->mmsMapping = MmsMapping_create(dataModel, self); self->mmsMapping = MmsMapping_create(dataModel, self);
if (self->mmsMapping) { if (self->mmsMapping)
{
self->mmsDevice = MmsMapping_getMmsDeviceModel(self->mmsMapping); self->mmsDevice = MmsMapping_getMmsDeviceModel(self->mmsMapping);
self->mmsServer = MmsServer_create(self->mmsDevice, tlsConfiguration); self->mmsServer = MmsServer_create(self->mmsDevice, tlsConfiguration);
#if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1) #if (CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME == 1)
if (serverConfiguration) { if (serverConfiguration)
{
MmsServer_enableFileService(self->mmsServer, serverConfiguration->enableFileService); MmsServer_enableFileService(self->mmsServer, serverConfiguration->enableFileService);
MmsServer_enableDynamicNamedVariableListService(self->mmsServer, serverConfiguration->enableDynamicDataSetService); MmsServer_enableDynamicNamedVariableListService(self->mmsServer, serverConfiguration->enableDynamicDataSetService);
MmsServer_setMaxAssociationSpecificDataSets(self->mmsServer, serverConfiguration->maxAssociationSpecificDataSets); MmsServer_setMaxAssociationSpecificDataSets(self->mmsServer, serverConfiguration->maxAssociationSpecificDataSets);
@ -668,7 +675,8 @@ IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguratio
IedServer_setTimeQuality(self, true, false, false, 10); IedServer_setTimeQuality(self, true, false, false, 10);
} }
else { else
{
IedServer_destroy(self); IedServer_destroy(self);
self = NULL; self = NULL;
} }
@ -1992,3 +2000,9 @@ IedServer_setControlBlockAccessHandler(IedServer self, IedServer_ControlBlockAcc
self->mmsMapping->controlBlockAccessHandler = handler; self->mmsMapping->controlBlockAccessHandler = handler;
self->mmsMapping->controlBlockAccessHandlerParameter = parameter; self->mmsMapping->controlBlockAccessHandlerParameter = parameter;
} }
void
IedServer_ingoreReadAccess(IedServer self, bool ignore)
{
self->ignoreReadAccess = ignore;
}

File diff suppressed because it is too large Load Diff

@ -3186,7 +3186,6 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo
} }
#endif #endif
#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) #if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1)
/* GOOSE control blocks - GO */ /* GOOSE control blocks - GO */
if (isGooseControlBlock(separator)) { if (isGooseControlBlock(separator)) {
@ -3213,8 +3212,8 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo
#if (CONFIG_IEC61850_REPORT_SERVICE == 1) #if (CONFIG_IEC61850_REPORT_SERVICE == 1)
/* Report control blocks - BR, RP */ /* Report control blocks - BR, RP */
if (isReportControlBlock(separator)) { if (isReportControlBlock(separator))
{
LinkedList reportControls = self->reportControls; LinkedList reportControls = self->reportControls;
LinkedList nextElement = reportControls; LinkedList nextElement = reportControls;
@ -3235,11 +3234,12 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo
else else
variableIdLen = strlen(variableId); variableIdLen = strlen(variableId);
while ((nextElement = LinkedList_getNext(nextElement)) != NULL) { while ((nextElement = LinkedList_getNext(nextElement)) != NULL)
{
ReportControl* rc = (ReportControl*) nextElement->data; ReportControl* rc = (ReportControl*) nextElement->data;
if (rc->domain == domain) { if (rc->domain == domain)
{
int parentLNNameStrLen = strlen(rc->parentLN->name); int parentLNNameStrLen = strlen(rc->parentLN->name);
if (parentLNNameStrLen != lnNameLength) if (parentLNNameStrLen != lnNameLength)
@ -3248,7 +3248,8 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo
if (memcmp(rc->parentLN->name, variableId, parentLNNameStrLen) != 0) if (memcmp(rc->parentLN->name, variableId, parentLNNameStrLen) != 0)
continue; continue;
if (strlen(rc->name) == variableIdLen) { if (strlen(rc->name) == variableIdLen)
{
if (strncmp(variableId, rc->name, variableIdLen) == 0) if (strncmp(variableId, rc->name, variableIdLen) == 0)
{ {
char* elementName = MmsMapping_getNextNameElement(reportName); char* elementName = MmsMapping_getNextNameElement(reportName);
@ -3665,15 +3666,26 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
if (DEBUG_IED_SERVER) if (DEBUG_IED_SERVER)
printf("IED_SERVER: mmsReadAccessHandler: Requested %s\n", variableId); printf("IED_SERVER: mmsReadAccessHandler: Requested %s\n", variableId);
if (self->iedServer->ignoreReadAccess)
{
if (DEBUG_IED_SERVER)
printf("IED_SERVER: mmsReadAccessHandler - ignore request\n");
return DATA_ACCESS_ERROR_NO_RESPONSE;
}
char* separator = strchr(variableId, '$'); char* separator = strchr(variableId, '$');
#if (CONFIG_IEC61850_SETTING_GROUPS == 1) #if (CONFIG_IEC61850_SETTING_GROUPS == 1)
if (separator) { if (separator)
if (isFunctionalConstraint("SE", separator)) { {
if (isFunctionalConstraint("SE", separator))
{
SettingGroup* sg = getSettingGroupByMmsDomain(self, domain); SettingGroup* sg = getSettingGroupByMmsDomain(self, domain);
if (sg != NULL) { if (sg != NULL)
{
if (sg->sgcb->editSG == 0) if (sg->sgcb->editSG == 0)
return DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE; return DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE;
} }
@ -3695,7 +3707,8 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
{ {
FunctionalConstraint fc = IEC61850_FC_NONE; FunctionalConstraint fc = IEC61850_FC_NONE;
if (separator != NULL) { if (separator != NULL)
{
fc = FunctionalConstraint_fromString(separator + 1); fc = FunctionalConstraint_fromString(separator + 1);
if (fc == IEC61850_FC_BR || fc == IEC61850_FC_US || if (fc == IEC61850_FC_BR || fc == IEC61850_FC_US ||
@ -3716,23 +3729,27 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
{ {
char* doStart = strchr(separator + 1, '$'); char* doStart = strchr(separator + 1, '$');
if (doStart != NULL) { if (doStart != NULL)
{
char* doEnd = strchr(doStart + 1, '$'); char* doEnd = strchr(doStart + 1, '$');
if (doEnd == NULL) { if (doEnd == NULL)
{
StringUtils_copyStringToBuffer(doStart + 1, str); StringUtils_copyStringToBuffer(doStart + 1, str);
} }
else { else
{
doEnd--; doEnd--;
StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) (doStart + 1), doEnd - doStart); StringUtils_createStringFromBufferInBuffer(str, (uint8_t*) (doStart + 1), doEnd - doStart);
} }
if (fc == IEC61850_FC_SP) { if (fc == IEC61850_FC_SP)
{
if (!strcmp(str, "SGCB")) if (!strcmp(str, "SGCB"))
{ {
if (self->controlBlockAccessHandler) { if (self->controlBlockAccessHandler)
{
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer,
connection); connection);
@ -3747,10 +3764,10 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
ModelNode* dobj = ModelNode_getChild((ModelNode*) ln, str); ModelNode* dobj = ModelNode_getChild((ModelNode*) ln, str);
if (dobj != NULL) { if (dobj != NULL)
{
if (dobj->modelType == DataObjectModelType) { if (dobj->modelType == DataObjectModelType)
{
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer,
connection); connection);
@ -3759,7 +3776,8 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
} }
} }
} }
else { else
{
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer,
connection); connection);
@ -3769,10 +3787,12 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
} }
} }
} }
else { else
{
LogicalNode* ln = LogicalDevice_getLogicalNode(ld, variableId); LogicalNode* ln = LogicalDevice_getLogicalNode(ld, variableId);
if (ln != NULL) { if (ln != NULL)
{
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection);
return self->readAccessHandler(ld, ln, NULL, fc, clientConnection, return self->readAccessHandler(ld, ln, NULL, fc, clientConnection,

Loading…
Cancel
Save