diff --git a/src/mms/inc_private/mms_client_internal.h b/src/mms/inc_private/mms_client_internal.h index 2c75a4a9..337fe833 100644 --- a/src/mms/inc_private/mms_client_internal.h +++ b/src/mms/inc_private/mms_client_internal.h @@ -88,8 +88,6 @@ struct sMmsOutstandingCall uint64_t timeout; }; -typedef struct sMmsOutstandingCall* MmsOutstandingCall; - /* private instance variables */ struct sMmsConnection { Semaphore lastInvokeIdLock; @@ -374,5 +372,8 @@ uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeId, ByteBuffer* response); +LIB61850_INTERNAL MmsOutstandingCall +mmsClient_getMatchingObtainFileRequest(MmsConnection self, const char* filename); + #endif /* MMS_MSG_INTERNAL_H_ */ diff --git a/src/mms/inc_private/mms_common_internal.h b/src/mms/inc_private/mms_common_internal.h index 8f8c92b6..f5431a87 100644 --- a/src/mms/inc_private/mms_common_internal.h +++ b/src/mms/inc_private/mms_common_internal.h @@ -1,7 +1,7 @@ /* * mms_common_internal.h * - * Copyright 2013-2018 Michael Zillgith + * Copyright 2013-2019 Michael Zillgith * * This file is part of libIEC61850. * @@ -42,11 +42,17 @@ #include "hal_filesystem.h" +typedef struct sMmsOutstandingCall* MmsOutstandingCall; + typedef struct { int32_t frsmId; uint32_t readPosition; uint32_t fileSize; FileHandle fileHandle; + +#if (MMS_OBTAIN_FILE_SERVICE == 1) + MmsOutstandingCall obtainRequest; +#endif } MmsFileReadStateMachine; /* include for MmsFileReadHandler definition */ diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index 1002c42a..5e8b39ad 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -314,6 +314,36 @@ removeFromOutstandingCalls(MmsConnection self, uint32_t invokeId) Semaphore_post(self->outstandingCallsLock); } +MmsOutstandingCall +mmsClient_getMatchingObtainFileRequest(MmsConnection self, const char* filename) +{ + int i = 0; + + Semaphore_wait(self->outstandingCallsLock); + + for (i = 0; i < OUTSTANDING_CALLS; i++) { + if (self->outstandingCalls[i].isUsed) { + + if (self->outstandingCalls[i].type == MMS_CALL_TYPE_OBTAIN_FILE) { + + char* storedFilename = (char*) self->outstandingCalls[i].internalParameter.ptr; + + if (storedFilename) { + + if (!strcmp(filename, storedFilename)) { + Semaphore_post(self->outstandingCallsLock); + return &(self->outstandingCalls[i]); + } + } + } + } + } + + Semaphore_post(self->outstandingCallsLock); + + return NULL; +} + static void sendMessage(MmsConnection self, ByteBuffer* message) { @@ -927,6 +957,11 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M MmsConnection_GenericServiceHandler handler = (MmsConnection_GenericServiceHandler) outstandingCall->userCallback; + if (outstandingCall->type == MMS_CALL_TYPE_OBTAIN_FILE) { + if (outstandingCall->internalParameter.ptr) + GLOBAL_FREEMEM(outstandingCall->internalParameter.ptr); + } + if (err != MMS_ERROR_NONE) { handler(outstandingCall->invokeId, outstandingCall->userParameter, err, false); } @@ -4050,7 +4085,11 @@ MmsConnection_obtainFileAsync(MmsConnection self, MmsError* mmsError, const char mmsClient_createObtainFileRequest(invokeId, payload, sourceFile, destinationFile); MmsClientInternalParameter intParam; - intParam.ptr = NULL; + + if (sourceFile) + intParam.ptr = StringUtils_copyString(sourceFile); + else + intParam.ptr = NULL; MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_OBTAIN_FILE, handler, parameter, intParam); diff --git a/src/mms/iso_mms/client/mms_client_files.c b/src/mms/iso_mms/client/mms_client_files.c index 9ddb26cb..b10ba7ae 100644 --- a/src/mms/iso_mms/client/mms_client_files.c +++ b/src/mms/iso_mms/client/mms_client_files.c @@ -127,12 +127,25 @@ mmsClient_handleFileOpenRequest( MmsFileReadStateMachine* frsm = getFreeFrsm(connection); if (frsm != NULL) { + + MmsOutstandingCall obtainFileCall = mmsClient_getMatchingObtainFileRequest(connection, filename); + + if (obtainFileCall) { + + if (DEBUG_MMS_CLIENT) + printf("MMS_CLIENT: file open is matching obtain file request for file %s\n", filename); + + obtainFileCall->timeout = Hal_getTimeInMs() + connection->requestTimeout; + } + FileHandle fileHandle = mmsMsg_openFile(MmsConnection_getFilestoreBasepath(connection), filename, false); if (fileHandle != NULL) { + frsm->fileHandle = fileHandle; frsm->readPosition = filePosition; frsm->frsmId = getNextFrsmId(connection); + frsm->obtainRequest = obtainFileCall; mmsMsg_createFileOpenResponse(MmsConnection_getFilestoreBasepath(connection), invokeId, response, filename, frsm); @@ -172,8 +185,12 @@ mmsClient_handleFileReadRequest( MmsFileReadStateMachine* frsm = getFrsm(connection, frsmId); - if (frsm != NULL) + if (frsm) { + if (frsm->obtainRequest) + frsm->obtainRequest->timeout = Hal_getTimeInMs() + connection->requestTimeout; + mmsMsg_createFileReadResponse(connection->parameters.maxPduSize, invokeId, response, frsm); + } else mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_FILE_OTHER); } @@ -189,11 +206,19 @@ mmsClient_handleFileCloseRequest( MmsFileReadStateMachine* frsm = getFrsm(connection, frsmId); - FileSystem_closeFile(frsm->fileHandle); - frsm->fileHandle = NULL; - frsm->frsmId = 0; + if (frsm) { + if (frsm->obtainRequest) + frsm->obtainRequest->timeout = Hal_getTimeInMs() + connection->requestTimeout; + + FileSystem_closeFile(frsm->fileHandle); + frsm->fileHandle = NULL; + frsm->frsmId = 0; + frsm->obtainRequest = NULL; - mmsMsg_createFileCloseResponse(invokeId, response); + mmsMsg_createFileCloseResponse(invokeId, response); + } + else + mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_FILE_OTHER); }