- MMS server: fixed potential crash when client connection closed during file upload (LIB61850-2)

- MMS client: fixed problem - doesn't close file when the setFile (obtainFile) service is interrupted e.g. due to connection loss (LIB61850-230)
v1.4
Michael Zillgith 4 years ago
parent 86a9f3169e
commit ebdc086b8e

@ -370,10 +370,13 @@ mmsClient_handleFileReadRequest(
LIB61850_INTERNAL void LIB61850_INTERNAL void
mmsClient_handleFileCloseRequest( mmsClient_handleFileCloseRequest(
MmsConnection connection, MmsConnection connection,
uint8_t* buffer, int bufPos, int maxBufPos, uint8_t* buffer, int bufPos, int maxBufPos,
uint32_t invokeId, uint32_t invokeId,
ByteBuffer* response); ByteBuffer* response);
LIB61850_INTERNAL void
mmsClient_closeOutstandingOpenFiles(MmsConnection connection);
LIB61850_INTERNAL MmsOutstandingCall LIB61850_INTERNAL MmsOutstandingCall
mmsClient_getMatchingObtainFileRequest(MmsConnection self, const char* filename); mmsClient_getMatchingObtainFileRequest(MmsConnection self, const char* filename);

@ -98,6 +98,9 @@ struct sMmsObtainFileTask {
uint64_t nextTimeout; uint64_t nextTimeout;
int32_t frmsId; int32_t frmsId;
int state; int state;
#if (CONFIG_MMS_THREADLESS_STACK != 1)
Semaphore taskLock;
#endif
}; };
#endif /* (MMS_OBTAIN_FILE_SERVICE == 1) */ #endif /* (MMS_OBTAIN_FILE_SERVICE == 1) */

@ -187,4 +187,7 @@ MmsServer_getConnectionCounter(MmsServer self);
LIB61850_INTERNAL void LIB61850_INTERNAL void
MmsServer_stopListeningThreadless(MmsServer self); MmsServer_stopListeningThreadless(MmsServer self);
LIB61850_INTERNAL const char*
MmsServer_getFilesystemBasepath(MmsServer self);
#endif /* MMS_SERVER_LIBINTERNAL_H_ */ #endif /* MMS_SERVER_LIBINTERNAL_H_ */

@ -1035,6 +1035,25 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload)
if (self->connectionLostHandler != NULL) if (self->connectionLostHandler != NULL)
self->connectionLostHandler(self, self->connectionLostHandlerParameter); self->connectionLostHandler(self, self->connectionLostHandlerParameter);
/* Cleanup outstanding calls */
{
int i;
for (i = 0; i < OUTSTANDING_CALLS; i++) {
if (self->outstandingCalls[i].isUsed) {
if (self->outstandingCalls[i].type != MMS_CALL_TYPE_NONE)
handleAsyncResponse(self, NULL, 0, &(self->outstandingCalls[i]), MMS_ERROR_SERVICE_TIMEOUT);
self->outstandingCalls[i].isUsed = false;
break;
}
}
}
Semaphore_post(self->outstandingCallsLock);
return true; return true;
} }
@ -1539,6 +1558,9 @@ MmsConnection_destroy(MmsConnection self)
if (self->filestoreBasepath != NULL) if (self->filestoreBasepath != NULL)
GLOBAL_FREEMEM(self->filestoreBasepath); GLOBAL_FREEMEM(self->filestoreBasepath);
#endif #endif
/* Close outstanding open files */
mmsClient_closeOutstandingOpenFiles(self);
#endif #endif
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);

@ -224,6 +224,19 @@ mmsClient_handleFileCloseRequest(
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_FILE_OTHER); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_FILE_OTHER);
} }
void
mmsClient_closeOutstandingOpenFiles(MmsConnection connection)
{
int i;
for (i = 0; i < CONFIG_MMS_MAX_NUMBER_OF_OPEN_FILES_PER_CONNECTION; i++) {
if (connection->frsms[i].fileHandle != NULL) {
FileSystem_closeFile(connection->frsms[i].fileHandle);
connection->frsms[i].fileHandle = NULL;
}
}
}
#endif /* (MMS_OBTAIN_FILE_SERVICE == 1) */ #endif /* (MMS_OBTAIN_FILE_SERVICE == 1) */

