diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c index b49a1fe7f..f2960f359 100644 --- a/src/iec61850/client/ied_connection.c +++ b/src/iec61850/client/ied_connection.c @@ -105,9 +105,6 @@ iedConnection_mapMmsErrorToIedError(MmsError mmsError) case MMS_ERROR_DEFINITION_OBJECT_UNDEFINED: return IED_ERROR_OBJECT_UNDEFINED; - case MMS_ERROR_ACCESS_TEMPORARILY_UNAVAILABLE: - return IED_ERROR_TEMPORARILY_UNAVAILABLE; - default: return IED_ERROR_UNKNOWN; } @@ -675,6 +672,15 @@ IedConnection_getRequestTimeout(IedConnection self) return 0; } +uint32_t +IedConnection_getInvokeId(IedConnection self) +{ + if (self->connection) { + return MmsConnection_getInvokeId(self->connection); + } + else + return 0; +} void IedConnection_setTimeQuality(IedConnection self, bool leapSecondKnown, bool clockFailure, bool clockNotSynchronized, int subsecondPrecision) { @@ -905,7 +911,7 @@ IedConnection_getVariableSpecification(IedConnection self, IedClientError* error *error = IED_ERROR_OK; else *error = iedConnection_mapMmsErrorToIedError(mmsError); - + cleanup_and_exit: return varSpec; @@ -1247,6 +1253,9 @@ IedConnection_readObject(IedConnection self, IedClientError* error, const char* else *error = iedConnection_mapMmsErrorToIedError(mmsError); + if (MmsValue_getType(value) == MMS_DATA_ACCESS_ERROR) + *error = iedConnection_mapDataAccessErrorToIedError(MmsValue_getDataAccessError(value)); + return value; } @@ -2464,7 +2473,7 @@ IedConnection_getLogicalNodeDirectory(IedConnection self, IedClientError* error, if (strlen(logicalNodeReference) > 129) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } char lnRefCopy[130]; @@ -2475,7 +2484,7 @@ IedConnection_getLogicalNodeDirectory(IedConnection self, IedClientError* error, if (ldSep == NULL) { *error = IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT; - return NULL; + return ' '; } *ldSep = 0; @@ -2494,7 +2503,7 @@ IedConnection_getLogicalNodeDirectory(IedConnection self, IedClientError* error, IedConnection_getDeviceModelFromServer(self, error); if (*error != IED_ERROR_OK) - return NULL; + return ' '; /* search for logical device */ @@ -2515,7 +2524,7 @@ IedConnection_getLogicalNodeDirectory(IedConnection self, IedClientError* error, if (ld == NULL) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } LinkedList lnDirectory = LinkedList_create(); @@ -2615,14 +2624,14 @@ IedConnection_getLogicalNodeVariables(IedConnection self, IedClientError* error, if (strlen(logicalNodeReference) > 129) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } if (self->logicalDevices == NULL) IedConnection_getDeviceModelFromServer(self, error); if (*error != IED_ERROR_OK) - return NULL; + return ' '; char lnRefCopy[130]; @@ -2632,7 +2641,7 @@ IedConnection_getLogicalNodeVariables(IedConnection self, IedClientError* error, if (ldSep == NULL) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } *ldSep = 0; @@ -2660,7 +2669,7 @@ IedConnection_getLogicalNodeVariables(IedConnection self, IedClientError* error, if (ld == NULL) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } if (DEBUG_IED_CLIENT) @@ -2698,14 +2707,14 @@ getDataDirectory(IedConnection self, IedClientError* error, if (strlen(dataReference) > 129) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } if (self->logicalDevices == NULL) IedConnection_getDeviceModelFromServer(self, error); if (*error != IED_ERROR_OK) - return NULL; + return ' '; char dataRefCopy[130]; @@ -2723,7 +2732,7 @@ getDataDirectory(IedConnection self, IedClientError* error, if (logicalNodeNameEnd == NULL) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } int logicalNodeNameLen = (int)(logicalNodeNameEnd - logicalNodeName); @@ -2734,7 +2743,7 @@ getDataDirectory(IedConnection self, IedClientError* error, if (dataNamePartLen < 1) { *error = IED_ERROR_OBJECT_REFERENCE_INVALID; - return NULL; + return ' '; } StringUtils_replace(dataNamePart, '.', '$'); @@ -3297,18 +3306,7 @@ uint32_t IedConnection_createDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference, LinkedList /* char* */ dataSetElements, IedConnection_GenericServiceHandler handler, void* parameter) { - MmsError mmsError = MMS_ERROR_NONE; - - 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; + uint32_t invokeId = 0; char domainIdBuffer[65]; char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1]; @@ -3352,6 +3350,19 @@ IedConnection_createDataSetAsync(IedConnection self, IedClientError* error, cons 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); @@ -3380,6 +3391,8 @@ IedConnection_createDataSetAsync(IedConnection self, IedClientError* error, cons &mmsError, domainId, itemId, dataSetEntries, createDataSetAsyncHandler, self); } + invokeId = call->invokeId; + *error = iedConnection_mapMmsErrorToIedError(mmsError); cleanup_list: @@ -3387,15 +3400,7 @@ IedConnection_createDataSetAsync(IedConnection self, IedClientError* error, cons LinkedList_destroyDeep(dataSetEntries, (LinkedListValueDeleteFunction) MmsVariableAccessSpecification_destroy); exit_function: - - if (*error != IED_ERROR_OK) { - iedConnection_releaseOutstandingCall(self, call); - - return 0; - } - else { - return call->invokeId; - } + return invokeId; } LinkedList /* */ @@ -3520,8 +3525,6 @@ getDataSetDirectoryAsyncHandler(uint32_t invokeId, void* parameter, MmsError mms if (handler) handler(call->invokeId, call->callbackParameter, err, dataSetMembers, deletable); - - iedConnection_releaseOutstandingCall(self, call); } if (specs) @@ -3532,7 +3535,7 @@ uint32_t IedConnection_getDataSetDirectoryAsync(IedConnection self, IedClientError* error, const char* dataSetReference, IedConnection_GetDataSetDirectoryHandler handler, void* parameter) { - MmsError mmsError = MMS_ERROR_NONE; + uint32_t invokeId = 0; IedConnectionOutstandingCall call = iedConnection_allocateOutstandingCall(self); @@ -3587,6 +3590,9 @@ IedConnection_getDataSetDirectoryAsync(IedConnection self, IedClientError* error isAssociationSpecific = true; } + MmsError mmsError = MMS_ERROR_NONE; + + if (isAssociationSpecific) MmsConnection_readNamedVariableListDirectoryAssociationSpecificAsync(self->connection, &(call->invokeId), &mmsError, itemId, getDataSetDirectoryAsyncHandler, self); @@ -3596,15 +3602,7 @@ IedConnection_getDataSetDirectoryAsync(IedConnection self, IedClientError* error *error = iedConnection_mapMmsErrorToIedError(mmsError); exit_function: - - if (*error != IED_ERROR_OK) { - iedConnection_releaseOutstandingCall(self, call); - - return 0; - } - else { - return call->invokeId; - } + return invokeId; } ClientDataSet diff --git a/src/iec61850/inc/iec61850_client.h b/src/iec61850/inc/iec61850_client.h index 852f21920..4e7bca395 100644 --- a/src/iec61850/inc/iec61850_client.h +++ b/src/iec61850/inc/iec61850_client.h @@ -266,6 +266,16 @@ IedConnection_setRequestTimeout(IedConnection self, uint32_t timeoutInMs); LIB61850_API uint32_t IedConnection_getRequestTimeout(IedConnection self); +/** + * \brief get current InvokeId + * + * \param self the connection object + * + * \return current InvokeId + */ +LIB61850_API uint32_t +IedConnection_getInvokeId(IedConnection self); + /** * \brief Set the time quality for all timestamps generated by this IedConnection instance * diff --git a/src/mms/inc/mms_client_connection.h b/src/mms/inc/mms_client_connection.h index 70bedc283..5e00ae275 100644 --- a/src/mms/inc/mms_client_connection.h +++ b/src/mms/inc/mms_client_connection.h @@ -170,6 +170,16 @@ MmsConnection_setRequestTimeout(MmsConnection self, uint32_t timeoutInMs); LIB61850_API uint32_t MmsConnection_getRequestTimeout(MmsConnection self); +/** + * \brief Get current invokeId + * + * \param self MmsConnection instance to operate on + * + * \return current invokeId + */ +LIB61850_API uint32_t +MmsConnection_getInvokeId(MmsConnection self); + /** * \brief Set the connect timeout in ms for this connection instance * diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index e1bb00393..7b79db8db 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -1658,6 +1658,12 @@ MmsConnection_getRequestTimeout(MmsConnection self) return self->requestTimeout; } +uint32_t +MmsConnection_getInvokeId(MmsConnection self) +{ + return self->nextInvokeId; +} + void MmsConnection_setConnectTimeout(MmsConnection self, uint32_t timeoutInMs) {