- MMS client: added asynchronous define named variable list functions

pull/93/head
Michael Zillgith 7 years ago
parent 80ce9c8967
commit 5692d0246b

@ -274,6 +274,8 @@ MmsConnection_abort(MmsConnection self, MmsError* mmsError);
void void
MmsConnection_conclude(MmsConnection self, MmsError* mmsError); MmsConnection_conclude(MmsConnection self, MmsError* mmsError);
typedef void
(*MmsConnection_GenericServiceHandler) (int invokeId, void* parameter, MmsError mmsError, bool success);
/** /**
* \brief Get the names of all VMD scope variables of the server. * \brief Get the names of all VMD scope variables of the server.
@ -664,6 +666,12 @@ void
MmsConnection_defineNamedVariableList(MmsConnection self, MmsError* mmsError, const char* domainId, MmsConnection_defineNamedVariableList(MmsConnection self, MmsError* mmsError, const char* domainId,
const char* listName, LinkedList variableSpecs); const char* listName, LinkedList variableSpecs);
uint32_t
MmsConnection_defineNamedVariableListAsync(MmsConnection self, MmsError* mmsError, const char* domainId,
const char* listName, LinkedList variableSpecs,
MmsConnection_GenericServiceHandler handler, void* parameter);
/** /**
* \brief Define a new association specific named variable list at the server. * \brief Define a new association specific named variable list at the server.
@ -678,6 +686,11 @@ void
MmsConnection_defineNamedVariableListAssociationSpecific(MmsConnection self, MmsError* mmsError, MmsConnection_defineNamedVariableListAssociationSpecific(MmsConnection self, MmsError* mmsError,
const char* listName, LinkedList variableSpecs); const char* listName, LinkedList variableSpecs);
uint32_t
MmsConnection_defineNamedVariableListAssociationSpecificAsync(MmsConnection self, MmsError* mmsError,
const char* listName, LinkedList variableSpecs,
MmsConnection_GenericServiceHandler handler, void* parameter);
/** /**
* \brief Read the entry list of a named variable list at the server. * \brief Read the entry list of a named variable list at the server.
* *
@ -698,6 +711,15 @@ MmsConnection_readNamedVariableListDirectory(MmsConnection self, MmsError* mmsEr
const char* domainId, const char* listName, bool* deletable); const char* domainId, const char* listName, bool* deletable);
typedef void
(*MmsConnection_ReadNVLDirectoryHandler) (int invokeId, void* parameter, MmsError mmsError, LinkedList /* <MmsVariableAccessSpecification*> */ specs, bool deletable);
uint32_t
MmsConnection_readNamedVariableListDirectoryAsync(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* listName,
MmsConnection_ReadNVLDirectoryHandler handler, void* parameter);
/** /**
* \brief Read the entry list of an association specific named variable list at the server. * \brief Read the entry list of an association specific named variable list at the server.
@ -712,6 +734,11 @@ LinkedList /* <MmsVariableAccessSpecification*> */
MmsConnection_readNamedVariableListDirectoryAssociationSpecific(MmsConnection self, MmsError* mmsError, MmsConnection_readNamedVariableListDirectoryAssociationSpecific(MmsConnection self, MmsError* mmsError,
const char* listName, bool* deletable); const char* listName, bool* deletable);
uint32_t
MmsConnection_readNamedVariableListDirectoryAssociationSpecificAsync(MmsConnection self, MmsError* mmsError,
const char* listName,
MmsConnection_ReadNVLDirectoryHandler handler, void* parameter);
/** /**
* \brief Delete a named variable list at the server. * \brief Delete a named variable list at the server.
* *

@ -65,7 +65,9 @@ typedef enum {
MMS_CALL_TYPE_NONE, MMS_CALL_TYPE_NONE,
MMS_CALL_TYPE_READ_VARIABLE, MMS_CALL_TYPE_READ_VARIABLE,
MMS_CALL_TYPE_WRITE_VARIABLE, MMS_CALL_TYPE_WRITE_VARIABLE,
MMS_CALL_TYPE_WRITE_MULTIPLE_VARIABLES MMS_CALL_TYPE_WRITE_MULTIPLE_VARIABLES,
MMS_CALL_TYPE_READ_NVL_DIRECTORY,
MMS_CALL_TYPE_DEFINE_NVL
} eMmsOutstandingCallType; } eMmsOutstandingCallType;
struct sMmsOutstandingCall struct sMmsOutstandingCall

@ -1,7 +1,7 @@
/* /*
* mms_client_connection.c * mms_client_connection.c
* *
* Copyright 2013, 2014, 2015 Michael Zillgith * Copyright 2013-2018 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -829,6 +829,45 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
} }
} }
} }
else if (outstandingCall->type == MMS_CALL_TYPE_READ_NVL_DIRECTORY) {
MmsConnection_ReadNVLDirectoryHandler handler =
(MmsConnection_ReadNVLDirectoryHandler) outstandingCall->userCallback;
if (err != MMS_ERROR_NONE) {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, NULL, false);
}
else {
if (response) {
bool deletable = false;
LinkedList accessSpec = mmsClient_parseGetNamedVariableListAttributesResponse(response, NULL, &deletable);
if (accessSpec == false)
err = MMS_ERROR_PARSING_RESPONSE;
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, accessSpec, deletable);
}
}
}
else if (outstandingCall->type == MMS_CALL_TYPE_DEFINE_NVL) {
MmsConnection_GenericServiceHandler handler =
(MmsConnection_GenericServiceHandler) outstandingCall->userCallback;
if (err != MMS_ERROR_NONE) {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, false);
}
else {
bool success = false;
if (!mmsClient_parseDefineNamedVariableResponse(response, NULL))
err = MMS_ERROR_PARSING_RESPONSE;
else
success = true;
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, success);
}
}
removeFromOutstandingCalls(self, outstandingCall->invokeId); removeFromOutstandingCalls(self, outstandingCall->invokeId);
@ -1707,32 +1746,27 @@ MmsConnection_getVariableListNamesAssociationSpecific(MmsConnection self, MmsErr
return mmsClient_getNameList(self, mmsError, NULL, MMS_OBJECT_CLASS_NAMED_VARIABLE_LIST, true); return mmsClient_getNameList(self, mmsError, NULL, MMS_OBJECT_CLASS_NAMED_VARIABLE_LIST, true);
} }
MmsValue* struct threeParameters
MmsConnection_readVariable(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* itemId)
{ {
MmsValue* value = NULL; void* param1;
void* param2;
void* param3;
};
if (getAssociationState(self) != MMS_STATE_CONNECTED) { static void
*mmsError = MMS_ERROR_CONNECTION_LOST; readVariableHandler(int invokeId, void* parameter, MmsError mmsError, MmsValue* value)
goto exit_function; {
} struct threeParameters* parameters = (struct threeParameters*) parameter;
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self);
mmsClient_createReadRequest(invokeId, domainId, itemId, payload);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); Semaphore waitForResponse = (Semaphore) parameters->param1;
MmsError* err = (MmsError*) parameters->param3;
if (responseMessage != NULL) parameters->param2 = value;
value = mmsClient_parseReadResponse(self->lastResponse, NULL, false);
releaseResponse(self); *err = mmsError;
exit_function: /* unblock user thread */
return value; Semaphore_post(waitForResponse);
} }
uint32_t uint32_t
@ -1762,6 +1796,40 @@ exit_function:
return invokeId; return invokeId;
} }
MmsValue*
MmsConnection_readVariable(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* itemId)
{
MmsValue* value = NULL;
Semaphore waitForResponse = Semaphore_create(1);
Semaphore_wait(waitForResponse);
struct threeParameters parameter;
MmsError respErr = MMS_ERROR_NONE;
parameter.param1 = waitForResponse;
parameter.param2 = NULL;
parameter.param3 = &respErr;
MmsConnection_readVariableAsync(self, &respErr, domainId, itemId, readVariableHandler, &parameter);
if (respErr == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
value = (MmsValue*) parameter.param2;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = respErr;
return value;
}
MmsValue* MmsValue*
MmsConnection_readArrayElements(MmsConnection self, MmsError* mmsError, MmsConnection_readArrayElements(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* itemId, const char* domainId, const char* itemId,
@ -1769,26 +1837,32 @@ MmsConnection_readArrayElements(MmsConnection self, MmsError* mmsError,
{ {
MmsValue* value = NULL; MmsValue* value = NULL;
if (getAssociationState(self) != MMS_STATE_CONNECTED) { Semaphore waitForResponse = Semaphore_create(1);
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient); Semaphore_wait(waitForResponse);
uint32_t invokeId = getNextInvokeId(self); struct threeParameters parameter;
mmsClient_createReadRequestAlternateAccessIndex(invokeId, domainId, itemId, startIndex, MmsError respErr = MMS_ERROR_NONE;
numberOfElements, payload);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); parameter.param1 = waitForResponse;
parameter.param2 = NULL;
parameter.param3 = &respErr;
if (responseMessage != NULL) MmsConnection_readArrayElementsAsync(self, &respErr, domainId, itemId, startIndex, numberOfElements,
value = mmsClient_parseReadResponse(self->lastResponse, NULL, false); readVariableHandler, &parameter);
releaseResponse(self); if (respErr == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
value = (MmsValue*) parameter.param2;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = respErr;
exit_function:
return value; return value;
} }
@ -1827,26 +1901,32 @@ MmsConnection_readSingleArrayElementWithComponent(MmsConnection self, MmsError*
{ {
MmsValue* value = NULL; MmsValue* value = NULL;
if (getAssociationState(self) != MMS_STATE_CONNECTED) { Semaphore waitForResponse = Semaphore_create(1);
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient); Semaphore_wait(waitForResponse);
uint32_t invokeId = getNextInvokeId(self); struct threeParameters parameter;
mmsClient_createReadRequestAlternateAccessSingleIndexComponent(invokeId, domainId, itemId, index, componentId, MmsError respErr = MMS_ERROR_NONE;
payload);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); parameter.param1 = waitForResponse;
parameter.param2 = NULL;
parameter.param3 = &respErr;
if (responseMessage != NULL) MmsConnection_readSingleArrayElementWithComponentAsync(self, &respErr, domainId, itemId, index, componentId,
value = mmsClient_parseReadResponse(self->lastResponse, NULL, false); readVariableHandler, &parameter);
releaseResponse(self); if (respErr == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
value = (MmsValue*) parameter.param2;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = respErr;
exit_function:
return value; return value;
} }
@ -1886,25 +1966,32 @@ MmsConnection_readMultipleVariables(MmsConnection self, MmsError* mmsError,
{ {
MmsValue* value = NULL; MmsValue* value = NULL;
if (getAssociationState(self) != MMS_STATE_CONNECTED) { Semaphore waitForResponse = Semaphore_create(1);
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient); Semaphore_wait(waitForResponse);
uint32_t invokeId = getNextInvokeId(self); struct threeParameters parameter;
mmsClient_createReadRequestMultipleValues(invokeId, domainId, items, payload); MmsError respErr = MMS_ERROR_NONE;
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); parameter.param1 = waitForResponse;
parameter.param2 = NULL;
parameter.param3 = &respErr;
if (responseMessage != NULL) MmsConnection_readMultipleVariablesAsync(self, &respErr, domainId, items,
value = mmsClient_parseReadResponse(self->lastResponse, NULL, true); readVariableHandler, &parameter);
releaseResponse(self); if (respErr == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
value = (MmsValue*) parameter.param2;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = respErr;
exit_function:
return value; return value;
} }
@ -1944,26 +2031,32 @@ MmsConnection_readNamedVariableListValues(MmsConnection self, MmsError* mmsError
{ {
MmsValue* value = NULL; MmsValue* value = NULL;
if (getAssociationState(self) != MMS_STATE_CONNECTED) { Semaphore waitForResponse = Semaphore_create(1);
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient); Semaphore_wait(waitForResponse);
uint32_t invokeId = getNextInvokeId(self); struct threeParameters parameter;
mmsClient_createReadNamedVariableListRequest(invokeId, domainId, listName, MmsError respErr = MMS_ERROR_NONE;
payload, specWithResult);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); parameter.param1 = waitForResponse;
parameter.param2 = NULL;
parameter.param3 = &respErr;
if (responseMessage != NULL) MmsConnection_readNamedVariableListValuesAsync(self, &respErr, domainId, listName, specWithResult,
value = mmsClient_parseReadResponse(self->lastResponse, NULL, true); readVariableHandler, &parameter);
releaseResponse(self); if (respErr == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
value = (MmsValue*) parameter.param2;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = respErr;
exit_function:
return value; return value;
} }
@ -2005,26 +2098,32 @@ MmsConnection_readNamedVariableListValuesAssociationSpecific(
{ {
MmsValue* value = NULL; MmsValue* value = NULL;
if (getAssociationState(self) != MMS_STATE_CONNECTED) { Semaphore waitForResponse = Semaphore_create(1);
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient); Semaphore_wait(waitForResponse);
uint32_t invokeId = getNextInvokeId(self); struct threeParameters parameter;
mmsClient_createReadAssociationSpecificNamedVariableListRequest(invokeId, listName, MmsError respErr = MMS_ERROR_NONE;
payload, specWithResult);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); parameter.param1 = waitForResponse;
parameter.param2 = NULL;
parameter.param3 = &respErr;
if (responseMessage != NULL) MmsConnection_readNamedVariableListValuesAssociationSpecificAsync(self, &respErr, listName, specWithResult,
value = mmsClient_parseReadResponse(self->lastResponse, NULL, true); readVariableHandler, &parameter);
releaseResponse(self); if (respErr == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
value = (MmsValue*) parameter.param2;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = respErr;
exit_function:
return value; return value;
} }
@ -2057,64 +2156,155 @@ exit_function:
return invokeId; return invokeId;
} }
struct readNVLDirectoryParameters
{
Semaphore waitForResponse;
MmsError err;
LinkedList specs;
bool deletable;
};
static void
readNVLDirectoryHandler(int invokeId, void* parameter, MmsError mmsError, LinkedList /* <MmsVariableAccessSpecification*> */ specs, bool deletable)
{
struct readNVLDirectoryParameters* parameters = (struct readNVLDirectoryParameters*) parameter;
parameters->err = mmsError;
parameters->deletable = deletable;
parameters->specs = specs;
/* unblock user thread */
Semaphore_post(parameters->waitForResponse);
}
LinkedList /* <MmsVariableAccessSpecification*> */ LinkedList /* <MmsVariableAccessSpecification*> */
MmsConnection_readNamedVariableListDirectory(MmsConnection self, MmsError* mmsError, MmsConnection_readNamedVariableListDirectory(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* listName, bool* deletable) const char* domainId, const char* listName, bool* deletable)
{ {
LinkedList attributes = NULL; LinkedList specs = NULL;
Semaphore waitForResponse = Semaphore_create(1);
Semaphore_wait(waitForResponse);
struct readNVLDirectoryParameters parameter;
MmsError err;
parameter.waitForResponse = waitForResponse;
MmsConnection_readNamedVariableListDirectoryAsync(self, &err, domainId, listName,
readNVLDirectoryHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
err = parameter.err;
specs = parameter.specs;
if (deletable)
*deletable = parameter.deletable;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = err;
return specs;
}
uint32_t
MmsConnection_readNamedVariableListDirectoryAsync(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* listName,
MmsConnection_ReadNVLDirectoryHandler handler, void* parameter)
{
uint32_t invokeId = 0;
if (getAssociationState(self) != MMS_STATE_CONNECTED) { if (getAssociationState(self) != MMS_STATE_CONNECTED) {
if (mmsError)
*mmsError = MMS_ERROR_CONNECTION_LOST; *mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function; goto exit_function;
} }
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient); ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self); invokeId = getNextInvokeId(self);
mmsClient_createGetNamedVariableListAttributesRequest(invokeId, payload, domainId, mmsClient_createGetNamedVariableListAttributesRequest(invokeId, payload, domainId,
listName); listName);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_READ_NVL_DIRECTORY, handler, parameter);
if (responseMessage != NULL) if (mmsError)
attributes = mmsClient_parseGetNamedVariableListAttributesResponse(self->lastResponse, NULL, *mmsError = err;
deletable);
releaseResponse(self);
exit_function: exit_function:
return attributes; return invokeId;
} }
LinkedList /* <MmsVariableAccessSpecification*> */ LinkedList /* <MmsVariableAccessSpecification*> */
MmsConnection_readNamedVariableListDirectoryAssociationSpecific(MmsConnection self, MmsError* mmsError, MmsConnection_readNamedVariableListDirectoryAssociationSpecific(MmsConnection self, MmsError* mmsError,
const char* listName, bool* deletable) const char* listName, bool* deletable)
{ {
LinkedList attributes = NULL; LinkedList specs = NULL;
Semaphore waitForResponse = Semaphore_create(1);
Semaphore_wait(waitForResponse);
struct readNVLDirectoryParameters parameter;
MmsError err;
parameter.waitForResponse = waitForResponse;
MmsConnection_readNamedVariableListDirectoryAssociationSpecificAsync(self, &err, listName,
readNVLDirectoryHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
err = parameter.err;
specs = parameter.specs;
if (deletable)
*deletable = parameter.deletable;
}
Semaphore_destroy(waitForResponse);
if (mmsError)
*mmsError = err;
return specs;
}
uint32_t
MmsConnection_readNamedVariableListDirectoryAssociationSpecificAsync(MmsConnection self, MmsError* mmsError,
const char* listName,
MmsConnection_ReadNVLDirectoryHandler handler, void* parameter)
{
uint32_t invokeId = 0;
if (getAssociationState(self) != MMS_STATE_CONNECTED) { if (getAssociationState(self) != MMS_STATE_CONNECTED) {
if (mmsError)
*mmsError = MMS_ERROR_CONNECTION_LOST; *mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function; goto exit_function;
} }
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient); ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self); invokeId = getNextInvokeId(self);
mmsClient_createGetNamedVariableListAttributesRequestAssociationSpecific(invokeId, payload, mmsClient_createGetNamedVariableListAttributesRequestAssociationSpecific(invokeId, payload,
listName); listName);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError); MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_READ_NVL_DIRECTORY, handler, parameter);
if (responseMessage != NULL)
attributes = mmsClient_parseGetNamedVariableListAttributesResponse(self->lastResponse, NULL,
deletable);
releaseResponse(self); if (mmsError)
*mmsError = err;
exit_function: exit_function:
return attributes; return invokeId;
} }
void void
@ -2145,6 +2335,36 @@ MmsConnection_defineNamedVariableList(MmsConnection self, MmsError* mmsError,
return; return;
} }
uint32_t
MmsConnection_defineNamedVariableListAsync(MmsConnection self, MmsError* mmsError, const char* domainId,
const char* listName, LinkedList variableSpecs,
MmsConnection_GenericServiceHandler handler, void* parameter)
{
uint32_t invokeId = 0;
if (getAssociationState(self) != MMS_STATE_CONNECTED) {
if (mmsError)
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
invokeId = getNextInvokeId(self);
mmsClient_createDefineNamedVariableListRequest(invokeId, payload, domainId,
listName, variableSpecs, false);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_DEFINE_NVL, handler, parameter);
if (mmsError)
*mmsError = err;
exit_function:
return invokeId;
}
void void
MmsConnection_defineNamedVariableListAssociationSpecific(MmsConnection self, MmsConnection_defineNamedVariableListAssociationSpecific(MmsConnection self,
MmsError* mmsError, const char* listName, LinkedList variableSpecs) MmsError* mmsError, const char* listName, LinkedList variableSpecs)
@ -2173,6 +2393,36 @@ MmsConnection_defineNamedVariableListAssociationSpecific(MmsConnection self,
return; return;
} }
uint32_t
MmsConnection_defineNamedVariableListAssociationSpecificAsync(MmsConnection self, MmsError* mmsError,
const char* listName, LinkedList variableSpecs,
MmsConnection_GenericServiceHandler handler, void* parameter)
{
uint32_t invokeId = 0;
if (getAssociationState(self) != MMS_STATE_CONNECTED) {
if (mmsError)
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
invokeId = getNextInvokeId(self);
mmsClient_createDefineNamedVariableListRequest(invokeId, payload, NULL,
listName, variableSpecs, false);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_DEFINE_NVL, handler, parameter);
if (mmsError)
*mmsError = err;
exit_function:
return invokeId;
}
bool bool
MmsConnection_deleteNamedVariableList(MmsConnection self, MmsError* mmsError, MmsConnection_deleteNamedVariableList(MmsConnection self, MmsError* mmsError,
const char* domainId, const char* listName) const char* domainId, const char* listName)
@ -2665,6 +2915,7 @@ exit_function:
return invokeId; return invokeId;
} }
#if 0
void void
MmsConnection_writeMultipleVariables(MmsConnection self, MmsError* mmsError, const char* domainId, MmsConnection_writeMultipleVariables(MmsConnection self, MmsError* mmsError, const char* domainId,
LinkedList /*<char*>*/items, LinkedList /*<char*>*/items,
@ -2689,6 +2940,59 @@ MmsConnection_writeMultipleVariables(MmsConnection self, MmsError* mmsError, con
releaseResponse(self); releaseResponse(self);
} }
#endif
static void
writeMultipleVariablesHandler(int invokeId, void* parameter, MmsError mmsError, LinkedList /* <MmsValue*> */ accessResults)
{
struct threeParameters* parameters = (struct threeParameters*) parameter;
Semaphore waitForResponse = (Semaphore) parameters->param1;
MmsError* err = (MmsError*) parameters->param3;
parameters->param2 = accessResults;
*err = mmsError;
/* unblock user thread */
Semaphore_post(waitForResponse);
}
void
MmsConnection_writeMultipleVariables(MmsConnection self, MmsError* mmsError, const char* domainId,
LinkedList /*<char*>*/items,
LinkedList /* <MmsValue*> */values,
/* OUTPUT */LinkedList* /* <MmsValue*> */accessResults)
{
Semaphore waitForResponse = Semaphore_create(1);
Semaphore_wait(waitForResponse);
struct threeParameters parameter;
MmsError respErr = MMS_ERROR_NONE;
parameter.param1 = waitForResponse;
parameter.param2 = NULL;
parameter.param3 = &respErr;
MmsConnection_writeMultipleVariablesAsync(self, &respErr, domainId, items, values, writeMultipleVariablesHandler, &parameter);
if (respErr == MMS_ERROR_NONE) {
Semaphore_wait(waitForResponse);
*accessResults = (LinkedList) parameter.param2;
}
else
*accessResults = NULL;
if (mmsError)
*mmsError = respErr;
Semaphore_destroy(waitForResponse);
}
uint32_t uint32_t
MmsConnection_writeMultipleVariablesAsync(MmsConnection self, MmsError* mmsError, const char* domainId, MmsConnection_writeMultipleVariablesAsync(MmsConnection self, MmsError* mmsError, const char* domainId,

@ -262,8 +262,11 @@ mmsClient_parseGetNamedVariableListAttributesResponse(ByteBuffer* message, uint3
if (rval.code == RC_OK) { if (rval.code == RC_OK) {
if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) { if (mmsPdu->present == MmsPdu_PR_confirmedResponsePdu) {
#if 0
//TODO remove
if (invokeId != NULL) if (invokeId != NULL)
*invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu); *invokeId = mmsClient_getInvokeId(&mmsPdu->choice.confirmedResponsePdu);
#endif
if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present == if (mmsPdu->choice.confirmedResponsePdu.confirmedServiceResponse.present ==
ConfirmedServiceResponse_PR_getNamedVariableListAttributes) ConfirmedServiceResponse_PR_getNamedVariableListAttributes)

@ -1,7 +1,7 @@
/* /*
* mms_client_write.c * mms_client_write.c
* *
* Copyright 2013 Michael Zillgith * Copyright 2013-2018 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *

Loading…
Cancel
Save