- IED client: added function IedConnection_createDataSetAsync

pull/367/head
Michael Zillgith 4 years ago
parent ce9584d122
commit 394bf4ccba

@ -2990,7 +2990,6 @@ void
IedConnection_createDataSet(IedConnection self, IedClientError* error, const char* dataSetReference,
LinkedList /* <char*> */dataSetElements)
{
char domainIdBuffer[65];
char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
@ -3250,6 +3249,135 @@ IedConnection_deleteDataSetAsync(IedConnection self, IedClientError* error, cons
return call->invokeId;
}
static void
createDataSetAsyncHandler(uint32_t invokeId, void* parameter, MmsError mmsError, bool success)
{
IedConnection self = (IedConnection) parameter;
IedConnectionOutstandingCall call = iedConnection_lookupOutstandingCall(self, invokeId);
if (call) {
IedConnection_GenericServiceHandler handler = (IedConnection_GenericServiceHandler)call->callback;
IedClientError err = iedConnection_mapMmsErrorToIedError(mmsError);
if (err == IED_ERROR_OK) {
if (success == false)
err = IED_ERROR_ACCESS_DENIED;
}
handler(invokeId, call->callbackParameter, err);
iedConnection_releaseOutstandingCall(self, call);
}
else {
if (DEBUG_IED_CLIENT)
printf("IED_CLIENT: internal error - no matching outstanding call!\n");
}
}
uint32_t
IedConnection_createDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference, LinkedList /* char* */ dataSetElements,
IedConnection_GenericServiceHandler handler, void* parameter)
{
int invokeId = 0;
char domainIdBuffer[65];
char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId;
const char* itemId;
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;
}
int domainIdLength = strlen(domainId);
if ((strlen(dataSetReference) - domainIdLength - 1) > 32) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
char* itemIdRef = StringUtils_copyStringToBuffer(dataSetReference + domainIdLength + 1, itemIdBuffer);
StringUtils_replace(itemIdRef, '.', '$');
itemId = itemIdRef;
}
}
else {
itemId = dataSetReference + 1;
isAssociationSpecific = true;
}
MmsError mmsError;
IedConnectionOutstandingCall call = iedConnection_allocateOutstandingCall(self);
if (call == NULL) {
*error = IED_ERROR_OUTSTANDING_CALL_LIMIT_REACHED;
goto exit_function;
}
call->callback = handler;
call->callbackParameter = parameter;
call->invokeId = 0;
LinkedList dataSetEntries = LinkedList_create();
LinkedList dataSetElement = LinkedList_getNext(dataSetElements);
while (dataSetElement != NULL) {
MmsVariableAccessSpecification* dataSetEntry =
MmsMapping_ObjectReferenceToVariableAccessSpec((char*) dataSetElement->data);
if (dataSetEntry == NULL) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto cleanup_list;
}
LinkedList_add(dataSetEntries, (void*) dataSetEntry);
dataSetElement = LinkedList_getNext(dataSetElement);
}
if (isAssociationSpecific) {
MmsConnection_defineNamedVariableListAssociationSpecificAsync(self->connection, &(call->invokeId),
&mmsError, itemId, dataSetEntries, createDataSetAsyncHandler, self);
}
else {
MmsConnection_defineNamedVariableListAsync(self->connection, &(call->invokeId),
&mmsError, domainId, itemId, dataSetEntries, createDataSetAsyncHandler, self);
}
invokeId = call->invokeId;
*error = iedConnection_mapMmsErrorToIedError(mmsError);
cleanup_list:
/* delete list and all elements */
LinkedList_destroyDeep(dataSetEntries, (LinkedListValueDeleteFunction) MmsVariableAccessSpecification_destroy);
exit_function:
return invokeId;
}
LinkedList /* <char*> */
IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, const char* dataSetReference, bool* isDeletable)
{

@ -1759,6 +1759,31 @@ IedConnection_readDataSetValuesAsync(IedConnection self, IedClientError* error,
LIB61850_API void
IedConnection_createDataSet(IedConnection self, IedClientError* error, const char* dataSetReference, LinkedList /* char* */ dataSetElements);
/**
* \brief create a new data set at the connected server device
*
* This function creates a new data set at the server. The parameter dataSetReference is the name of the new data set
* to create. It is either in the form LDName/LNodeName.dataSetName for permanent domain or VMD scope data sets or
* @dataSetName for an association specific data set. If the LDName part of the reference is missing the resulting
* data set will be of VMD scope.
*
* The dataSetElements parameter 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].
*
* \param connection the connection object
* \param error the error code if an error occurs
* \param dataSetReference object reference of the data set
* \param dataSetElements a list of object references defining the members of the new 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_createDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference, LinkedList /* char* */ dataSetElements,
IedConnection_GenericServiceHandler handler, void* parameter);
/**
* \brief delete a deletable data set at the connected server device
*

Loading…
Cancel
Save