- MMS client: added asynchronous file service functions

pull/93/head
Michael Zillgith 7 years ago
parent d9800a5f74
commit 069646f954

@ -924,9 +924,24 @@ MmsConnection_getServerStatusAsync(MmsConnection self, MmsError* mmsError, bool
typedef void
(*MmsFileDirectoryHandler) (void* parameter, char* filename, uint32_t size, uint64_t lastModified);
/**
* \brief Callback handler for the get file directory service
*
* Will be called once for each file directory entry and after the last entry with \ref filename = NULL to indicate
* with \ref moreFollows if more data is available at the server. In case of an error the callback will be called with
* \ref mmsError != MMS_ERROR_NONE and moreFollows = false.
*/
typedef void
(*MmsConnection_FileDirectoryHandler) (int invokeId, void* parameter, MmsError mmsError, char* filename, uint32_t size, uint64_t lastModfified,
bool moreFollows);
typedef void
(*MmsFileReadHandler) (void* parameter, int32_t frsmId, uint8_t* buffer, uint32_t bytesReceived);
typedef void
(*MmsConnection_FileReadHandler) (int invokeId, void* parameter, MmsError mmsError, uint8_t* buffer, uint32_t byteReceived,
bool moreFollows);
/**
* \brief open a file for read
@ -940,6 +955,14 @@ int32_t
MmsConnection_fileOpen(MmsConnection self, MmsError* mmsError, const char* filename, uint32_t initialPosition,
uint32_t* fileSize, uint64_t* lastModified);
typedef void
(*MmsConnection_FileOpenHandler) (int invokeId, void* parameter, MmsError mmsError, int32_t frsmId, uint32_t fileSize, uint64_t lastModified);
uint32_t
MmsConnection_fileOpenAsync(MmsConnection self, MmsError* mmsError, const char* filename, uint32_t initialPosition, MmsConnection_FileOpenHandler handler,
void* parameter);
/**
* \brief read the next data block from the file
*
@ -954,6 +977,9 @@ MmsConnection_fileOpen(MmsConnection self, MmsError* mmsError, const char* filen
bool
MmsConnection_fileRead(MmsConnection self, MmsError* mmsError, int32_t frsmId, MmsFileReadHandler handler, void* handlerParameter);
uint32_t
MmsConnection_fileReadAsync(MmsConnection self, MmsError* mmsError, int32_t frsmId, MmsConnection_FileReadHandler handler, void* parameter);
/**
* \brief close the file with the specified frsmID
*
@ -964,6 +990,9 @@ MmsConnection_fileRead(MmsConnection self, MmsError* mmsError, int32_t frsmId, M
void
MmsConnection_fileClose(MmsConnection self, MmsError* mmsError, int32_t frsmId);
uint32_t
MmsConnection_fileCloseAsync(MmsConnection self, MmsError* mmsError, uint32_t frsmId, MmsConnection_GenericServiceHandler handler, void* parameter);
/**
* \brief delete the file with the specified name
*
@ -974,6 +1003,10 @@ MmsConnection_fileClose(MmsConnection self, MmsError* mmsError, int32_t frsmId);
void
MmsConnection_fileDelete(MmsConnection self, MmsError* mmsError, const char* fileName);
uint32_t
MmsConnection_fileDeleteAsync(MmsConnection self, MmsError* mmsError, const char* fileName,
MmsConnection_GenericServiceHandler handler, void* parameter);
/**
* \brief rename the file with the specified name
*
@ -985,6 +1018,9 @@ MmsConnection_fileDelete(MmsConnection self, MmsError* mmsError, const char* fil
void
MmsConnection_fileRename(MmsConnection self, MmsError* mmsError, const char* currentFileName, const char* newFileName);
uint32_t
MmsConnection_fileRenameAsync(MmsConnection self, MmsError* mmsError, const char* currentFileName, const char* newFileName,
MmsConnection_GenericServiceHandler handler, void* parameter);
/**
* \brief Send an obtainFile request to the server (used to initiate file download to server)
@ -997,6 +1033,10 @@ MmsConnection_fileRename(MmsConnection self, MmsError* mmsError, const char* cur
void
MmsConnection_obtainFile(MmsConnection self, MmsError* mmsError, const char* sourceFile, const char* destinationFile);
uint32_t
MmsConnection_obtainFileAsync(MmsConnection self, MmsError* mmsError, const char* sourceFile, const char* destinationFile,
MmsConnection_GenericServiceHandler handler, void* parameter);
/**
* \brief get the file directory of the server.
*
@ -1017,6 +1057,10 @@ bool
MmsConnection_getFileDirectory(MmsConnection self, MmsError* mmsError, const char* fileSpecification, const char* continueAfter,
MmsFileDirectoryHandler handler, void* handlerParameter);
uint32_t
MmsConnection_getFileDirectoryAsync(MmsConnection self, MmsError* mmsError, const char* fileSpecification, const char* continueAfter,
MmsConnection_FileDirectoryHandler handler, void* parameter);
typedef struct sMmsJournalEntry* MmsJournalEntry;
typedef struct sMmsJournalVariable* MmsJournalVariable;

@ -74,7 +74,14 @@ typedef enum {
MMS_CALL_TYPE_GET_SERVER_STATUS,
MMS_CALL_TYPE_IDENTIFY,
MMS_CALL_TYPE_READ_JOURNAL,
MMS_CALL_TYPE_GET_NAME_LIST
MMS_CALL_TYPE_GET_NAME_LIST,
MMS_CALL_TYPE_FILE_OPEN,
MMS_CALL_TYPE_FILE_READ,
MMS_CALL_TYPE_FILE_CLOSE,
MMS_CALL_TYPE_FILE_DELETE,
MMS_CALL_TYPE_FILE_RENAME,
MMS_CALL_TYPE_OBTAIN_FILE,
MMS_CALL_TYPE_GET_FILE_DIR
} eMmsOutstandingCallType;
struct sMmsOutstandingCall
@ -312,8 +319,7 @@ void
mmsClient_createFileDirectoryRequest(uint32_t invokeId, ByteBuffer* request, const char* fileSpecification, const char* continueAfter);
bool
mmsClient_parseFileDirectoryResponse(MmsConnection self, MmsFileDirectoryHandler handler, void* handlerParameter,
bool* moreFollows);
mmsClient_parseFileDirectoryResponse(ByteBuffer* response, int bufPos, uint32_t invokeId, MmsConnection_FileDirectoryHandler handler, void* parameter);
bool
mmsClient_parseInitiateResponse(MmsConnection self);

@ -56,7 +56,7 @@ bool
mmsMsg_parseFileOpenResponse(uint8_t* buffer, int bufPos, int maxBufPos, int32_t* frsmId, uint32_t* fileSize, uint64_t* lastModified);
bool
mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, int32_t frsmId, bool* moreFollows, MmsFileReadHandler handler, void* handlerParameter);
mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, bool* moreFollows, uint8_t** dataBuffer, int* dataLength);
void
mmsMsg_createFileReadResponse(int maxPduSize, uint32_t invokeId, ByteBuffer* response, MmsFileReadStateMachine* frsm);

@ -990,7 +990,78 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, nameList, moreFollows);
}
}
}
else if (outstandingCall->type == MMS_CALL_TYPE_FILE_OPEN) {
MmsConnection_FileOpenHandler handler =
(MmsConnection_FileOpenHandler) outstandingCall->userCallback;
if (err != MMS_ERROR_NONE) {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, 0, 0, 0);
}
else {
int32_t frsmId;
uint32_t fileSize;
uint64_t lastModified;
if (mmsMsg_parseFileOpenResponse(ByteBuffer_getBuffer(response), bufPos, ByteBuffer_getSize(response),
&frsmId, &fileSize, &lastModified) == false)
{
handler(outstandingCall->invokeId, outstandingCall->userParameter, MMS_ERROR_PARSING_RESPONSE, 0, 0, 0);
}
else {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, frsmId, fileSize, lastModified);
}
}
}
else if (outstandingCall->type == MMS_CALL_TYPE_FILE_READ) {
MmsConnection_FileReadHandler handler =
(MmsConnection_FileReadHandler) outstandingCall->userCallback;
if (err != MMS_ERROR_NONE) {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, NULL, 0, false);
}
else {
bool moreFollows;
uint8_t* dataBuffer;
int dataLength;
if (mmsMsg_parseFileReadResponse(ByteBuffer_getBuffer(response), bufPos, ByteBuffer_getSize(response), &moreFollows, &dataBuffer, &dataLength) == false)
{
handler(outstandingCall->invokeId, outstandingCall->userParameter, MMS_ERROR_PARSING_RESPONSE, NULL, 0, false);
}
else {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, dataBuffer, dataLength, moreFollows);
}
}
}
else if ((outstandingCall->type == MMS_CALL_TYPE_FILE_CLOSE) ||
(outstandingCall->type == MMS_CALL_TYPE_FILE_DELETE) ||
(outstandingCall->type == MMS_CALL_TYPE_FILE_RENAME) ||
(outstandingCall->type == MMS_CALL_TYPE_OBTAIN_FILE))
{
MmsConnection_GenericServiceHandler handler =
(MmsConnection_GenericServiceHandler) outstandingCall->userCallback;
if (err != MMS_ERROR_NONE) {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, false);
}
else {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, true);
}
}
else if (outstandingCall->type == MMS_CALL_TYPE_GET_FILE_DIR) {
MmsConnection_FileDirectoryHandler handler =
(MmsConnection_FileDirectoryHandler) outstandingCall->userCallback;
if (err != MMS_ERROR_NONE) {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, NULL, 0, 0, false);
}
else {
if (mmsClient_parseFileDirectoryResponse(response, bufPos, outstandingCall->invokeId, handler, outstandingCall->userParameter) == false)
handler(outstandingCall->invokeId, outstandingCall->userParameter, MMS_ERROR_PARSING_RESPONSE, NULL, 0, 0, false);
}
}
removeFromOutstandingCalls(self, outstandingCall->invokeId);
@ -3220,34 +3291,103 @@ exit_function:
return invokeId;
}
struct fileOpenParameters
{
Semaphore waitForResponse;
MmsError err;
int32_t frsmId;
uint32_t fileSize;
uint64_t lastModified;
};
static void
fileOpenHandler(int invokeId, void* parameter, MmsError mmsError, int32_t frsmId, uint32_t fileSize, uint64_t lastModified)
{
struct fileOpenParameters* parameters = (struct fileOpenParameters*) parameter;
parameters->err = mmsError;
parameters->frsmId = frsmId;
parameters->fileSize = fileSize;
parameters->lastModified = lastModified;
/* unblock user thread */
Semaphore_post(parameters->waitForResponse);
}
int32_t
MmsConnection_fileOpen(MmsConnection self, MmsError* mmsError, const char* filename, uint32_t initialPosition,
uint32_t* fileSize, uint64_t* lastModified)
{
#if (MMS_FILE_SERVICE == 1)
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self);
struct fileOpenParameters parameter;
int32_t frsmId = -1;
MmsError err = MMS_ERROR_NONE;
mmsClient_createFileOpenRequest(invokeId, payload, filename, initialPosition);
parameter.waitForResponse = Semaphore_create(1);
parameter.err = MMS_ERROR_NONE;
parameter.frsmId = 0;
parameter.fileSize = 0;
parameter.lastModified = 0;
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
Semaphore_wait(parameter.waitForResponse);
if (responseMessage != NULL) {
MmsConnection_fileOpenAsync(self, &err, filename, initialPosition, fileOpenHandler, &parameter);
uint8_t* buffer = self->lastResponse->buffer;
int maxBufPos = self->lastResponse->size;
int bufPos = self->lastResponseBufPos;
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
if (mmsMsg_parseFileOpenResponse(buffer, bufPos, maxBufPos, &frsmId, fileSize, lastModified) == false)
*mmsError = MMS_ERROR_PARSING_RESPONSE;
err = parameter.err;
}
releaseResponse(self);
Semaphore_destroy(parameter.waitForResponse);
if (fileSize)
*fileSize = parameter.fileSize;
if (lastModified)
*lastModified = parameter.lastModified;
if (mmsError)
*mmsError = err;
return parameter.frsmId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
return 0;
#endif
}
uint32_t
MmsConnection_fileOpenAsync(MmsConnection self, MmsError* mmsError, const char* filename, uint32_t initialPosition, MmsConnection_FileOpenHandler handler,
void* parameter)
{
#if (MMS_FILE_SERVICE == 1)
uint32_t invokeId = 0;
if (getAssociationState(self) != MMS_STATE_CONNECTED) {
if (mmsError)
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
return frsmId;
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
invokeId = getNextInvokeId(self);
mmsClient_createFileOpenRequest(invokeId, payload, filename, initialPosition);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_FILE_OPEN, handler, parameter, NULL);
if (mmsError)
*mmsError = err;
exit_function:
return invokeId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
@ -3257,26 +3397,92 @@ MmsConnection_fileOpen(MmsConnection self, MmsError* mmsError, const char* filen
#endif
}
struct fileOperationParameters
{
Semaphore waitForResponse;
MmsError err;
bool success;
};
static void
fileOperationHandler(int invokeId, void* parameter, MmsError mmsError, bool success)
{
struct fileOperationParameters* parameters = (struct fileOperationParameters*) parameter;
parameters->err = mmsError;
parameters->success = success;
/* unblock user thread */
Semaphore_post(parameters->waitForResponse);
}
void
MmsConnection_fileClose(MmsConnection self, MmsError* mmsError, int32_t frsmId)
{
#if (MMS_FILE_SERVICE == 1)
struct fileOperationParameters parameter;
MmsError err = MMS_ERROR_NONE;
parameter.waitForResponse = Semaphore_create(1);
parameter.err = MMS_ERROR_NONE;
parameter.success = false;
Semaphore_wait(parameter.waitForResponse);
MmsConnection_fileCloseAsync(self, &err, frsmId, fileOperationHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
err = parameter.err;
}
Semaphore_destroy(parameter.waitForResponse);
if (mmsError)
*mmsError = err;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
#endif
}
uint32_t
MmsConnection_fileCloseAsync(MmsConnection self, MmsError* mmsError, uint32_t frsmId, MmsConnection_GenericServiceHandler handler, void* parameter)
{
#if (MMS_FILE_SERVICE == 1)
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);
uint32_t invokeId = getNextInvokeId(self);
invokeId = getNextInvokeId(self);
mmsClient_createFileCloseRequest(invokeId, payload, frsmId);
sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_FILE_CLOSE, handler, parameter, NULL);
/* nothing to do - response contains no data to evaluate */
if (mmsError)
*mmsError = err;
releaseResponse(self);
exit_function:
return invokeId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
return 0;
#endif
}
@ -3284,51 +3490,134 @@ void
MmsConnection_fileDelete(MmsConnection self, MmsError* mmsError, const char* fileName)
{
#if (MMS_FILE_SERVICE == 1)
struct fileOperationParameters parameter;
MmsError err = MMS_ERROR_NONE;
parameter.waitForResponse = Semaphore_create(1);
parameter.err = MMS_ERROR_NONE;
parameter.success = false;
Semaphore_wait(parameter.waitForResponse);
MmsConnection_fileDeleteAsync(self, &err, fileName, fileOperationHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
err = parameter.err;
}
Semaphore_destroy(parameter.waitForResponse);
if (mmsError)
*mmsError = err;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
#endif
}
uint32_t
MmsConnection_fileDeleteAsync(MmsConnection self, MmsError* mmsError, const char* fileName,
MmsConnection_GenericServiceHandler handler, void* parameter)
{
#if (MMS_FILE_SERVICE == 1)
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);
uint32_t invokeId = getNextInvokeId(self);
invokeId = getNextInvokeId(self);
mmsClient_createFileDeleteRequest(invokeId, payload, fileName);
sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_FILE_DELETE, handler, parameter, NULL);
/* nothing to do - response contains no data to evaluate */
if (mmsError)
*mmsError = err;
releaseResponse(self);
exit_function:
return invokeId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
return 0;
#endif
}
struct fileReadParameters
{
Semaphore waitForResponse;
MmsError err;
int32_t frsmId;
MmsFileReadHandler handler;
void* handlerParameter;
bool moreFollows;
};
static void
fileReadHandler(int invokeId, void* parameter, MmsError mmsError, uint8_t* buffer, uint32_t byteReceived,
bool moreFollows)
{
struct fileReadParameters* parameters = (struct fileReadParameters*) parameter;
parameters->err = mmsError;
if (mmsError == MMS_ERROR_NONE)
parameters->handler(parameters->handlerParameter, parameters->frsmId, buffer, byteReceived);
parameters->moreFollows = moreFollows;
/* unblock user thread */
Semaphore_post(parameters->waitForResponse);
}
bool
MmsConnection_fileRead(MmsConnection self, MmsError* mmsError, int32_t frsmId, MmsFileReadHandler handler,
void* handlerParameter)
{
#if (MMS_FILE_SERVICE == 1)
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self);
struct fileReadParameters parameter;
bool moreFollows = false;
mmsClient_createFileReadRequest(invokeId, payload, frsmId);
MmsError err = MMS_ERROR_NONE;
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
parameter.waitForResponse = Semaphore_create(1);
parameter.err = MMS_ERROR_NONE;
parameter.frsmId = frsmId;
parameter.handler = handler;
parameter.handlerParameter = handlerParameter;
parameter.moreFollows = false;
if (responseMessage != NULL) {
uint8_t* buffer = self->lastResponse->buffer;
int maxBufPos = self->lastResponse->size;
int bufPos = self->lastResponseBufPos;
Semaphore_wait(parameter.waitForResponse);
MmsConnection_fileReadAsync(self, &err, frsmId, fileReadHandler, &parameter);
if (mmsMsg_parseFileReadResponse(buffer, bufPos, maxBufPos, frsmId, &moreFollows, handler, handlerParameter) == false)
*mmsError = MMS_ERROR_PARSING_RESPONSE;
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
err = parameter.err;
}
releaseResponse(self);
Semaphore_destroy(parameter.waitForResponse);
if (mmsError)
*mmsError = err;
return parameter.moreFollows;
return moreFollows;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
@ -3338,27 +3627,98 @@ MmsConnection_fileRead(MmsConnection self, MmsError* mmsError, int32_t frsmId, M
#endif
}
uint32_t
MmsConnection_fileReadAsync(MmsConnection self, MmsError* mmsError, int32_t frsmId, MmsConnection_FileReadHandler handler, void* parameter)
{
#if (MMS_FILE_SERVICE == 1)
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_createFileReadRequest(invokeId, payload, frsmId);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_FILE_READ, handler, parameter, NULL);
if (mmsError)
*mmsError = err;
exit_function:
return invokeId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
return 0;
#endif
}
struct getFileDirParameters
{
Semaphore waitForResponse;
MmsError err;
bool moreFollows;
MmsFileDirectoryHandler handler;
void* handlerParameter;
};
static void
getFileDirHandler(int invokeId, void* parameter, MmsError mmsError, char* filename, uint32_t size, uint64_t lastModified,
bool moreFollows)
{
struct getFileDirParameters* parameters = (struct getFileDirParameters*) parameter;
parameters->err = mmsError;
if ((mmsError != MMS_ERROR_NONE) || (filename == NULL)) {
parameters->moreFollows = moreFollows;
/* last call --> unblock user thread */
Semaphore_post(parameters->waitForResponse);
}
else {
parameters->handler(parameters->handlerParameter, filename, size, lastModified);
}
}
bool
MmsConnection_getFileDirectory(MmsConnection self, MmsError* mmsError, const char* fileSpecification, const char* continueAfter,
MmsFileDirectoryHandler handler, void* handlerParameter)
{
#if (MMS_FILE_SERVICE == 1)
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self);
bool moreFollows = false;
mmsClient_createFileDirectoryRequest(invokeId, payload, fileSpecification, continueAfter);
struct getFileDirParameters parameter;
parameter.handler = handler;
parameter.handlerParameter = handlerParameter;
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
MmsError err;
bool moreFollows = false;
parameter.waitForResponse = Semaphore_create(1);
if (responseMessage != NULL) {
if (mmsClient_parseFileDirectoryResponse(self, handler, handlerParameter, &moreFollows) == false)
*mmsError = MMS_ERROR_PARSING_RESPONSE;
Semaphore_wait(parameter.waitForResponse);
MmsConnection_getFileDirectoryAsync(self, &err, fileSpecification, continueAfter, getFileDirHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
err = parameter.err;
moreFollows = parameter.moreFollows;
}
releaseResponse(self);
Semaphore_destroy(parameter.waitForResponse);
if (mmsError)
*mmsError = err;
return moreFollows;
#else
@ -3370,26 +3730,108 @@ MmsConnection_getFileDirectory(MmsConnection self, MmsError* mmsError, const cha
#endif
}
uint32_t
MmsConnection_getFileDirectoryAsync(MmsConnection self, MmsError* mmsError, const char* fileSpecification, const char* continueAfter,
MmsConnection_FileDirectoryHandler handler, void* parameter)
{
#if (MMS_FILE_SERVICE == 1)
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_createFileDirectoryRequest(invokeId, payload, fileSpecification, continueAfter);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_GET_FILE_DIR, handler, parameter, NULL);
if (mmsError)
*mmsError = err;
exit_function:
return invokeId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
return 0;
#endif
}
void
MmsConnection_fileRename(MmsConnection self, MmsError* mmsError, const char* currentFileName, const char* newFileName)
{
#if (MMS_FILE_SERVICE == 1)
struct fileOperationParameters parameter;
MmsError err = MMS_ERROR_NONE;
parameter.waitForResponse = Semaphore_create(1);
parameter.err = MMS_ERROR_NONE;
parameter.success = false;
Semaphore_wait(parameter.waitForResponse);
MmsConnection_fileRenameAsync(self, &err, currentFileName, newFileName, fileOperationHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
err = parameter.err;
}
Semaphore_destroy(parameter.waitForResponse);
if (mmsError)
*mmsError = err;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
#endif
}
uint32_t
MmsConnection_fileRenameAsync(MmsConnection self, MmsError* mmsError, const char* currentFileName, const char* newFileName,
MmsConnection_GenericServiceHandler handler, void* parameter)
{
#if (MMS_FILE_SERVICE == 1)
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);
uint32_t invokeId = getNextInvokeId(self);
invokeId = getNextInvokeId(self);
mmsClient_createFileRenameRequest(invokeId, payload, currentFileName, newFileName);
sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_FILE_RENAME, handler, parameter, NULL);
/* nothing to do - response contains no data to evaluate */
if (mmsError)
*mmsError = err;
releaseResponse(self);
exit_function:
return invokeId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
return 0;
#endif
}
@ -3397,17 +3839,30 @@ void
MmsConnection_obtainFile(MmsConnection self, MmsError* mmsError, const char* sourceFile, const char* destinationFile)
{
#if ((MMS_FILE_SERVICE == 1) && (MMS_OBTAIN_FILE_SERVICE == 1))
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self);
struct fileOperationParameters parameter;
mmsClient_createObtainFileRequest(invokeId, payload, sourceFile, destinationFile);
MmsError err = MMS_ERROR_NONE;
sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
parameter.waitForResponse = Semaphore_create(1);
parameter.err = MMS_ERROR_NONE;
parameter.success = false;
/* nothing to do - response contains no data to evaluate */
Semaphore_wait(parameter.waitForResponse);
MmsConnection_obtainFileAsync(self, &err, sourceFile, destinationFile, fileOperationHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
err = parameter.err;
}
Semaphore_destroy(parameter.waitForResponse);
if (mmsError)
*mmsError = err;
releaseResponse(self);
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
@ -3423,6 +3878,41 @@ struct writeVariableParameters
MmsDataAccessError accessError;
};
uint32_t
MmsConnection_obtainFileAsync(MmsConnection self, MmsError* mmsError, const char* sourceFile, const char* destinationFile,
MmsConnection_GenericServiceHandler handler, void* parameter)
{
#if (MMS_FILE_SERVICE == 1)
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_createObtainFileRequest(invokeId, payload, sourceFile, destinationFile);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_OBTAIN_FILE, handler, parameter, NULL);
if (mmsError)
*mmsError = err;
exit_function:
return invokeId;
#else
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: service not supported\n");
*mmsError = MMS_ERROR_OTHER;
return 0;
#endif
}
static void
writeVariableHandler(int invokeId, void* parameter, MmsError mmsError, MmsDataAccessError accessError)
{

@ -455,7 +455,7 @@ parseFileAttributes(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* fileSi
}
static bool
parseDirectoryEntry(uint8_t* buffer, int bufPos, int maxBufPos, MmsFileDirectoryHandler handler, void* handlerParameter)
parseDirectoryEntry(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeId, MmsConnection_FileDirectoryHandler handler, void* parameter)
{
char fileNameMemory[400];
char* filename = NULL;
@ -507,7 +507,7 @@ parseDirectoryEntry(uint8_t* buffer, int bufPos, int maxBufPos, MmsFileDirectory
}
if (filename != NULL)
handler(handlerParameter, filename, fileSize, lastModified);
handler(invokeId, parameter, MMS_ERROR_NONE, filename, fileSize, lastModified, true);
else
return false;
@ -515,8 +515,8 @@ parseDirectoryEntry(uint8_t* buffer, int bufPos, int maxBufPos, MmsFileDirectory
}
static bool
parseListOfDirectoryEntries(uint8_t* buffer, int bufPos, int maxBufPos,
MmsFileDirectoryHandler handler, void* handlerParameter)
parseListOfDirectoryEntries(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeId,
MmsConnection_FileDirectoryHandler handler, void* parameter)
{
uint8_t tag = buffer[bufPos++];
@ -544,7 +544,7 @@ parseListOfDirectoryEntries(uint8_t* buffer, int bufPos, int maxBufPos,
switch (tag) {
case 0x30: /* Sequence */
parseDirectoryEntry(buffer, bufPos, bufPos + length, handler, handlerParameter);
parseDirectoryEntry(buffer, bufPos, bufPos + length, invokeId, handler, parameter);
bufPos += length;
break;
default:
@ -560,12 +560,10 @@ parseListOfDirectoryEntries(uint8_t* buffer, int bufPos, int maxBufPos,
bool
mmsClient_parseFileDirectoryResponse(MmsConnection self, MmsFileDirectoryHandler handler, void* handlerParameter,
bool* moreFollows)
mmsClient_parseFileDirectoryResponse(ByteBuffer* response, int bufPos, uint32_t invokeId, MmsConnection_FileDirectoryHandler handler, void* parameter)
{
uint8_t* buffer = self->lastResponse->buffer;
int maxBufPos = self->lastResponse->size;
int bufPos = self->lastResponseBufPos;
uint8_t* buffer = response->buffer;
int maxBufPos = response->size;
int length;
uint8_t tag = buffer[bufPos++];
@ -595,7 +593,7 @@ mmsClient_parseFileDirectoryResponse(MmsConnection self, MmsFileDirectoryHandler
return false;
}
*moreFollows = false;
bool moreFollows = false;
while (bufPos < endPos) {
tag = buffer[bufPos++];
@ -605,12 +603,12 @@ mmsClient_parseFileDirectoryResponse(MmsConnection self, MmsFileDirectoryHandler
switch (tag) {
case 0xa0: /* listOfDirectoryEntries */
parseListOfDirectoryEntries(buffer, bufPos, bufPos + length, handler, handlerParameter);
parseListOfDirectoryEntries(buffer, bufPos, bufPos + length, invokeId, handler, parameter);
bufPos += length;
break;
case 0x81: /* moreFollows */
*moreFollows = BerDecoder_decodeBoolean(buffer, bufPos);
moreFollows = BerDecoder_decodeBoolean(buffer, bufPos);
bufPos += length;
break;
default:
@ -621,6 +619,8 @@ mmsClient_parseFileDirectoryResponse(MmsConnection self, MmsFileDirectoryHandler
}
}
handler(invokeId, parameter, MMS_ERROR_NONE, NULL, 0, 0, moreFollows);
return true;
}
@ -632,7 +632,7 @@ mmsMsg_parseFileOpenResponse(uint8_t* buffer, int bufPos, int maxBufPos, int32_t
uint8_t tag = buffer[bufPos++];
if (tag != 0xbf) {
//if (DEBUG_MMS_CLIENT)
if (DEBUG_MMS_CLIENT)
printf("MMS: mmsClient_parseFileOpenResponse: unknown tag %02x\n", tag);
return false;
}
@ -640,7 +640,7 @@ mmsMsg_parseFileOpenResponse(uint8_t* buffer, int bufPos, int maxBufPos, int32_t
tag = buffer[bufPos++];
if (tag != 0x48) {
//if (DEBUG_MMS_CLIENT)
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: mmsClient_parseFileOpenResponse: unknown tag %02x\n", tag);
return false;
}
@ -686,9 +686,8 @@ mmsMsg_parseFileOpenResponse(uint8_t* buffer, int bufPos, int maxBufPos, int32_t
return true;
}
bool
mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, int frsmId, bool* moreFollows, MmsFileReadHandler handler, void* handlerParameter)
mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, bool* moreFollows, uint8_t** dataBuffer, int* dataLength)
{
int length;
@ -703,6 +702,8 @@ mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, int frs
tag = buffer[bufPos++];
*moreFollows = true;
*dataBuffer = NULL;
*dataLength = 0;
if (tag != 0x49) {
if (DEBUG_MMS_CLIENT)
@ -728,16 +729,19 @@ mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, int frs
if (bufPos < 0)
return false;
switch (tag) {
switch (tag)
{
case 0x80: /* fileData */
handler(handlerParameter, frsmId, buffer + bufPos, length);
*dataBuffer = buffer + bufPos;
*dataLength = length;
bufPos += length;
break;
case 0x81: /* moreFollows */
*moreFollows = BerDecoder_decodeBoolean(buffer, bufPos);
bufPos += length;
break;
default:
bufPos += length;
if (DEBUG_MMS_CLIENT)
@ -747,6 +751,9 @@ mmsMsg_parseFileReadResponse(uint8_t* buffer, int bufPos, int maxBufPos, int frs
}
}
if (*dataBuffer == NULL)
return false;
return true;
}

@ -538,8 +538,12 @@ handleConfirmedResponsePdu(
if (fileTask != NULL) {
bool moreFollows;
uint8_t* dataBuffer = NULL;
int dataLength = 0;
if (mmsMsg_parseFileReadResponse(buffer, startBufPos, maxBufPos, fileTask->frmsId, &moreFollows, mmsFileReadHandler, (void*) fileTask)) {
if (mmsMsg_parseFileReadResponse(buffer, startBufPos, maxBufPos, &moreFollows, &dataBuffer, &dataLength)) {
mmsFileReadHandler((void*) fileTask, fileTask->frmsId, dataBuffer, dataLength);
if (moreFollows) {
fileTask->state = MMS_FILE_UPLOAD_STATE_SEND_FILE_READ;

Loading…
Cancel
Save