summaryrefslogtreecommitdiff
path: root/cesar/maximus/system/src
diff options
context:
space:
mode:
authorsave2008-04-07 14:17:42 +0000
committersave2008-04-07 14:17:42 +0000
commit3d58a62727346b7ac1a6cb36fed1a06ed72228dd (patch)
treed7788c3cf9f76426aef0286d0202e2097f0fa0eb /cesar/maximus/system/src
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/system/src')
-rw-r--r--cesar/maximus/system/src/Station.cpp555
-rw-r--r--cesar/maximus/system/src/StationConfiguration.cpp142
-rw-r--r--cesar/maximus/system/src/StationConfigurationTest.cpp51
-rw-r--r--cesar/maximus/system/src/StationTest.cpp61
-rw-r--r--cesar/maximus/system/src/SystemManager.cpp546
-rw-r--r--cesar/maximus/system/src/SystemManagerTest.cpp202
-rw-r--r--cesar/maximus/system/src/SystemSciMsg.cpp285
-rw-r--r--cesar/maximus/system/src/SystemSciMsgTest.cpp108
8 files changed, 1950 insertions, 0 deletions
diff --git a/cesar/maximus/system/src/Station.cpp b/cesar/maximus/system/src/Station.cpp
new file mode 100644
index 0000000000..91792630f1
--- /dev/null
+++ b/cesar/maximus/system/src/Station.cpp
@@ -0,0 +1,555 @@
+/************************************************************************
+ Station.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/system/src/Station.cpp
+**************************************************************************/
+
+#include "Station.h"
+
+#include "StationConfiguration.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include "host/socket.h" // for 'STATION_SOCK'
+
+#include <sys/types.h> // for 'waitpid()'
+#include <sys/wait.h> // for 'waitpid()'
+#include <fcntl.h>
+#include <unistd.h> // for 'exec()' and 'system()'
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <iomanip> // for 'setfill()' and 'setw()'
+using namespace std;
+
+extern bool UNITTEST;
+extern string stationTest;
+
+
+// Constructors/Destructors
+//
+
+
+Station::Station ( const string & station_executable, const Network_Clock_Tick current_tick_value ):
+mInputFileDescriptor(-1),
+mOutputFileDescriptor(-1),
+mLogPipe(-1),
+mPid(0),
+mStationStatus(MAXIMUS_STATION_STATUS_NONE),
+mStationIdleCounter(1), // once a station has been launched, Maximus has to wait for a system IDLE message
+mpStationConfiguration(NULL)
+{
+ logFunction();
+ string stationExecutable = station_executable;
+
+ if (UNITTEST)
+ {
+ stationExecutable = stationTest;
+ }
+
+ mpStationConfiguration = new StationConfiguration (stationExecutable);
+ if (NULL == mpStationConfiguration)
+ {
+ throw Error(__PRETTY_FUNCTION__ , "Station configuration pointer is NULL");
+ }
+
+ initAttributes();
+
+ startProcess(current_tick_value);
+}
+
+
+void Station::initAttributes ( )
+{
+ logFunction();
+}
+
+
+Station::~Station ( )
+{
+ logFunction();
+ clog << logger(LOG_COM) << "delete station " \
+ << getStationId() << " (0x" << setfill('0') << setw(4) << uppercase << hex << getStationId() << ")" << dec << endl;
+
+ stopProcess();
+ if (NULL != mpStationConfiguration)
+ {
+ delete (mpStationConfiguration);
+ mpStationConfiguration = NULL;
+ }
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+bool Station::operator== ( const Station & station ) const
+{
+ logFunction();
+ bool bOperator = false;
+
+ if ( (getStationStatus() == station.getStationStatus())
+ && (getStationConfiguration() == station.getStationConfiguration())
+ && (getInputFileDescriptor() == station.getInputFileDescriptor())
+ && (getOutputFileDescriptor() == station.getOutputFileDescriptor())
+ && (getLogFileDescriptor() == station.getLogFileDescriptor())
+ && (getStationId() == station.getStationId()) )
+ {
+ bOperator = true;
+ }
+
+ return bOperator;
+}
+
+
+Station & Station::operator= ( const Station & station )
+{
+ logFunction();
+
+ if ( (!setInputFileDescriptor (station.getInputFileDescriptor()))
+ || (!setOutputFileDescriptor (station.getOutputFileDescriptor()))
+ || (!setLogFileDescriptor (station.getLogFileDescriptor()))
+ || (!setStationStatus (station.getStationStatus()))
+ || (!setStationConfiguration (station.getStationConfiguration())) )
+ {
+ throw Error(__PRETTY_FUNCTION__ , "Error when setting attributes");
+ }
+
+ return *this;
+}
+
+
+void Station::displayStation ( ) const
+{
+ logFunction();
+
+ clog << logger(LOG_INFO) << "\t[input file descriptor = " << dec << getInputFileDescriptor() \
+ << ", output file descriptor = " << getOutputFileDescriptor() \
+ << ", log file descriptor = " << getLogFileDescriptor() \
+ << ", process id = " << getStationId() << " (0x" << setfill('0') << setw(4) << uppercase << hex << getStationId() << ")" \
+ << ", executable = " << getStationConfiguration()->getStationExecutable() \
+ << ", name = " << getStationConfiguration()->getStationName() << "]" << dec << endl;
+}
+
+
+bool Station::launchDebugger ( const string & command_line ) const
+{
+ logFunction();
+ bool bLaunch = false;
+
+ string commandLine(command_line);
+ size_t found = 0;
+
+ do
+ {
+ found = commandLine.find("%n", found, 2);
+ if (string::npos != found)
+ {
+ commandLine.replace(found, 2, getStationConfiguration()->getStationName());
+ }
+ }
+ while (found != string::npos);
+
+ found = 0;
+ do
+ {
+ found = commandLine.find("%e", found, 2);
+ if (string::npos != found)
+ {
+ commandLine.replace(found, 2, getStationConfiguration()->getStationExecutable());
+ }
+ }
+ while (found != string::npos);
+
+ found = 0;
+ do
+ {
+ found = commandLine.find("%p", found, 2);
+ if (string::npos != found)
+ {
+ char processId[6];
+ sprintf(processId, "%d", getPid());
+ commandLine.replace(found, 2, processId);
+ }
+ }
+ while (found != string::npos);
+
+ clog << logger(LOG_INFO) << "debugger command line = " << commandLine << endl;
+
+ system(commandLine.c_str());
+
+ return bLaunch;
+}
+
+
+// Accessor methods
+//
+
+
+// public attribute accessor methods
+//
+
+
+// private attribute accessor methods
+//
+
+
+const Sci_Msg_Station_Id Station::getStationId ( ) const
+{
+ return static_cast<Sci_Msg_Station_Id>(mPid);
+}
+
+
+const pid_t Station::getPid ( ) const
+{
+ return mPid;
+}
+
+
+bool Station::setInputFileDescriptor ( const File_Descriptor input_file_descriptor )
+{
+ mInputFileDescriptor = input_file_descriptor;
+
+ return true;
+}
+
+
+bool Station::setOutputFileDescriptor ( const File_Descriptor output_file_descriptor )
+{
+ mOutputFileDescriptor = output_file_descriptor;
+
+ return true;
+}
+
+
+bool Station::setLogFileDescriptor ( const File_Descriptor log_file_descriptor )
+{
+ mLogPipe = log_file_descriptor;
+
+ return true;
+}
+
+
+const File_Descriptor Station::getInputFileDescriptor ( ) const
+{
+ return mInputFileDescriptor;
+}
+
+
+const File_Descriptor Station::getOutputFileDescriptor ( ) const
+{
+ return mOutputFileDescriptor;
+}
+
+
+const File_Descriptor Station::getLogFileDescriptor ( ) const
+{
+ return mLogPipe;
+}
+
+
+Station_Status Station::getStationStatus ( ) const
+{
+ return mStationStatus;
+}
+
+
+bool Station::setStationStatus ( const Station_Status status )
+{
+ mStationStatus = status;
+
+ return true;
+}
+
+
+const unsigned short int Station::getStationIdleCounter ( ) const
+{
+ return mStationIdleCounter;
+}
+
+
+bool Station::incrementStationIdleCounter ( )
+{
+ mStationIdleCounter++;
+
+ return true;
+}
+
+
+bool Station::decrementStationIdleCounter ( )
+{
+ logFunction();
+ bool bDecrement = false;
+
+ if (0 < mStationIdleCounter)
+ {
+ mStationIdleCounter--;
+ bDecrement = true;
+ }
+ else
+ {
+ clog << logger(LOG_WARNING) << "station with id " << dec << getStationId() \
+ << " (0x" << setfill('0') << setw(4) << uppercase << hex << getStationId() \
+ << ") is already IDLE" << dec << endl;
+ }
+
+ return bDecrement;
+}
+
+
+bool Station::setStationConfiguration ( StationConfiguration * p_station_configuration )
+{
+ logFunction();
+ bool bSetConfig = false;
+
+ if (NULL != p_station_configuration)
+ {
+ mpStationConfiguration = p_station_configuration;
+ bSetConfig = true;
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__ , "Station configuration pointer is NULL", errno);
+ }
+
+ return bSetConfig;
+}
+
+
+StationConfiguration * Station::getStationConfiguration ( ) const
+{
+ if (NULL == mpStationConfiguration)
+ {
+ throw Error(__PRETTY_FUNCTION__ , "Station configuration pointer is NULL");
+ }
+
+ return mpStationConfiguration;
+}
+
+
+bool Station::setStationName ( const std::string & station_name )
+{
+ return getStationConfiguration()->setStationName(station_name);
+}
+
+
+// private methods
+//
+
+
+void Station::startProcess ( const Network_Clock_Tick current_tick_value )
+{
+ logFunction();
+
+ // Start the station process
+ //
+ if(getStationConfiguration()->getStationExecutable().empty())
+ {
+ throw Error(__PRETTY_FUNCTION__, "Executable not set", errno);
+ }
+ if(0 == (mPid = fork()))
+ {
+ char stationExecutable[getStationConfiguration()->getStationExecutable().size()+1];
+ size_t stringLength = getStationConfiguration()->getStationExecutable().copy(stationExecutable, getStationConfiguration()->getStationExecutable().size());
+ stationExecutable[stringLength] = '\0';
+
+ char currentTickValue[32];
+ sprintf(currentTickValue, "%llu", current_tick_value);
+
+ if (-1 == execlp(stationExecutable, stationExecutable, currentTickValue, NULL))
+ {
+ throw Error(__PRETTY_FUNCTION__, "Cannot launch station executable", errno);
+ }
+ exit(1);
+ }
+
+ // Loop until pipe creation: max = STATION_WAIT_LOOP_NB * STATION_WAIT_TIMEOUT_MS ms
+ //
+ int loop;
+ int fd_status;
+ char nameBuffer[256];
+
+ #ifdef STATION_SOCK
+
+ struct sockaddr_un sockaddr;
+ int bufsize = STATION_MAX_SOCK_BUFFER_SIZE;
+ sprintf(nameBuffer, "%s/%s_sock_%d", STATION_SOCK_PATH, STATION_SOCK_PREFIX, getPid());
+ // open the socket
+ if((mInputFileDescriptor = socket (PF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ throw Error(__FUNCTION__ , "Cannot create socket", errno);
+ }
+
+ // avoid other stations to inherit the socket
+ fd_status = fcntl(mInputFileDescriptor, F_GETFD);
+ fcntl(mInputFileDescriptor, F_SETFD, fd_status | FD_CLOEXEC);
+
+ // extend send buffer size
+ if(setsockopt (mInputFileDescriptor, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) < 0)
+ {
+ throw Error(__FUNCTION__ , "Cannot increase buffer size", errno);
+ }
+ sockaddr.sun_family = AF_UNIX;
+ strcpy (sockaddr.sun_path, nameBuffer);
+
+ for(loop = 0; loop < STATION_WAIT_LOOP_NB; loop++)
+ {
+ // Connect to server
+ //
+ if((connect(mInputFileDescriptor, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) >= 0)
+ {
+ break;
+ }
+ usleep(STATION_WAIT_TIMEOUT_MS * 1000);
+ }
+
+ if(loop >= STATION_WAIT_LOOP_NB)
+ {
+ stopProcess();
+ throw Error(__FUNCTION__ , "Cannot connect to station", errno);
+ }
+ else
+ {
+ setOutputFileDescriptor(mInputFileDescriptor);
+ }
+
+ #else /* !STATION_SOCK */
+
+ // Open input pipe
+ sprintf(nameBuffer, "%s/%s_out_%d", STATION_PIPE_PATH, STATION_PIPE_PREFIX, getPid());
+ for(loop = 0; loop < STATION_WAIT_LOOP_NB; loop++)
+ {
+ // Connect to server
+ //
+ if((mInputFileDescriptor = open(nameBuffer, O_RDONLY | O_NONBLOCK)) >= 0)
+ {
+ break;
+ }
+ usleep(STATION_WAIT_TIMEOUT_MS * 1000);
+ }
+ if(loop >= STATION_WAIT_LOOP_NB)
+ {
+ stopProcess();
+ throw Error(__FUNCTION__ , "Cannot connect to station", errno);
+ }
+
+ // avoid other stations to inherit the pipe
+ fd_status = fcntl(mInputFileDescriptor, F_GETFD);
+ fcntl(mInputFileDescriptor, F_SETFD, fd_status | FD_CLOEXEC);
+
+ // Open output pipe
+ sprintf(nameBuffer, "%s/%s_in_%d", STATION_PIPE_PATH, STATION_PIPE_PREFIX, getPid());
+ if((mOutputFileDescriptor = open(nameBuffer, O_WRONLY | O_NONBLOCK)) < 0)
+ {
+ stopProcess();
+ throw Error(__PRETTY_FUNCTION__, "Cannot open output pipe", errno);
+ }
+ // avoid other stations to inherit the pipe
+ fd_status = fcntl(mOutputFileDescriptor, F_GETFD);
+ fcntl(mOutputFileDescriptor, F_SETFD, fd_status | FD_CLOEXEC);
+
+ #endif /* STATION_SOCK */
+
+ // Open log pipe
+ //
+ sprintf(nameBuffer, "%s/%s_log_%d", STATION_PIPE_PATH, STATION_PIPE_PREFIX, getPid());
+ if((mLogPipe = open(nameBuffer, O_RDONLY | O_NONBLOCK)) < 0)
+ {
+ stopProcess();
+ throw Error(__PRETTY_FUNCTION__, "Cannot open log pipe", errno);
+ }
+
+ // avoid other stations to inherit the pipe
+ fd_status = fcntl(mLogPipe, F_GETFD);
+ fcntl(mLogPipe, F_SETFD, fd_status | FD_CLOEXEC);
+}
+
+
+void Station::stopProcess ( )
+{
+ logFunction();
+ if(mInputFileDescriptor >= 0)
+ {
+ close(mInputFileDescriptor);
+ }
+ if(mOutputFileDescriptor >= 0)
+ {
+ close(mOutputFileDescriptor);
+ }
+ if(mLogPipe >= 0)
+ {
+ close(mLogPipe);
+ }
+ if(mPid > 0)
+ {
+ kill(mPid, SIGTERM);
+ waitpid(mPid, NULL, 0);
+ }
+}
+
+
+void Station::displayStationStatus ( ) const
+{
+ logFunction();
+
+ switch (getStationStatus())
+ {
+ case 0:
+ clog << logger(LOG_INFO) << "MAXIMUS_STATION_STATUS_NONE" << endl;
+ break;
+ case 1:
+ clog << logger(LOG_INFO) << "MAXIMUS_STATION_STATUS_IDLE" << endl;
+ break;
+ case 2:
+ clog << logger(LOG_INFO) << "MAXIMUS_STATION_STATUS_BUSY" << endl;
+ break;
+ case 3:
+ clog << logger(LOG_INFO) << "MAXIMUS_STATION_STATUS_DEACTIVATED" << endl;
+ break;
+ default:
+ clog << logger(LOG_INFO) << "unknown!" << endl;
+ break;
+ }
+}
+
+
+// protected methods
+//
+
diff --git a/cesar/maximus/system/src/StationConfiguration.cpp b/cesar/maximus/system/src/StationConfiguration.cpp
new file mode 100644
index 0000000000..6d1a9c8308
--- /dev/null
+++ b/cesar/maximus/system/src/StationConfiguration.cpp
@@ -0,0 +1,142 @@
+/************************************************************************
+ StationConfiguration.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/system/src/StationConfiguration.cpp
+**************************************************************************/
+
+#include "StationConfiguration.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <iostream> // for 'cout', 'cerr' and 'clog'
+using namespace std;
+
+
+// Constructors/Destructors
+//
+
+
+StationConfiguration::StationConfiguration ( string & station_executable, string station_name )
+{
+ logFunction();
+
+ if ( !setStationExecutable(station_executable) || !setStationName(station_name) )
+ {
+ throw Error(__PRETTY_FUNCTION__, "Error during initialization");
+ }
+ initAttributes();
+}
+
+
+void StationConfiguration::initAttributes ( )
+{
+ logFunction();
+}
+
+
+StationConfiguration::~StationConfiguration ( )
+{
+ logFunction();
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+// private methods
+//
+
+
+// protected methods
+//
+
+
+// Accessor methods
+//
+
+
+// public attribute accessor methods
+//
+
+
+// private attribute accessor methods
+//
+
+
+bool StationConfiguration::setStationExecutable ( const string & station_executable )
+{
+ if (station_executable.empty())
+ {
+ throw Error(__PRETTY_FUNCTION__, "Station executable is an empty string");
+ }
+ else
+ {
+ mStationExecutable = station_executable;
+ }
+
+ return true;
+}
+
+
+const string & StationConfiguration::getStationExecutable ( ) const
+{
+ if (mStationExecutable.empty())
+ {
+ throw Error(__PRETTY_FUNCTION__, "Station executable is an empty string");
+ }
+ return mStationExecutable;
+}
+
+
+bool StationConfiguration::setStationName ( const string & station_name )
+{
+ mStationName = station_name;
+
+ return true;
+}
+
+
+const string & StationConfiguration::getStationName ( ) const
+{
+ return mStationName;
+}
+
+
+// protected attribute accessor methods
+//
+
diff --git a/cesar/maximus/system/src/StationConfigurationTest.cpp b/cesar/maximus/system/src/StationConfigurationTest.cpp
new file mode 100644
index 0000000000..00c982d20e
--- /dev/null
+++ b/cesar/maximus/system/src/StationConfigurationTest.cpp
@@ -0,0 +1,51 @@
+
+#include "StationConfigurationTest.h"
+
+#include "StationConfiguration.h"
+
+#include "Logger.h"
+
+#include <iostream>
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (StationConfigurationTest);
+
+
+void StationConfigurationTest::setUp (void)
+{
+ logTest();
+
+ string station_executable = "../stationtest/obj/stationtest.elf";
+ mpStationConfiguration = new StationConfiguration (station_executable);
+}
+
+
+void StationConfigurationTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpStationConfiguration)
+ {
+ delete mpStationConfiguration;
+ mpStationConfiguration = NULL;
+ }
+}
+
+
+void StationConfigurationTest::setStationNameTest (void)
+{
+ logTest();
+
+ if (NULL == mpStationConfiguration)
+ {
+ CPPUNIT_FAIL ( "The initialized StationConfiguration pointer is NULL" );
+ }
+ else
+ {
+ string stationName = "This is my station name";
+
+ CPPUNIT_ASSERT_MESSAGE ( "setStationName failed",
+ mpStationConfiguration->setStationName(stationName) );
+ }
+}
+
diff --git a/cesar/maximus/system/src/StationTest.cpp b/cesar/maximus/system/src/StationTest.cpp
new file mode 100644
index 0000000000..d0ca985293
--- /dev/null
+++ b/cesar/maximus/system/src/StationTest.cpp
@@ -0,0 +1,61 @@
+
+#include "StationTest.h"
+
+#include "Station.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <iostream>
+#include <string>
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (StationTest);
+
+
+void StationTest::setUp (void)
+{
+ logTest();
+
+ try
+ {
+ mpStation = NULL;
+ string stationExecutable;
+ mpStation = new Station(stationExecutable, 0);
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ }
+}
+
+
+void StationTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpStation)
+ {
+ delete (mpStation);
+ mpStation = NULL;
+ }
+}
+
+
+void StationTest::setStationNameTest (void)
+{
+ logTest();
+
+ if (NULL == mpStation)
+ {
+ CPPUNIT_FAIL ( "The initialized Station pointer is NULL" );
+ }
+ else
+ {
+ string stationName = "This is my station name";
+
+ CPPUNIT_ASSERT_MESSAGE ( "setStationName failed",
+ mpStation->setStationName(stationName) );
+ }
+}
+
diff --git a/cesar/maximus/system/src/SystemManager.cpp b/cesar/maximus/system/src/SystemManager.cpp
new file mode 100644
index 0000000000..4c40ae88ea
--- /dev/null
+++ b/cesar/maximus/system/src/SystemManager.cpp
@@ -0,0 +1,546 @@
+/************************************************************************
+ SystemManager.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/system/src/SystemManager.cpp
+**************************************************************************/
+
+#include "SystemManager.h"
+
+#include "Station.h"
+#include "ISci.h"
+#include "SystemSciMsg.h"
+#include "INetworkClock.h"
+
+#include "sci_types.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <iomanip> // for 'setfill()' and 'setw()'
+#include <iostream> // for 'cout', 'cerr' and 'clog'
+using namespace std;
+
+
+// Constructors/Destructors
+//
+
+
+SystemManager::SystemManager ( ISci * p_sci_server ):
+mpSciServer(NULL),
+mpNetworkClock(NULL)
+{
+ logFunction();
+
+ if (NULL != p_sci_server)
+ {
+ mpSciServer = p_sci_server;
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI server pointer is NULL", errno);
+ }
+ initAttributes();
+}
+
+
+void SystemManager::initAttributes ( )
+{
+ logFunction();
+
+ if (NULL != mpSciServer)
+ {
+ if ( (!mpSciServer->registerSpecializedSciMsg(SCI_MSG_TYPE_SYSTEM, new SystemSciMsg(this)))
+ || (!mpSciServer->setStationsList(&mListOfStations)) )
+ {
+ throw Error(__PRETTY_FUNCTION__, "Error when initializing SCI server");
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI server pointer is NULL");
+ }
+}
+
+
+SystemManager::~SystemManager ( )
+{
+ logFunction();
+
+ removeAllStations();
+ if (NULL != mpSciServer)
+ {
+ mpSciServer = NULL;
+ }
+ if (NULL != mpNetworkClock)
+ {
+ mpNetworkClock = NULL;
+ }
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+bool SystemManager::init ( const string & station_executable, const string & debugger )
+{
+ logFunction();
+
+ mDefaultStationExecutable = station_executable;
+ mDebugger = debugger;
+
+ return true;
+}
+
+
+Sci_Msg_Station_Id SystemManager::createStation ( const string & station_executable )
+{
+ logFunction();
+ Sci_Msg_Station_Id stationId = 0;
+
+ Station * createdStation = new Station(station_executable, getNetworkClock()->getCurrentTickValue());
+
+ if (NULL != createdStation)
+ {
+ mListOfStations.push_back(createdStation);
+ stationId = createdStation->getStationId();
+ createdStation = NULL;
+ }
+ clog << logger(LOG_COM) << "create station " \
+ << stationId << " (0x" << setfill('0') << setw(4) << uppercase << hex << stationId << ")" << dec << endl;
+
+ displayListOfStations();
+
+ return stationId;
+}
+
+
+bool SystemManager::receiveIdleMsg ( const SystemSciMsg & system_sci_msg ) const
+{
+ bool bReceive = false;
+
+ Station * pStation = findStation(system_sci_msg.getSciMsgStationId());
+ if (NULL != pStation)
+ {
+ pStation->decrementStationIdleCounter();
+ if ( (0 == pStation->getStationIdleCounter())
+ && (MAXIMUS_STATION_STATUS_DEACTIVATED != pStation->getStationStatus()) )
+ {
+ pStation->setStationStatus(MAXIMUS_STATION_STATUS_IDLE);
+ }
+ bReceive = true;
+ }
+ pStation = NULL;
+
+ return bReceive;
+}
+
+
+bool SystemManager::removeStation ( const Sci_Msg_Station_Id station_id )
+{
+ logFunction();
+ bool bRemove = false;
+
+ if (!mListOfStations.empty())
+ {
+ for (StationsList::iterator it = mListOfStations.begin(); it != mListOfStations.end(); ++it)
+ {
+ StationsList::iterator pos = it;
+ Station * pStation = *pos;
+ if ( (NULL != pStation) && (station_id == pStation->getStationId()) )
+ {
+ delete(pStation);
+ mListOfStations.erase(pos);
+ bRemove = true;
+ break;
+ }
+ }
+ }
+ displayListOfStations();
+
+ // Remove events that should be sent to the removed station
+ getNetworkClock()->removeEvts(station_id);
+
+ return bRemove;
+}
+
+
+bool SystemManager::isStationIdle ( Sci_Msg_Station_Id station_id ) const
+{
+ logFunction();
+ bool bIdle = false;
+
+ Station * pStation = findStation(station_id);
+ if ( (NULL != pStation) && (MAXIMUS_STATION_STATUS_IDLE == pStation->getStationStatus()) )
+ {
+ bIdle = true;
+ }
+ pStation = NULL;
+
+ return bIdle;
+}
+
+
+bool SystemManager::areAllActiveStationsIdle ( ) const
+{
+ logFunction();
+ bool bIdle = true;
+
+ if (!mListOfStations.empty())
+ {
+ for (StationsList::const_iterator it = mListOfStations.begin(); it != mListOfStations.end(); ++it)
+ {
+ if (NULL != *it)
+ {
+ if ( (MAXIMUS_STATION_STATUS_DEACTIVATED != (*it)->getStationStatus())
+ && (MAXIMUS_STATION_STATUS_IDLE != (*it)->getStationStatus()) )
+ {
+ bIdle = false;
+ it = mListOfStations.end();
+ --it;
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "Station pointer is NULL");
+ }
+ }
+ }
+
+ return bIdle;
+}
+
+
+bool SystemManager::deactivateStation ( const Sci_Msg_Station_Id station_id )
+{
+ logFunction();
+ bool bDeactivate = false;
+
+ Station * pStation = findStation(station_id);
+ if (NULL != pStation)
+ {
+ bDeactivate = pStation->setStationStatus(MAXIMUS_STATION_STATUS_DEACTIVATED);
+ }
+ pStation = NULL;
+
+ return bDeactivate;
+}
+
+
+bool SystemManager::activateStation ( const Sci_Msg_Station_Id station_id )
+{
+ logFunction();
+ bool bActivate = false;
+
+ Station * pStation = findStation(station_id);
+ if (NULL != pStation)
+ {
+ bActivate = pStation->setStationStatus(MAXIMUS_STATION_STATUS_IDLE);
+ }
+ pStation = NULL;
+
+ return bActivate;
+}
+
+
+bool SystemManager::debugStation ( const Sci_Msg_Station_Id station_id )
+{
+ logFunction();
+ bool bDebug = false;
+
+ Station * pStation = findStation(station_id);
+ if (NULL != pStation)
+ {
+ bDebug = pStation->launchDebugger(getDebugger());
+ }
+ pStation = NULL;
+
+ return bDebug;
+}
+
+
+Station_Status SystemManager::getStationStatus ( const Sci_Msg_Station_Id station_id ) const
+{
+ logFunction();
+ Station_Status status = MAXIMUS_STATION_STATUS_NONE;
+
+ Station * pStation = findStation(station_id);
+ if (NULL != pStation)
+ {
+ status = pStation->getStationStatus();
+ }
+
+ return status;
+}
+
+
+bool SystemManager::updateStationStatus ( const Sci_Msg_Station_Id station_id, const Station_Status new_status )
+{
+ logFunction();
+ bool bSetIdle = false;
+
+ Station * pStation = findStation(station_id);
+ if (NULL != pStation)
+ {
+ bSetIdle = pStation->setStationStatus(new_status);
+ }
+
+ return bSetIdle;
+}
+
+
+bool SystemManager::removeAllStations ( )
+{
+ logFunction();
+ bool bRemove = false;
+ unsigned short int nbOfStations = 0;
+
+ if (!mListOfStations.empty())
+ {
+ for (StationsList::const_iterator it = mListOfStations.begin(); it != mListOfStations.end(); ++it)
+ {
+ if (NULL != *it)
+ {
+ delete (*it);
+ nbOfStations++;
+ }
+ }
+ mListOfStations.clear();
+ }
+ if (mListOfStations.empty())
+ {
+ bRemove = true;
+ clog << logger(LOG_COM) << "delete " << nbOfStations << " station(s)" << endl;
+ }
+
+ return bRemove;
+}
+
+
+bool SystemManager::setNetworkClock ( INetworkClock * p_network_clock )
+{
+ if (NULL == p_network_clock)
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Network Clock pointer is NULL", errno);
+ }
+ mpNetworkClock = p_network_clock;
+
+ return true;
+}
+
+
+const string & SystemManager::getDefaultStationExecutable ( ) const
+{
+ return mDefaultStationExecutable;
+}
+
+
+bool SystemManager::setStationName ( const Sci_Msg_Station_Id station_id, const std::string & station_name )
+{
+ logFunction();
+ bool bSetName = false;
+
+ Station * pStation = findStation(station_id);
+ if (NULL != pStation)
+ {
+ bSetName = pStation->setStationName(station_name);
+ }
+
+ /* Send a System SCI message to the station to configure its name. */
+
+ SystemSciMsg systemSciMsg(this);
+
+ // Fill specialized SCI msg data length and specialized SCI msg data
+ //
+ bSetName &= systemSciMsg.setSpecializedSciMsgDataLength(station_name.length() + 1);
+ bSetName &= systemSciMsg.setSpecializedSciMsgData((unsigned char *)station_name.c_str());
+
+ // Fill specialized SCI msg header
+ //
+ struct System_Header header = { SYSTEM_VERSION,
+ SYSTEM_TYPE_STATION_NAME,
+ 0x0000 }; // flags
+
+ // Set specialized SCI msg header
+ //
+ bSetName &= systemSciMsg.setSpecializedSciMsgHeader(header);
+
+ // Fill specialized SCI msg attributes:
+ // - header size
+ //
+ bSetName &= systemSciMsg.setSpecializedSciMsgHeaderSize(sizeof(struct System_Header));
+
+ // Fill SCI msg attributes:
+ // - type
+ // - station ID
+ //
+ bSetName &= systemSciMsg.setSciMsgType(SCI_MSG_TYPE_SYSTEM);
+ bSetName &= systemSciMsg.setSciMsgStationId(station_id);
+
+ if (bSetName)
+ {
+ if (NULL != mpSciServer)
+ {
+ bSetName = mpSciServer->fillSciMsg(systemSciMsg);
+ bSetName &= mpSciServer->sendSciMsg(systemSciMsg);
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI server pointer is NULL");
+ }
+ }
+ else
+ {
+ clog << logger(LOG_ERROR) << "system SCI message cannot be sent because it is not correctly filled in!" << endl;
+ }
+
+ return bSetName;
+}
+
+
+// private methods
+//
+
+
+void SystemManager::displayListOfStations ( ) const
+{
+ logFunction();
+ clog << logger(LOG_INFO) << "list of stations = " << endl;
+
+ if (!mListOfStations.empty())
+ {
+ for (StationsList::const_iterator it = mListOfStations.begin(); it != mListOfStations.end(); ++it)
+ {
+ if (NULL != *it)
+ {
+ const_cast<Station *>(*it)->displayStation();
+ }
+ }
+ }
+ else
+ {
+ clog << logger(LOG_INFO) << "\tempty!" << endl;
+ }
+}
+
+
+void SystemManager::registerSystemSciMsg ( )
+{
+ logFunction();
+
+ if (NULL != mpSciServer)
+ {
+ mpSciServer->registerSpecializedSciMsg(SCI_MSG_TYPE_SYSTEM, new SystemSciMsg(this));
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI server pointer is NULL");
+ }
+}
+
+
+// protected methods
+//
+
+
+// Accessor methods
+//
+
+
+// public attribute accessor methods
+//
+
+
+// private attribute accessor methods
+//
+
+
+StationsList * SystemManager::getListOfStations ( )
+{
+ return &mListOfStations;
+}
+
+
+Station * SystemManager::findStation ( const Sci_Msg_Station_Id station_id ) const
+{
+ logFunction();
+ Station * pStation = NULL;
+
+ if (!mListOfStations.empty())
+ {
+ for (StationsList::const_iterator it = mListOfStations.begin(); it != mListOfStations.end(); ++it)
+ {
+ if ( (NULL != *it) && (station_id == (*it)->getStationId()) )
+ {
+ pStation = *it;
+ it = mListOfStations.end();
+ --it;
+ }
+ }
+ }
+ if (NULL == pStation)
+ {
+ clog << logger(LOG_FATAL) << "station with id " << dec << station_id << " (0x" << setfill('0') << setw(4) << uppercase << hex << station_id << ") does not exist" << dec << endl;
+ errno = ENONET;
+ throw Error(__PRETTY_FUNCTION__, "Station does not exist", errno);
+ }
+
+ return pStation;
+}
+
+
+const string SystemManager::getDebugger ( ) const
+{
+ return mDebugger;
+}
+
+
+INetworkClock * SystemManager::getNetworkClock ( ) const
+{
+ if (NULL == mpNetworkClock)
+ {
+ throw Error(__PRETTY_FUNCTION__, "Network Clock pointer is NULL");
+ }
+
+ return mpNetworkClock;
+}
+
+
+// protected attribute accessor methods
+//
+
diff --git a/cesar/maximus/system/src/SystemManagerTest.cpp b/cesar/maximus/system/src/SystemManagerTest.cpp
new file mode 100644
index 0000000000..6b71009730
--- /dev/null
+++ b/cesar/maximus/system/src/SystemManagerTest.cpp
@@ -0,0 +1,202 @@
+
+#include "SystemManagerTest.h"
+
+#include "SystemManager.h"
+#include "SciServer.h"
+#include "PhyProcessor.h"
+#include "NetworkClockProcessor.h"
+#include "FunctionCallManager.h"
+#include "EthernetProcessor.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (SystemManagerTest);
+
+
+void SystemManagerTest::setUp (void)
+{
+ logTest();
+
+ mpSciServer = new SciServer ();
+ mpSystemManager = new SystemManager (mpSciServer);
+
+ mpFunctionCall = new FunctionCallManager (mpSciServer);
+ mpPhy = new PhyProcessor (mpSciServer);
+ mpEthernet = new EthernetProcessor (mpSciServer);
+ mpNetworkClock = new NetworkClockProcessor (mpSciServer, mpSystemManager, mpFunctionCall, mpPhy, mpEthernet);
+ mpSystemManager->setNetworkClock(mpNetworkClock);
+}
+
+
+void SystemManagerTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpSystemManager)
+ {
+ delete mpSystemManager;
+ mpSystemManager = NULL;
+ }
+ if (NULL != mpSciServer)
+ {
+ delete mpSciServer;
+ mpSciServer = NULL;
+ }
+ if (NULL != mpFunctionCall)
+ {
+ delete mpFunctionCall;
+ mpFunctionCall = NULL;
+ }
+ if (NULL != mpPhy)
+ {
+ delete mpPhy;
+ mpPhy = NULL;
+ }
+ if (NULL != mpEthernet)
+ {
+ delete mpEthernet;
+ mpEthernet = NULL;
+ }
+ if (NULL != mpNetworkClock)
+ {
+ delete mpNetworkClock;
+ mpNetworkClock = NULL;
+ }
+}
+
+
+void SystemManagerTest::createStationTest (void)
+{
+ logTest();
+
+ try
+ {
+ Sci_Msg_Station_Id stationId = mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable()); // will be deleted in 'tearDown()'
+ CPPUNIT_ASSERT_MESSAGE ( "createStation failed",
+ 0 != stationId );
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ }
+}
+
+
+void SystemManagerTest::removeStationTest (void)
+{
+ logTest();
+
+ try
+ {
+ // Create Station 1
+ //
+ Sci_Msg_Station_Id stationId1 = mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ // Create Station 2
+ //
+ Sci_Msg_Station_Id stationId2 = mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ // Create Station 3
+ //
+ Sci_Msg_Station_Id stationId3 = mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ INetworkClock * pNetworkClock = new NetworkClockProcessor();
+ mpSystemManager->setNetworkClock(pNetworkClock);
+
+ CPPUNIT_ASSERT_MESSAGE ( "removeStation failed",
+ mpSystemManager->removeStation (stationId2) );
+
+ CPPUNIT_ASSERT_MESSAGE ( "removeStation failed",
+ mpSystemManager->removeStation (stationId1) );
+
+ CPPUNIT_ASSERT_MESSAGE ( "removeStation failed",
+ mpSystemManager->removeStation (stationId3) );
+
+ if (NULL != pNetworkClock)
+ {
+ delete (pNetworkClock);
+ pNetworkClock = NULL;
+ }
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ }
+}
+
+
+void SystemManagerTest::areAllActiveStationsIdleTest (void)
+{
+ logTest();
+
+ try
+ {
+ // Create Station 1
+ //
+ mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ // Create Station 2
+ //
+ mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ // Create Station 3
+ //
+ mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ CPPUNIT_ASSERT_MESSAGE ( "areAllActiveStationsIdle failed",
+ !mpSystemManager->areAllActiveStationsIdle() );
+
+ CPPUNIT_ASSERT_MESSAGE ( "removeAllStations failed",
+ mpSystemManager->removeAllStations() );
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ }
+}
+
+
+void SystemManagerTest::setNetworkClockTest (void)
+{
+ logTest();
+
+ INetworkClock * pNetworkClock = new NetworkClockProcessor();
+
+ CPPUNIT_ASSERT_MESSAGE ( "setNetworkClock failed",
+ mpSystemManager->setNetworkClock(pNetworkClock) );
+
+ if (NULL != pNetworkClock)
+ {
+ delete (pNetworkClock);
+ pNetworkClock = NULL;
+ }
+}
+
+
+void SystemManagerTest::setStationNameTest (void)
+{
+ logTest();
+
+ if (NULL == mpSystemManager)
+ {
+ CPPUNIT_FAIL ( "The initialized System Manager pointer is NULL" );
+ }
+ else
+ {
+ string stationName = "This is my station name";
+
+ Sci_Msg_Station_Id stationId = mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+ mpSystemManager->updateStationStatus(stationId, MAXIMUS_STATION_STATUS_IDLE);
+ NetworkClockProcessor networkClock;
+ mpSystemManager->setNetworkClock((INetworkClock *)&networkClock);
+
+ CPPUNIT_ASSERT_MESSAGE ( "setStationName failed",
+ mpSystemManager->setStationName(stationId, stationName) );
+
+ mpSystemManager->removeStation(stationId);
+ }
+}
+
diff --git a/cesar/maximus/system/src/SystemSciMsg.cpp b/cesar/maximus/system/src/SystemSciMsg.cpp
new file mode 100644
index 0000000000..048924b8da
--- /dev/null
+++ b/cesar/maximus/system/src/SystemSciMsg.cpp
@@ -0,0 +1,285 @@
+/************************************************************************
+ SystemSciMsg.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/system/src/SystemSciMsg.cpp
+**************************************************************************/
+
+#include "SystemSciMsg.h"
+
+#include "ISystem.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <iomanip> // for 'setfill()' and 'setw()'
+#include <netinet/in.h> // for 'ntohl()' and 'ntohs()'
+#include <iostream> // for 'cout', 'cerr' and 'clog'
+using namespace std;
+
+
+// Constructors/Destructors
+//
+
+
+SystemSciMsg::SystemSciMsg ( ISystem * p_system_manager ):
+mSpecializedSciMsgType(SYSTEM_TYPE_NONE),
+mpSystemManager(NULL)
+{
+ logFunction();
+
+ initAttributes ();
+ if (NULL != p_system_manager)
+ {
+ mpSystemManager = p_system_manager;
+ }
+ else
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "System manager pointer is NULL", errno);
+ }
+}
+
+
+void SystemSciMsg::initAttributes ( )
+{
+ logFunction();
+
+ mSpecializedSciMsgHeader.version = 0x00;
+ mSpecializedSciMsgHeader.type = 0x00;
+ mSpecializedSciMsgHeader.flags = 0x0000;
+}
+
+
+SystemSciMsg::~SystemSciMsg ( )
+{
+ logFunction();
+
+ if (NULL != mpSystemManager)
+ {
+ mpSystemManager = NULL;
+ }
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+SciMsg * SystemSciMsg::create ( ) const
+{
+ logFunction();
+
+ return new SystemSciMsg (mpSystemManager);
+}
+
+
+bool SystemSciMsg::dispatchMsg ( )
+{
+ logFunction();
+ bool bDispatch = false;
+
+ if (NULL != mpSystemManager)
+ {
+ if ( SYSTEM_TYPE_IDLE == getSpecializedSciMsgType() )
+ {
+ bDispatch = mpSystemManager->receiveIdleMsg(*this);
+ }
+ else
+ {
+ clog << logger(LOG_ERROR) << "type is not SYSTEM_TYPE_IDLE!" << endl;
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "System manager pointer is NULL");
+ }
+
+ return bDispatch;
+}
+
+
+// When receiving a SCI msg, specialized SCI msg header has to be extracted from received SCI msg data
+//
+bool SystemSciMsg::identifySpecializedSciMsgHeader ( )
+{
+ logFunction();
+ bool bIdentifyHeader = false;
+
+ if (NULL != SciMsg::getSciMsgData())
+ {
+ // Set specialized SCI msg header size
+ //
+ SciMsg::setSpecializedSciMsgHeaderSize(static_cast<unsigned long>(sizeof(struct System_Header)));
+
+ // Get specialized SCI message header contents
+ //
+ if (SciMsg::getSciMsgDataLength() >= SciMsg::getSpecializedSciMsgHeaderSize()) // check that there are enough data to get the specialized SCI message header
+ {
+ mSpecializedSciMsgHeader = *((System_Header*)SciMsg::getSciMsgData());
+ mSpecializedSciMsgHeader.flags = ntohs(getSpecializedSciMsgHeader().flags);
+
+ bIdentifyHeader = setSpecializedSciMsgType (static_cast<System_Type>(getSpecializedSciMsgHeader().type));
+
+ displaySpecializedSciMsgHeader();
+ }
+ else
+ {
+ errno = ENODATA;
+ throw Error(__PRETTY_FUNCTION__, "Not enough data to get the system SCI message header", errno);
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI message data pointer is NULL");
+ }
+
+ return bIdentifyHeader;
+}
+
+
+// Check specialized SCI msg compatibility (check specialized SCI msg version)
+//
+bool SystemSciMsg::checkCompatibility ( ) const
+{
+ logFunction();
+ bool bCheck = false;
+
+ if (SYSTEM_VERSION == getSpecializedSciMsgHeader().version)
+ {
+ bCheck = SciMsg::checkCompatibility();
+ }
+
+ return bCheck;
+}
+
+
+void SystemSciMsg::displaySpecializedSciMsgHeader ( ) const
+{
+ logFunction();
+
+ clog << logger(LOG_INFO) << "system SCI msg header = " << endl;
+ clog << logger(LOG_INFO) << "\tversion = 0x" << setfill('0') << setw(2) << uppercase << hex << static_cast<unsigned short int>(getSpecializedSciMsgHeader().version) << endl;
+ displaySpecializedSciMsgType(LOG_INFO);
+ clog << logger(LOG_INFO) << "\tflags = 0x" << setfill('0') << setw(4) << uppercase << hex << getSpecializedSciMsgHeader().flags << dec << endl;
+}
+
+
+void SystemSciMsg::displaySpecializedSciMsgType ( int log_level ) const
+{
+ logFunction();
+
+ switch (getSpecializedSciMsgType())
+ {
+ case 0:
+ clog << logger(log_level) << "\ttype = SYSTEM_TYPE_NONE" << endl;
+ break;
+ case 1:
+ clog << logger(log_level) << "\ttype = SYSTEM_TYPE_IDLE" << endl;
+ break;
+ case 2:
+ clog << logger(log_level) << "\ttype = SYSTEM_TYPE_STATION_NAME" << endl;
+ break;
+ default:
+ clog << logger(log_level) << "\ttype = unknown!" << endl;
+ break;
+ }
+}
+
+
+// private methods
+//
+
+
+// protected methods
+//
+
+
+// Accessor methods
+//
+
+
+// public attribute accessor methods
+//
+
+
+// private attribute accessor methods
+//
+
+
+System_Type SystemSciMsg::getSpecializedSciMsgType ( ) const
+{
+ return mSpecializedSciMsgType;
+}
+
+
+bool SystemSciMsg::setSpecializedSciMsgType ( const System_Type type )
+{
+ mSpecializedSciMsgType = type;
+
+ return true;
+}
+
+
+void * SystemSciMsg::returnSpecializedSciMsgHeader ( ) const
+{
+ return (void*)&mSpecializedSciMsgHeader;
+}
+
+
+const System_Header & SystemSciMsg::getSpecializedSciMsgHeader ( ) const
+{
+ return mSpecializedSciMsgHeader;
+}
+
+
+bool SystemSciMsg::setSpecializedSciMsgHeader ( const System_Header & specialized_sci_msg_header )
+{
+ logFunction();
+ bool bSetHeader = false;
+
+ mSpecializedSciMsgHeader = specialized_sci_msg_header;
+
+ bSetHeader = setSpecializedSciMsgType (static_cast<System_Type>(getSpecializedSciMsgHeader().type));
+
+ displaySpecializedSciMsgHeader();
+
+ return bSetHeader;
+}
+
+
+// protected attribute accessor methods
+//
+
diff --git a/cesar/maximus/system/src/SystemSciMsgTest.cpp b/cesar/maximus/system/src/SystemSciMsgTest.cpp
new file mode 100644
index 0000000000..b8015ffee7
--- /dev/null
+++ b/cesar/maximus/system/src/SystemSciMsgTest.cpp
@@ -0,0 +1,108 @@
+
+#include "SystemSciMsgTest.h"
+
+#include "SystemSciMsg.h"
+#include "SciServer.h"
+#include "SystemManager.h"
+#include "PhyProcessor.h"
+#include "NetworkClockProcessor.h"
+#include "FunctionCallManager.h"
+#include "EthernetProcessor.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <iostream>
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (SystemSciMsgTest);
+
+
+void SystemSciMsgTest::setUp (void)
+{
+ logTest();
+
+ mpSciServer = new SciServer();
+ mpSystemManager = new SystemManager (mpSciServer);
+ mpSystemSciMsg = new SystemSciMsg (mpSystemManager);
+}
+
+
+void SystemSciMsgTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpSystemSciMsg)
+ {
+ delete mpSystemSciMsg;
+ mpSystemSciMsg = NULL;
+ }
+ if (NULL != mpSystemManager)
+ {
+ delete (mpSystemManager);
+ mpSystemManager = NULL;
+ }
+ if (NULL != mpSciServer)
+ {
+ delete (mpSciServer);
+ mpSciServer = NULL;
+ }
+}
+
+
+void SystemSciMsgTest::dispatchMsgTest (void)
+{
+ logTest();
+
+ if (NULL != mpSystemSciMsg)
+ {
+ try
+ {
+ CPPUNIT_ASSERT_MESSAGE ( "setSpecializedSciMsgType failed",
+ mpSystemSciMsg->setSpecializedSciMsgType(SYSTEM_TYPE_IDLE) );
+
+ IFunctionCall * pFunctionCall = new FunctionCallManager (mpSciServer);
+ IPhy * pPhy = new PhyProcessor (mpSciServer);
+ IEthernet * pEthernet = new EthernetProcessor (mpSciServer);
+ INetworkClock * pNetworkClock = new NetworkClockProcessor (mpSciServer, mpSystemManager, pFunctionCall, pPhy, pEthernet);
+ mpSystemManager->setNetworkClock(pNetworkClock);
+ Sci_Msg_Station_Id stationId = mpSystemManager->createStation(mpSystemManager->getDefaultStationExecutable());
+
+ CPPUNIT_ASSERT_MESSAGE ( "setSciMsgStationId failed",
+ mpSystemSciMsg->setSciMsgStationId(stationId) );
+
+ CPPUNIT_ASSERT_MESSAGE ( "dispatchMsg failed",
+ mpSystemSciMsg->dispatchMsg() );
+
+ if (NULL != pFunctionCall)
+ {
+ delete (pFunctionCall);
+ pFunctionCall = NULL;
+ }
+ if (NULL != pPhy)
+ {
+ delete (pPhy);
+ pPhy = NULL;
+ }
+ if (NULL != pEthernet)
+ {
+ delete (pEthernet);
+ pEthernet = NULL;
+ }
+ if (NULL != pNetworkClock)
+ {
+ delete (pNetworkClock);
+ pNetworkClock = NULL;
+ }
+ }
+ catch ( Error &e )
+ {
+ e.display();
+ }
+ }
+ else
+ {
+ CPPUNIT_FAIL ( "Initialized SystemSciMsg pointer is NULL" );
+ }
+}
+