summaryrefslogtreecommitdiff
path: root/cesar/maximus/sci
diff options
context:
space:
mode:
authorsave2008-04-07 14:17:42 +0000
committersave2008-04-07 14:17:42 +0000
commit3d58a62727346b7ac1a6cb36fed1a06ed72228dd (patch)
treed7788c3cf9f76426aef0286d0202e2097f0fa0eb /cesar/maximus/sci
parent095dca4b0a8d4924093bab424f71f588fdd84613 (diff)
Moved the complete svn base into the cesar directory.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@1769 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/maximus/sci')
-rw-r--r--cesar/maximus/sci/Module5
-rw-r--r--cesar/maximus/sci/inc/ISci.h143
-rw-r--r--cesar/maximus/sci/inc/SciMsg.h333
-rw-r--r--cesar/maximus/sci/inc/SciMsgTest.h50
-rw-r--r--cesar/maximus/sci/inc/SciServer.h248
-rw-r--r--cesar/maximus/sci/inc/SciServerTest.h62
-rw-r--r--cesar/maximus/sci/src/SciMsg.cpp711
-rw-r--r--cesar/maximus/sci/src/SciMsgTest.cpp129
-rw-r--r--cesar/maximus/sci/src/SciServer.cpp1005
-rw-r--r--cesar/maximus/sci/src/SciServerTest.cpp510
10 files changed, 3196 insertions, 0 deletions
diff --git a/cesar/maximus/sci/Module b/cesar/maximus/sci/Module
new file mode 100644
index 0000000000..b9b574b21c
--- /dev/null
+++ b/cesar/maximus/sci/Module
@@ -0,0 +1,5 @@
+SOURCES := SciMsg.cpp SciServer.cpp
+ifdef UNITTEST
+SOURCES += SciServerTest.cpp SciMsgTest.cpp
+endif
+HOST_INCLUDES += maximus/sci/inc
diff --git a/cesar/maximus/sci/inc/ISci.h b/cesar/maximus/sci/inc/ISci.h
new file mode 100644
index 0000000000..cea7f4b954
--- /dev/null
+++ b/cesar/maximus/sci/inc/ISci.h
@@ -0,0 +1,143 @@
+/************************************************************************
+ ISci.h - Copyright buret
+
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the "headings" directory in uml to point to a directory
+where you have your heading files.
+
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+
+/usr/share/apps/umbrello/headings/heading.h
+
+-->Code Generators searches for heading files based on the file extension
+ i.e. it will look for a file name ending in ".h" to include in C++ header
+ files, and for a file name ending in ".java" to include in all generated
+ java code.
+ If you name the file "heading.<extension>", Code Generator will always
+ choose this file even if there are other files with the same extension in the
+ directory. If you name the file something else, it must be the only one with that
+ extension in the directory to guarantee that Code Generator will choose it.
+
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/sci/inc/ISci.h
+**************************************************************************/
+
+#ifndef ISCI_H
+#define ISCI_H
+
+#include "ISystem.h"
+
+#include "networkclock_types.h"
+#include "sci_types.h"
+
+#include <string>
+#include <vector>
+
+class SciMsg;
+
+typedef std::vector<Sci_Msg_Station_Id> DestStationsList;
+
+
+/**
+ * class ISci
+ */
+
+class ISci
+{
+
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ ISci ( ) { }
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~ISci ( ) { }
+
+ // public methods
+ //
+
+ /**
+ * @return bool
+ * @param station_log_file
+ */
+ virtual bool init ( const std::string station_log ) = 0;
+
+ /**
+ * @return bool
+ */
+ virtual bool process ( ) = 0;
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ */
+ virtual bool fillSciMsg ( SciMsg & sci_msg_to_send ) const = 0;
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ */
+ virtual bool sendSciMsg ( const SciMsg & sci_msg_to_send ) const = 0;
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ */
+ virtual bool sendSciMsgToAllActiveStations ( SciMsg & sci_msg_to_send ) const = 0;
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ * @param list_of_dest_stations
+ */
+ virtual bool sendSciMsgToDestStations ( SciMsg & sci_msg_to_send, DestStationsList & list_of_dest_stations ) const = 0;
+
+ /**
+ * Set a value into mpSpecializedSciMsgArray
+ * @return bool
+ * @param sci_msg_type the array position to set
+ * @param sci_msg the new value of mpSpecializedSciMsgArray[sci_msg_type]
+ */
+ virtual bool registerSpecializedSciMsg ( const Sci_Msg_Type sci_msg_type, SciMsg * sci_msg ) = 0;
+
+ /**
+ * @return bool
+ * @param header
+ * @param data_length
+ * @param received_data
+ */
+ virtual bool receiveMsg ( const Sci_Msg_Header * header,
+ const unsigned long data_length,
+ const unsigned char * received_data ) const = 0;
+
+ virtual void displaySpecializedSciMsgArray ( ) const = 0;
+
+ /**
+ * @return bool
+ * @param p_list_of_stations
+ */
+ virtual bool setStationsList ( StationsList * p_list_of_stations ) = 0;
+
+ /**
+ * @return bool
+ * @param current_tick_value
+ */
+ virtual bool updateTickValue ( const Network_Clock_Tick current_tick_value ) = 0;
+
+};
+
+
+#endif // ISCI_H
diff --git a/cesar/maximus/sci/inc/SciMsg.h b/cesar/maximus/sci/inc/SciMsg.h
new file mode 100644
index 0000000000..7ed2608be5
--- /dev/null
+++ b/cesar/maximus/sci/inc/SciMsg.h
@@ -0,0 +1,333 @@
+/************************************************************************
+ SciMsg.h - Copyright buret
+
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the "headings" directory in uml to point to a directory
+where you have your heading files.
+
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+
+/usr/share/apps/umbrello/headings/heading.h
+
+-->Code Generators searches for heading files based on the file extension
+ i.e. it will look for a file name ending in ".h" to include in C++ header
+ files, and for a file name ending in ".java" to include in all generated
+ java code.
+ If you name the file "heading.<extension>", Code Generator will always
+ choose this file even if there are other files with the same extension in the
+ directory. If you name the file something else, it must be the only one with that
+ extension in the directory to guarantee that Code Generator will choose it.
+
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/sci/inc/SciMsg.h
+**************************************************************************/
+
+#ifndef SCIMSG_H
+#define SCIMSG_H
+
+#include "sci_types.h"
+
+
+/**
+ * class SciMsg
+ */
+
+class SciMsg
+{
+
+public:
+
+ // public attributes
+ //
+
+private:
+
+ // private attributes
+ //
+
+ Sci_Msg_Status mSciMsgStatus; // NOT USED YET
+
+ // Values of SCI message header
+ //
+ Sci_Msg_Type mSciMsgType;
+ Sci_Msg_Station_Id mSciMsgStationId;
+ static Sci_Msg_Id mSciMsgId; // to send to station
+ Sci_Msg_Flag mSciMsgFlag;
+
+ // SCI message header, SCI message data length, and SCI message data
+ //
+ Sci_Msg_Header mSciMsgHeader;
+ unsigned long mSciMsgDataLength;
+ unsigned char * mpSciMsgData;
+
+protected:
+
+ // protected attributes
+ //
+
+ // Specialized SCI message header size, specialized SCI message data length, and specialized SCI message data
+ //
+ unsigned long mSpecializedSciMsgHeaderSize;
+ unsigned long mSpecializedSciMsgDataLength;
+ unsigned char * mpSpecializedSciMsgData;
+
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ SciMsg ( );
+
+ /**
+ * Copy Constructors
+ */
+ SciMsg ( const SciMsg & sci_msg );
+ SciMsg ( const SciMsg * p_sci_msg );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~SciMsg ( );
+
+ // public methods
+ //
+
+ /**
+ * @return SciMsg *
+ */
+ virtual SciMsg * create ( ) const = 0;
+
+ /**
+ * @return bool
+ */
+ virtual bool dispatchMsg ( ) = 0;
+
+ /**
+ * @return bool
+ */
+ virtual bool identifySpecializedSciMsgHeader ( ) = 0;
+
+ /**
+ * @return bool
+ */
+ virtual bool checkCompatibility ( ) const;
+
+ /**
+ * @return bool
+ */
+ virtual bool checkValidity ( ) const;
+
+ /**
+ * @return bool
+ */
+ bool identifySpecializedSciMsgData ( );
+
+ void displaySciMsgHeader ( ) const;
+
+ void displaySciMsgData ( ) const;
+
+ virtual void displaySpecializedSciMsgHeader ( ) const = 0;
+
+ /**
+ * Display the specialized SCI message type.
+ */
+ virtual void displaySpecializedSciMsgType ( int log_level ) const = 0;
+
+ void displaySpecializedSciMsgData ( ) const;
+
+ /**
+ * @return SCI_MSG_MAGIC converted to uint32_t
+ */
+ uint32_t getDefinedSciMsgMagicId ( ) const;
+
+ /**
+ * @return SCI_MSG_VERSION
+ */
+ uint8_t getDefinedSciMsgVersion ( ) const;
+
+ // public attribute accessor methods
+ //
+
+ // private attribute accessor methods
+ //
+
+ /**
+ * @return mSciMsgStatus
+ */
+ Sci_Msg_Status getSciMsgStatus ( ) const;
+
+ /**
+ * @return bool
+ * @param status the new value of mSciMsgStatus
+ */
+ bool setSciMsgStatus ( const Sci_Msg_Status status );
+
+ /**
+ * @return the value of mSciMsgType
+ */
+ Sci_Msg_Type getSciMsgType ( ) const;
+
+ /**
+ * @return bool
+ * @param type the new value of mSciMsgType
+ */
+ bool setSciMsgType ( const Sci_Msg_Type type );
+
+ /**
+ * Get the value of mSciMsgStationId
+ * @return the value of mSciMsgStationId
+ */
+ Sci_Msg_Station_Id getSciMsgStationId ( ) const;
+
+ /**
+ * Set the value of mSciMsgStationId
+ * @return bool
+ * @param station_id the new value of mSciMsgStationId
+ */
+ bool setSciMsgStationId ( const Sci_Msg_Station_Id station_id );
+
+ /**
+ * Get the value of mSciMsgId
+ * @return the value of mSciMsgId
+ */
+ Sci_Msg_Id getSciMsgId ( ) const;
+
+ /**
+ * Increment the value of mSciMsgId
+ * @return bool
+ */
+ bool incrementSciMsgId ( );
+
+ /**
+ * @return the value of mSciMsgFlag
+ */
+ Sci_Msg_Flag getSciMsgFlag ( ) const;
+
+ /**
+ * @return bool
+ * @param flag the new value of mSciMsgFlag
+ */
+ bool setSciMsgFlag ( const Sci_Msg_Flag flag );
+
+ /**
+ * @return a pointer to mSciMsgHeader
+ */
+ Sci_Msg_Header * getSciMsgHeader ( ) const;
+
+ /**
+ * @return bool
+ * @param sci_msg_header the new value of mSciMsgHeader
+ */
+ bool setSciMsgHeader ( const Sci_Msg_Header & sci_msg_header );
+
+ /**
+ * Get the value of mSciMsgDataLength
+ * @return the value of mSciMsgDataLength
+ */
+ unsigned long getSciMsgDataLength ( ) const;
+
+ /**
+ * Set the value of mSciMsgDataLength
+ * @return bool
+ * @param data_length the new value of mSciMsgDataLength
+ */
+ bool setSciMsgDataLength ( const unsigned long data_length );
+
+ /**
+ * Get the value of mpSciMsgData
+ * @return the value of mpSciMsgData
+ */
+ unsigned char * getSciMsgData ( ) const;
+
+ /**
+ * Set the value of mpSciMsgData
+ * @return bool
+ * @param p_data the new value of mpSciMsgData
+ */
+ bool setSciMsgData ( const unsigned char * p_data );
+
+ // protected attribute accessor methods
+ //
+
+ /**
+ * Get the value of mSpecializedSciMsgHeaderSize
+ * @return the value of mSpecializedSciMsgHeaderSize
+ */
+ virtual unsigned long getSpecializedSciMsgHeaderSize ( ) const;
+
+ /**
+ * Set the value of mSpecializedSciMsgHeaderSize
+ * @return bool
+ * @param header_size the new value of mSpecializedSciMsgHeaderSize
+ */
+ virtual bool setSpecializedSciMsgHeaderSize ( const unsigned long header_size );
+
+ /**
+ * Get the value of mpSpecializedSciMsgHeader
+ * @return the value of mpSpecializedSciMsgHeader into a void pointer
+ */
+ virtual void * returnSpecializedSciMsgHeader ( ) const = 0;
+
+ /**
+ * Get the value of mSpecializedSciMsgDataLength
+ * @return the value of mSpecializedSciMsgDataLength
+ */
+ virtual unsigned long getSpecializedSciMsgDataLength ( ) const;
+
+ /**
+ * Set the value of mSpecializedSciMsgDataLength
+ * @return bool
+ * @param data_length the new value of mSpecializedSciMsgDataLength
+ */
+ virtual bool setSpecializedSciMsgDataLength ( const unsigned long data_length );
+
+ /**
+ * Get the value of mpSpecializedSciMsgData
+ * @return the value of mpSpecializedSciMsgData
+ */
+ virtual unsigned char * getSpecializedSciMsgData ( ) const;
+
+ /**
+ * Set the value of mpSpecializedSciMsgData
+ * @return bool
+ * @param p_data the new value of mpSpecializedSciMsgData
+ */
+ virtual bool setSpecializedSciMsgData ( const unsigned char * p_data );
+
+ void displaySciMsgType ( ) const;
+
+private:
+
+ // private methods
+ //
+
+ void initAttributes ( ) ;
+
+ void displaySciMsgFlag ( ) const;
+
+protected:
+
+ // protected methods
+ //
+
+ /**
+ * @return bool
+ * @param data_length_to_remove
+ * @param data_length
+ * @param pp_data
+ */
+ bool removeData ( const unsigned long data_length_to_remove, unsigned long & data_length, unsigned char ** pp_data );
+
+};
+
+
+#endif // SCIMSG_H
diff --git a/cesar/maximus/sci/inc/SciMsgTest.h b/cesar/maximus/sci/inc/SciMsgTest.h
new file mode 100644
index 0000000000..d588f55ce7
--- /dev/null
+++ b/cesar/maximus/sci/inc/SciMsgTest.h
@@ -0,0 +1,50 @@
+
+#ifndef SCIMSGTEST_H
+#define SCIMSGTEST_H
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+class SciMsg;
+class IFunctionCall;
+class ISci;
+class ISystem;
+class IPhy;
+class IEthernet;
+class INetworkClock;
+
+
+class SciMsgTest : public CPPUNIT_NS::TestFixture
+{
+
+ CPPUNIT_TEST_SUITE (SciMsgTest);
+ CPPUNIT_TEST (simpleTest);
+ CPPUNIT_TEST_SUITE_END ();
+
+public:
+
+ void setUp (void);
+ void tearDown (void);
+
+protected:
+
+ void simpleTest (void);
+
+private:
+
+ SciMsg * mpFunctionSciMsg;
+ SciMsg * mpClockSciMsg;
+ SciMsg * mpSystemSciMsg;
+ SciMsg * mpPhySciMsg;
+ SciMsg * mpEtherSciMsg;
+ IFunctionCall * mpFunctionCallManager;
+ ISci * mpSciServer;
+ ISystem * mpSystemManager;
+ IPhy * mpPhyProcessor;
+ IEthernet * mpEthernet;
+ INetworkClock * mpNetworkClock;
+
+};
+
+
+#endif // SCIMSGTEST_H
diff --git a/cesar/maximus/sci/inc/SciServer.h b/cesar/maximus/sci/inc/SciServer.h
new file mode 100644
index 0000000000..1aa49b8964
--- /dev/null
+++ b/cesar/maximus/sci/inc/SciServer.h
@@ -0,0 +1,248 @@
+/************************************************************************
+ SciServer.h - Copyright buret
+
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the "headings" directory in uml to point to a directory
+where you have your heading files.
+
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+
+/usr/share/apps/umbrello/headings/heading.h
+
+-->Code Generators searches for heading files based on the file extension
+ i.e. it will look for a file name ending in ".h" to include in C++ header
+ files, and for a file name ending in ".java" to include in all generated
+ java code.
+ If you name the file "heading.<extension>", Code Generator will always
+ choose this file even if there are other files with the same extension in the
+ directory. If you name the file something else, it must be the only one with that
+ extension in the directory to guarantee that Code Generator will choose it.
+
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/sci/inc/SciServer.h
+**************************************************************************/
+
+#ifndef SCISERVER_H
+#define SCISERVER_H
+
+#include "ISci.h"
+#include "SystemManager.h" // for 'StationsList'
+
+#include "networkclock_types.h"
+#include "system_types.h"
+
+class Station;
+class SciMsg;
+
+
+/**
+ * class SciServer
+ */
+
+class SciServer : public ISci
+{
+
+public:
+
+ // public attributes
+ //
+
+private:
+
+ // private attributes
+ //
+
+ std::string mStationLog;
+ SciMsg ** mpSpecializedSciMsgArray;
+ unsigned int mArraySize;
+ StationsList * mpListOfStations;
+ Network_Clock_Tick mNetworkClockTick;
+
+protected:
+
+ // protected attributes
+ //
+
+public:
+
+ // Constructors/Destructors
+ //
+
+ /**
+ * Empty Constructor
+ */
+ SciServer ( );
+
+ /**
+ * Copy Constructor
+ */
+ SciServer ( const SciServer & );
+
+ /**
+ * Empty Destructor
+ */
+ virtual ~SciServer ( );
+
+ // public methods
+ //
+
+ /**
+ * @return bool
+ * @param station_log_file
+ */
+ bool init ( const std::string station_log );
+
+ /**
+ * @return bool
+ */
+ bool process ( );
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ */
+ bool fillSciMsg ( SciMsg & sci_msg_to_send ) const;
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ */
+ bool sendSciMsg ( const SciMsg & sci_msg_to_send ) const;
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ */
+ bool sendSciMsgToAllActiveStations ( SciMsg & sci_msg_to_send ) const;
+
+ /**
+ * @return bool
+ * @param sci_msg_to_send
+ * @param
+ */
+ bool sendSciMsgToDestStations ( SciMsg & sci_msg_to_send, DestStationsList & list_of_dest_stations ) const;
+
+ /**
+ * Set a value into mpSpecializedSciMsgArray
+ * @return bool
+ * @param sci_msg_type the array position to set
+ * @param sci_msg the new value of mpSpecializedSciMsgArray[sci_msg_type]
+ */
+ bool registerSpecializedSciMsg ( const Sci_Msg_Type sci_msg_type, SciMsg * sci_msg );
+
+ /**
+ * @return bool
+ * @param header
+ * @param data_length
+ * @param received_data
+ */
+ bool receiveMsg ( const Sci_Msg_Header * header,
+ const unsigned long data_length,
+ const unsigned char * received_data ) const;
+
+ void displaySpecializedSciMsgArray ( ) const;
+
+ // public attribute accessor methods
+ //
+
+ // private attribute accessor methods
+ //
+
+ /**
+ * @return StationsList *
+ */
+ StationsList * getStationsList ( ) const;
+
+ /**
+ * @return bool
+ * @param p_list_of_stations
+ */
+ bool setStationsList ( StationsList * p_list_of_stations );
+
+ /**
+ * Get the value of mArraySize
+ * @return the value of mArraySize
+ */
+ unsigned int getArraySize ( ) const;
+
+ /**
+ * Get the value of mpSpecializedSciMsgArray
+ * @return the value of mpSpecializedSciMsgArray
+ */
+ SciMsg ** getSpecializedSciMsgArray ( ) const;
+
+ /**
+ * @return bool
+ * @param current_tick_value
+ */
+ bool updateTickValue ( const Network_Clock_Tick current_tick_value );
+
+ /**
+ * @return Network_Clock_Tick
+ */
+ Network_Clock_Tick getNetworkClockTick ( ) const;
+
+ // protected attribute accessor methods
+ //
+
+private:
+
+ // private methods
+ //
+
+ bool log ( ) const;
+
+ /**
+ * @return bool
+ * @param type
+ * @param received_sci_msg
+ */
+ bool createSciMsg ( const Sci_Msg_Type type, SciMsg ** received_sci_msg ) const;
+
+ /**
+ * @return bool
+ * @param msg_header
+ * @param data_length
+ * @param remaining_data
+ * @param received_sci_msg
+ */
+ bool fillSciMsg ( const Sci_Msg_Header * msg_header,
+ const unsigned long data_length,
+ const unsigned char * received_data,
+ SciMsg ** created_sci_msg ) const;
+
+ /**
+ * @return bool
+ * @param received_sci_msg
+ */
+ bool processSciMsg ( SciMsg * received_sci_msg ) const;
+
+ std::string displaySciMsgType ( uint8_t sci_msg_type ) const;
+
+ void displayStatus ( ) const;
+
+ void initAttributes ( );
+
+ // private attribute accessor methods
+ //
+
+ /**
+ * @return std::string
+ */
+ std::string getStationLog ( ) const;
+
+protected:
+
+ // protected methods
+ //
+
+};
+
+
+#endif // SCISERVER_H
diff --git a/cesar/maximus/sci/inc/SciServerTest.h b/cesar/maximus/sci/inc/SciServerTest.h
new file mode 100644
index 0000000000..e92eac8abc
--- /dev/null
+++ b/cesar/maximus/sci/inc/SciServerTest.h
@@ -0,0 +1,62 @@
+
+#ifndef SCISERVERTEST_H
+#define SCISERVERTEST_H
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "sci_types.h" // for 'Sci_Msg_Header'
+
+class SciServer;
+class FunctionCallManager;
+class SystemManager;
+class PhyProcessor;
+class NetworkClockProcessor;
+class FunctionSciMsg;
+class IEthernet;
+
+void functionSciMsgCallback ( const FunctionSciMsg & function_sci_msg );
+
+
+class SciServerTest : public CPPUNIT_NS::TestFixture
+{
+
+ CPPUNIT_TEST_SUITE (SciServerTest);
+ CPPUNIT_TEST (registerSpecializedSciMsgTest);
+ CPPUNIT_TEST (receiveMsgTest);
+ CPPUNIT_TEST_SUITE_END ();
+
+public:
+
+ void setUp (void);
+ void tearDown (void);
+
+protected:
+
+ void registerSpecializedSciMsgTest (void);
+ void receiveMsgTest (void);
+
+private:
+
+ SciServer * mpSciServer;
+ FunctionCallManager * mpFunctionCallManager;
+ SystemManager * mpSystemManager;
+ PhyProcessor * mpPhyProcessor;
+ NetworkClockProcessor * mpNetworkClockProcessor;
+ IEthernet * mpEthernet;
+
+ void registerClockSciMsgTest (void);
+ void registerPhySciMsgTest (void);
+ void registerSystemSciMsgTest (void);
+ void registerFunctionSciMsgTest (void);
+ void registerEtherSciMsgTest (void);
+ void receiveClockSciMsgTest ( Sci_Msg_Header & msg_header );
+ void receivePhySciMsgTest ( Sci_Msg_Header & msg_header );
+ void receiveSystemSciMsgTest ( Sci_Msg_Header & msg_header );
+ void receiveFunctionSciMsgTest ( Sci_Msg_Header & msg_header );
+ void receiveEtherSciMsgTest ( Sci_Msg_Header & msg_header );
+
+};
+
+
+#endif // SCISERVERTEST_H
diff --git a/cesar/maximus/sci/src/SciMsg.cpp b/cesar/maximus/sci/src/SciMsg.cpp
new file mode 100644
index 0000000000..cf31f0b69a
--- /dev/null
+++ b/cesar/maximus/sci/src/SciMsg.cpp
@@ -0,0 +1,711 @@
+/************************************************************************
+ SciMsg.cpp - Copyright buret
+
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the "headings" directory in uml to point to a directory
+where you have your heading files.
+
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+
+/usr/share/apps/umbrello/headings/heading.cpp
+
+-->Code Generators searches for heading files based on the file extension
+ i.e. it will look for a file name ending in ".h" to include in C++ header
+ files, and for a file name ending in ".java" to include in all generated
+ java code.
+ If you name the file "heading.<extension>", Code Generator will always
+ choose this file even if there are other files with the same extension in the
+ directory. If you name the file something else, it must be the only one with that
+ extension in the directory to guarantee that Code Generator will choose it.
+
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/sci/src/SciMsg.cpp
+**************************************************************************/
+
+#include "SciMsg.h"
+
+#include "Station.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <sstream> // for 'ostringstream'
+#include <iomanip> // for 'setfill()' and 'setw()'
+#include <iostream> // for 'cout', 'cerr' and 'clog'
+using namespace std;
+
+
+// Constructors/Destructors
+//
+
+
+Sci_Msg_Id SciMsg::mSciMsgId = 0;
+
+
+SciMsg::SciMsg ( ):
+mSciMsgStatus(MAXIMUS_SCI_MSG_STATUS_NONE),
+mSciMsgType(SCI_MSG_TYPE_NONE),
+mSciMsgStationId(0),
+mSciMsgFlag(SCI_MSG_FLAG_NONE),
+mSciMsgDataLength(0),
+mpSciMsgData(NULL),
+mSpecializedSciMsgHeaderSize(0),
+mSpecializedSciMsgDataLength(0),
+mpSpecializedSciMsgData(NULL)
+{
+ logFunction();
+
+ initAttributes();
+}
+
+
+void SciMsg::initAttributes ( )
+{
+ logFunction();
+
+ mSciMsgHeader.magic_id = 0x00000000;
+ mSciMsgHeader.version = 0x00;
+ mSciMsgHeader.type = 0x00;
+ mSciMsgHeader.length = 0x0000;
+ mSciMsgHeader.station_id = 0x0000;
+ mSciMsgHeader.msg_id = 0x0000;
+ mSciMsgHeader.netclock_high = 0x00000000;
+ mSciMsgHeader.netclock_low = 0x00000000;
+ mSciMsgHeader.flags = 0x0000;
+ mSciMsgHeader.reserved = 0x0000;
+}
+
+
+SciMsg::SciMsg ( const SciMsg & sci_msg )
+{
+ logFunction();
+
+ initAttributes();
+
+ mSciMsgStatus = sci_msg.getSciMsgStatus();
+
+ mSciMsgType = sci_msg.getSciMsgType();
+ mSciMsgStationId = sci_msg.getSciMsgStationId();
+ mSciMsgFlag = sci_msg.getSciMsgFlag();
+
+ setSciMsgHeader(*(sci_msg.getSciMsgHeader()));
+ mSciMsgDataLength = sci_msg.getSciMsgDataLength();
+ mpSciMsgData = sci_msg.getSciMsgData();
+
+ mSpecializedSciMsgHeaderSize = sci_msg.getSpecializedSciMsgHeaderSize();
+ mSpecializedSciMsgDataLength = sci_msg.getSpecializedSciMsgDataLength();
+ mpSpecializedSciMsgData = sci_msg.getSpecializedSciMsgData();
+}
+
+
+SciMsg::SciMsg ( const SciMsg * p_sci_msg )
+{
+ logFunction();
+
+ initAttributes();
+
+ if (NULL != p_sci_msg)
+ {
+ mSciMsgStatus = p_sci_msg->getSciMsgStatus();
+
+ mSciMsgType = p_sci_msg->getSciMsgType();
+ mSciMsgStationId = p_sci_msg->getSciMsgStationId();
+ mSciMsgFlag = p_sci_msg->getSciMsgFlag();
+
+ setSciMsgHeader(*(p_sci_msg->getSciMsgHeader()));
+ mSciMsgDataLength = p_sci_msg->getSciMsgDataLength();
+ mpSciMsgData = p_sci_msg->getSciMsgData();
+
+ mSpecializedSciMsgHeaderSize = p_sci_msg->getSpecializedSciMsgHeaderSize();
+ mSpecializedSciMsgDataLength = p_sci_msg->getSpecializedSciMsgDataLength();
+ mpSpecializedSciMsgData = p_sci_msg->getSpecializedSciMsgData();
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message pointer is NULL", errno);
+ }
+}
+
+
+SciMsg::~SciMsg ( )
+{
+ logFunction();
+
+ if (NULL != mpSciMsgData)
+ {
+ delete [] mpSciMsgData;
+ mpSciMsgData = NULL;
+ }
+ if (NULL != mpSpecializedSciMsgData)
+ {
+ delete [] mpSpecializedSciMsgData;
+ mpSpecializedSciMsgData = NULL;
+ }
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+// Check SCI msg compatibility (check SCI msg version)
+//
+bool SciMsg::checkCompatibility ( ) const
+{
+ logFunction();
+
+ return (getDefinedSciMsgVersion() == getSciMsgHeader()->version);
+}
+
+
+// Check SCI msg validity (check SCI msg magic id and SCI msg id)
+//
+bool SciMsg::checkValidity ( ) const
+{
+ logFunction();
+ bool bCheck = false;
+
+ if ( (getDefinedSciMsgMagicId() == getSciMsgHeader()->magic_id)
+ && (SCI_MSG_ID_STATION <= getSciMsgHeader()->msg_id) )
+ {
+ bCheck = true;
+ }
+
+ return bCheck;
+}
+
+
+// Remove specialized SCI message header from specialized SCI msg data
+// Then, set specialized SCI message data length, and specialized SCI msg data
+//
+bool SciMsg::identifySpecializedSciMsgData ( )
+{
+ logFunction();
+ bool bIdentifyData = false;
+
+ if (NULL != getSciMsgData())
+ {
+ // Check data lengths coherence
+ //
+ if (getSciMsgDataLength() == getSciMsgHeader()->length)
+ {
+ // Create temporary variables
+ //
+ unsigned long tempDataLength = getSciMsgDataLength();
+ unsigned char * pTempData = new unsigned char [tempDataLength];
+
+ if (NULL != pTempData)
+ {
+ for (unsigned long i=0; i<tempDataLength; i++)
+ {
+ *(pTempData+i) = *(getSciMsgData()+i);
+ }
+
+ bIdentifyData = removeData (getSpecializedSciMsgHeaderSize(), tempDataLength, &pTempData);
+
+ if (0 != bIdentifyData)
+ {
+ bIdentifyData &= setSpecializedSciMsgDataLength (tempDataLength);
+ bIdentifyData &= setSpecializedSciMsgData (pTempData);
+ }
+
+ // Free temporary allocated memory
+ //
+ delete [] pTempData;
+ pTempData = NULL;
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Initialized data pointer is NULL");
+ }
+ }
+ else
+ {
+ errno = EPROTO;
+ throw Error(__PRETTY_FUNCTION__, "Incoherent data lengths between SCI message header and set data length", errno);
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Received data pointer is NULL");
+ }
+
+ return bIdentifyData;
+}
+
+
+void SciMsg::displaySciMsgHeader ( ) const
+{
+ logFunction();
+
+ clog << logger(LOG_INFO) << "SCI msg header = " << endl;
+ clog << logger(LOG_INFO) << "\tmagic_id = 0x" << setfill('0') << setw(8) << uppercase << hex << getSciMsgHeader()->magic_id << endl;
+ clog << logger(LOG_INFO) << "\tversion = 0x" << setfill('0') << setw(2) << uppercase << hex << static_cast<unsigned short int>(getSciMsgHeader()->version) << endl;
+ displaySciMsgType();
+ clog << logger(LOG_INFO) << "\tlength = " << dec << getSciMsgHeader()->length << " bytes (0x" << setfill('0') << setw(4) << uppercase << hex << getSciMsgHeader()->length << ")" << endl;
+ clog << logger(LOG_INFO) << "\tstation_id = " << dec << getSciMsgHeader()->station_id << " (0x" << setfill('0') << setw(4) << uppercase << hex << getSciMsgHeader()->station_id << ")" << endl;
+ clog << logger(LOG_INFO) << "\tmsg_id = 0x" << setfill('0') << setw(4) << uppercase << hex << getSciMsgHeader()->msg_id << endl;
+ clog << logger(LOG_INFO) << "\tnetclock = 0x" << setfill('0') << setw(8) << uppercase << hex << getSciMsgHeader()->netclock_high \
+ << setfill('0') << setw(8) << uppercase << hex << getSciMsgHeader()->netclock_low << endl;
+ displaySciMsgFlag();
+ clog << logger(LOG_INFO) << "\treserved = 0x" << setfill('0') << setw(4) << uppercase << hex << getSciMsgHeader()->reserved << dec << endl;
+}
+
+
+void SciMsg::displaySciMsgData ( ) const
+{
+ logFunction();
+
+ ostringstream oss;
+ oss << "SCI msg data = ";
+ if (NULL != getSciMsgData())
+ {
+ for (unsigned long i=0; i<getSciMsgDataLength(); i++)
+ {
+ if ( '\0' == *(getSciMsgData()+i) )
+ {
+ oss << "\\0";
+ }
+ else
+ {
+ oss << *(getSciMsgData()+i);
+ }
+ }
+ }
+ else
+ {
+ oss << "NULL!";
+ }
+ oss << endl;
+ oss.flush();
+ clog << logger(LOG_INFO) << oss.str();
+}
+
+
+void SciMsg::displaySpecializedSciMsgData ( ) const
+{
+ logFunction();
+
+ ostringstream oss;
+ oss << "specialized SCI msg data = ";
+ if (NULL != getSpecializedSciMsgData())
+ {
+ for (unsigned long i=0; i<getSpecializedSciMsgDataLength(); i++)
+ {
+ if ( '\0' == *(getSpecializedSciMsgData()+i) )
+ {
+ oss << "\\0";
+ }
+ else
+ {
+ oss << *(getSpecializedSciMsgData()+i);
+ }
+ }
+ }
+ else
+ {
+ oss << "NULL!";
+ }
+ oss << endl;
+ oss.flush();
+ clog << logger(LOG_INFO) << oss.str();
+}
+
+
+uint32_t SciMsg::getDefinedSciMsgMagicId ( ) const
+{
+ logFunction();
+
+ // Convert char * to uint32_t
+ //
+ char * pMagicId = SCI_MSG_MAGIC;
+ uint32_t magicId = (static_cast<uint8_t>(*(pMagicId))<<24) + (static_cast<uint8_t>(*(pMagicId+1))<<16) + (static_cast<uint8_t>(*(pMagicId+2))<<8) + static_cast<uint8_t>(*(pMagicId+3));
+
+ return magicId;
+}
+
+
+uint8_t SciMsg::getDefinedSciMsgVersion ( ) const
+{
+ return SCI_MSG_VERSION;
+}
+
+
+void SciMsg::displaySciMsgType ( ) const
+{
+ logFunction();
+
+ switch (getSciMsgHeader()->type)
+ {
+ case 0:
+ clog << logger(LOG_INFO) << "\ttype = SCI_MSG_TYPE_NONE" << endl;
+ break;
+ case 1:
+ clog << logger(LOG_INFO) << "\ttype = SCI_MSG_TYPE_NETWORK_CLOCK" << endl;
+ break;
+ case 2:
+ clog << logger(LOG_INFO) << "\ttype = SCI_MSG_TYPE_FUNCTION_CALL" << endl;
+ break;
+ case 3:
+ clog << logger(LOG_INFO) << "\ttype = SCI_MSG_TYPE_PHY" << endl;
+ break;
+ case 4:
+ clog << logger(LOG_INFO) << "\ttype = SCI_MSG_TYPE_SYSTEM" << endl;
+ break;
+ case 5:
+ clog << logger(LOG_INFO) << "\ttype = SCI_MSG_TYPE_ETHERNET" << endl;
+ break;
+ default:
+ clog << logger(LOG_INFO) << "\ttype = unknown!" << endl;
+ break;
+ }
+}
+
+
+// private methods
+//
+
+
+void SciMsg::displaySciMsgFlag ( ) const
+{
+ logFunction();
+
+ switch (getSciMsgHeader()->flags)
+ {
+ case 0:
+ clog << logger(LOG_INFO) << "\tflags = SCI_MSG_FLAG_NONE" << endl;
+ break;
+ case 1:
+ clog << logger(LOG_INFO) << "\tflags = SCI_MSG_FLAG_RESP" << endl;
+ break;
+ case 2:
+ clog << logger(LOG_INFO) << "\tflags = SCI_MSG_FLAG_ACK" << endl;
+ break;
+ case 3:
+ clog << logger(LOG_INFO) << "\tflags = SCI_MSG_FLAG_NEEDACK" << endl;
+ break;
+ case 4:
+ clog << logger(LOG_INFO) << "\tflags = SCI_MSG_FLAG_SYNC" << endl;
+ break;
+ default:
+ clog << logger(LOG_INFO) << "\tflags = unknown!" << endl;
+ break;
+ }
+}
+
+
+// protected methods
+//
+
+
+// Remove required data length from data, and update data length
+//
+bool SciMsg::removeData ( const unsigned long data_length_to_remove, unsigned long & data_length, unsigned char ** pp_data )
+{
+ logFunction();
+ bool bRemoveData = false;
+
+ if ( (data_length >= data_length_to_remove) // check that there are enough data to remove the required data length
+ && (NULL != *pp_data) )
+ {
+ // Create temporary variable and copy data
+ //
+ unsigned char * remainingData = new unsigned char [data_length-data_length_to_remove];
+ for (unsigned long i=data_length_to_remove; i<data_length; i++)
+ {
+ *(remainingData+i-data_length_to_remove) = *((*pp_data)+i);
+ }
+
+ // Update data length
+ //
+ data_length -= data_length_to_remove;
+
+ // Fill data
+ //
+ for (unsigned long i=0; i<data_length; i++)
+ {
+ *((*pp_data)+i) = *(remainingData+i);
+ }
+
+ // Free temporary allocated memory
+ //
+ delete [] remainingData;
+ remainingData = NULL;
+
+ bRemoveData = true;
+ }
+ else
+ {
+ errno = ENODATA;
+ throw Error(__PRETTY_FUNCTION__, "Not enough data", errno);
+ }
+
+ return bRemoveData;
+}
+
+
+// Accessor methods
+//
+
+
+// public attribute accessor methods
+//
+
+
+// private attribute accessor methods
+//
+
+
+Sci_Msg_Status SciMsg::getSciMsgStatus ( ) const
+{
+ return mSciMsgStatus;
+}
+
+
+bool SciMsg::setSciMsgStatus ( const Sci_Msg_Status status )
+{
+ mSciMsgStatus = status;
+
+ return true;
+}
+
+
+Sci_Msg_Type SciMsg::getSciMsgType ( ) const
+{
+ return mSciMsgType;
+}
+
+
+bool SciMsg::setSciMsgType ( const Sci_Msg_Type type )
+{
+ mSciMsgType = type;
+
+ return true;
+}
+
+
+Sci_Msg_Station_Id SciMsg::getSciMsgStationId ( ) const
+{
+ return mSciMsgStationId;
+}
+
+
+bool SciMsg::setSciMsgStationId ( const Sci_Msg_Station_Id station_id )
+{
+ mSciMsgStationId = station_id;
+
+ return true;
+}
+
+
+Sci_Msg_Id SciMsg::getSciMsgId ( ) const
+{
+ return mSciMsgId;
+}
+
+
+bool SciMsg::incrementSciMsgId ( )
+{
+ logFunction();
+
+ if ( SCI_MSG_ID_STATION > (mSciMsgId+1) )
+ {
+ mSciMsgId++;
+ }
+ else
+ {
+ mSciMsgId = 0x0001;
+ }
+
+ return true;
+}
+
+
+Sci_Msg_Flag SciMsg::getSciMsgFlag ( ) const
+{
+ return mSciMsgFlag;
+}
+
+
+bool SciMsg::setSciMsgFlag ( const Sci_Msg_Flag flag )
+{
+ mSciMsgFlag = flag;
+
+ return true;
+}
+
+
+Sci_Msg_Header * SciMsg::getSciMsgHeader ( ) const
+{
+ return (Sci_Msg_Header *)&mSciMsgHeader;
+}
+
+
+bool SciMsg::setSciMsgHeader ( const Sci_Msg_Header & sci_msg_header )
+{
+ logFunction();
+ bool bSetHeader = false;
+
+ mSciMsgHeader = sci_msg_header;
+
+ // Set SCI msg attributes from SCI msg header
+ //
+ setSciMsgType (static_cast<Sci_Msg_Type>(getSciMsgHeader()->type));
+ setSciMsgStationId (static_cast<Sci_Msg_Station_Id>(getSciMsgHeader()->station_id));
+ setSciMsgFlag (static_cast<Sci_Msg_Flag>(getSciMsgHeader()->flags));
+
+ displaySciMsgHeader();
+ bSetHeader = true;
+
+ return bSetHeader;
+}
+
+
+unsigned long SciMsg::getSciMsgDataLength ( ) const
+{
+ return mSciMsgDataLength;
+}
+
+
+bool SciMsg::setSciMsgDataLength ( const unsigned long data_length )
+{
+ logFunction();
+
+ if ( SCI_MSG_MAX_SIZE >= data_length )
+ {
+ mSciMsgDataLength = data_length;
+ }
+ else
+ {
+ errno = EMSGSIZE;
+ throw Error(__PRETTY_FUNCTION__, "Data length exceeds max size", errno);
+ }
+
+ return true;
+}
+
+
+unsigned char * SciMsg::getSciMsgData ( ) const
+{
+ return mpSciMsgData;
+}
+
+
+bool SciMsg::setSciMsgData ( const unsigned char * p_data )
+{
+ logFunction();
+ bool bSetData = false;
+
+ if (NULL != mpSciMsgData)
+ {
+ delete [] mpSciMsgData;
+ mpSciMsgData = NULL;
+ }
+
+ if (NULL != p_data)
+ {
+ mpSciMsgData = new unsigned char [getSciMsgDataLength()];
+ if (NULL != mpSciMsgData)
+ {
+ for (unsigned int i=0; i<getSciMsgDataLength(); i++)
+ {
+ *(mpSciMsgData+i) = *(p_data+i);
+ }
+
+ displaySciMsgData();
+ bSetData = true;
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI message data pointer is NULL");
+ }
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Received data pointer is NULL", errno);
+ }
+
+ return bSetData;
+}
+
+
+// protected attribute accessor methods
+//
+
+
+unsigned long SciMsg::getSpecializedSciMsgHeaderSize ( ) const
+{
+ return mSpecializedSciMsgHeaderSize;
+}
+
+
+bool SciMsg::setSpecializedSciMsgHeaderSize ( const unsigned long header_size )
+{
+ mSpecializedSciMsgHeaderSize = header_size;
+
+ return true;
+}
+
+
+unsigned long SciMsg::getSpecializedSciMsgDataLength ( ) const
+{
+ return mSpecializedSciMsgDataLength;
+}
+
+
+bool SciMsg::setSpecializedSciMsgDataLength ( const unsigned long data_length )
+{
+ mSpecializedSciMsgDataLength = data_length;
+
+ return true;
+}
+
+
+unsigned char * SciMsg::getSpecializedSciMsgData ( ) const
+{
+ return mpSpecializedSciMsgData;
+}
+
+
+bool SciMsg::setSpecializedSciMsgData ( const unsigned char * p_data )
+{
+ logFunction();
+
+ if (NULL != mpSpecializedSciMsgData)
+ {
+ delete [] mpSpecializedSciMsgData;
+ mpSpecializedSciMsgData = NULL;
+ }
+
+ if (NULL != p_data)
+ {
+ mpSpecializedSciMsgData = new unsigned char [getSpecializedSciMsgDataLength()];
+ if (NULL != mpSpecializedSciMsgData)
+ {
+ for (unsigned long i=0; i<getSpecializedSciMsgDataLength(); i++)
+ {
+ *(mpSpecializedSciMsgData+i) = *(p_data+i);
+ }
+ }
+ }
+
+ return true;
+}
+
diff --git a/cesar/maximus/sci/src/SciMsgTest.cpp b/cesar/maximus/sci/src/SciMsgTest.cpp
new file mode 100644
index 0000000000..a45f3b5f28
--- /dev/null
+++ b/cesar/maximus/sci/src/SciMsgTest.cpp
@@ -0,0 +1,129 @@
+
+#include "SciMsgTest.h"
+
+#include "SciMsg.h"
+#include "FunctionSciMsg.h"
+#include "SystemSciMsg.h"
+#include "PhySciMsg.h"
+#include "ClockSciMsg.h"
+#include "EtherSciMsg.h"
+#include "FunctionCallManager.h"
+#include "SciServer.h"
+#include "SystemManager.h"
+#include "PhyProcessor.h"
+#include "EthernetProcessor.h"
+#include "NetworkClockProcessor.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <iostream>
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (SciMsgTest);
+
+
+void SciMsgTest::setUp (void)
+{
+ logTest();
+
+ try
+ {
+ mpSciServer = new SciServer();
+ mpFunctionCallManager = new FunctionCallManager(mpSciServer);
+ mpPhyProcessor = new PhyProcessor(mpSciServer);
+ mpSystemManager = new SystemManager(mpSciServer);
+ mpEthernet = new EthernetProcessor(mpSciServer);
+ mpNetworkClock = new NetworkClockProcessor(mpSciServer, mpSystemManager, mpFunctionCallManager, mpPhyProcessor, mpEthernet);
+ mpFunctionSciMsg = new FunctionSciMsg (mpFunctionCallManager);
+ mpPhySciMsg = new PhySciMsg (mpPhyProcessor);
+ mpSystemSciMsg = new SystemSciMsg(mpSystemManager);
+ mpEtherSciMsg = new EtherSciMsg(mpEthernet);
+ mpClockSciMsg = new ClockSciMsg (mpNetworkClock);
+ }
+ catch ( Error &e )
+ {
+ e.display();
+
+ CPPUNIT_FAIL ( "setUp failed" );
+ }
+}
+
+
+void SciMsgTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpFunctionSciMsg)
+ {
+ delete mpFunctionSciMsg;
+ mpFunctionSciMsg = NULL;
+ }
+ if (NULL != mpClockSciMsg)
+ {
+ delete mpClockSciMsg;
+ mpClockSciMsg = NULL;
+ }
+ if (NULL != mpPhySciMsg)
+ {
+ delete mpPhySciMsg;
+ mpPhySciMsg = NULL;
+ }
+ if (NULL != mpSystemSciMsg)
+ {
+ delete mpSystemSciMsg;
+ mpSystemSciMsg = NULL;
+ }
+ if (NULL != mpEtherSciMsg)
+ {
+ delete mpEtherSciMsg;
+ mpEtherSciMsg = NULL;
+ }
+
+ if (NULL != mpSciServer)
+ {
+ delete mpSciServer;
+ mpSciServer = NULL;
+ }
+ if (NULL != mpFunctionCallManager)
+ {
+ delete mpFunctionCallManager;
+ mpFunctionCallManager = NULL;
+ }
+ if (NULL != mpPhyProcessor)
+ {
+ delete mpPhyProcessor;
+ mpPhyProcessor = NULL;
+ }
+ if (NULL != mpSystemManager)
+ {
+ delete mpSystemManager;
+ mpSystemManager = NULL;
+ }
+ if (NULL != mpEthernet)
+ {
+ delete mpEthernet;
+ mpEthernet = NULL;
+ }
+ if (NULL != mpNetworkClock)
+ {
+ delete mpNetworkClock;
+ mpNetworkClock = NULL;
+ }
+}
+
+
+void SciMsgTest::simpleTest (void)
+{
+ logTest();
+
+ if ( (NULL == mpClockSciMsg)
+ || (NULL == mpFunctionSciMsg)
+ || (NULL == mpPhySciMsg)
+ || (NULL == mpSystemSciMsg)
+ || (NULL == mpEtherSciMsg) )
+ {
+ CPPUNIT_FAIL ( "At least one of the initialized SciMsg pointers is NULL" );
+ }
+}
+
diff --git a/cesar/maximus/sci/src/SciServer.cpp b/cesar/maximus/sci/src/SciServer.cpp
new file mode 100644
index 0000000000..daea096581
--- /dev/null
+++ b/cesar/maximus/sci/src/SciServer.cpp
@@ -0,0 +1,1005 @@
+/************************************************************************
+ SciServer.cpp - Copyright buret
+
+Here you can write a license for your code, some comments or any other
+information you want to have in your generated code. To to this simply
+configure the "headings" directory in uml to point to a directory
+where you have your heading files.
+
+or you can just replace the contents of this file with your own.
+If you want to do this, this file is located at
+
+/usr/share/apps/umbrello/headings/heading.cpp
+
+-->Code Generators searches for heading files based on the file extension
+ i.e. it will look for a file name ending in ".h" to include in C++ header
+ files, and for a file name ending in ".java" to include in all generated
+ java code.
+ If you name the file "heading.<extension>", Code Generator will always
+ choose this file even if there are other files with the same extension in the
+ directory. If you name the file something else, it must be the only one with that
+ extension in the directory to guarantee that Code Generator will choose it.
+
+you can use variables in your heading files which are replaced at generation
+time. possible variables are : author, date, time, filename and filepath.
+just write %variable_name%
+
+This file was generated on %date% at %time%
+The original location of this file is /home/buret/eclipse/maximus/sci/src/SciServer.cpp
+**************************************************************************/
+
+#include "SciServer.h"
+
+#include "Station.h"
+#include "SciMsg.h"
+#include "ClockSciMsg.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <sstream> // for 'ostringstream'
+#include <fstream> // for 'ofstream'
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/select.h>
+#include <iomanip>
+#include <netinet/in.h> // for 'ntohl()' and 'ntohs()'
+#include <iostream> // for 'cout', 'cerr' and 'clog'
+using namespace std;
+
+
+// Constructors/Destructors
+//
+
+
+SciServer::SciServer ( ) :
+mpSpecializedSciMsgArray(NULL),
+mArraySize(0),
+mpListOfStations(NULL),
+mNetworkClockTick(0)
+{
+ logFunction();
+
+ initAttributes();
+}
+
+
+void SciServer::initAttributes ( )
+{
+ logFunction();
+
+ // Init array
+ //
+ mArraySize = 10;
+ mpSpecializedSciMsgArray = new SciMsg * [mArraySize];
+ if (NULL != mpSpecializedSciMsgArray)
+ {
+ for (unsigned int i=0; i<mArraySize; i++)
+ {
+ *(mpSpecializedSciMsgArray+i) = NULL;
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Specialized SCI message array pointer is NULL");
+ }
+}
+
+
+SciServer::~SciServer ( )
+{
+ logFunction();
+
+ // Do not free stations list
+ // Station list is deleted when SystemManager is deleted
+ // Only set pointer to NULL
+ //
+ if (NULL != mpListOfStations)
+ {
+ mpListOfStations = NULL;
+ }
+
+ // Free array
+ //
+ if (NULL != mpSpecializedSciMsgArray)
+ {
+ for (unsigned int i=0; i<mArraySize; i++)
+ {
+ if (NULL != (*(mpSpecializedSciMsgArray+i)))
+ {
+ delete(*(mpSpecializedSciMsgArray+i));
+ (*(mpSpecializedSciMsgArray+i)) = NULL;
+ }
+ }
+ delete [] mpSpecializedSciMsgArray;
+ mpSpecializedSciMsgArray = NULL;
+ }
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+bool SciServer::init ( const std::string station_log )
+{
+ logFunction();
+
+ mStationLog = station_log;
+
+ return true;
+}
+
+
+bool SciServer::process ( )
+{
+ logFunction();
+ bool bProcess = false;
+
+ int fd_max, fd_index;
+ fd_set read_fds;
+ struct timeval timeout;
+ int result;
+ Station *station;
+ StationsList::iterator it;
+
+ // timeout set to 1s
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ // Read input pipes
+ //
+ FD_ZERO(&read_fds);
+ fd_max = 0;
+ for(it = getStationsList()->begin() ; it != getStationsList()->end(); it++)
+ {
+ station = *it;
+
+ FD_SET(station->getInputFileDescriptor(), &read_fds);
+ if(station->getInputFileDescriptor() > fd_max)
+ fd_max = station->getInputFileDescriptor();
+ }
+
+ result = select(fd_max + 1, &read_fds, NULL, NULL, &timeout);
+
+ if(result > 0)
+ {
+ // skim through the list...
+ for(fd_index = 0; fd_index <= fd_max; fd_index++)
+ {
+ if(FD_ISSET(fd_index, &read_fds))
+ {
+ int len, header_len;
+ struct Sci_Msg_Header header;
+ unsigned char *buffer;
+ header_len = sizeof(struct Sci_Msg_Header);
+ if((len = read(fd_index, &header, sizeof(struct Sci_Msg_Header))) < header_len)
+ {
+ clog << logger(LOG_ERROR) << "header read error: len = " << dec << len << ", errno = " << errno << endl;
+ throw Error(__PRETTY_FUNCTION__, "Header read error: len < header_len", errno);
+ }
+ else
+ {
+ // check for header
+ if(memcmp(&header.magic_id, SCI_MSG_MAGIC, 4))
+ {
+ clog << logger(LOG_ERROR) << "bad magic id: 0x" << hex << htonl(header.magic_id) << endl;
+ continue;
+ }
+ header.length = ntohs (header.length);
+ if((header.type <= SCI_MSG_TYPE_NONE)
+ || (header.type >= SCI_MSG_TYPE_NB))
+ {
+ clog << logger(LOG_ERROR) << "bad type: " << dec << header.type << endl;
+ continue;
+ }
+ if(header.version != SCI_MSG_VERSION)
+ {
+ clog << logger(LOG_ERROR) << "bad version: " << dec << header.version << endl;
+ continue;
+ }
+ header.magic_id = ntohl(header.magic_id);
+ header.msg_id = ntohs (header.msg_id);
+ header.station_id = ntohs(header.station_id);
+ header.netclock_high = ntohl(header.netclock_high);
+ header.netclock_low = ntohl(header.netclock_low);
+ header.reserved = ntohs(header.reserved);
+ header.flags = ntohs(header.flags);
+
+ buffer = (unsigned char *)malloc(header.length);
+ if((len = read(fd_index, buffer, header.length)) != header.length)
+ {
+ clog << logger(LOG_ERROR) << "data read error: len = " << dec << len << ", errno = " << errno << endl;
+ free(buffer);
+ if (0 == len)
+ {
+ throw Error(__PRETTY_FUNCTION__, "Data read error: len = 0", errno);
+ }
+ continue;
+ }
+ receiveMsg(&header, header.length, buffer);
+ free(buffer);
+ }
+ }
+ }
+ }
+ station = NULL;
+
+ // Read log pipes
+ //
+ log();
+
+ return bProcess;
+}
+
+
+bool SciServer::log ( ) const
+{
+ logFunction();
+ bool bLog;
+
+ ofstream stationLogFile;
+ if ( (!getStationLog().empty()) && (getStationLog().compare("-")) )
+ {
+ stationLogFile.open(getStationLog().c_str(), ios_base::app | ios_base::ate | ios_base::out);
+ }
+
+ // Skim through stations list
+ //
+ if ( (NULL != mpListOfStations) && (!mpListOfStations->empty()) )
+ {
+ int length;
+ int maxLength = 1024;
+ char * pBuffer = new char [maxLength];
+
+ for (StationsList::const_iterator it = mpListOfStations->begin(); it != mpListOfStations->end(); ++it)
+ {
+ if (NULL != *it)
+ {
+ // Read logs coming from all stations (from log pipes)
+ //
+ length = 0;
+ memset(pBuffer, '\0', maxLength);
+
+ length = read((*it)->getLogFileDescriptor(), pBuffer, maxLength);
+ if (-1 != length)
+ {
+ if (stationLogFile.is_open())
+ {
+ stationLogFile.write(pBuffer, length);
+ }
+ else
+ {
+ cout << dec << pBuffer;
+ }
+ bLog = true;
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "A station pointer is NULL");
+ }
+ }
+
+ delete [] pBuffer;
+ }
+
+ stationLogFile.close();
+
+ return bLog;
+}
+
+bool SciServer::fillSciMsg ( SciMsg & sci_msg_to_send ) const
+{
+ logFunction();
+ bool bFill = false;
+
+ // Fill SCI msg data length
+ //
+ bFill = sci_msg_to_send.setSciMsgDataLength(sci_msg_to_send.getSpecializedSciMsgHeaderSize() + sci_msg_to_send.getSpecializedSciMsgDataLength());
+
+ // Decompose current tick value into two uint32_t values
+ //
+ uint32_t netclockHigh=0, netclockLow=0;
+ netclockLow = (uint32_t)(getNetworkClockTick());
+ netclockHigh = (uint32_t)(((uint64_t)(getNetworkClockTick()) >> 32));
+
+ // Fill SCI msg header
+ //
+ bFill &= sci_msg_to_send.incrementSciMsgId(); // to have an updated msg id
+ struct Sci_Msg_Header sciMsgHeader = { sci_msg_to_send.getDefinedSciMsgMagicId(),
+ sci_msg_to_send.getDefinedSciMsgVersion(),
+ static_cast<uint8_t>(sci_msg_to_send.getSciMsgType()),
+ static_cast<uint16_t>(sci_msg_to_send.getSciMsgDataLength()),
+ sci_msg_to_send.getSciMsgStationId(),
+ sci_msg_to_send.getSciMsgId(),
+ netclockHigh,
+ netclockLow,
+ 0, // flags
+ 0 }; // reserved
+ bFill &= sci_msg_to_send.setSciMsgHeader(sciMsgHeader);
+
+ // As SCI msg header will be sent on an output pipe, 'hton' functions have to be called
+ //
+ sci_msg_to_send.getSciMsgHeader()->magic_id = htonl(sci_msg_to_send.getSciMsgHeader()->magic_id);
+ sci_msg_to_send.getSciMsgHeader()->length = htons(sci_msg_to_send.getSciMsgHeader()->length);
+ sci_msg_to_send.getSciMsgHeader()->station_id = htons(sci_msg_to_send.getSciMsgHeader()->station_id);
+ sci_msg_to_send.getSciMsgHeader()->msg_id = htons(sci_msg_to_send.getSciMsgHeader()->msg_id);
+ sci_msg_to_send.getSciMsgHeader()->netclock_high = htonl(sci_msg_to_send.getSciMsgHeader()->netclock_high);
+ sci_msg_to_send.getSciMsgHeader()->netclock_low = htonl(sci_msg_to_send.getSciMsgHeader()->netclock_low);
+
+ // Fill SCI msg data length
+ // When sending a SCI msg, SCI msg data contain:
+ // - SCI msg header,
+ // - specialized SCI msg header,
+ // - and specialized SCI msg data
+ //
+ bFill = sci_msg_to_send.setSciMsgDataLength(static_cast<unsigned long>(sizeof(struct Sci_Msg_Header)) + sci_msg_to_send.getSpecializedSciMsgHeaderSize() + sci_msg_to_send.getSpecializedSciMsgDataLength());
+
+ // Fill SCI msg data
+ // When sending a SCI msg, since only SCI msg data will be sent on an output pipe,
+ // SCI msg header and specialized SCI msg header have to be copied into SCI msg data
+ // Then, specialized SCI msg data have to be copied into SCI msg data
+ //
+ unsigned char * pTempData = new unsigned char [sci_msg_to_send.getSciMsgDataLength()];
+ if (NULL != pTempData)
+ {
+ memcpy(pTempData, (unsigned char *)sci_msg_to_send.getSciMsgHeader(), sizeof(struct Sci_Msg_Header));
+ memcpy(pTempData+sizeof(Sci_Msg_Header), (unsigned char *)sci_msg_to_send.returnSpecializedSciMsgHeader(), sci_msg_to_send.getSpecializedSciMsgHeaderSize());
+ memcpy(pTempData+sizeof(Sci_Msg_Header)+sci_msg_to_send.getSpecializedSciMsgHeaderSize(), sci_msg_to_send.getSpecializedSciMsgData(), sci_msg_to_send.getSpecializedSciMsgDataLength());
+ }
+ bFill &= sci_msg_to_send.setSciMsgData(pTempData);
+
+ // Free temporary allocated memory
+ //
+ if (NULL != pTempData)
+ {
+ delete [] pTempData;
+ pTempData = NULL;
+ }
+
+ return bFill;
+}
+
+
+bool SciServer::sendSciMsg ( const SciMsg & sci_msg_to_send ) const
+{
+ logFunction();
+ bool bSend = false;
+
+ // Retrieve destination station
+ //
+ if (NULL != mpListOfStations)
+ {
+ // Skim through stations list
+ //
+ for (StationsList::const_iterator it = mpListOfStations->begin(); it != mpListOfStations->end(); ++it)
+ {
+ // Before sending a SCI msg, check that station status is 'IDLE'
+ //
+ if ( (NULL != *it)
+ && ((*it)->getStationId() == sci_msg_to_send.getSciMsgStationId())
+ && (MAXIMUS_STATION_STATUS_IDLE == (*it)->getStationStatus()) )
+ {
+ bSend = true;
+
+ // Write data into output pipe
+ //
+ int length = 0;
+ int totalLength = 0;
+ while(totalLength < (int)sci_msg_to_send.getSciMsgDataLength())
+ {
+ length = write((*it)->getOutputFileDescriptor(), sci_msg_to_send.getSciMsgData() + totalLength, sci_msg_to_send.getSciMsgDataLength()-totalLength);
+ if(length < 0)
+ {
+ if (EAGAIN != errno)
+ {
+ throw Error(__PRETTY_FUNCTION__, "write data failed", errno);
+ }
+ else
+ {
+ length = 0;
+ }
+ }
+ totalLength += length;
+ }
+
+ // Station status is set to 'BUSY'
+ // Station status will stay 'BUSY' until all system 'IDLE' msgs will be received
+ //
+ (*it)->setStationStatus(MAXIMUS_STATION_STATUS_BUSY);
+ (*it)->incrementStationIdleCounter();
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Stations list pointer is NULL");
+ }
+
+ if (bSend)
+ {
+ clog << logger(LOG_COM) << "<--- send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to station " << dec << sci_msg_to_send.getSciMsgStationId() \
+ << " (0x" << setfill('0') << setw(4) << uppercase << hex << sci_msg_to_send.getSciMsgStationId() << ")" << dec << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_COM);
+ }
+ else
+ {
+ clog << logger(LOG_ERROR) << "--- did not send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to station " << dec << sci_msg_to_send.getSciMsgStationId() \
+ << " (0x" << setfill('0') << setw(4) << uppercase << hex << sci_msg_to_send.getSciMsgStationId() << ")" << dec << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_ERROR);
+ }
+
+ return bSend;
+}
+
+
+bool SciServer::sendSciMsgToAllActiveStations ( SciMsg & sci_msg_to_send ) const
+{
+ logFunction();
+ bool bSend = false;
+
+ if (NULL != mpListOfStations)
+ {
+ const Sci_Msg_Station_Id txStationId = sci_msg_to_send.getSciMsgStationId(); // get id of the transmitting station
+ int length;
+ int totalLength;
+ bool bWrite;
+
+ // Skim through stations list
+ //
+ for (StationsList::const_iterator it = mpListOfStations->begin(); it != mpListOfStations->end(); ++it)
+ {
+ // Send message to all active stations except the sender
+ //
+ if ( (NULL != *it)
+ && (MAXIMUS_STATION_STATUS_DEACTIVATED != (*it)->getStationStatus())
+ && fillSciMsg(sci_msg_to_send) )
+ {
+ bSend = true;
+ }
+
+ if (txStationId != (*it)->getStationId())
+ {
+ // Write data into output pipe
+ //
+ length = 0;
+ totalLength = 0;
+ bWrite = true;
+ while(totalLength < (int)sci_msg_to_send.getSciMsgDataLength())
+ {
+ length = write((*it)->getOutputFileDescriptor(), sci_msg_to_send.getSciMsgData() + totalLength, sci_msg_to_send.getSciMsgDataLength()-totalLength);
+ if(length < 0)
+ {
+ if (EAGAIN != errno)
+ {
+ throw Error(__PRETTY_FUNCTION__, "write data failed", errno);
+ }
+ else
+ {
+ length = 0;
+ }
+ }
+ totalLength += length;
+ }
+
+ if (bWrite)
+ {
+ // Station status is set to 'BUSY'
+ // Station status will stay 'BUSY' until all system 'IDLE' msgs will be received
+ //
+ (*it)->setStationStatus(MAXIMUS_STATION_STATUS_BUSY);
+ (*it)->incrementStationIdleCounter();
+ }
+
+ clog << logger(LOG_INFO) << "--- send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to station " << dec << (*it)->getStationId() \
+ << " (0x" << setfill('0') << setw(4) << uppercase << hex << (*it)->getStationId() << ")" << dec << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_INFO);
+ }
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Stations list pointer is NULL");
+ }
+
+ if (bSend)
+ {
+ clog << logger(LOG_COM) << "<--- send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to all stations" << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_COM);
+ }
+ else
+ {
+ clog << logger(LOG_ERROR) << "--- did not send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to all stations!" << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_ERROR);
+ }
+
+ return bSend;
+}
+
+
+bool SciServer::sendSciMsgToDestStations ( SciMsg & sci_msg_to_send, DestStationsList & list_of_dest_stations ) const
+{
+ logFunction();
+ bool bSend = list_of_dest_stations.empty();
+
+ if (bSend)
+ {
+ clog << logger(LOG_COM) << "--- did not send " << displaySciMsgType(sci_msg_to_send.getSciMsgType()) \
+ << " SCI message because no station requested it" << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_COM);
+ }
+ else
+ {
+ if (NULL != mpListOfStations)
+ {
+ Sci_Msg_Station_Id txStationId;
+ while (!list_of_dest_stations.empty())
+ {
+ txStationId = list_of_dest_stations.back();
+ int length;
+ int totalLength;
+ bool bWrite;
+
+ // Skim through stations list
+ //
+ for (StationsList::const_iterator it = mpListOfStations->begin(); it != mpListOfStations->end(); ++it)
+ {
+ // Send message to destination stations
+ //
+ if ( (NULL != *it)
+ && (txStationId == (*it)->getStationId())
+ && (MAXIMUS_STATION_STATUS_DEACTIVATED != (*it)->getStationStatus())
+ && fillSciMsg(sci_msg_to_send) )
+ {
+ bSend = true;
+
+ // Write data into output pipe
+ //
+ length = 0;
+ totalLength = 0;
+ bWrite = true;
+ while(totalLength < (int)sci_msg_to_send.getSciMsgDataLength())
+ {
+ length = write((*it)->getOutputFileDescriptor(), sci_msg_to_send.getSciMsgData() + totalLength, sci_msg_to_send.getSciMsgDataLength()-totalLength);
+ if(length < 0)
+ {
+ if (EAGAIN != errno)
+ {
+ throw Error(__PRETTY_FUNCTION__, "write data failed", errno);
+ }
+ else
+ {
+ length = 0;
+ }
+ }
+ totalLength += length;
+ }
+
+ if (bWrite)
+ {
+ // Station status is set to 'BUSY'
+ // Station status will stay 'BUSY' until all system 'IDLE' msgs will be received
+ //
+ (*it)->setStationStatus(MAXIMUS_STATION_STATUS_BUSY);
+ (*it)->incrementStationIdleCounter();
+ }
+
+ clog << logger(LOG_INFO) << "--- send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to station " << dec << (*it)->getStationId() \
+ << " (0x" << setfill('0') << setw(4) << uppercase << hex << (*it)->getStationId() << ")" << dec << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_INFO);
+ }
+ }
+ list_of_dest_stations.pop_back();
+ }
+ if (bSend)
+ {
+ clog << logger(LOG_COM) << "<--- send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to destination stations" << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_COM);
+ }
+ else
+ {
+ clog << logger(LOG_ERROR) << "--- did not send " << displaySciMsgType(sci_msg_to_send.getSciMsgHeader()->type) \
+ << " SCI message to destination stations!" << endl;
+ sci_msg_to_send.displaySpecializedSciMsgType(LOG_ERROR);
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Stations list pointer is NULL");
+ }
+ }
+
+ return bSend;
+}
+
+
+bool SciServer::registerSpecializedSciMsg ( const Sci_Msg_Type sci_msg_type, SciMsg * sci_msg )
+{
+ logFunction();
+ bool bRegister = false;
+
+ if (NULL != sci_msg)
+ {
+ if (getArraySize() > (unsigned int)sci_msg_type)
+ {
+ if (NULL != getSpecializedSciMsgArray())
+ {
+ if (NULL != *(mpSpecializedSciMsgArray + (unsigned int)sci_msg_type))
+ {
+ delete(*(mpSpecializedSciMsgArray + (unsigned int)sci_msg_type));
+ *(mpSpecializedSciMsgArray + (unsigned int)sci_msg_type) = NULL;
+ }
+ *(mpSpecializedSciMsgArray + (unsigned int)sci_msg_type) = sci_msg; // set mpSpecializedSciMsgArray
+ bRegister = true;
+ }
+ }
+ else
+ {
+ errno = ENOMSG;
+ throw Error(__PRETTY_FUNCTION__, "SCI message type exceeds specialized SCI message array size", errno);
+ }
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message pointer is NULL", errno);
+ }
+
+ return bRegister;
+}
+
+
+bool SciServer::receiveMsg ( const Sci_Msg_Header * header,
+ const unsigned long data_length,
+ const unsigned char * received_data ) const
+{
+ logFunction();
+ bool bReceiveMsg = false;
+
+ if (NULL != header)
+ {
+ clog << logger(LOG_COM) << "---> receive " << displaySciMsgType(header->type) << " SCI message from station " << dec << header->station_id << " (" << setfill('0') << setw(4) << uppercase << hex << header->station_id << ")" << dec << endl;
+
+ // Create a specialized SCI message according to the message header type
+ //
+ SciMsg * sciMsg = NULL;
+ Sci_Msg_Type type = static_cast<Sci_Msg_Type>(header->type);
+ bReceiveMsg = createSciMsg (type, &sciMsg);
+
+ // Process the created specialized SCI message
+ //
+ if ( (NULL != sciMsg) && (0 != bReceiveMsg) )
+ {
+ if (NULL != received_data)
+ {
+ // Fill SCI msg
+ //
+ bReceiveMsg = fillSciMsg (header, data_length, received_data, &sciMsg);
+ sciMsg->displaySpecializedSciMsgData();
+ sciMsg->displaySpecializedSciMsgType(LOG_COM);
+
+ // Check msg compatibility (check msg versions)
+ // Check msg validity
+ //
+ if (0 != bReceiveMsg)
+ {
+ bReceiveMsg = sciMsg->checkCompatibility();
+ bReceiveMsg &= sciMsg->checkValidity();
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI message not correctly filled in");
+ }
+
+ // Process SCI msg
+ //
+ if (0 != bReceiveMsg)
+ {
+ bReceiveMsg = processSciMsg (sciMsg);
+ }
+ else
+ {
+ errno = EPROTO;
+ throw Error(__PRETTY_FUNCTION__, "SCI message not valid", errno);
+ }
+
+ // Free allocated memory
+ //
+ if (NULL != sciMsg)
+ {
+ clog << logger(LOG_INFO) << "delete SCI message" << endl;
+ delete (sciMsg);
+ sciMsg = NULL;
+ }
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Data pointer is NULL", errno);
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Error when creating SCI message");
+ }
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message header pointer is NULL", errno);
+ }
+
+ return bReceiveMsg;
+}
+
+
+void SciServer::displaySpecializedSciMsgArray ( ) const
+{
+ logFunction();
+
+ ostringstream oss;
+ oss << "specialized SCI msg array = " << endl;
+ for (unsigned int i=0; i<getArraySize(); i++)
+ {
+ if (NULL != *(getSpecializedSciMsgArray()+i))
+ {
+ oss << "\t" << hex << setfill('0') << setw(8) << uppercase << *(getSpecializedSciMsgArray()+i) << endl;
+ }
+ else
+ {
+ oss << "\tNULL" << endl;
+ }
+ }
+ oss.flush();
+ clog << logger(LOG_INFO) << oss.str() << dec;
+}
+
+
+// private methods
+//
+
+
+bool SciServer::createSciMsg ( const Sci_Msg_Type type, SciMsg ** received_sci_msg ) const
+{
+ logFunction();
+ bool bCreateMsg = false;
+
+ // Create a specialized SCI message according to the header type
+ //
+ if (NULL != received_sci_msg)
+ {
+ if ( (getArraySize() > (unsigned int)type) && (NULL != *(getSpecializedSciMsgArray() + (unsigned int)type)) )
+ {
+ *received_sci_msg = (*(getSpecializedSciMsgArray() + type))->create();
+ }
+ else
+ {
+ errno = ENOMSG;
+ throw Error(__PRETTY_FUNCTION__, "SCI message type is invalid: no corresponding SCI message", errno);
+ }
+
+ // Check if the just created SCI msg is valid
+ //
+ if (NULL != *received_sci_msg)
+ {
+ bCreateMsg = true;
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message pointer is invalid", errno);
+ }
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message pointer is invalid", errno);
+ }
+
+ return bCreateMsg;
+}
+
+
+bool SciServer::fillSciMsg ( const Sci_Msg_Header * p_msg_header,
+ const unsigned long data_length,
+ const unsigned char * p_received_data,
+ SciMsg ** created_sci_msg ) const
+{
+ logFunction();
+ bool bFillMsg = false;
+
+ // Fill SCI message contents
+ //
+ if (NULL != created_sci_msg)
+ {
+ if (NULL != p_msg_header)
+ {
+ // Set SCI message header
+ // Set SCI message attributes
+ //
+ bFillMsg = (*created_sci_msg)->setSciMsgHeader(*p_msg_header);
+
+ bFillMsg &= (*created_sci_msg)->setSciMsgDataLength(data_length);
+ if (NULL != p_received_data)
+ {
+ bFillMsg &= (*created_sci_msg)->setSciMsgData(p_received_data);
+
+ // Set specialized SCI message header
+ // Set specialized attributes
+ //
+ bFillMsg &= (*created_sci_msg)->identifySpecializedSciMsgHeader();
+
+ // Remove specialized SCI message header from specialized SCI msg data
+ // Then, set specialized SCI message data length, and specialized SCI message data
+ //
+ bFillMsg &= (*created_sci_msg)->identifySpecializedSciMsgData();
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Data pointer is NULL", errno);
+ }
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message header pointer is NULL", errno);
+ }
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message pointer is NULL", errno);
+ }
+
+ return bFillMsg;
+}
+
+
+bool SciServer::processSciMsg ( SciMsg * received_sci_msg ) const
+{
+ logFunction();
+ bool bProcessMsg = false;
+
+ if (NULL != received_sci_msg)
+ {
+ bProcessMsg = received_sci_msg->dispatchMsg();
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI message pointer is NULL", errno);
+ }
+
+ return bProcessMsg;
+}
+
+
+string SciServer::displaySciMsgType ( uint8_t sci_msg_type ) const
+{
+ logFunction();
+ string type;
+
+ switch (sci_msg_type)
+ {
+ case 1:
+ type.assign("network clock");
+ break;
+ case 2:
+ type.assign("function call");
+ break;
+ case 3:
+ type.assign("PHY");
+ break;
+ case 4:
+ type.assign("system");
+ break;
+ case 5:
+ type.assign("ethernet");
+ break;
+ case 0:
+ default:
+ type.assign("unknown");
+ break;
+ }
+
+ return type;
+}
+
+
+// protected methods
+//
+
+
+// Accessor methods
+//
+
+
+// public attribute accessor methods
+//
+
+
+// private attribute accessor methods
+//
+
+
+StationsList * SciServer::getStationsList ( ) const
+{
+ return mpListOfStations;
+}
+
+
+bool SciServer::setStationsList ( StationsList * p_list_of_stations )
+{
+ logFunction();
+ bool bSetList = false;
+
+ if (NULL != p_list_of_stations)
+ {
+ mpListOfStations = p_list_of_stations;
+ bSetList = true;
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "List of stations pointer is NULL", errno);
+ }
+
+ return bSetList;
+}
+
+
+SciMsg ** SciServer::getSpecializedSciMsgArray ( ) const
+{
+ return mpSpecializedSciMsgArray;
+}
+
+
+unsigned int SciServer::getArraySize ( ) const
+{
+ return mArraySize;
+}
+
+
+Network_Clock_Tick SciServer::getNetworkClockTick ( ) const
+{
+ return mNetworkClockTick;
+}
+
+
+bool SciServer::updateTickValue ( const Network_Clock_Tick current_tick_value )
+{
+ mNetworkClockTick = current_tick_value;
+
+ return true;
+}
+
+
+std::string SciServer::getStationLog ( ) const
+{
+ return mStationLog;
+}
+
+
+// protected attribute accessor methods
+//
+
diff --git a/cesar/maximus/sci/src/SciServerTest.cpp b/cesar/maximus/sci/src/SciServerTest.cpp
new file mode 100644
index 0000000000..d5a2e59dde
--- /dev/null
+++ b/cesar/maximus/sci/src/SciServerTest.cpp
@@ -0,0 +1,510 @@
+
+#include "SciServerTest.h"
+
+#include "SciServer.h"
+#include "FunctionCallManager.h"
+#include "SystemManager.h"
+#include "PhyProcessor.h"
+#include "NetworkClockProcessor.h"
+#include "ClockSciMsg.h"
+#include "SystemSciMsg.h"
+#include "PhySciMsg.h"
+#include "FunctionSciMsg.h"
+#include "EthernetProcessor.h"
+#include "EtherSciMsg.h"
+
+#include "networkclock_types.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <string>
+#include <iomanip>
+#include <netinet/in.h> // for 'htonl()' and 'htons()'
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (SciServerTest);
+
+
+void SciServerTest::setUp (void)
+{
+ logTest();
+
+ mpSciServer = new SciServer ();
+ mpFunctionCallManager = new FunctionCallManager(mpSciServer);
+ mpSystemManager = new SystemManager(mpSciServer);
+ mpPhyProcessor = new PhyProcessor(mpSciServer);
+ mpEthernet = new EthernetProcessor(mpSciServer);
+ mpNetworkClockProcessor = new NetworkClockProcessor(mpSciServer, mpSystemManager, mpFunctionCallManager, mpPhyProcessor, mpEthernet);
+}
+
+
+void SciServerTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpNetworkClockProcessor)
+ {
+ delete mpNetworkClockProcessor;
+ mpNetworkClockProcessor = NULL;
+ }
+ if (NULL != mpPhyProcessor)
+ {
+ delete mpPhyProcessor;
+ mpPhyProcessor = NULL;
+ }
+ if (NULL != mpSystemManager)
+ {
+ delete mpSystemManager;
+ mpSystemManager = NULL;
+ }
+ if (NULL != mpFunctionCallManager)
+ {
+ delete mpFunctionCallManager;
+ mpFunctionCallManager = NULL;
+ }
+ if (NULL != mpSciServer)
+ {
+ delete mpSciServer;
+ mpSciServer = NULL;
+ }
+ if (NULL != mpEthernet)
+ {
+ delete mpEthernet;
+ mpEthernet = NULL;
+ }
+}
+
+
+void SciServerTest::registerSpecializedSciMsgTest (void)
+{
+ logTest();
+
+ if (NULL != mpSciServer)
+ {
+ try
+ {
+ registerFunctionSciMsgTest ();
+ registerSystemSciMsgTest ();
+ registerPhySciMsgTest ();
+ registerClockSciMsgTest ();
+ registerEtherSciMsgTest ();
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ CPPUNIT_FAIL ("Catch exception");
+ }
+ }
+ else
+ {
+ CPPUNIT_FAIL ("SciServer pointer is NULL");
+ }
+}
+
+
+void SciServerTest::receiveMsgTest (void)
+{
+ logTest();
+
+ if (NULL != mpSciServer)
+ {
+ // Before receiving a message, SCI messages have to be registered
+ //
+ try
+ {
+ registerFunctionSciMsgTest ();
+ registerSystemSciMsgTest ();
+ registerPhySciMsgTest ();
+ registerClockSciMsgTest ();
+ registerEtherSciMsgTest ();
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ CPPUNIT_FAIL ("Catch exception");
+ }
+
+ mpSciServer->displaySpecializedSciMsgArray();
+
+ // Create a station
+ //
+ Sci_Msg_Station_Id stationId = mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ // Convert char * to uint32_t
+ //
+ char * pMagicId = SCI_MSG_MAGIC;
+ uint32_t magicId = (static_cast<uint8_t>(*(pMagicId))<<24) + (static_cast<uint8_t>(*(pMagicId+1))<<16) + (static_cast<uint8_t>(*(pMagicId+2))<<8) + static_cast<uint8_t>(*(pMagicId+3));
+
+ Sci_Msg_Header msgHeader = { magicId, // uint32_t magic_id
+ SCI_MSG_VERSION, // uint8_t version = 0x01
+ SCI_MSG_TYPE_NONE, // uint8_t type = 0x00
+ 0x0000, // uint16_t length
+ stationId, // uint16_t station_id
+ SCI_MSG_ID_STATION, // uint16_t msg_id
+ 0x01234567, // uint32_t netclock_high
+ 0x89101112, // uint32_t netclock_low
+ 0xFFFF, //uint16_t flags
+ 0xFFFF }; // uint16_t reserved
+
+ mpSystemManager->updateStationStatus ( stationId, MAXIMUS_STATION_STATUS_IDLE );
+
+ try
+ {
+ receiveClockSciMsgTest (msgHeader);
+ receivePhySciMsgTest (msgHeader);
+ receiveSystemSciMsgTest (msgHeader);
+ receiveFunctionSciMsgTest (msgHeader);
+ receiveEtherSciMsgTest (msgHeader);
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ CPPUNIT_FAIL ("Catch exception");
+ }
+
+ // Remove station
+ //
+ mpSystemManager->removeStation(stationId);
+ }
+ else
+ {
+ CPPUNIT_FAIL ("SciServer pointer is NULL");
+ }
+}
+
+
+void SciServerTest::registerClockSciMsgTest (void)
+{
+ logTest();
+
+ // Test a network clock SCI message registration
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "registerSpecializedSciMsg failed",
+ mpSciServer->registerSpecializedSciMsg(SCI_MSG_TYPE_NETWORK_CLOCK, new ClockSciMsg(mpNetworkClockProcessor)) );
+
+ // Check results
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "KO",
+ (*((mpSciServer->getSpecializedSciMsgArray())+(unsigned int)SCI_MSG_TYPE_NETWORK_CLOCK)) != NULL );
+}
+
+
+void SciServerTest::registerFunctionSciMsgTest (void)
+{
+ logTest();
+
+ // Test a function call SCI message registration
+ //
+ if (NULL != mpFunctionCallManager)
+ {
+ CPPUNIT_ASSERT_MESSAGE ( "registerSpecializedSciMsg failed",
+ mpSciServer->registerSpecializedSciMsg(SCI_MSG_TYPE_FUNCTION_CALL, new FunctionSciMsg(mpFunctionCallManager)) );
+ }
+ else
+ {
+ CPPUNIT_FAIL ("FunctionCallManager pointer is NULL");
+ }
+
+ // Check results
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "KO",
+ (*((mpSciServer->getSpecializedSciMsgArray())+(unsigned int)SCI_MSG_TYPE_FUNCTION_CALL)) != NULL );
+}
+
+
+void SciServerTest::registerPhySciMsgTest (void)
+{
+ logTest();
+
+ // Test a PHY SCI message registration
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "registerSpecializedSciMsg failed",
+ mpSciServer->registerSpecializedSciMsg(SCI_MSG_TYPE_PHY, new PhySciMsg(mpPhyProcessor)) );
+
+ // Check results
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "KO",
+ (*((mpSciServer->getSpecializedSciMsgArray())+(unsigned int)SCI_MSG_TYPE_PHY)) != NULL );
+}
+
+
+void SciServerTest::registerSystemSciMsgTest (void)
+{
+ logTest();
+
+ // Test a system SCI message registration
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "registerSpecializedSciMsg failed",
+ mpSciServer->registerSpecializedSciMsg(SCI_MSG_TYPE_SYSTEM, new SystemSciMsg(mpSystemManager)) );
+
+ // Check results
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "KO",
+ (*((mpSciServer->getSpecializedSciMsgArray())+(unsigned int)SCI_MSG_TYPE_SYSTEM)) != NULL );
+}
+
+
+void SciServerTest::registerEtherSciMsgTest (void)
+{
+ logTest();
+
+ // Test an Ether SCI message registration
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "registerSpecializedSciMsg failed",
+ mpSciServer->registerSpecializedSciMsg(SCI_MSG_TYPE_ETHERNET, new EtherSciMsg(mpEthernet)) );
+
+ // Check results
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "KO",
+ (*((mpSciServer->getSpecializedSciMsgArray())+(unsigned int)SCI_MSG_TYPE_ETHERNET)) != NULL );
+}
+
+
+void SciServerTest::receiveClockSciMsgTest ( Sci_Msg_Header & msg_header )
+{
+ logTest();
+
+ // Message header type and length have to be set to the corresponding specialized SCI message
+ //
+ msg_header.type = SCI_MSG_TYPE_NETWORK_CLOCK; // uint8_t type = 0x01
+
+ unsigned long dataLength = (unsigned long)sizeof(Network_Clock_Header);
+ msg_header.length = (uint16_t)dataLength;
+
+ unsigned char * pData = new unsigned char [dataLength];
+ if (NULL != pData)
+ {
+ *pData = static_cast<unsigned char>(NETWORK_CLOCK_VERSION); // uint8_t version = 0x01
+ *(pData+1) = static_cast<unsigned char>(NETWORK_CLOCK_TYPE_STATION); // uint8_t type = 0x02
+ *(pData+2) = static_cast<unsigned char>(0x01); // uint16_t id
+ *(pData+3) = static_cast<unsigned char>(0x23);
+ *(pData+4) = static_cast<unsigned char>(0x45); // uint16_t flags
+ *(pData+5) = static_cast<unsigned char>(0x67);
+ *(pData+6) = static_cast<unsigned char>(0x89); // uint16_t reserved
+ *(pData+7) = static_cast<unsigned char>(0x12);
+ *(pData+8) = static_cast<unsigned char>(0x01); // uint32_t tick_high
+ *(pData+9) = static_cast<unsigned char>(0x23);
+ *(pData+10) = static_cast<unsigned char>(0x45);
+ *(pData+11) = static_cast<unsigned char>(0x67);
+ *(pData+12) = static_cast<unsigned char>(0x89); // uint32_t tick_low
+ *(pData+13) = static_cast<unsigned char>(0x10);
+ *(pData+14) = static_cast<unsigned char>(0x11);
+ *(pData+15) = static_cast<unsigned char>(0x13);
+ }
+
+ // Test the receiveMsg method
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "receiveMsg ClockSciMsg failed",
+ mpSciServer->receiveMsg (&msg_header, dataLength, pData) );
+
+ // Free allocated memory
+ //
+ if (NULL != pData)
+ {
+ delete [] pData;
+ pData = NULL;
+ }
+}
+
+
+void SciServerTest::receiveSystemSciMsgTest ( Sci_Msg_Header & msg_header )
+{
+ logTest();
+
+ // Message header type and length have to be set to the corresponding specialized SCI message
+ //
+ msg_header.type = SCI_MSG_TYPE_SYSTEM; // uint8_t type = 0x04
+
+ unsigned long dataLength = sizeof(struct System_Header);
+ msg_header.length = (uint16_t)dataLength;
+
+ unsigned char * pData = new unsigned char [dataLength];
+ if (NULL != pData)
+ {
+ *pData = static_cast<unsigned char>(SYSTEM_VERSION); // uint8_t version = 0x01
+ *(pData+1) = static_cast<unsigned char>(SYSTEM_TYPE_IDLE); // uint8_t type = 0x01
+ *(pData+2) = static_cast<unsigned char>(0xFF); // uint16_t flags
+ *(pData+3) = static_cast<unsigned char>(0xFF);
+ }
+
+ // Test the receiveMsg method
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "receiveMsg SystemSciMsg failed",
+ mpSciServer->receiveMsg (&msg_header, dataLength, pData) );
+
+ // Free allocated memory
+ //
+ if (NULL != pData)
+ {
+ delete [] pData;
+ pData = NULL;
+ }
+}
+
+
+void SciServerTest::receivePhySciMsgTest ( Sci_Msg_Header & msg_header )
+{
+ logTest();
+
+ // Message header type and length have to be set to the corresponding specialized SCI message
+ //
+ msg_header.type = SCI_MSG_TYPE_PHY; // uint8_t type = 0x03
+
+ uint32_t iv[3];
+ memset(iv, 'z', 3*sizeof(uint32_t));
+ uint32_t nek[4];
+ memset(nek, 'a', 4*sizeof(uint32_t));
+ uint32_t pbMeasurement [PHY_PB_MAX_NB];
+ memset(pbMeasurement, 'b', PHY_PB_MAX_NB*sizeof(uint32_t));
+ uint32_t pbHeader [PHY_PB_MAX_NB];
+ memset(pbHeader, 'c', PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ Phy_Header phyHeader;
+ phyHeader.version = PHY_VERSION;
+ phyHeader.type = PHY_TYPE_PREAMBLE;
+ phyHeader.mpdu_format = PHY_MPDU_FORMAT_NONE;
+ phyHeader.pb_nb = 0x00;
+ phyHeader.msg_nb = 0x01;
+ phyHeader.fc_mode = 0x01;
+ phyHeader.short_ppdu = 0x01;
+ phyHeader.mod = 0x01;
+ phyHeader.fecrate = 0x01;
+ phyHeader.gil = 0x01;
+ phyHeader.tonemap_index = 0x02;
+ phyHeader.reserved = 0xFF;
+ phyHeader.tx_id = htons(0x0001);
+ phyHeader.flags = htons(PHY_FLAG_CRC_OK);
+ phyHeader.symbol_nb = htonl(0x00000010);
+
+ memcpy(phyHeader.iv, iv, 3*sizeof(uint32_t));
+ memcpy(phyHeader.nek, nek, 4*sizeof(uint32_t));
+ memcpy(phyHeader.pb_measurement, pbMeasurement, PHY_PB_MAX_NB*sizeof(uint32_t));
+ memcpy(phyHeader.pb_header, pbHeader, PHY_PB_MAX_NB*sizeof(uint32_t));
+
+ unsigned long dataLength = sizeof(struct Phy_Header);
+ msg_header.length = (uint16_t)dataLength;
+
+ unsigned char * pData = new unsigned char [dataLength];
+ if (NULL != pData)
+ {
+ memcpy(pData, (unsigned char *)&phyHeader, sizeof(struct Phy_Header));
+ }
+
+ //Test the receiveMsg method
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "receiveMsg PhySciMsg failed",
+ mpSciServer->receiveMsg (&msg_header, dataLength, pData) );
+
+ // Free allocated memory
+ //
+ if (NULL != pData)
+ {
+ delete [] pData;
+ pData = NULL;
+ }
+}
+
+
+void SciServerTest::receiveFunctionSciMsgTest ( Sci_Msg_Header & msg_header )
+{
+ logTest();
+
+ // Message header type and length have to be set to the corresponding specialized SCI message
+ //
+ msg_header.type = SCI_MSG_TYPE_FUNCTION_CALL;
+
+ stringstream ioss;
+ ioss << static_cast<unsigned char>(FUNCTION_CALL_VERSION); // uint8_t version = 0x01
+ ioss << static_cast<unsigned char>(FUNCTION_CALL_TYPE_RSP); // uint8_t type = 0x01
+ ioss << static_cast<unsigned char>(0x00); // uint16_t msg_id = 0x0001
+ ioss << static_cast<unsigned char>(0x01);
+ ioss << static_cast<unsigned char>(0x02); // uint8_t param_nb
+ ioss << static_cast<unsigned char>(0xFF); // uint8_t flags
+ ioss << static_cast<unsigned char>(0x00); // uint16_t reserved = 0x0000
+ ioss << static_cast<unsigned char>(0x00);
+ ioss << "functionSciMsgCallback"; // function call id: null terminated string; id of the called function
+ ioss << '\0';
+ // parameter list: for each parameter inside the function call message
+ ioss << "parameter1"; // parameter id: null terminated string; id of the parameter
+ ioss << '\0';
+ ioss << static_cast<unsigned char>(0x00); // parameter length: 2 bytes; length of parameter data
+ ioss << static_cast<unsigned char>(0x01);
+ ioss << static_cast<unsigned char>(0x02); // parameter data: binary content of parameter data
+ ioss << "parameter2"; // parameter id: null terminated string; id of the parameter
+ ioss << '\0';
+ ioss << static_cast<unsigned char>(0x00); // parameter length: 2 bytes; length of parameter data
+ ioss << static_cast<unsigned char>(0x02);
+ ioss << static_cast<unsigned char>(0x01); // parameter data: binary content of parameter data
+ ioss << static_cast<unsigned char>(0x23);
+
+ unsigned long dataLength = ioss.str().length();
+ msg_header.length = (uint16_t)dataLength;
+
+ unsigned char * pData = new unsigned char [dataLength+1];
+ if (NULL != pData)
+ {
+ ioss >> pData;
+ }
+
+ // Register callback
+ //
+ if (NULL != mpFunctionCallManager)
+ {
+ CPPUNIT_ASSERT_MESSAGE ( "registerCallback failed",
+ mpFunctionCallManager->registerCallback (0x0001, &functionSciMsgCallback) );
+ }
+ else
+ {
+ CPPUNIT_FAIL ("FunctionCallManager pointer is NULL");
+ }
+
+ // Test the receiveMsg method
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "receiveMsg FunctionSciMsg failed",
+ mpSciServer->receiveMsg (&msg_header, dataLength, pData) );
+
+ // Free allocated memory
+ //
+ if (NULL != pData)
+ {
+ delete [] pData;
+ pData = NULL;
+ }
+}
+
+
+void SciServerTest::receiveEtherSciMsgTest ( Sci_Msg_Header & msg_header )
+{
+ logTest();
+
+ // Message header type and length have to be set to the corresponding specialized SCI message
+ //
+ msg_header.type = SCI_MSG_TYPE_ETHERNET; // uint8_t type = 0x05
+
+ Ethernet_Header ethernetHeader;
+ ethernetHeader.version = ETHERNET_VERSION;
+ ethernetHeader.type = ETHERNET_TYPE_DATA;
+ ethernetHeader.sniffer_type = 0;
+ ethernetHeader.flags = 0x00;
+ ethernetHeader.reserved = 0xFFFFFFFF;
+
+ unsigned long dataLength = 1500;
+ unsigned char data[sizeof(struct Ethernet_Header) + dataLength];
+ memcpy(data, (unsigned char *)&ethernetHeader, sizeof(struct Ethernet_Header));
+ memset(data + sizeof(struct Ethernet_Header), 'D', dataLength);
+ dataLength += sizeof(struct Ethernet_Header);
+ msg_header.length = (uint16_t)dataLength;
+
+ // Test the receiveMsg method
+ //
+ CPPUNIT_ASSERT_MESSAGE ( "receiveMsg EtherSciMsg failed",
+ mpSciServer->receiveMsg (&msg_header, dataLength, data) );
+}
+
+
+void functionSciMsgCallback ( const FunctionSciMsg & function_sci_msg )
+{
+ logTest();
+}
+