From 372df34018f6eca52ffcd6284233b427c2884aca Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Mon, 25 Jul 2016 20:11:50 +0200 Subject: [PATCH] - added client side fuctionality to provide user access to raw MMS messages --- config/stack_config.h | 3 ++ config/stack_config.h.cmake | 3 ++ examples/mms_utility/mms_utility.c | 26 +++++++++++++++- src/mms/inc/mms_client_connection.h | 27 ++++++++++++++++ src/mms/inc_private/mms_client_internal.h | 9 ++++++ .../iso_mms/client/mms_client_connection.c | 31 +++++++++++++++++++ src/vs/libiec61850-wo-goose.def | 1 + src/vs/libiec61850.def | 1 + 8 files changed, 100 insertions(+), 1 deletion(-) diff --git a/config/stack_config.h b/config/stack_config.h index c414690d..0ad96456 100644 --- a/config/stack_config.h +++ b/config/stack_config.h @@ -216,4 +216,7 @@ /* use short FC defines as in old API */ #define CONFIG_PROVIDE_OLD_FC_DEFINES 0 +/* Support user acccess to raw messages */ +#define CONFIG_MMS_RAW_MESSAGE_LOGGING 1 + #endif /* STACK_CONFIG_H_ */ diff --git a/config/stack_config.h.cmake b/config/stack_config.h.cmake index 78bf6f88..ec478b0f 100644 --- a/config/stack_config.h.cmake +++ b/config/stack_config.h.cmake @@ -196,4 +196,7 @@ /* use short FC defines as in old API */ #define CONFIG_PROVIDE_OLD_FC_DEFINES 0 +/* Support user acccess to raw messages */ +#cmakedefine01 CONFIG_MMS_RAW_MESSAGE_LOGGING + #endif /* STACK_CONFIG_H_ */ diff --git a/examples/mms_utility/mms_utility.c b/examples/mms_utility/mms_utility.c index 28d43794..d1c2eed9 100644 --- a/examples/mms_utility/mms_utility.c +++ b/examples/mms_utility/mms_utility.c @@ -21,6 +21,7 @@ print_help() printf("-f show file list\n"); printf("-g get file attributes\n"); printf("-j read journal\n"); + printf("-m print raw MMS messages\n"); } static void @@ -77,6 +78,21 @@ printJournalEntries(LinkedList journalEntries) } } +void* +printRawMmsMessage(void* parameter, uint8_t* message, int messageLength, bool received) +{ + if (received) + printf("RECV: "); + else + printf("SEND: "); + + int i; + for (i = 0; i < messageLength; i++) { + printf("%02x ", message[i]); + } + + printf("\n"); +} int main(int argc, char** argv) { @@ -97,11 +113,16 @@ int main(int argc, char** argv) { int showFileList = 0; int getFileAttributes = 0; int readJournal = 0; + int printRawMmsMessages = 0; int c; - while ((c = getopt(argc, argv, "ifdh:p:l:t:a:r:g:j:")) != -1) + while ((c = getopt(argc, argv, "mifdh:p:l:t:a:r:g:j:")) != -1) switch (c) { + case 'm': + printRawMmsMessages = 1; + break; + case 'h': hostname = copyString(optarg); break; @@ -154,6 +175,9 @@ int main(int argc, char** argv) { /* Set maximum MMS PDU size (local detail) to 2000 byte */ MmsConnection_setLocalDetail(con, maxPduSize); + if (printRawMmsMessages) + MmsConnection_setRawMessageHandler(con, (MmsRawMessageHandler) printRawMmsMessage, NULL); + if (!MmsConnection_connect(con, &error, hostname, tcpPort)) { printf("MMS connect failed!\n"); goto exit; diff --git a/src/mms/inc/mms_client_connection.h b/src/mms/inc/mms_client_connection.h index 593f1dea..1a0c0176 100644 --- a/src/mms/inc/mms_client_connection.h +++ b/src/mms/inc/mms_client_connection.h @@ -79,6 +79,33 @@ typedef struct sMmsConnection* MmsConnection; MmsConnection MmsConnection_create(void); +/** + * \brief Callback function to intercept raw MMS messages + * + * IMPORTANT: the message buffer is only valid in the context of the the callback function. If the + * message data is required elsewhere it has to be copied here! + * + * \param parameter user provided parameter that is passed to the callback function + * \param message buffer of the message. + * \param messageLength length of the message in bytes + * \param received if true message has been received, false when message has been sent. + */ +typedef void (*MmsRawMessageHandler) (void* parameter, uint8_t* message, int messageLength, bool received); + +/** + * \brief Set the callback handler to intercept the raw MMS messages of the connection + * + * This function can be used to log raw MMS messages. It may be useful for debugging purposes + * or advanced test tools. This function will only work when the flag CONFIG_MMS_RAW_MESSAGE_LOGGING + * it set in stack_config.h + * + * \param self MmsConnection instance to operate on + * \param handler the connection specific callback function + * \param a user provided parameter passed to the callback function (use NULL if not required). + */ +void +MmsConnection_setRawMessageHandler(MmsConnection self, MmsRawMessageHandler handler, void* parameter); + /** * \brief Set the request timeout in ms for this connection * diff --git a/src/mms/inc_private/mms_client_internal.h b/src/mms/inc_private/mms_client_internal.h index fad704a3..0962cd3f 100644 --- a/src/mms/inc_private/mms_client_internal.h +++ b/src/mms/inc_private/mms_client_internal.h @@ -32,6 +32,10 @@ #include "hal_thread.h" +#ifndef CONFIG_MMS_RAW_MESSAGE_LOGGING +#define CONFIG_MMS_RAW_MESSAGE_LOGGING 0 +#endif + #ifndef DEBUG_MMS_CLIENT #define DEBUG_MMS_CLIENT 0 #endif @@ -85,6 +89,11 @@ struct sMmsConnection { MmsConnectionLostHandler connectionLostHandler; void* connectionLostHandlerParameter; +#if (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) + void* rawMmsMessageHandler; + void* rawMmsMessageHandlerParameter; +#endif + /* state of an active connection conclude/release process */ int concludeState; }; diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index b3a99d24..ba570e55 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -295,6 +295,13 @@ sendRequestAndWaitForResponse(MmsConnection self, uint32_t invokeId, ByteBuffer* addToOutstandingCalls(self, invokeId); +#if (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) + if (self->rawMmsMessageHandler != NULL) { + MmsRawMessageHandler handler = (MmsRawMessageHandler) self->rawMmsMessageHandler; + handler(self->rawMmsMessageHandlerParameter, message->buffer, message->size, false); + } +#endif /* (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) */ + IsoClientConnection_sendMessage(self->isoClient, message); while (currentTime < waitUntilTime) { @@ -607,6 +614,13 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) uint8_t* buf = ByteBuffer_getBuffer(payload); +#if (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) + if (self->rawMmsMessageHandler != NULL) { + MmsRawMessageHandler handler = (MmsRawMessageHandler) self->rawMmsMessageHandler; + handler(self->rawMmsMessageHandlerParameter, buf, payload->size, true); + } +#endif /* (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) */ + uint8_t tag = buf[0]; if (DEBUG_MMS_CLIENT) @@ -804,6 +818,16 @@ MmsConnection_destroy(MmsConnection self) GLOBAL_FREEMEM(self); } +void +MmsConnection_setRawMessageHandler(MmsConnection self, MmsRawMessageHandler handler, void* parameter) +{ +#if (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) + self->rawMmsMessageHandler = (void*) handler; + self->rawMmsMessageHandlerParameter = parameter; +#endif +} + + void MmsConnection_setConnectionLostHandler(MmsConnection self, MmsConnectionLostHandler handler, void* handlerParameter) { @@ -879,6 +903,13 @@ MmsConnection_connect(MmsConnection self, MmsError* mmsError, const char* server mmsClient_createInitiateRequest(self, payload); +#if (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) + if (self->rawMmsMessageHandler != NULL) { + MmsRawMessageHandler handler = (MmsRawMessageHandler) self->rawMmsMessageHandler; + handler(self->rawMmsMessageHandlerParameter, payload->buffer, payload->size, false); + } +#endif /* (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) */ + self->connectionState = MMS_CON_WAITING; IsoClientConnection_associate(self->isoClient, self->isoParameters, payload, diff --git a/src/vs/libiec61850-wo-goose.def b/src/vs/libiec61850-wo-goose.def index 68873dbb..0735c33f 100644 --- a/src/vs/libiec61850-wo-goose.def +++ b/src/vs/libiec61850-wo-goose.def @@ -549,3 +549,4 @@ EXPORTS CDC_DPL_create SV_ASDU_addFLOAT64 SV_ASDU_setFLOAT64 + MmsConnection_setRawMessageHandler diff --git a/src/vs/libiec61850.def b/src/vs/libiec61850.def index 157f2161..ee2495f2 100644 --- a/src/vs/libiec61850.def +++ b/src/vs/libiec61850.def @@ -625,3 +625,4 @@ EXPORTS CDC_DPL_create SV_ASDU_addFLOAT64 SV_ASDU_setFLOAT64 + MmsConnection_setRawMessageHandler