- IED client: added new function IedConnection_deleteDataSetAsync

pull/367/head
Michael Zillgith 4 years ago
parent 09c77afee4
commit ce9584d122

@ -3134,6 +3134,122 @@ exit_function:
return isDeleted;
}
static void
deleteNamedVariableListHandler(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_deleteDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference,
IedConnection_GenericServiceHandler handler, void* parameter)
{
*error = IED_ERROR_OK;
char domainIdBuf[65];
char *domainId = domainIdBuf;
char itemId[DATA_SET_MAX_NAME_LENGTH + 1];
bool isAssociationSpecific = false;
bool isDeleted = false;
int dataSetReferenceLength = strlen(dataSetReference);
if (dataSetReference[0] != '@') {
if ((dataSetReference[0] == '/')
|| (strchr(dataSetReference, '/') == NULL)) {
domainId = NULL;
if (dataSetReference[0] == '/')
strcpy(itemId, dataSetReference + 1);
else
strcpy(itemId, dataSetReference);
}
else {
if (MmsMapping_getMmsDomainFromObjectReference(dataSetReference,
domainId) == NULL) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
return 0;
}
const char *itemIdString = dataSetReference + strlen(domainId) + 1;
if (strlen(itemIdString) > DATA_SET_MAX_NAME_LENGTH) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
return 0;
}
StringUtils_copyStringToBuffer(itemIdString, itemId);
StringUtils_replace(itemId, '.', '$');
}
}
else {
if (dataSetReferenceLength > 33) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
return 0;
}
strcpy(itemId, dataSetReference + 1);
isAssociationSpecific = true;
}
MmsError mmsError;
if ((domainId == NULL) || (itemId == NULL)) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
return 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;
if (isAssociationSpecific) {
MmsConnection_deleteAssociationSpecificNamedVariableListAsync(self->connection, &(call->invokeId), &mmsError, itemId, deleteNamedVariableListHandler, self);
}
else {
MmsConnection_deleteNamedVariableListAsync(self->connection, &(call->invokeId), &mmsError, domainId, itemId, deleteNamedVariableListHandler, self);
}
if (*error != IED_ERROR_OK) {
iedConnection_releaseOutstandingCall(self, call);
return 0;
}
return call->invokeId;
}
LinkedList /* <char*> */
IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, const char* dataSetReference, bool* isDeletable)
{

@ -1,7 +1,7 @@
/*
* iec61850_client.h
*
* Copyright 2013-2019 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -1775,6 +1775,26 @@ IedConnection_createDataSet(IedConnection self, IedClientError* error, const cha
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
*
* 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.
*
* The data set was deleted successfully when the callback parameter "error" is IED_ERROR_OK. Otherwise the "error"
* parameter contains a particular error code.
*
* \param connection the connection object
* \param 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_deleteDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference,
IedConnection_GenericServiceHandler handler, void* parameter);
/**
* \brief returns the object references of the elements of a data set

@ -291,7 +291,7 @@ mmsClient_createDeleteNamedVariableListRequest(long invokeId, ByteBuffer* writeB
const char* domainId, const char* listNameId);
LIB61850_INTERNAL bool
mmsClient_parseDeleteNamedVariableListResponse(ByteBuffer* message, uint32_t* invokeId);
mmsClient_parseDeleteNamedVariableListResponse(ByteBuffer* message, uint32_t* invokeId, long* numberDeleted, long* numberMatched);
LIB61850_INTERNAL void
mmsClient_createDeleteAssociationSpecificNamedVariableListRequest(

@ -804,9 +804,19 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
else {
bool success = false;
if (mmsClient_parseDeleteNamedVariableListResponse(response, NULL))
long numberMatched = 0;
long numberDeleted = 0;
if (mmsClient_parseDeleteNamedVariableListResponse(response, NULL, &numberDeleted, &numberMatched))
success = true;
if (numberMatched == 0)
err = MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT;
else {
if (numberDeleted == 0)
err = MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED;
}
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, success);
}
}

@ -117,7 +117,7 @@ mmsClient_createDeleteAssociationSpecificNamedVariableListRequest(
}
bool
mmsClient_parseDeleteNamedVariableListResponse(ByteBuffer* message, uint32_t* invokeId)
mmsClient_parseDeleteNamedVariableListResponse(ByteBuffer* message, uint32_t* invokeId, long* numberDeleted, long* numberMatched)
{
MmsPdu_t* mmsPdu = 0;
@ -138,11 +138,10 @@ mmsClient_parseDeleteNamedVariableListResponse(ByteBuffer* message, uint32_t* in
DeleteNamedVariableListResponse_t* response =
&(mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.choice.deleteNamedVariableList);
long numberDeleted;
asn_INTEGER2long(&(response->numberDeleted), numberDeleted);
asn_INTEGER2long(&(response->numberMatched), numberMatched);
asn_INTEGER2long(&(response->numberDeleted), &numberDeleted);
if (numberDeleted == 1)
if (*numberDeleted == 1)
retVal = true;
}
}

Loading…
Cancel
Save