diff --git a/src/hal/filesystem/linux/file_provider_linux.c b/src/hal/filesystem/linux/file_provider_linux.c index b807319c..05b1689e 100644 --- a/src/hal/filesystem/linux/file_provider_linux.c +++ b/src/hal/filesystem/linux/file_provider_linux.c @@ -58,6 +58,12 @@ FileSystem_readFile(FileHandle handle, uint8_t* buffer, int maxSize) return fread(buffer, maxSize, 1, (FILE*) handle); } +int +FileSystem_writeFile(FileHandle handle, uint8_t* buffer, int size) +{ + return fwrite(buffer, size, 1, (FILE*) handle); +} + void FileSystem_closeFile(FileHandle handle) { diff --git a/src/hal/filesystem/win32/file_provider_win32.c b/src/hal/filesystem/win32/file_provider_win32.c index 21511289..2f531e1d 100644 --- a/src/hal/filesystem/win32/file_provider_win32.c +++ b/src/hal/filesystem/win32/file_provider_win32.c @@ -64,6 +64,12 @@ FileSystem_readFile(FileHandle handle, uint8_t* buffer, int maxSize) return fread(buffer, maxSize, 1, (FILE*) handle); } +int +FileSystem_writeFile(FileHandle handle, uint8_t* buffer, int size) +{ + return fwrite(buffer, size, 1, (FILE*) handle); +} + void FileSystem_closeFile(FileHandle handle) { diff --git a/src/hal/inc/hal_filesystem.h b/src/hal/inc/hal_filesystem.h index f18f6745..4248810a 100644 --- a/src/hal/inc/hal_filesystem.h +++ b/src/hal/inc/hal_filesystem.h @@ -63,7 +63,7 @@ FileSystem_openFile(char* pathName, bool readWrite); * * This function will read the next block of the file. The maximum number of bytes to read * is given. A call to this function will move the file position by the number of bytes read. - * If the file position reaches the end of file then subseqeuent calls of this function shall + * If the file position reaches the end of file then subsequent calls of this function shall * return 0. * * \param handle the file handle to identify the file @@ -75,6 +75,18 @@ FileSystem_openFile(char* pathName, bool readWrite); int FileSystem_readFile(FileHandle handle, uint8_t* buffer, int maxSize); +/** + * \brief write to an open file + * + * \param handle the file handle to identify the file + * \param buffer the buffer with the data to write + * \param size the number of bytes to write + * + * \return the number of bytes actually written + */ +int +FileSystem_writeFile(FileHandle handle, uint8_t* buffer, int size); + /** * \brief close an open file * diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index 70ea8841..36775725 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -736,7 +736,8 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) #if (MMS_OBTAIN_FILE_SERVICE == 1) else if (tag == 0xa0) { - printf("MMS_CLIENT: received confirmed request PDU (size=%i)\n", payload->size); + if (DEBUG_MMS_CLIENT) + printf("MMS_CLIENT: received confirmed request PDU (size=%i)\n", payload->size); // TODO handle confirmed request PDU only when obtainFile service is enabled // TODO extract function @@ -761,20 +762,14 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) bufPos = BerDecoder_decodeLength(buf, &length, bufPos, payload->size); - // printf("tag:%02x len:%i\n", tag, length); - -// if (bufPos < 0) { -// mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response); -// return; -// } - if (extendedTag) { switch(tag) { #if (MMS_FILE_SERVICE == 1) case 0x48: /* file-open-request */ { - printf("MMS_CLIENT: received file-open-request\n"); + if (DEBUG_MMS_CLIENT) + printf("MMS_CLIENT: received file-open-request\n"); ByteBuffer* response = IsoClientConnection_allocateTransmitBuffer(self->isoClient); @@ -788,7 +783,8 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) case 0x49: /* file-read-request */ { - printf("MMS_CLIENT: received file-read-request\n"); + if (DEBUG_MMS_CLIENT) + printf("MMS_CLIENT: received file-read-request\n"); ByteBuffer* response = IsoClientConnection_allocateTransmitBuffer(self->isoClient); @@ -802,7 +798,8 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) case 0x4a: /* file-close-request */ { - printf("MMS_CLIENT: received file-close-request\n"); + if (DEBUG_MMS_CLIENT) + printf("MMS_CLIENT: received file-close-request\n"); ByteBuffer* response = IsoClientConnection_allocateTransmitBuffer(self->isoClient); @@ -817,8 +814,9 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) default: // mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response); + if (DEBUG_MMS_CLIENT) + printf("MMS_CLIENT: unexpected message from server!\n"); - printf("MMS_CLIENT: unexpected message from server!\n"); IsoClientConnection_releaseReceiveBuffer(self->isoClient); break; @@ -836,8 +834,10 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) default: // mmsServer_writeMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE, response); - printf("MMS_CLIENT: unexpected message from server!\n"); - IsoClientConnection_releaseReceiveBuffer(self->isoClient); + if (DEBUG_MMS_CLIENT) + printf("MMS_CLIENT: unexpected message from server!\n"); + + IsoClientConnection_releaseReceiveBuffer(self->isoClient); goto exit_with_error; @@ -2087,8 +2087,6 @@ MmsConnection_obtainFile(MmsConnection self, MmsError* mmsError, const char* sou uint32_t invokeId = getNextInvokeId(self); - //TODO enable file service - mmsClient_createObtainFileRequest(invokeId, payload, sourceFile, destinationFile); ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload); diff --git a/src/mms/iso_mms/client/mms_client_files.c b/src/mms/iso_mms/client/mms_client_files.c index d1c1a6c3..38dff428 100644 --- a/src/mms/iso_mms/client/mms_client_files.c +++ b/src/mms/iso_mms/client/mms_client_files.c @@ -96,8 +96,6 @@ openFile(char* fileName, bool readWrite) createExtendedFilename(extendedFileName, fileName); - printf("open file %s\n", extendedFileName); - return FileSystem_openFile(extendedFileName, readWrite); } @@ -222,7 +220,7 @@ mmsClient_handleFileReadRequest( MmsFileReadStateMachine* frsm = getFrsm(connection, frsmId); if (frsm != NULL) - mmsMsg_createFileReadResponse(connection, invokeId, response, frsm); + mmsMsg_createFileReadResponse(connection->parameters.maxPduSize, invokeId, response, frsm); else mmsServer_createServiceErrorPdu(invokeId, response, MMS_ERROR_FILE_OTHER); } diff --git a/src/mms/iso_mms/server/mms_file_service.c b/src/mms/iso_mms/server/mms_file_service.c index 77ff3033..7c5b63ba 100644 --- a/src/mms/iso_mms/server/mms_file_service.c +++ b/src/mms/iso_mms/server/mms_file_service.c @@ -376,34 +376,25 @@ createObtainFileResponse(uint32_t invokeId, ByteBuffer* response) createNullResponseExtendedTag(invokeId, response, 0x2e); } - -//#define MMS_FILE_UPLOAD_STATE_COMPLETE 11 - void mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task) { - //send response message - - /* - * states: - * 0 - no state / not used - * 1 - - * 2 - file open sent - * 3 - file read sent - * 4 - file close sent - * - */ - printf("mmsServer_fileUploadTask (%p) state=%i\n", task, task->state); - switch (task->state) { - case MMS_FILE_UPLOAD_STATE_NOT_USED: /* state: not-used */ + + case MMS_FILE_UPLOAD_STATE_NOT_USED: break; case MMS_FILE_UPLOAD_STATE_FILE_OPEN_SENT: { if (Hal_getTimeInMs() > task->nextTimeout) { - printf("MMS_SERVER: file open timeout!\n"); - task->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_RESPONSE; + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: file open timeout!\n"); + + task->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; + + FileSystem_closeFile(task->fileHandle); + deleteFile(task->destinationFilename); } } break; @@ -430,8 +421,14 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task) case MMS_FILE_UPLOAD_STATE_FILE_READ_SENT: if (Hal_getTimeInMs() > task->nextTimeout) { - printf("MMS_SERVER: file read timeout!\n"); - task->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_RESPONSE; + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: file read timeout!\n"); + + task->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; + + FileSystem_closeFile(task->fileHandle); + deleteFile(task->destinationFilename); } break; @@ -457,8 +454,14 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task) case MMS_FILE_UPLOAD_STATE_FILE_CLOSE_SENT: if (Hal_getTimeInMs() > task->nextTimeout) { - printf("MMS_SERVER: file close timeout!\n"); - task->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_RESPONSE; + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: file close timeout!\n"); + + task->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; + + FileSystem_closeFile(task->fileHandle); + deleteFile(task->destinationFilename); } break; @@ -473,7 +476,15 @@ mmsServer_fileUploadTask(MmsServer self, MmsObtainFileTask task) break; + case MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_DESTINATION: + + //TODO send ObtainFileError + printf("MMS_SERVER: ObtainFile service: failed to create local file\n"); + + task->state = MMS_FILE_UPLOAD_STATE_NOT_USED; + + break; case MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_RESPONSE: { @@ -550,29 +561,39 @@ mmsServer_handleObtainFileRequest( //TODO check if destination file already exists. If exists return error message - printf("Download file %s from client to local file %s...\n", sourceFilename, destinationFilename); + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: Start download file %s from client to local file %s...\n", sourceFilename, destinationFilename); MmsObtainFileTask task = MmsServer_getObtainFileTask(connection->server); if (task != NULL) { - /* send file open request */ - task->lastRequestInvokeId = MmsServerConnection_getNextRequestInvokeId(connection); - task->connection = connection; + FileHandle fileHandle = openFile(destinationFilename, true); - strcpy(task->destinationFilename, destinationFilename); + if (fileHandle == NULL) { + task->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_DESTINATION; + } + else { + /* send file open request */ + task->lastRequestInvokeId = MmsServerConnection_getNextRequestInvokeId(connection); + task->connection = connection; + task->fileHandle = fileHandle; + task->obtainFileRequestInvokeId = invokeId; - ByteBuffer* request = MmsServer_reserveTransmitBuffer(connection->server); + strcpy(task->destinationFilename, destinationFilename); - mmsClient_createFileOpenRequest(task->lastRequestInvokeId, request, sourceFilename, 0); + ByteBuffer* request = MmsServer_reserveTransmitBuffer(connection->server); - IsoConnection_sendMessage(task->connection->isoConnection, request, false); + mmsClient_createFileOpenRequest(task->lastRequestInvokeId, request, sourceFilename, 0); - MmsServer_releaseTransmitBuffer(connection->server); + IsoConnection_sendMessage(task->connection->isoConnection, request, false); - task->nextTimeout = Hal_getTimeInMs() + 2000; /* timeout 2000 ms */ + MmsServer_releaseTransmitBuffer(connection->server); - task->state = MMS_FILE_UPLOAD_STATE_FILE_OPEN_SENT; + task->nextTimeout = Hal_getTimeInMs() + 2000; /* timeout 2000 ms */ + + task->state = MMS_FILE_UPLOAD_STATE_FILE_OPEN_SENT; + } } else goto exit_unavailable; diff --git a/src/mms/iso_mms/server/mms_server_connection.c b/src/mms/iso_mms/server/mms_server_connection.c index 92d5f189..3b5dccee 100644 --- a/src/mms/iso_mms/server/mms_server_connection.c +++ b/src/mms/iso_mms/server/mms_server_connection.c @@ -291,8 +291,10 @@ mmsFileReadHandler(void* parameter, int32_t frsmId, uint8_t* buffer, uint32_t by { MmsObtainFileTask task = (MmsObtainFileTask) parameter; - printf(" FILE %i received %i bytes\n", frsmId, bytesReceived); - //TODO write data to file + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: FILE %i received %i bytes\n", frsmId, bytesReceived); + + FileSystem_writeFile(task->fileHandle, buffer, bytesReceived); } static void @@ -328,7 +330,9 @@ handleConfirmedResponsePdu( #if (MMS_FILE_SERVICE == 1) case 0x48: /* file-open-response */ - printf("MMS_SERVER: received file-open-response\n"); + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: received file-open-response\n"); { MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId); @@ -338,26 +342,30 @@ handleConfirmedResponsePdu( int32_t frmsId; if (mmsMsg_parseFileOpenResponse(buffer, startBufPos, maxBufPos, &frmsId, NULL, NULL)) { - printf("MMS_SERVER: received file-open-response with frmsId=%i\n", frmsId); - fileTask->frmsId = frmsId; fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_READ; } else { - printf("MMS_SERVER: error parsing file-open-response\n"); + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: error parsing file-open-response\n"); fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; } } - else - printf("MMS_SERVER: unexpected file-open-response\n"); + else { + /* ignore */ + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: unexpected file-open-response\n"); + } } break; case 0x49: /* file-read-response */ - printf("MMS_SERVER: received file-read-response\n"); - { + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: received file-read-response\n"); + MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId); if (fileTask != NULL) { @@ -366,42 +374,47 @@ handleConfirmedResponsePdu( if (mmsMsg_parseFileReadResponse(buffer, startBufPos, maxBufPos, fileTask->frmsId, &moreFollows, mmsFileReadHandler, (void*) fileTask)) { - printf("MMS_SERVER: received file data\n"); - if (moreFollows) { fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_READ; } else { - - //TODO close local file - fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_CLOSE; } } else { fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE; - printf("MMS_SERVER: error parsing file-read-response\n"); + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: error parsing file-read-response\n"); } } - else - printf("MMS_SERVER: unexpected file-read-response\n"); + else { + /* ignore */ + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: unexpected file-read-response\n"); + } } break; case 0x4a: /* file-close-response */ { - - printf("MMS_SERVER: received file-close-response\n"); - + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: received file-close-response\n"); MmsObtainFileTask fileTask = getUploadTaskByInvokeId(self->server, invokeId); if (fileTask != NULL) { + FileSystem_closeFile(fileTask->fileHandle); fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_RESPONSE; } - else - printf("MMS_SERVER: unexpected file-close-response\n"); + else { + /* ignore */ + + if (DEBUG_MMS_SERVER) + printf("MMS_SERVER: unexpected file-close-response\n"); + } } break; #endif /* MMS_FILE_SERVICE == 1 */ diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index c658a995..c8c5be1d 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -554,3 +554,4 @@ EXPORTS MmsServer_installObtainFileHandler MmsServer_installGetFileCompleteHandler MmsServer_handleBackgroundTasks + FileSystem_writeFile diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 1d59bc29..f0e70d8f 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -632,3 +632,4 @@ EXPORTS MmsServer_installObtainFileHandler MmsServer_installGetFileCompleteHandler MmsServer_handleBackgroundTasks + FileSystem_writeFile