- IedConnection: Add function IedConnection_getDataSetDirectoryAsync

pull/367/head
Michael Zillgith 4 years ago
parent 89812fd333
commit 36c65bd2e2

@ -3280,7 +3280,7 @@ uint32_t
IedConnection_createDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference, LinkedList /* char* */ dataSetElements,
IedConnection_GenericServiceHandler handler, void* parameter)
{
int invokeId = 0;
uint32_t invokeId = 0;
char domainIdBuffer[65];
char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
@ -3443,8 +3443,8 @@ IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, con
dataSetMembers = LinkedList_create();
while (entry != NULL) {
MmsVariableAccessSpecification* varAccessSpec = (MmsVariableAccessSpecification*) entry->data;
while (entry) {
MmsVariableAccessSpecification* varAccessSpec = (MmsVariableAccessSpecification*)LinkedList_getData(entry);
char* objectReference = MmsMapping_varAccessSpecToObjectReference(varAccessSpec);
@ -3465,6 +3465,120 @@ exit_function:
return dataSetMembers;
}
static void
getDataSetDirectoryAsyncHandler(uint32_t invokeId, void* parameter, MmsError mmsError, LinkedList /* <MmsVariableAccessSpecification*> */ specs, bool deletable)
{
IedConnection self = (IedConnection)parameter;
IedClientError err = IED_ERROR_OK;
IedConnectionOutstandingCall call = iedConnection_lookupOutstandingCall(self, invokeId);
if (call) {
LinkedList dataSetMembers = NULL;
if (mmsError != MMS_ERROR_NONE)
err = iedConnection_mapMmsErrorToIedError(mmsError);
if (specs) {
dataSetMembers = LinkedList_create();
LinkedList specElem = LinkedList_getNext(specs);
while (specElem) {
MmsVariableAccessSpecification* varAccessSpec = (MmsVariableAccessSpecification*)LinkedList_getData(specElem);
char* objectReference = MmsMapping_varAccessSpecToObjectReference(varAccessSpec);
LinkedList_add(dataSetMembers, objectReference);
specElem = LinkedList_getNext(specElem);
}
}
IedConnection_GetDataSetDirectoryHandler handler = (IedConnection_GetDataSetDirectoryHandler)call->callback;
if (handler)
handler(call->invokeId, call->callbackParameter, err, dataSetMembers, deletable);
}
if (specs)
LinkedList_destroyDeep(specs, (LinkedListValueDeleteFunction) MmsVariableAccessSpecification_destroy);
}
uint32_t
IedConnection_getDataSetDirectoryAsync(IedConnection self, IedClientError* error, const char* dataSetReference,
IedConnection_GetDataSetDirectoryHandler handler, void* parameter)
{
uint32_t invokeId = 0;
IedConnectionOutstandingCall call = iedConnection_allocateOutstandingCall(self);
if (call == NULL) {
*error = IED_ERROR_OUTSTANDING_CALL_LIMIT_REACHED;
return 0;
}
call->callback = handler;
call->callbackParameter = parameter;
call->invokeId = 0;
char domainIdBuffer[65];
char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId = NULL;
const char* itemId = NULL;
bool isAssociationSpecific = false;
if (dataSetReference[0] != '@') {
if ((dataSetReference[0] == '/') || (strchr(dataSetReference, '/') == NULL)) {
domainId = NULL;
if (dataSetReference[0] == '/')
itemId = dataSetReference + 1;
else
itemId = dataSetReference;
}
else {
domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
if (domainId == NULL) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
const char* itemIdRef = dataSetReference + strlen(domainId) + 1;
if (strlen(itemIdRef) > DATA_SET_MAX_NAME_LENGTH) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
char* itemIdRefInBuffer = StringUtils_copyStringToBuffer(itemIdRef, itemIdBuffer);
StringUtils_replace(itemIdRefInBuffer, '.', '$');
itemId = itemIdRefInBuffer;
}
}
else {
itemId = dataSetReference + 1;
isAssociationSpecific = true;
}
MmsError mmsError = MMS_ERROR_NONE;
if (isAssociationSpecific)
MmsConnection_readNamedVariableListDirectoryAssociationSpecificAsync(self->connection, &(call->invokeId), &mmsError, itemId, getDataSetDirectoryAsyncHandler, self);
else
MmsConnection_readNamedVariableListDirectoryAsync(self->connection, &(call->invokeId), &mmsError, domainId, itemId, getDataSetDirectoryAsyncHandler, self);
*error = iedConnection_mapMmsErrorToIedError(mmsError);
exit_function:
return invokeId;
}
ClientDataSet
IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const char* dataSetReference,
ClientDataSet dataSet)

@ -1801,7 +1801,7 @@ LIB61850_API bool
IedConnection_deleteDataSet(IedConnection self, IedClientError* error, const char* dataSetReference);
/**
* \brief delete a deletable data set at the connected server device - async version
* \brief delete a deletable data set at the connected server device - asynchronous version
*
* This function deletes a data set at the server. The parameter dataSetReference is the name of the data set
* to delete. It is either in the form LDName/LNodeName.dataSetName or @dataSetName for an association specific data set.
@ -1822,7 +1822,7 @@ IedConnection_deleteDataSetAsync(IedConnection self, IedClientError* error, cons
IedConnection_GenericServiceHandler handler, void* parameter);
/**
* \brief returns the object references of the elements of a data set
* \brief read the data set directory
*
* The return value contains a linked list containing the object references of FCDs or FCDAs. The format of
* this object references is LDName/LNodeName.item(arrayIndex)component[FC].
@ -1838,6 +1838,34 @@ IedConnection_deleteDataSetAsync(IedConnection self, IedClientError* error, cons
LIB61850_API LinkedList /* <char*> */
IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, const char* dataSetReference, bool* isDeletable);
/**
* \brief GetDataSetDirectory response or timeout callback
*
* \param dataSetDirectory a linked list containing the object references of FCDs or FCDAs. The format of
* this object references is LDName/LNodeName.item(arrayIndex)component[FC].
* \param isDeletable this is an output parameter indicating that the requested data set is deletable by clients.
*/
typedef void
(*IedConnection_GetDataSetDirectoryHandler) (uint32_t invokeId, void* parameter, IedClientError err, LinkedList /* <char*> */ dataSetDirectory, bool isDeletable);
/**
* \brief read the data set directory - asynchronous version
*
* The result data is a linked list containing the object references of FCDs or FCDAs. The format of
* this object references is LDName/LNodeName.item(arrayIndex)component[FC].
*
* \param connection the connection object
* \param[out] error the error code if an error occurs
* \param dataSetReference object reference of the data set
* \param handler the callback handler that is called when the response is received or timeout
* \param parameter user provided parameter that is passed to the callback handler
*
* \return the invoke ID of the request
*/
LIB61850_API uint32_t
IedConnection_getDataSetDirectoryAsync(IedConnection self, IedClientError* error, const char* dataSetReference,
IedConnection_GetDataSetDirectoryHandler handler, void* parameter);
/**
* \brief Write the data set values to the server
*

Loading…
Cancel
Save