@ -431,7 +431,7 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task)
FileSystem_closeFile(task->fileHandle); FileSystem_closeFile(task->fileHandle);
task->fileHandle = NULL; task->fileHandle = NULL;
} }
deleteFile(MmsServerConnection_getFilesystemBasepath(task->connection), task->destinationFilename); deleteFile(MmsServer_getFilesystemBasepath(self), task->destinationFilename);
} }
} }
break; break;
@ -471,7 +471,7 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task)
FileSystem_closeFile(task->fileHandle); FileSystem_closeFile(task->fileHandle);
task->fileHandle = NULL; task->fileHandle = NULL;
} }
deleteFile(MmsServerConnection_getFilesystemBasepath(task->connection), task->destinationFilename); deleteFile(MmsServer_getFilesystemBasepath(self), task->destinationFilename);
} }
break; break;
@ -510,7 +510,7 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task)
FileSystem_closeFile(task->fileHandle); FileSystem_closeFile(task->fileHandle);
task->fileHandle = NULL; task->fileHandle = NULL;
deleteFile(MmsServerConnection_getFilesystemBasepath(task->connection), task->destinationFilename); deleteFile(MmsServer_getFilesystemBasepath(self), task->destinationFilename);
} }
break; break;
@ -535,7 +535,8 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task)
FileSystem_closeFile(task->fileHandle); FileSystem_closeFile(task->fileHandle);
task->fileHandle = NULL; task->fileHandle = NULL;
} }
deleteFile(MmsServerConnection_getFilesystemBasepath(task->connection), task->destinationFilename);
deleteFile(MmsServer_getFilesystemBasepath(self), task->destinationFilename);
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: ObtainFile service: failed to open file from client\n"); printf("MMS_SERVER: ObtainFile service: failed to open file from client\n");
@ -563,8 +564,8 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task)
FileSystem_closeFile(task->fileHandle); FileSystem_closeFile(task->fileHandle);
task->fileHandle = NULL; task->fileHandle = NULL;
if (task->destinationFilename) if (task->destinationFilename[0])
deleteFile(MmsServerConnection_getFilesystemBasepath(task->connection), task->destinationFilename); deleteFile(MmsServer_getFilesystemBasepath(self), task->destinationFilename);
} }
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)
@ -602,8 +603,9 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task)
if (task->fileHandle){ if (task->fileHandle){
FileSystem_closeFile(task->fileHandle); FileSystem_closeFile(task->fileHandle);
task->fileHandle = NULL; task->fileHandle = NULL;
if (task->destinationFilename)
deleteFile(MmsServerConnection_getFilesystemBasepath(task->connection), task->destinationFilename); if (task->destinationFilename[0])
deleteFile(MmsServer_getFilesystemBasepath(self), task->destinationFilename);
} }
task->state = MMS_FILE_UPLOAD_STATE_NOT_USED; task->state = MMS_FILE_UPLOAD_STATE_NOT_USED;
} }
@ -625,8 +627,13 @@ mmsServerConnection_stopFileUploadTasks(MmsServerConnection self)
if (server->fileUploadTasks[i].state != 0) { if (server->fileUploadTasks[i].state != 0) {
if (server->fileUploadTasks[i].connection == self) { if (server->fileUploadTasks[i].connection == self) {
Semaphore_wait(server->fileUploadTasks[i].taskLock);
/* stop file upload task */ /* stop file upload task */
server->fileUploadTasks[i].state = MMS_FILE_UPLOAD_STATE_INTERRUPTED; server->fileUploadTasks[i].state = MMS_FILE_UPLOAD_STATE_INTERRUPTED;
Semaphore_post(server->fileUploadTasks[i].taskLock);
} }
} }

@ -202,6 +202,8 @@ MmsServer_getObtainFileTask(MmsServer self)
if (self->fileUploadTasks[i].state == 0) { if (self->fileUploadTasks[i].state == 0) {
self->fileUploadTasks[i].state = 1; self->fileUploadTasks[i].state = 1;
if (self->fileUploadTasks[i].taskLock == NULL)
self->fileUploadTasks[i].taskLock = Semaphore_create(1);
return &(self->fileUploadTasks[i]); return &(self->fileUploadTasks[i]);
} }
@ -314,6 +316,16 @@ MmsServer_destroy(MmsServer self)
GLOBAL_FREEMEM(self->filestoreBasepath); GLOBAL_FREEMEM(self->filestoreBasepath);
#endif #endif
#if (MMS_OBTAIN_FILE_SERVICE == 1)
{
int i;
for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++) {
if (self->fileUploadTasks[i].taskLock)
Semaphore_destroy(self->fileUploadTasks[i].taskLock);
}
}
#endif
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
} }
@ -508,8 +520,15 @@ MmsServer_handleBackgroundTasks(MmsServer self)
int i; int i;
for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++) for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++)
{ {
if (self->fileUploadTasks[i].state != 0) if (self->fileUploadTasks[i].state != 0) {
mmsServer_fileUploadTask(self, &(self->fileUploadTasks[i]));
Semaphore_wait(self->fileUploadTasks[i].taskLock);
if (self->fileUploadTasks[i].state != 0)
mmsServer_fileUploadTask(self, &(self->fileUploadTasks[i]));
Semaphore_post(self->fileUploadTasks[i].taskLock);
}
} }
#endif /* (MMS_OBTAIN_FILE_SERVICE == 1) */ #endif /* (MMS_OBTAIN_FILE_SERVICE == 1) */
@ -535,3 +554,17 @@ MmsServer_stopListeningThreadless(MmsServer self)
IsoServer_stopListeningThreadless(self->isoServer); IsoServer_stopListeningThreadless(self->isoServer);
} }
const char*
MmsServer_getFilesystemBasepath(MmsServer self)
{
#if (CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME == 1)
if (self->filestoreBasepath != NULL)
return self->filestoreBasepath;
else
return CONFIG_VIRTUAL_FILESTORE_BASEPATH;
#else
return CONFIG_VIRTUAL_FILESTORE_BASEPATH;
#endif
}

Loading…
Cancel
Save