summaryrefslogtreecommitdiff
path: root/cesar/maximus/ethernet/src
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/maximus/ethernet/src')
-rw-r--r--cesar/maximus/ethernet/src/EtherSciMsg.cpp372
-rw-r--r--cesar/maximus/ethernet/src/EtherSciMsgTest.cpp225
-rw-r--r--cesar/maximus/ethernet/src/EthernetProcessor.cpp292
-rw-r--r--cesar/maximus/ethernet/src/EthernetProcessorTest.cpp139
4 files changed, 1028 insertions, 0 deletions
diff --git a/cesar/maximus/ethernet/src/EtherSciMsg.cpp b/cesar/maximus/ethernet/src/EtherSciMsg.cpp
new file mode 100644
index 0000000000..7869fb9cd3
--- /dev/null
+++ b/cesar/maximus/ethernet/src/EtherSciMsg.cpp
@@ -0,0 +1,372 @@
+/************************************************************************
+ EtherSciMsg.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/phy/src/EtherSciMsg.cpp
+**************************************************************************/
+
+#include "EtherSciMsg.h"
+#include "IEthernet.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include "interface/sniffer/defs.h" // for 'SNIFFER_BEACON' and 'SNIFFER_MME'
+
+#include <iomanip> // for 'setfill()' and 'setw()'
+using namespace std;
+
+
+// Constructors/Destructors
+//
+
+
+EtherSciMsg::EtherSciMsg ( IEthernet * p_ethernet ):
+mSpecializedSciMsgType(ETHERNET_TYPE_NONE),
+mSnifferType(0),
+mFlags(ETHERNET_FLAG_NONE),
+mpEthernet(NULL)
+{
+ logFunction();
+
+ if (NULL == p_ethernet)
+ {
+ throw Error(__PRETTY_FUNCTION__, "Ethernet processor pointer is NULL");
+ }
+
+ mpEthernet = p_ethernet;
+ initAttributes ();
+}
+
+
+void EtherSciMsg::initAttributes ( )
+{
+ logFunction();
+
+ mSpecializedSciMsgHeader.version = ETHERNET_VERSION;
+ mSpecializedSciMsgHeader.type = ETHERNET_TYPE_NONE;
+ mSpecializedSciMsgHeader.sniffer_type = 0x00;
+ mSpecializedSciMsgHeader.flags = ETHERNET_FLAG_NONE;
+ mSpecializedSciMsgHeader.reserved = 0x00000000;
+}
+
+
+EtherSciMsg::~EtherSciMsg ( )
+{
+ logFunction();
+
+ if (NULL != mpEthernet)
+ {
+ mpEthernet = NULL;
+ }
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+SciMsg * EtherSciMsg::create ( ) const
+{
+ logFunction();
+
+ return new EtherSciMsg (getEthernet());
+}
+
+
+bool EtherSciMsg::dispatchMsg ( )
+{
+ logFunction();
+
+ bool bDispatch = getEthernet()->receiveEther(*this);
+
+ if (!bDispatch)
+ {
+ throw Error(__PRETTY_FUNCTION__, "error while receiving Ether SCI message");
+ }
+
+ return bDispatch;
+}
+
+
+bool EtherSciMsg::identifySpecializedSciMsgHeader ( )
+{
+ logFunction();
+ bool bIdentifyHeader = false;
+
+ if (NULL != SciMsg::getSciMsgData())
+ {
+ // Set specialized SCI msg header size
+ //
+ SciMsg::setSpecializedSciMsgHeaderSize((unsigned long)sizeof(struct Ethernet_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
+ {
+ setSpecializedSciMsgHeader(*((Ethernet_Header*)SciMsg::getSciMsgData()));
+
+ // Set specialized SCI msg attributes from specialized SCI msg header
+ //
+ setSpecializedSciMsgType (static_cast<Ethernet_Type>(getSpecializedSciMsgHeader().type));
+ setSnifferType (static_cast<Ethernet_Sniffer_Type>(getSpecializedSciMsgHeader().sniffer_type));
+ setFlags (static_cast<Ethernet_Flags>(getSpecializedSciMsgHeader().flags));
+ displaySpecializedSciMsgHeader();
+ bIdentifyHeader = true;
+ }
+ else
+ {
+ errno = ENODATA;
+ throw Error(__PRETTY_FUNCTION__, "Not enough data to get the specialized SCI message header", errno);
+ }
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI message data pointer is NULL");
+ }
+
+ return bIdentifyHeader;
+}
+
+
+bool EtherSciMsg::checkCompatibility ( ) const
+{
+ logFunction();
+ bool bCheck = false;
+
+ if (ETHERNET_VERSION == getSpecializedSciMsgHeader().version)
+ {
+ bCheck = SciMsg::checkCompatibility();
+ }
+
+ return bCheck;
+}
+
+
+bool EtherSciMsg::checkValidity ( ) const
+{
+ logFunction();
+ bool bCheck = false;
+
+ // Check header values ranges
+ //
+ if ((ETHERNET_TYPE_NB > getSpecializedSciMsgHeader().type)
+ && (ETHERNET_TYPE_NONE < getSpecializedSciMsgHeader().type)
+ && (SNIFFER_MME >= getSpecializedSciMsgHeader().sniffer_type)
+ && (ETHERNET_FLAG_MAX >= getSpecializedSciMsgHeader().flags))
+ {
+ bCheck = SciMsg::checkValidity();
+ }
+
+ return bCheck;
+}
+
+
+void EtherSciMsg::displaySpecializedSciMsgHeader ( ) const
+{
+ logFunction();
+
+ clog << logger(LOG_INFO) << "Ether SCI message 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) << "\tsniffer type = 0x" << setfill('0') << setw(2) << uppercase << hex << static_cast<unsigned short int>(getSpecializedSciMsgHeader().sniffer_type) << endl;
+ clog << logger(LOG_INFO) << "\tflags = 0x" << setfill('0') << setw(2) << uppercase << hex << static_cast<unsigned short int>(getSpecializedSciMsgHeader().flags) << endl;
+ clog << logger(LOG_INFO) << "\treserved = 0x" << setfill('0') << setw(8) << uppercase << hex << getSpecializedSciMsgHeader().reserved << endl;
+}
+
+
+void EtherSciMsg::displaySpecializedSciMsgType ( int log_level ) const
+{
+ logFunction();
+
+ switch (getSpecializedSciMsgHeader().type)
+ {
+ case 0:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_NONE" << endl;
+ break;
+ case 1:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_DATA" << endl;
+ break;
+ case 2:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_MME" << endl;
+ break;
+ case 3:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_DATA_BUFFER_ADD" << endl;
+ break;
+ case 4:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_MME_BUFFER_ADD" << endl;
+ break;
+ case 5:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_INTERFACE_BUFFER_ADD" << endl;
+ break;
+ case 6:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_BUFFER_RELEASED" << endl;
+ break;
+ case 7:
+ clog << logger(log_level) << "\ttype = ETHERNET_TYPE_SNIFFER" << 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
+//
+
+
+// protected attribute accessor methods
+//
+
+
+void * EtherSciMsg::returnSpecializedSciMsgHeader ( ) const
+{
+ return (void*)&mSpecializedSciMsgHeader;
+}
+
+
+const Ethernet_Header & EtherSciMsg::getSpecializedSciMsgHeader ( ) const
+{
+ return mSpecializedSciMsgHeader;
+}
+
+
+bool EtherSciMsg::setSpecializedSciMsgHeader ( const Ethernet_Header & specialized_sci_msg_header )
+{
+ logFunction();
+
+ mSpecializedSciMsgHeader = specialized_sci_msg_header;
+ displaySpecializedSciMsgHeader();
+
+ return true;
+}
+
+
+IEthernet * EtherSciMsg::getEthernet ( ) const
+{
+ if (NULL == mpEthernet)
+ {
+ throw Error(__PRETTY_FUNCTION__, "Ethernet processor pointer is NULL");
+ }
+
+ return mpEthernet;
+}
+
+
+Ethernet_Type EtherSciMsg::getSpecializedSciMsgType ( ) const
+{
+ return mSpecializedSciMsgType;
+}
+
+
+bool EtherSciMsg::setSpecializedSciMsgType ( const Ethernet_Type type )
+{
+ if ((ETHERNET_TYPE_NB <= type) || (ETHERNET_TYPE_NONE >= type))
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Ether SCI message header type is out-of-range", errno);
+ }
+ mSpecializedSciMsgType = type;
+
+ return true;
+}
+
+
+const Ethernet_Sniffer_Type EtherSciMsg::getSnifferType ( ) const
+{
+ if (SNIFFER_MME < mSnifferType)
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Ether SCI message header sniffer type is out-of-range", errno);
+ }
+
+ return mSnifferType;
+}
+
+
+bool EtherSciMsg::setSnifferType ( const Ethernet_Sniffer_Type sniffer_type )
+{
+ if (SNIFFER_MME < sniffer_type)
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Sniffer type is out-of-range", errno);
+ }
+ mSnifferType = sniffer_type;
+
+ return true;
+}
+
+
+const Ethernet_Flags EtherSciMsg::getFlags ( ) const
+{
+ if (ETHERNET_FLAG_MAX < mFlags)
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Ether SCI message header flags are out-of-range", errno);
+ }
+
+ return mFlags;
+}
+
+
+bool EtherSciMsg::setFlags ( const Ethernet_Flags flags )
+{
+ if (ETHERNET_FLAG_MAX < flags)
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Ether SCI message header flags are out-of-range", errno);
+ }
+ mFlags = flags;
+
+ return true;
+}
+
diff --git a/cesar/maximus/ethernet/src/EtherSciMsgTest.cpp b/cesar/maximus/ethernet/src/EtherSciMsgTest.cpp
new file mode 100644
index 0000000000..59a84a98ba
--- /dev/null
+++ b/cesar/maximus/ethernet/src/EtherSciMsgTest.cpp
@@ -0,0 +1,225 @@
+
+#include "EtherSciMsgTest.h"
+
+#include "EtherSciMsg.h"
+#include "EthernetProcessor.h"
+#include "SciServer.h"
+#include "SystemManager.h"
+#include "PhyProcessor.h"
+#include "NetworkClockProcessor.h"
+#include "FunctionCallManager.h"
+
+#include "Logger.h"
+#include "Error.h"
+
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (EtherSciMsgTest);
+
+
+void EtherSciMsgTest::setUp (void)
+{
+ logTest();
+
+ mpSci = new SciServer();
+ mpEthernet = new EthernetProcessor (mpSci);
+ mpEtherSciMsg = new EtherSciMsg (mpEthernet);
+ CPPUNIT_ASSERT_MESSAGE("EtherSciMsg pointer is NULL", NULL != mpEtherSciMsg);
+
+ unsigned long frameLength = 1500;
+ unsigned char frame[frameLength];
+ memset(frame, 'F', frameLength);
+ mpEtherSciMsg->setSpecializedSciMsgDataLength(frameLength);
+ mpEtherSciMsg->setSpecializedSciMsgData(frame);
+
+ Ethernet_Header header;
+ header.version = ETHERNET_VERSION;
+ header.type = ETHERNET_TYPE_SNIFFER;
+ header.sniffer_type = 0;
+ header.flags = ETHERNET_FLAG_ENCRYPTED;
+ header.reserved = 0x12345678;
+ mpEtherSciMsg->setSpecializedSciMsgHeader(header);
+}
+
+
+void EtherSciMsgTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpEtherSciMsg)
+ {
+ delete (mpEtherSciMsg);
+ mpEtherSciMsg = NULL;
+ }
+ if (NULL != mpEthernet)
+ {
+ delete (mpEthernet);
+ mpEthernet = NULL;
+ }
+ if (NULL != mpSci)
+ {
+ delete (mpSci);
+ mpSci = NULL;
+ }
+}
+
+
+void EtherSciMsgTest::createTest (void)
+{
+ logTest();
+
+ SciMsg * pSciMsg = NULL;
+ pSciMsg = mpEtherSciMsg->create();
+ CPPUNIT_ASSERT_MESSAGE("createTest failed", NULL != pSciMsg);
+
+ delete (pSciMsg);
+ pSciMsg = NULL;
+}
+
+
+void EtherSciMsgTest::dispatchMsgTest (void)
+{
+ logTest();
+
+ ISystem * pSystem = new SystemManager(mpSci);
+ CPPUNIT_ASSERT_MESSAGE("ISystem pointer is NULL", NULL != pSystem);
+
+ IFunctionCall * pFunctionCall = new FunctionCallManager (mpSci);
+ IPhy * pPhy = new PhyProcessor (mpSci);
+ INetworkClock * pNetworkClock = new NetworkClockProcessor (mpSci, pSystem, pFunctionCall, pPhy, mpEthernet);
+ pSystem->setNetworkClock(pNetworkClock);
+
+ pSystem->createStation(pSystem->getDefaultStationExecutable());
+ CPPUNIT_ASSERT_MESSAGE("dispatchMsg failed", mpEtherSciMsg->dispatchMsg());
+
+ delete (pSystem);
+ pSystem = NULL;
+
+ if (NULL != pFunctionCall)
+ {
+ delete (pFunctionCall);
+ pFunctionCall = NULL;
+ }
+ if (NULL != pPhy)
+ {
+ delete (pPhy);
+ pPhy = NULL;
+ }
+ if (NULL != pNetworkClock)
+ {
+ delete (pNetworkClock);
+ pNetworkClock = NULL;
+ }
+}
+
+
+void EtherSciMsgTest::identifySpecializedSciMsgHeaderTest (void)
+{
+ logTest();
+
+ unsigned long frameLength = 1500;
+ unsigned char frame[frameLength];
+ memset(frame, 0x01, frameLength);
+ mpEtherSciMsg->setSciMsgDataLength(frameLength);
+ mpEtherSciMsg->setSciMsgData(frame);
+ CPPUNIT_ASSERT_MESSAGE("identifySpecializedSciMsgHeader failed",
+ mpEtherSciMsg->identifySpecializedSciMsgHeader());
+}
+
+
+void EtherSciMsgTest::checkCompatibilityTest (void)
+{
+ logTest();
+
+ Sci_Msg_Header header;
+ header.version = SCI_MSG_VERSION;
+ mpEtherSciMsg->setSciMsgHeader(header);
+ CPPUNIT_ASSERT_MESSAGE("checkCompatibility failed",
+ mpEtherSciMsg->checkCompatibility());
+}
+
+
+void EtherSciMsgTest::checkValidityTest (void)
+{
+ logTest();
+
+ Sci_Msg_Header header;
+ header.magic_id = mpEtherSciMsg->getDefinedSciMsgMagicId();
+ header.msg_id = 0x8000;
+ mpEtherSciMsg->setSciMsgHeader(header);
+ CPPUNIT_ASSERT_MESSAGE("checkValidity failed",
+ mpEtherSciMsg->checkValidity());
+}
+
+
+void EtherSciMsgTest::displaySpecializedSciMsgHeaderTest (void)
+{
+ logTest();
+
+ mpEtherSciMsg->displaySpecializedSciMsgHeader();
+}
+
+
+void EtherSciMsgTest::displaySpecializedSciMsgTypeTest (void)
+{
+ logTest();
+
+ mpEtherSciMsg->displaySpecializedSciMsgType(LOG_INFO);
+}
+
+
+void EtherSciMsgTest::returnSpecializedSciMsgHeaderTest (void)
+{
+ logTest();
+
+ void * vpHeader = NULL;
+ vpHeader = mpEtherSciMsg->returnSpecializedSciMsgHeader();
+ CPPUNIT_ASSERT_MESSAGE("void pointer is NULL", NULL != vpHeader);
+ Ethernet_Header * pHeader = (Ethernet_Header *)vpHeader;
+ CPPUNIT_ASSERT_MESSAGE("returnSpecializedSciMsgHeader failed",
+ (mpEtherSciMsg->getSpecializedSciMsgHeader().version == pHeader->version)
+ && (mpEtherSciMsg->getSpecializedSciMsgHeader().type == pHeader->type)
+ && (mpEtherSciMsg->getSpecializedSciMsgHeader().sniffer_type == pHeader->sniffer_type)
+ && (mpEtherSciMsg->getSpecializedSciMsgHeader().flags == pHeader->flags)
+ && (mpEtherSciMsg->getSpecializedSciMsgHeader().reserved == pHeader->reserved));
+}
+
+
+void EtherSciMsgTest::setSpecializedSciMsgHeaderTest (void)
+{
+ logTest();
+
+ CPPUNIT_ASSERT_MESSAGE("setSpecializedSciMsgHeader failed",
+ ETHERNET_TYPE_SNIFFER == mpEtherSciMsg->getSpecializedSciMsgHeader().type);
+}
+
+
+void EtherSciMsgTest::setSpecializedSciMsgTypeTest (void)
+{
+ logTest();
+
+ CPPUNIT_ASSERT_MESSAGE("setSpecializedSciMsgType failed",
+ mpEtherSciMsg->setSpecializedSciMsgType(ETHERNET_TYPE_DATA)
+ && (ETHERNET_TYPE_DATA == mpEtherSciMsg->getSpecializedSciMsgType()));
+}
+
+
+void EtherSciMsgTest::setSnifferTypeTest (void)
+{
+ logTest();
+
+ CPPUNIT_ASSERT_MESSAGE("setSnifferType failed",
+ mpEtherSciMsg->setSnifferType(1)
+ && (1 == mpEtherSciMsg->getSnifferType()));
+}
+
+
+void EtherSciMsgTest::setFlagsTest (void)
+{
+ logTest();
+
+ CPPUNIT_ASSERT_MESSAGE("setFlags failed",
+ mpEtherSciMsg->setFlags(ETHERNET_FLAG_MAX)
+ && (ETHERNET_FLAG_MAX == mpEtherSciMsg->getFlags()));
+}
+
diff --git a/cesar/maximus/ethernet/src/EthernetProcessor.cpp b/cesar/maximus/ethernet/src/EthernetProcessor.cpp
new file mode 100644
index 0000000000..406748dd8d
--- /dev/null
+++ b/cesar/maximus/ethernet/src/EthernetProcessor.cpp
@@ -0,0 +1,292 @@
+/************************************************************************
+ EthernetProcessor.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/ethernet/src/EthernetProcessor.cpp
+**************************************************************************/
+
+#include "EthernetProcessor.h"
+
+#include "EtherSciMsg.h"
+#include "ISci.h"
+
+#include "Error.h"
+#include "Logger.h"
+
+#include <sys/socket.h> // for 'struct sockaddr'
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <sys/ioctl.h>
+#include <fcntl.h> // for 'O_RDWR'
+#include <unistd.h> // for 'system()'
+using namespace std;
+
+
+// Constructors/Destructors
+//
+
+
+EthernetProcessor::EthernetProcessor ( ISci * p_sci ):
+mpSci(NULL),
+mInterfaceCb(NULL)
+{
+ logFunction();
+
+ if (NULL == p_sci)
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "SCI pointer is NULL", errno);
+ }
+ mpSci = p_sci;
+ initAttributes();
+}
+
+
+void EthernetProcessor::initAttributes ( )
+{
+ logFunction();
+
+ registerEtherSciMsg();
+}
+
+
+EthernetProcessor::~EthernetProcessor ( )
+{
+ logFunction();
+
+ if (NULL != mpSci)
+ {
+ mpSci = NULL;
+ }
+ if (NULL != mInterfaceCb)
+ {
+ mInterfaceCb = NULL;
+ }
+}
+
+
+//
+// Methods
+//
+
+
+// Other methods
+//
+
+
+// public methods
+//
+
+
+bool EthernetProcessor::init ( EtherCb interface_cb )
+{
+ logFunction();
+
+ if (NULL == interface_cb)
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "Callback function address is NULL", errno);
+ }
+ mInterfaceCb = interface_cb;
+
+ return true;
+}
+
+
+EtherSciMsg * EthernetProcessor::createEther ( )
+{
+ logFunction();
+
+ return new EtherSciMsg(this);
+}
+
+
+bool EthernetProcessor::sendEther ( EtherSciMsg & ether_sci_msg )
+{
+ logFunction();
+ bool bSend = false;
+
+ if ( fillEther(ether_sci_msg) && (0 != ether_sci_msg.getSciMsgStationId()) )
+ {
+ bSend = getSci()->sendSciMsg(ether_sci_msg);
+ }
+ if (!bSend)
+ {
+ throw Error(__PRETTY_FUNCTION__, "cannot send Ether SCI message", errno);
+ }
+
+ return bSend;
+}
+
+
+bool EthernetProcessor::receiveEther ( EtherSciMsg & ether_sci_msg )
+{
+ logFunction();
+
+ // Check Ether SCI message data length and data
+ if ( (0 == ether_sci_msg.getSpecializedSciMsgDataLength())
+ || (NULL == ether_sci_msg.getSpecializedSciMsgData()) )
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "received Ether SCI message is incorrect", errno);
+ }
+
+ // Go back up to user
+ if (NULL != getInterfaceCb())
+ {
+ getInterfaceCb()(ether_sci_msg);
+ }
+
+ return true;
+}
+
+
+File_Descriptor EthernetProcessor::allocTap ( char * dev ) const
+{
+ logFunction();
+ int etherLogFileDescriptor = -1;
+
+ if (0 > (etherLogFileDescriptor = open("/dev/net/tun", O_RDWR)))
+ {
+ throw Error(__PRETTY_FUNCTION__, "open /dev/net/tun failed", errno);
+ }
+ else
+ {
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP; // TAP device
+ if (* dev)
+ {
+ strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+ }
+ if (0 > ioctl(etherLogFileDescriptor, TUNSETIFF, (void *)&ifr))
+ {
+ close(etherLogFileDescriptor);
+ etherLogFileDescriptor = -1;
+ if (EPERM == errno)
+ {
+ throw Error(__PRETTY_FUNCTION__, "please launch the program with root rights", errno);
+ }
+ else
+ {
+ throw Error(__PRETTY_FUNCTION__, "ioctl failed", errno);
+ }
+ }
+ else
+ {
+ //system("wireshark");
+ strcpy(dev, ifr.ifr_name);
+ }
+ }
+
+ return etherLogFileDescriptor;
+}
+
+
+// private methods
+//
+
+
+void EthernetProcessor::registerEtherSciMsg ( )
+{
+ logFunction();
+
+ if (!getSci()->registerSpecializedSciMsg(SCI_MSG_TYPE_ETHERNET, new EtherSciMsg((IEthernet *)this)))
+ {
+ throw Error(__PRETTY_FUNCTION__, "cannot register Ether SCI message to SCI");
+ }
+}
+
+
+bool EthernetProcessor::fillEther ( EtherSciMsg & ether_sci_msg ) const
+{
+ logFunction();
+ bool bFill = false;
+
+ // Fill specialized SCI msg header
+ //
+ struct Ethernet_Header ethernetHeader;
+ ethernetHeader.version = ether_sci_msg.getSpecializedSciMsgHeader().version;
+ ethernetHeader.type = ether_sci_msg.getSpecializedSciMsgType();
+ ethernetHeader.sniffer_type = ether_sci_msg.getSnifferType();
+ ethernetHeader.flags = ether_sci_msg.getFlags();
+ ethernetHeader.reserved = ether_sci_msg.getSpecializedSciMsgHeader().reserved;
+
+ // Set specialized SCI msg header
+ //
+ bFill = ether_sci_msg.setSpecializedSciMsgHeader(ethernetHeader);
+
+ // Fill specialized SCI msg attributes:
+ // - header size
+ //
+ bFill &= ether_sci_msg.setSpecializedSciMsgHeaderSize(sizeof(struct Ethernet_Header));
+
+ // Fill SCI msg attributes:
+ // - type
+ //
+ bFill &= ether_sci_msg.setSciMsgType(SCI_MSG_TYPE_ETHERNET);
+ bFill &= getSci()->fillSciMsg(ether_sci_msg);
+
+ return bFill;
+}
+
+
+// protected methods
+//
+
+
+// Accessor methods
+//
+
+
+// public attribute accessor methods
+//
+
+
+// private attribute accessor methods
+//
+
+
+ISci * EthernetProcessor::getSci ( ) const
+{
+ if (NULL == mpSci)
+ {
+ throw Error(__PRETTY_FUNCTION__, "SCI pointer is NULL");
+ }
+
+ return mpSci;
+}
+
+
+EtherCb EthernetProcessor::getInterfaceCb ( ) const
+{
+ return mInterfaceCb;
+}
+
+
+// protected attribute accessor methods
+//
+
diff --git a/cesar/maximus/ethernet/src/EthernetProcessorTest.cpp b/cesar/maximus/ethernet/src/EthernetProcessorTest.cpp
new file mode 100644
index 0000000000..8fee360a58
--- /dev/null
+++ b/cesar/maximus/ethernet/src/EthernetProcessorTest.cpp
@@ -0,0 +1,139 @@
+
+#include "EthernetProcessorTest.h"
+
+#include "EthernetProcessor.h"
+#include "CoreEngine.h"
+#include "ISystem.h"
+#include "EtherSciMsg.h"
+
+#include "Logger.h"
+#include "Error.h"
+
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (EthernetProcessorTest);
+
+bool bTest = false;
+
+void interfaceCbTest ( EtherSciMsg & ether )
+{
+ logTest();
+
+ bTest = true;
+}
+
+
+void EthernetProcessorTest::setUp (void)
+{
+ logTest();
+
+ mpCoreEngine = new CoreEngine();
+ mpEthernetProcessor = (EthernetProcessor *)mpCoreEngine->getEthernet();
+ CPPUNIT_ASSERT_MESSAGE ( "Ethernet processor pointer is NULL", NULL != mpEthernetProcessor );
+}
+
+
+void EthernetProcessorTest::tearDown (void)
+{
+ logTest();
+
+ if (NULL != mpEthernetProcessor)
+ {
+ mpEthernetProcessor = NULL;
+ }
+ if (NULL != mpCoreEngine)
+ {
+ delete (mpCoreEngine);
+ mpCoreEngine = NULL;
+ }
+}
+
+
+void EthernetProcessorTest::initTest (void)
+{
+ logTest();
+
+ CPPUNIT_ASSERT_MESSAGE ( "init failed", mpEthernetProcessor->init(&interfaceCbTest) );
+}
+
+
+void EthernetProcessorTest::createEtherTest (void)
+{
+ logTest();
+
+ EtherSciMsg * pEtherSciMsg = mpEthernetProcessor->createEther();
+ CPPUNIT_ASSERT_MESSAGE ( "createEther failed", NULL != pEtherSciMsg );
+
+ delete (pEtherSciMsg);
+ pEtherSciMsg = NULL;
+}
+
+
+void EthernetProcessorTest::sendEtherTest (void)
+{
+ logTest();
+
+ EtherSciMsg * pEtherSciMsg = mpEthernetProcessor->createEther();
+ CPPUNIT_ASSERT_MESSAGE ( "Ether SCI message pointer is NULL", NULL != pEtherSciMsg );
+
+ // create the destination station
+ Sci_Msg_Station_Id stationId = mpCoreEngine->getSystem()->createStation(mpCoreEngine->getSystem()->getDefaultStationExecutable());
+ mpCoreEngine->getSystem()->updateStationStatus(stationId, MAXIMUS_STATION_STATUS_IDLE);
+ pEtherSciMsg->setSciMsgStationId(stationId);
+
+ CPPUNIT_ASSERT_MESSAGE ( "Ether SCI message has not been sent", mpEthernetProcessor->sendEther(*pEtherSciMsg) );
+
+ mpCoreEngine->getSystem()->removeStation(stationId);
+
+ if (NULL != pEtherSciMsg)
+ {
+ delete (pEtherSciMsg);
+ pEtherSciMsg = NULL;
+ }
+}
+
+
+void EthernetProcessorTest::receiveEtherTest (void)
+{
+ logTest();
+
+ EtherSciMsg * pEtherSciMsg = mpEthernetProcessor->createEther();
+
+ unsigned long length = 100;
+ unsigned char payload[length];
+ memset(payload, 'M', length);
+ pEtherSciMsg->setSpecializedSciMsgDataLength(length);
+ pEtherSciMsg->setSpecializedSciMsgData(payload);
+
+ // create the destination station
+ Sci_Msg_Station_Id stationId = mpCoreEngine->getSystem()->createStation(mpCoreEngine->getSystem()->getDefaultStationExecutable());
+
+ CPPUNIT_ASSERT_MESSAGE ( "receiveEther failed",
+ mpEthernetProcessor->receiveEther(*pEtherSciMsg) );
+
+ mpCoreEngine->getSystem()->removeStation(stationId);
+
+ if (NULL != pEtherSciMsg)
+ {
+ delete (pEtherSciMsg);
+ pEtherSciMsg = NULL;
+ }
+}
+
+
+void EthernetProcessorTest::allocTapTest (void)
+{
+ logTest();
+
+ try
+ {
+ char dev[] = "tap0\0";
+ CPPUNIT_ASSERT_MESSAGE ( "allocTap failed",
+ 0 <= mpEthernetProcessor->allocTap(dev) );
+ }
+ catch (...)
+ {
+ CPPUNIT_ASSERT_MESSAGE ( "allocTap failed", (EPERM == errno) || (EACCES == errno) );
+ }
+}
+