summaryrefslogtreecommitdiff
path: root/cesar/maximus/processors
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/maximus/processors')
-rw-r--r--cesar/maximus/processors/Module3
-rw-r--r--cesar/maximus/processors/inc/ClockProcessor.h47
-rw-r--r--cesar/maximus/processors/inc/EthernetProcessor.h43
-rw-r--r--cesar/maximus/processors/inc/FunctionCallProcessor.h54
-rw-r--r--cesar/maximus/processors/inc/PhyProcessor.h221
-rw-r--r--cesar/maximus/processors/inc/Processor.h52
-rw-r--r--cesar/maximus/processors/inc/SystemProcessor.h46
-rw-r--r--cesar/maximus/processors/processors.h23
-rw-r--r--cesar/maximus/processors/src/ClockProcessor.cpp95
-rw-r--r--cesar/maximus/processors/src/EthernetProcessor.cpp80
-rw-r--r--cesar/maximus/processors/src/FunctionCallProcessor.cpp175
-rw-r--r--cesar/maximus/processors/src/PhyProcessor.cpp762
-rw-r--r--cesar/maximus/processors/src/Processor.cpp31
-rw-r--r--cesar/maximus/processors/src/SystemProcessor.cpp123
14 files changed, 1755 insertions, 0 deletions
diff --git a/cesar/maximus/processors/Module b/cesar/maximus/processors/Module
new file mode 100644
index 0000000000..401017927d
--- /dev/null
+++ b/cesar/maximus/processors/Module
@@ -0,0 +1,3 @@
+SOURCES := Processor.cpp EthernetProcessor.cpp FunctionCallProcessor.cpp
+SOURCES += ClockProcessor.cpp PhyProcessor.cpp SystemProcessor.cpp
+
diff --git a/cesar/maximus/processors/inc/ClockProcessor.h b/cesar/maximus/processors/inc/ClockProcessor.h
new file mode 100644
index 0000000000..3f95694966
--- /dev/null
+++ b/cesar/maximus/processors/inc/ClockProcessor.h
@@ -0,0 +1,47 @@
+#ifndef maximus_processors_inc_clockprocessor_h
+#define maximus_processors_inc_clockprocessor_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/inc/ClockProcessor.h
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/common/types.h"
+#include "maximus/processors/inc/Processor.h"
+#include "maximus/sci/inc/ClockSciMsg.h"
+
+class ClockProcessor : public Processor
+{
+private:
+
+ /* Transmitted clock sci message have no data. */
+ ClockSciMsg msg_to_send;
+
+public:
+
+ ClockProcessor (
+ SciServer &ref1,
+ MaximusCallBack &ref2);
+
+ virtual ~ClockProcessor ();
+
+ SciMsg* create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer);
+
+ void dispatchMsgProc (
+ SciMsg *msg_rx);
+
+ void scheduler_send_event (
+ Sci_Msg_Station_Id clock_staid,
+ Network_Clock_Id clock_id,
+ SciMsg *msg);
+};
+
+#endif // maximus_processors_inc_clockprocessor_h
diff --git a/cesar/maximus/processors/inc/EthernetProcessor.h b/cesar/maximus/processors/inc/EthernetProcessor.h
new file mode 100644
index 0000000000..01ef68bbcb
--- /dev/null
+++ b/cesar/maximus/processors/inc/EthernetProcessor.h
@@ -0,0 +1,43 @@
+#ifndef maximus_processors_inc_ethernetprocessor_h
+#define maximus_processors_inc_ethernetprocessor_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/inc/EthernetProcessor.h
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/common/types.h"
+#include "maximus/processors/inc/Processor.h"
+#include <string>
+
+class EthernetProcessor : public Processor
+{
+public:
+
+ EthernetProcessor (
+ SciServer &ref1,
+ MaximusCallBack &ref2);
+
+ virtual ~EthernetProcessor ();
+
+ void dispatchMsgProc (
+ SciMsg *msg_rx);
+
+ SciMsg *create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer);
+
+ void sendEther (
+ std::string &payload,
+ Ethernet_Type type,
+ Sci_Msg_Station_Id sta_id);
+
+};
+
+#endif // maximus_processors_inc_ethernetprocessor_h
diff --git a/cesar/maximus/processors/inc/FunctionCallProcessor.h b/cesar/maximus/processors/inc/FunctionCallProcessor.h
new file mode 100644
index 0000000000..a07bf4a8b2
--- /dev/null
+++ b/cesar/maximus/processors/inc/FunctionCallProcessor.h
@@ -0,0 +1,54 @@
+#ifndef maximus_processors_inc_functioncallprocessor_h
+#define maximus_processors_inc_functioncallprocessor_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/inc/FunctionCallProcessor.h
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/common/types.h"
+#include "maximus/processors/inc/Processor.h"
+#include "maximus/interface/msg/msg.h"
+#include <boost/function.hpp> // for 'CallbackFunction_t'
+#include <map>
+
+typedef boost::function <void (FunctionSciMsg &)> CallbackFunction_t;
+
+typedef std::map <Function_Call_Msg_Id, const CallbackFunction_t>
+CallbacksList_t;
+
+class FunctionCallProcessor : public Processor
+{
+private:
+
+ CallbacksList_t fc_msg_cb_list;
+
+ void displayListOfCallbacks () const;
+
+public:
+
+ FunctionCallProcessor (
+ SciServer &ref1,
+ MaximusCallBack &ref2);
+
+ virtual ~FunctionCallProcessor ();
+
+ SciMsg *create_sci_msg (struct Sci_Msg_Header &header,
+ unsigned char *buffer);
+
+ void sendMsg (
+ MsgFunctionCall &user_msg,
+ const CallbackFunction_t cb);
+
+ void dispatchMsgProc (SciMsg *msg_rx);
+
+ bool is_FunctionCall_empty ();
+};
+
+#endif // maximus_processors_inc_functioncallprocessor_h
diff --git a/cesar/maximus/processors/inc/PhyProcessor.h b/cesar/maximus/processors/inc/PhyProcessor.h
new file mode 100644
index 0000000000..f04b3438c6
--- /dev/null
+++ b/cesar/maximus/processors/inc/PhyProcessor.h
@@ -0,0 +1,221 @@
+#ifndef maximus_processors_inc_phyprocessor_h
+#define maximus_processors_inc_phyprocessor_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/inc/PhyProcessor.h
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/common/types.h"
+#include "maximus/interface/msg/msg.h"
+#include "maximus/processors/inc/Processor.h"
+#include "maximus/sci/inc/PhySciMsg.h"
+#include <boost/random/mersenne_twister.hpp>
+#include <map>
+#include <list>
+
+class ChannelComputer;
+
+struct Expected_Tx
+{
+ /* Expected transmission ID. */
+ Phy_Tx_Id src_tx_id;
+ /* Expected transmitting station ID. */
+ Sci_Msg_Station_Id src_station_id;
+};
+
+struct lttx
+{
+ bool operator() (
+ const Expected_Tx &tx1,
+ const Expected_Tx &tx2) const
+ {
+ if (tx1.src_tx_id != tx2.src_tx_id)
+ return tx1.src_tx_id < tx2.src_tx_id;
+ else
+ return tx1.src_station_id < tx2.src_station_id;
+ }
+};
+
+struct Frame_Control
+{
+ uint32_t fc_10;
+ uint32_t fc_av[4];
+};
+
+/* list of received Frame Control. */
+typedef std::map <const Expected_Tx,
+ Frame_Control,
+ lttx> rx_fc_list_t;
+
+typedef std::multimap <std::pair <Phy_Tx_Id,
+ Sci_Msg_Station_Id>,
+ Sci_Msg_Station_Id> rx_activated_list_t;
+
+typedef std::list <std::pair <MsgMpdu *,
+ PhySciMsg *> > MsgMpdu_list_t;
+
+class PhyProcessor : public Processor
+{
+private:
+
+ ChannelComputer * mpChannel;
+
+ bool mIsChannelEnabled;
+
+ unsigned int mNbOfCarriers;
+ uint8_t * mpTonemask;
+
+ /* unique ID incremented for each transmission. */
+ Phy_Tx_Id phy_TxId;
+ /* (PREAMBLE, FC, MPDU, and NOISE if enabled). */
+ rx_activated_list_t rx_activated_list;
+ rx_fc_list_t rx_fc_list;
+ MsgMpdu_list_t MsgMpdu_list;
+
+ Network_Clock_Tick ZeroCross_interval;
+ PhySciMsg PhySciMsg_ZeroCross;
+
+ /* For the wrong preambles transmission feature. */
+ bool Is_FalseAlarm;
+ PhySciMsg PhySciMsg_WrongPre;
+ boost::mt19937 FalseAlarm_mersenne_twister;
+ Network_Clock_Tick FalseAlarm_avg_interval;
+ float FalseAlarm_deviation;
+
+public:
+
+ PhyProcessor (
+ SciServer &ref1,
+ MaximusCallBack &ref2);
+
+ virtual ~PhyProcessor ();
+
+ void dispatchMsgProc (SciMsg *msg_rx);
+
+ void scheduler_send_event (
+ Sci_Msg_Station_Id clock_staid,
+ Network_Clock_Id clock_id,
+ SciMsg *msg);
+
+ void scheduler_drop_event (SciMsg *msg);
+
+ SciMsg *create_sci_msg (struct Sci_Msg_Header &header,
+ unsigned char *buffer);
+
+ void mpdu_schedule (
+ MsgMpdu *mpdu,
+ PhySciMsg *preamble,
+ PhySciMsg *fc,
+ PhySciMsg *payload);
+
+ void receiveInvalid (PhySciMsg &sci);
+ void receivePre (PhySciMsg &sci);
+ void receiveFc (PhySciMsg &sci);
+ void receivePrs (PhySciMsg &sci);
+ void receive_payload (PhySciMsg &sci);
+ void receiveTonemask (PhySciMsg &sci);
+ void receiveTonemap (PhySciMsg &sci);
+ void receive_rx (PhySciMsg &sci);
+
+ /**
+ * Activate the wrong preambles transmission feature.
+ * @param average_duration average number of ticks 25 MHz between two consecutive wrong preambles
+ * @param std_deviation the standard deviation
+ * @return bool
+ */
+ void activateFalseAlarm (
+ const Network_Clock_Tick avg_interval,
+ const float deviation);
+
+ /**
+ * Deactivate the wrong preambles transmission feature.
+ * @return bool
+ */
+ void deactivateFalseAlarm ();
+
+ /**
+ * @return bool
+ * @param p_channel the new value of mpChannel
+ */
+ bool setChannel (ChannelComputer * p_channel);
+
+ /**
+ * Sets the channel perturbation.
+ * @param is_channel_enabled the new value of mIsChannelEnabled
+ */
+ bool setIsChannelEnabled (const bool is_channel_enabled);
+
+ /**
+ * Gets the tonemask.
+ * @return mpTonemask
+ */
+ const uint8_t * getTonemask () const;
+
+ /**
+ * Check if the channel perturbation is enabled.
+ * @return mIsChannelEnabled
+ */
+ bool isChannelEnabled () const;
+
+ void set_zerocross_freq (const float frequency);
+
+private:
+
+ void del_phy_msg (PhySciMsg *msg);
+
+ void schedule_next_zero_cross ();
+
+ /**
+ * Computes Frame Control transmission duration.
+ * @return Frame Control delay in ticks
+ */
+ Network_Clock_Tick calculateFcDelay (
+ Phy_Fc_Mode fc_mode) const;
+
+ /**
+ * Gets a pointer to Channel.
+ * @return mpChannel
+ */
+ ChannelComputer * getChannel () const;
+
+ /**
+ * Gets the number of carriers.
+ * @return mNbOfCarriers
+ */
+ unsigned int getNbOfCarriers () const;
+
+ /**
+ * Sets the number of carriers.
+ * @return bool
+ * @param nb_of_carriers the new value of mNbOfCarriers
+ */
+ bool setNbOfCarriers (const unsigned int nb_of_carriers);
+
+ void setTonemask (
+ const unsigned int length,
+ const uint8_t * p_tonemask);
+
+ /**
+ * Sends PHY SCI message(s) of type MPDU
+ * and a PHY SCI message of type NOISE
+ * to destination stations.
+ * @param mpdu the PHY SCI message of type MPDU
+ * @return bool
+ */
+ inline void send_mpdu_and_noise (PhySciMsg &sci_payload);
+
+ Network_Clock_Tick roll_die_next_interval () const;
+
+ bool scheduleNextWrongPre (
+ const Network_Clock_Tick next_interval);
+};
+
+
+#endif // maximus_processors_inc_phyprocessor_h
diff --git a/cesar/maximus/processors/inc/Processor.h b/cesar/maximus/processors/inc/Processor.h
new file mode 100644
index 0000000000..e1a650ab56
--- /dev/null
+++ b/cesar/maximus/processors/inc/Processor.h
@@ -0,0 +1,52 @@
+#ifndef maximus_processors_inc_processor_h
+#define maximus_processors_inc_processor_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/inc/Processor.h
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/common/types.h"
+#include "maximus/processors/processors.h"
+#include "maximus/scheduler/scheduler.h"
+#include "maximus/interface/maximus.h"
+#include "maximus/sci/sci_msg.h"
+
+class Processor
+{
+private:
+ Sci_Msg_Type processor_type;
+
+protected:
+
+ SciServer &sci_server;
+ MaximusCallBack &maximus_cb;
+ Scheduler *p_scheduler;
+
+public:
+
+ Processor (SciServer &ref1,
+ MaximusCallBack &ref2,
+ Sci_Msg_Type type);
+
+ virtual ~Processor ();
+
+ virtual SciMsg* create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer) = 0;
+
+ virtual void dispatchMsgProc (SciMsg *msg_rx) = 0;
+
+ inline void register_scheduler (Scheduler *p)
+ {
+ p_scheduler = p;
+ }
+};
+
+#endif /* maximus_processors_inc_processor_h */
diff --git a/cesar/maximus/processors/inc/SystemProcessor.h b/cesar/maximus/processors/inc/SystemProcessor.h
new file mode 100644
index 0000000000..27ce3ef6c8
--- /dev/null
+++ b/cesar/maximus/processors/inc/SystemProcessor.h
@@ -0,0 +1,46 @@
+#ifndef maximus_processors_inc_systemprocessor_h
+#define maximus_processors_inc_systemprocessor_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/inc/SystemProcessor.h
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/common/types.h"
+#include "maximus/processors/inc/Processor.h"
+#include "maximus/interface/station/station.h"
+
+class SystemProcessor : public Processor
+{
+private:
+
+ const stations_list_t &sta_list;
+
+public:
+
+ SystemProcessor (
+ SciServer &ref1,
+ MaximusCallBack &ref2,
+ stations_list_t &ref3);
+
+ virtual ~SystemProcessor ( );
+
+ SciMsg *create_sci_msg (struct Sci_Msg_Header &header,
+ unsigned char *buffer);
+
+ void dispatchMsgProc (SciMsg *msg_rx);
+
+ void send_name (const Station &sta);
+
+ Station *findStation (
+ const Sci_Msg_Station_Id station_id) const;
+
+};
+
+#endif // maximus_processors_inc_systemprocessor_h
diff --git a/cesar/maximus/processors/processors.h b/cesar/maximus/processors/processors.h
new file mode 100644
index 0000000000..801e075747
--- /dev/null
+++ b/cesar/maximus/processors/processors.h
@@ -0,0 +1,23 @@
+#ifndef maximus_processors_processors_h
+#define maximus_processors_processors_h
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/processors.h
+ * \ingroup maximus_processors
+ *
+ */
+class Processor;
+
+class PhyProcessor;
+class FunctionCallProcessor;
+class ClockProcessor;
+class SystemProcessor;
+class EthernetProcessor;
+
+#endif /* maximus_processors_processors_h */
diff --git a/cesar/maximus/processors/src/ClockProcessor.cpp b/cesar/maximus/processors/src/ClockProcessor.cpp
new file mode 100644
index 0000000000..711858dc06
--- /dev/null
+++ b/cesar/maximus/processors/src/ClockProcessor.cpp
@@ -0,0 +1,95 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/src/ClockProcessor.cpp
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/processors/inc/ClockProcessor.h"
+#include "maximus/sci/inc/ClockSciMsg.h"
+#include "maximus/scheduler/inc/Scheduler.h"
+#include "maximus/utils/inc/Logger.h"
+
+ClockProcessor::ClockProcessor (SciServer &ref1,
+ MaximusCallBack &ref2):
+ Processor (ref1, ref2, SCI_MSG_TYPE_NETWORK_CLOCK),
+ msg_to_send (0)
+{
+ logFunction ();
+
+ msg_to_send.set_clock_type (NETWORK_CLOCK_TYPE_STATION);
+}
+
+ClockProcessor::~ClockProcessor ()
+{
+ logFunction ();
+}
+
+SciMsg *
+ClockProcessor::create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer)
+{
+ logFunction ();
+
+ return new ClockSciMsg (header, buffer);
+}
+
+void
+ClockProcessor::dispatchMsgProc (SciMsg *msg_rx)
+{
+ logFunction ();
+
+ ClockSciMsg &msg = static_cast <ClockSciMsg &> (*msg_rx);
+
+ if (NETWORK_CLOCK_VERSION == msg.get_clock_version ())
+ {
+ Sci_Msg_Station_Id from_sta_id = msg.get_sci_stationid ();
+ Network_Clock_Type type = msg.get_clock_type ();
+ Network_Clock_Id id = msg.get_clock_id ();
+ Network_Clock_Tick msg_tick = msg.get_clock_tick ();
+
+ switch (type)
+ {
+ case NETWORK_CLOCK_TYPE_NB:
+ case NETWORK_CLOCK_TYPE_NONE:
+ maximus_log (LOG_WARNING,
+ "bad event type => do nothing");
+ break;
+
+ case NETWORK_CLOCK_TYPE_REMOVE:
+ p_scheduler->remove_event (
+ msg_tick, from_sta_id, id);
+ break;
+
+ case NETWORK_CLOCK_TYPE_STATION:
+ case NETWORK_CLOCK_TYPE_FUNCTION_CALL:
+ case NETWORK_CLOCK_TYPE_PHY:
+ case NETWORK_CLOCK_TYPE_SYSTEM:
+ case NETWORK_CLOCK_TYPE_ETHERNET:
+ p_scheduler->add_event (
+ msg_tick, from_sta_id, id, type);
+ break;
+ }
+ }
+
+ delete (msg_rx);
+}
+
+void
+ClockProcessor::scheduler_send_event (
+ Sci_Msg_Station_Id clock_staid,
+ Network_Clock_Id clock_id,
+ SciMsg *msg)
+{
+ logFunction ();
+
+ msg_to_send.set_clock_id (clock_id);
+ msg_to_send.set_sci_stationid (clock_staid);
+ msg_to_send.setup_and_send (sci_server);
+}
diff --git a/cesar/maximus/processors/src/EthernetProcessor.cpp b/cesar/maximus/processors/src/EthernetProcessor.cpp
new file mode 100644
index 0000000000..72f4bc6340
--- /dev/null
+++ b/cesar/maximus/processors/src/EthernetProcessor.cpp
@@ -0,0 +1,80 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/src/EthernetProcessor.cpp
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/processors/inc/Processor.h"
+#include "maximus/processors/inc/EthernetProcessor.h"
+#include "maximus/sci/inc/EtherSciMsg.h"
+#include "maximus/interface/inc/MaximusCallBack.h"
+#include "maximus/utils/inc/Error.h"
+#include "maximus/utils/inc/Logger.h"
+#include <cstring>
+
+EthernetProcessor::EthernetProcessor (SciServer &ref1,
+ MaximusCallBack &ref2):
+ Processor (ref1, ref2, SCI_MSG_TYPE_ETHERNET)
+{
+ logFunction ();
+}
+
+EthernetProcessor::~EthernetProcessor ()
+{
+ logFunction ();
+}
+
+SciMsg *
+EthernetProcessor::create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer)
+{
+ logFunction ();
+
+ return new EtherSciMsg (header, buffer);
+}
+
+void
+EthernetProcessor::sendEther (
+ std::string &payload,
+ Ethernet_Type type,
+ Sci_Msg_Station_Id sta_id)
+{
+ logFunction ();
+
+ EtherSciMsg msg (payload.length ());
+
+ unsigned char *data = msg.get_ether_data_addr ();
+ memcpy (data, payload.data (), payload.length ());
+
+ msg.set_ether_type (type);
+ msg.set_sci_stationid (sta_id);
+
+ msg.setup_and_send (sci_server);
+}
+
+void
+EthernetProcessor::dispatchMsgProc (SciMsg *msg_rx)
+{
+ logFunction ();
+
+ EtherSciMsg &msg = static_cast <EtherSciMsg &> (*msg_rx);
+
+ if (ETHERNET_VERSION == msg.get_ether_version ()
+ && 0 != msg.get_ether_data_size ())
+ {
+ maximus_cb.recv_ether_cb (
+ (char *) msg.get_ether_data_addr (),
+ (int) msg.get_ether_data_size (),
+ msg.get_ether_type (),
+ msg.get_sci_stationid ());
+ }
+
+ delete msg_rx;
+}
diff --git a/cesar/maximus/processors/src/FunctionCallProcessor.cpp b/cesar/maximus/processors/src/FunctionCallProcessor.cpp
new file mode 100644
index 0000000000..aae74e9f0a
--- /dev/null
+++ b/cesar/maximus/processors/src/FunctionCallProcessor.cpp
@@ -0,0 +1,175 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/src/FunctionCallProcessor.cpp
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/processors/inc/FunctionCallProcessor.h"
+#include "maximus/sci/inc/FunctionSciMsg.h"
+#include "maximus/interface/msg/inc/MsgFunctionCall.h"
+#include "maximus/utils/inc/Logger.h"
+#include <netinet/in.h>
+#include <iostream>
+
+FunctionCallProcessor::FunctionCallProcessor (SciServer &ref1,
+ MaximusCallBack &ref2):
+ Processor (ref1, ref2, SCI_MSG_TYPE_FUNCTION_CALL)
+{
+ logFunction ();
+}
+
+FunctionCallProcessor::~FunctionCallProcessor ()
+{
+ logFunction ();
+}
+
+SciMsg *
+FunctionCallProcessor::create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer)
+{
+ logFunction ();
+
+ return new FunctionSciMsg (header, buffer);
+}
+
+void
+FunctionCallProcessor::sendMsg (
+ MsgFunctionCall &user_msg,
+ const CallbackFunction_t cb)
+{
+ logFunction ();
+
+ const std::string &name = user_msg.get_function_name ();
+ const ParametersList &list = user_msg.get_parameter_list ();
+
+ /* 1°) Check. */
+ assert (!name.empty());
+ assert (FUNCTION_CALL_ID_MAX_SIZE > name.size());
+ assert (FUNCTION_CALL_PARAM_MAX_NB >= list.size ());
+
+ /* 2°) Register call back function */
+ std::pair <CallbacksList_t::iterator, bool> result;
+ result = fc_msg_cb_list.insert (
+ std::pair <Function_Call_Msg_Id, CallbackFunction_t> (
+ user_msg.get_tx_msg_id (), cb));
+ assert (result.second);
+
+ /* 3°) Determine the size of payload needed. */
+ size_t alloc_size = name.size () + 1;
+
+ ParametersList::const_iterator it;
+ for (it = list.begin (); it != list.end (); ++it)
+ {
+ alloc_size += (*it)->getName ().size ();
+ alloc_size += (*it)->getValueLength ();
+ alloc_size += 3;
+ }
+
+ /* 4°) Fill the payload. */
+ FunctionSciMsg msg (alloc_size);
+ unsigned char *p_data = msg.get_fc_data_addr ();
+
+ int size = name.size ();
+ memcpy (p_data, name.data (), size);
+ p_data[size] = '\0';
+ p_data += size + 1;
+
+ for (it = list.begin (); it != list.end (); ++it)
+ {
+ /* Name field. */
+ size = (*it)->getName ().size ();
+ memcpy (p_data,
+ (*it)->getName ().data (),
+ size);
+ p_data[size] = '\0';
+ p_data += size + 1;
+
+ /* Length field, in big endian. */
+ uint16_t length = (*it)->getValueLength();
+ p_data[0] = static_cast <unsigned char> (length >> 8);
+ p_data[1] = static_cast <unsigned char> (length);
+ p_data += 2;
+
+ /* Value field. */
+ memcpy (p_data,
+ (*it)->getValue (),
+ length);
+ p_data += length;
+ }
+
+ msg.set_fc_msg_id (user_msg.get_msg_id ());
+ msg.set_fc_param_nb (list.size ());
+ msg.set_sci_stationid (user_msg.get_sta_id ());
+
+ msg.setup_and_send (sci_server);
+}
+
+void
+FunctionCallProcessor::dispatchMsgProc (SciMsg *msg_rx)
+{
+ logFunction ();
+
+ FunctionSciMsg &msg = static_cast <FunctionSciMsg &> (*msg_rx);
+
+ if (FUNCTION_CALL_VERSION == msg.get_fc_version ()
+ && FUNCTION_CALL_TYPE_RSP == msg.get_fc_type ())
+ {
+ CallbacksList_t::iterator fc_msg_cb;
+
+ displayListOfCallbacks();
+ fc_msg_cb = fc_msg_cb_list.find (msg.get_fc_msgid ());
+
+ if (fc_msg_cb != fc_msg_cb_list.end ())
+ {
+ const CallbackFunction_t cb = fc_msg_cb->second;
+
+ /* Unregister call back before call it. */
+ fc_msg_cb_list.erase (fc_msg_cb);
+
+ (cb) (msg);
+ }
+ }
+
+ delete msg_rx;
+}
+
+bool
+FunctionCallProcessor::is_FunctionCall_empty ()
+{
+ return fc_msg_cb_list.empty ();
+}
+
+void
+FunctionCallProcessor::displayListOfCallbacks () const
+{
+#if CONFIG_LOG
+ logFunction();
+
+ maximus_log (LOG_INFO, "list of callbacks = ");
+
+ if (!fc_msg_cb_list.empty ())
+ {
+ for (CallbacksList_t::const_iterator
+ it = fc_msg_cb_list.begin();
+ it != fc_msg_cb_list.end();
+ ++it)
+ {
+ maximus_log (LOG_INFO,
+ " [msg id = 0x"
+ << std::hex << it->first
+ << ", callback address = " << &(it->second) << "]");
+ }
+ }
+ else
+ {
+ maximus_log (LOG_INFO, " empty!");
+ }
+#endif /* CONFIG_LOG */
+}
diff --git a/cesar/maximus/processors/src/PhyProcessor.cpp b/cesar/maximus/processors/src/PhyProcessor.cpp
new file mode 100644
index 0000000000..242de992ec
--- /dev/null
+++ b/cesar/maximus/processors/src/PhyProcessor.cpp
@@ -0,0 +1,762 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/src/PhyProcessor.cpp
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/processors/inc/PhyProcessor.h"
+#include "maximus/interface/inc/Maximus.h"
+#include "maximus/scheduler/inc/Scheduler.h"
+#include "maximus/sci/inc/PhySciMsg.h"
+#include "maximus/interface/msg/inc/MsgMpdu.h"
+#include "maximus/processors/inc/ClockProcessor.h"
+#include "maximus/channel/inc/ChannelComputer.h"
+#include "maximus/utils/inc/Error.h"
+#include "maximus/utils/inc/Logger.h"
+#include "common/std.h"
+#include "hal/phy/maximus/dur/inc/maximus_dur.h"
+#include "hal/phy/maximus/inc/maximus_defs.h"
+#include "mac/common/timings.h"
+#include <netinet/in.h>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/variate_generator.hpp>
+
+PhyProcessor::PhyProcessor (SciServer &ref1,
+ MaximusCallBack &ref2):
+ Processor (ref1, ref2, SCI_MSG_TYPE_PHY),
+ mpChannel (NULL),
+ mIsChannelEnabled (false),
+ mNbOfCarriers (0),
+ mpTonemask (NULL),
+ phy_TxId (0),
+ ZeroCross_interval (0),
+ PhySciMsg_ZeroCross (0),
+ Is_FalseAlarm (false),
+ PhySciMsg_WrongPre (0),
+ FalseAlarm_avg_interval (0),
+ FalseAlarm_deviation (0)
+{
+ logFunction ();
+
+ PhySciMsg_ZeroCross.set_phy_type (PHY_TYPE_ZERO_CROSS);
+ PhySciMsg_ZeroCross.set_phy_flags (PHY_FLAG_CRC_OK);
+ PhySciMsg_ZeroCross.set_sci_stationid (getpid());
+
+ PhySciMsg_WrongPre.set_phy_type (PHY_TYPE_PREAMBLE);
+ PhySciMsg_WrongPre.set_phy_flags (PHY_FLAG_CRC_OK
+ | PHY_FLAG_WRONG_PREAMBLE);
+
+ FalseAlarm_mersenne_twister.seed (time (0));
+}
+
+PhyProcessor::~PhyProcessor ()
+{
+ logFunction ();
+
+ delete [] mpTonemask;
+}
+
+SciMsg *
+PhyProcessor::create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer)
+{
+ logFunction ();
+
+ return new PhySciMsg (header, buffer);
+}
+
+inline void
+PhyProcessor::del_phy_msg (PhySciMsg *msg)
+{
+ static MsgMpdu_list_t::iterator it;
+ MsgMpdu *mpdu = NULL;
+
+ for (it = MsgMpdu_list.begin ();
+ it != MsgMpdu_list.end ();
+ ++it)
+ {
+ if (it->second == msg)
+ {
+ mpdu = it->first;
+ MsgMpdu_list.erase (it);
+ break;
+ }
+ }
+
+ if (msg != &PhySciMsg_ZeroCross && msg != &PhySciMsg_WrongPre)
+ delete msg;
+
+ if (mpdu)
+ {
+ maximus_log (LOG_INFO, "mpdu sent");
+ mpdu->set_is_sent ();
+ }
+}
+
+void
+PhyProcessor::scheduler_drop_event (SciMsg *msg)
+{
+ logFunction ();
+
+ PhySciMsg *phy_msg = static_cast <PhySciMsg *> (msg);
+
+ del_phy_msg (phy_msg);
+}
+
+void
+PhyProcessor::mpdu_schedule (
+ MsgMpdu *mpdu,
+ PhySciMsg *preamble,
+ PhySciMsg *fc,
+ PhySciMsg *payload)
+{
+ logFunction ();
+
+ /* An Mpdu is composed of 3 (or 2) PhySciMsg messages */
+ if (!preamble || !fc || !payload)
+ {
+ Error e (
+ __PRETTY_FUNCTION__,
+ "Null pointer in input of this function", errno);
+ e.display ();
+ return;
+ }
+
+ Network_Clock_Tick current_tick;
+ Network_Clock_Tick tickPre;
+ Network_Clock_Tick tickFc;
+ Network_Clock_Tick tickMpdu;
+
+ current_tick = p_scheduler->get_current_tick ();
+
+ /* Schedule PREAMBLE message. */
+ tickPre = current_tick
+ + MAXIMUS_PHY_PREAMBLE_DETECTION_DELAY_TCK;
+ p_scheduler->add_phy_event (
+ tickPre, 0, 0, preamble);
+
+ /* Schedule FC message. */
+ Phy_Fc_Mode fc_mode = fc->get_phy_FcMode ();
+
+ unsigned int preDuration = MAC_PREAMBLE_TCK;
+ unsigned int fcDuration = MAC_FC_AV_TCK;
+
+ if ((PHY_FC_MODE_HYBRID_2 == fc_mode)
+ || (PHY_FC_MODE_AV_2 == fc_mode))
+ {
+ fcDuration *= 2;
+ }
+ if ((PHY_FC_MODE_HYBRID_1 == fc_mode)
+ || (PHY_FC_MODE_HYBRID_2 == fc_mode))
+ {
+ preDuration = MAC_PREAMBLE_HYBRID_TCK;
+ fcDuration += MAC_FC_10_TCK;
+ }
+ tickFc = current_tick
+ + (preDuration - MAXIMUS_PHY_PREAMBLE_DETECTION_DELAY_TCK)
+ + fcDuration
+ + MAXIMUS_PHY_FC_RECEPTION_DELAY_TCK;
+
+ p_scheduler->add_phy_event (
+ tickFc, 0, 0, fc);
+
+ /* Schedule PAYLOAD message. */
+ if (!payload->get_phy_shortppdu ())
+ {
+ Phy_Mod mod = payload->get_phy_mod ();
+ Phy_Fecrate fecrate = payload->get_phy_FecRate ();
+ Phy_Flags flags = payload->get_phy_flags ();
+ Phy_Nb_Of_Pbs pb_nb = payload->get_phy_NbOfPbs ();
+ Phy_Gil gil = payload->get_phy_gil ();
+
+ /* MPDU delay depends on tonemask, modulation, fecrate,
+ * PB size, number of PBs, guard interval,
+ * number of bits per symbol, and number of symbols. */
+
+ /* Calculate MPDU payload transimission time. */
+ unsigned int bitsPerSymbol = maximus_dur_bits_per_symbol (
+ mod, getTonemask(), NULL, getNbOfCarriers());
+
+ phy_pb_size_t pbSize = (PHY_FLAG_PB512 & flags) ?
+ PHY_PB_SIZE_520 : PHY_PB_SIZE_136;
+
+ unsigned int symbolNb = maximus_dur_symbol_nb (
+ mod, fecrate, pbSize, bitsPerSymbol, pb_nb);
+
+ unsigned int durationInTicks = maximus_dur_data_tck (
+ gil, symbolNb);
+
+ tickMpdu = current_tick
+ + durationInTicks
+ - MAXIMUS_PHY_FC_RECEPTION_DELAY_TCK
+ + MAXIMUS_PHY_MPDU_RECEPTION_DELAY_TCK;
+
+ p_scheduler->add_phy_event (
+ tickMpdu, 0, 1, payload);
+
+ MsgMpdu_list.push_back (
+ std::make_pair (mpdu, payload));
+ }
+ else
+ {
+ del_phy_msg (payload);
+ MsgMpdu_list.push_back (
+ std::make_pair (mpdu, fc));
+ }
+}
+
+void
+PhyProcessor::dispatchMsgProc (SciMsg *msg_rx)
+{
+ logFunction ();
+
+ typedef void (PhyProcessor::*receive_t)(PhySciMsg &);
+
+ static const receive_t fct[PHY_TYPE_NB] = {
+ &PhyProcessor::receiveInvalid,
+ &PhyProcessor::receivePre,
+ &PhyProcessor::receiveFc,
+ &PhyProcessor::receiveFc,
+ &PhyProcessor::receivePrs,
+ &PhyProcessor::receive_payload,
+ &PhyProcessor::receiveTonemask,
+ &PhyProcessor::receiveTonemap,
+ &PhyProcessor::receiveInvalid,
+ &PhyProcessor::receive_rx,
+ &PhyProcessor::receiveInvalid };
+
+ PhySciMsg &msg = static_cast <PhySciMsg &> (*msg_rx);
+ Phy_Type type = msg.get_phy_type ();
+
+ if (msg.check_phy_fields ()
+ && PHY_VERSION == msg.get_phy_version ()
+ && type < PHY_TYPE_NB)
+ {
+ (this->*fct[type]) (msg);
+ }
+
+ del_phy_msg (static_cast <PhySciMsg *> (msg_rx));
+}
+
+void
+PhyProcessor::scheduler_send_event (
+ Sci_Msg_Station_Id clock_staid,
+ Network_Clock_Id clock_id,
+ SciMsg *msg)
+{
+ PhySciMsg *phy_msg = static_cast <PhySciMsg *> (msg);
+ assert (phy_msg);
+
+ Phy_Type phy_type = phy_msg->get_phy_type ();
+ phy_msg->set_sci_stationid (getpid ());
+
+ switch (phy_type)
+ {
+ case PHY_TYPE_NONE:
+ case PHY_TYPE_NB:
+ errno = EINVAL;
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "Phy_type is invalid", errno);
+
+ case PHY_TYPE_PREAMBLE:
+ phy_TxId++;
+ phy_msg->set_phy_TxId (phy_TxId);
+
+ if (phy_msg->get_phy_flags () & PHY_FLAG_WRONG_PREAMBLE)
+ {
+ if (Is_FalseAlarm)
+ {
+ phy_msg->setup_and_send_to_all (sci_server);
+ scheduleNextWrongPre (roll_die_next_interval ());
+ }
+ }
+ else
+ phy_msg->setup_and_send_to_all (sci_server);
+ break;
+
+ case PHY_TYPE_MPDU_PAYLOAD:
+ phy_msg->set_phy_TxId (phy_TxId);
+ send_mpdu_and_noise (*phy_msg);
+ break;
+
+ case PHY_TYPE_ZERO_CROSS:
+ phy_msg->setup_and_send_to_all (sci_server);
+ schedule_next_zero_cross ();
+ break;
+
+ case PHY_TYPE_PRS:
+ case PHY_TYPE_TONEMASK:
+ case PHY_TYPE_TONEMAP:
+ case PHY_TYPE_RX:
+ /* XXX : is it not a bug ? */
+ phy_msg->setup_and_send_to_all (sci_server);
+ break;
+
+ case PHY_TYPE_NOISE:
+ phy_msg->set_phy_flags (PHY_FLAG_CRC_OK);
+ phy_msg->setup_and_send_to_all (sci_server);
+ break;
+
+ case PHY_TYPE_FC_HYBRID_MODE:
+ case PHY_TYPE_FC_AV_ONLY_MODE:
+ phy_msg->set_phy_TxId (phy_TxId);
+ phy_msg->setup_and_send_to_all (sci_server);
+ break;
+ }
+
+ del_phy_msg (phy_msg);
+}
+
+void
+PhyProcessor::receiveInvalid (PhySciMsg &sci)
+{
+ logFunction();
+
+ errno = ENOMSG;
+ throw Error (__PRETTY_FUNCTION__,
+ "receive PHY SCI message of invalid type",
+ errno);
+}
+
+void
+PhyProcessor::receivePre (PhySciMsg &sci)
+{
+ logFunction ();
+
+ if (isChannelEnabled())
+ {
+ getChannel()->receivePre (
+ sci.get_sci_stationid (),
+ p_scheduler->get_current_tick ());
+ }
+
+ sci.setup_and_send_to_all (sci_server);
+}
+
+void
+PhyProcessor::receiveFc (PhySciMsg &sci)
+{
+ logFunction ();
+ const Phy_Type fc_type = sci.get_phy_type ();
+
+ Frame_Control fc;
+ unsigned char * pDataIndex = sci.get_phy_data_addr ();
+
+ if (PHY_TYPE_FC_HYBRID_MODE == fc_type)
+ {
+ memcpy(&fc.fc_10, pDataIndex, sizeof(uint32_t));
+ pDataIndex += sizeof(uint32_t);
+ }
+ else
+ fc.fc_10 = 0;
+
+ memcpy(fc.fc_av, pDataIndex, 4*sizeof(uint32_t));
+
+ Expected_Tx tx;
+ tx.src_tx_id = sci.get_phy_TxId ();
+ tx.src_station_id = sci.get_sci_stationid();
+ rx_fc_list[tx] = fc;
+
+ if (isChannelEnabled())
+ {
+ getChannel()->receiveFc (
+ sci.get_sci_stationid (),
+ p_scheduler->get_current_tick ());
+ }
+
+ sci.setup_and_send_to_all (sci_server);
+}
+
+void
+PhyProcessor::receivePrs (PhySciMsg &sci)
+{
+ logFunction ();
+ sci.setup_and_send_to_all (sci_server);
+}
+
+void
+PhyProcessor::receive_payload (PhySciMsg &sci)
+{
+ logFunction ();
+
+ Expected_Tx tx;
+ tx.src_tx_id = sci.get_phy_TxId ();
+ tx.src_station_id = sci.get_sci_stationid();
+
+ maximus_cb.recv_phy_mpdu_cb (
+ static_cast <unsigned long> (rx_fc_list[tx].fc_10),
+ (unsigned long *) rx_fc_list[tx].fc_av,
+ sci);
+
+ rx_fc_list.erase (tx);
+ send_mpdu_and_noise (sci);
+}
+
+void
+PhyProcessor::receiveTonemask (PhySciMsg &sci)
+{
+ logFunction ();
+
+ /* Check PHY SCI message data length. */
+ if (((sizeof(unsigned int) + (PHY_CARRIER_NB+7)/8) != sci.get_phy_data_size ())
+ || (NULL == sci.get_phy_data_addr ()))
+ {
+ errno = EINVAL;
+ throw Error(__PRETTY_FUNCTION__, "received PHY SCI message TONEMASK is incorrect", errno);
+ }
+
+ /* Set number of active carriers. */
+ unsigned int nbOfCarriers;
+ memcpy(&nbOfCarriers, sci.get_phy_data_addr (), sizeof(unsigned int));
+ setNbOfCarriers(nbOfCarriers);
+
+ setTonemask (sci.get_phy_data_size () - sizeof (unsigned int),
+ sci.get_phy_data_addr () + sizeof (unsigned int));
+
+ if (isChannelEnabled())
+ {
+ getChannel()->setTonemask (getTonemask ());
+ }
+}
+
+void
+PhyProcessor::receiveTonemap (PhySciMsg & sci)
+{
+ logFunction ();
+
+ if (isChannelEnabled ())
+ {
+ getChannel ()->setTonemap (
+ sci.get_sci_stationid (),
+ sci.get_phy_data_size (),
+ sci.get_phy_data_addr ());
+ }
+}
+
+void
+PhyProcessor::receive_rx (PhySciMsg &sci)
+{
+ logFunction ();
+
+ Sci_Msg_Station_Id sta_id_rx = sci.get_sci_stationid ();
+ unsigned char *data = sci.get_phy_data_addr ();
+
+ /* payload is composed with only one field. */
+ /* TODO XXX : improve this reading operation. */
+ Sci_Msg_Station_Id *sta_id_sender =
+ (Sci_Msg_Station_Id *) data;
+
+ std::pair <Phy_Tx_Id, Sci_Msg_Station_Id> key;
+ key.first = sci.get_phy_TxId ();
+ key.second = *sta_id_sender;
+
+ maximus_log (LOG_INFO, "rx_activated_list.insert (<< 0x" << std::hex << key.first
+ << " , 0x" << std::hex << key.second << "> , 0x"
+ << std::hex << sta_id_rx << ">)");
+
+ rx_activated_list.insert (
+ std::pair <std::pair <Phy_Tx_Id, Sci_Msg_Station_Id>,
+ Sci_Msg_Station_Id> (key, sta_id_rx));
+}
+
+void
+PhyProcessor::activateFalseAlarm (
+ const Network_Clock_Tick avg_interval,
+ const float deviation)
+{
+ logFunction ();
+
+ /* Check input values. */
+ if ((0 == avg_interval) || (0 > deviation))
+ {
+ errno = EINVAL;
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "average duration and/or standard \
+ deviation are out-of-range",
+ errno);
+ }
+
+ FalseAlarm_avg_interval = avg_interval;
+ FalseAlarm_deviation = deviation;
+
+ if (Is_FalseAlarm)
+ {
+ Is_FalseAlarm = true;
+ /* Schedules the first PHY SCI message of type
+ * PREAMBLE with the flag PHY_FLAG_WRONG_PREAMBLE set. */
+ scheduleNextWrongPre (
+ MAXIMUS_PHY_PREAMBLE_DETECTION_DELAY_TCK);
+ }
+}
+
+void
+PhyProcessor::deactivateFalseAlarm ()
+{
+ logFunction ();
+
+ Is_FalseAlarm = false;
+}
+
+void
+PhyProcessor::set_zerocross_freq (
+ const float frequency)
+{
+ logFunction ();
+
+ if (frequency)
+ {
+ ZeroCross_interval = 25000000 / (2 * frequency);
+
+ schedule_next_zero_cross ();
+
+ if (isChannelEnabled ())
+ getChannel ()->setBeaconPeriod (frequency);
+ }
+ else
+ ZeroCross_interval = 0;
+}
+
+bool
+PhyProcessor::setChannel (
+ ChannelComputer * p_channel)
+{
+ logFunction ();
+ bool bSetChannel = true;
+
+ if (NULL == p_channel)
+ {
+ errno = EINVAL;
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "Channel pointer is NULL", errno);
+ }
+
+ mpChannel = p_channel;
+ if (NULL != mpTonemask)
+ {
+ bSetChannel = p_channel->setTonemask(getTonemask());
+ }
+
+ return bSetChannel;
+}
+
+ChannelComputer *
+PhyProcessor::getChannel () const
+{
+ if (NULL == mpChannel)
+ {
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "Channel pointer is NULL");
+ }
+
+ return mpChannel;
+}
+
+bool
+PhyProcessor::setIsChannelEnabled (
+ const bool is_channel_enabled)
+{
+ mIsChannelEnabled = is_channel_enabled;
+
+ return true;
+}
+
+bool
+PhyProcessor::isChannelEnabled () const
+{
+ return mIsChannelEnabled;
+}
+
+unsigned int
+PhyProcessor::getNbOfCarriers () const
+{
+ if ((PHY_CARRIER_NB < mNbOfCarriers)
+ || (0 == mNbOfCarriers))
+ {
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "number of carriers has not been correctly set");
+ }
+
+ return mNbOfCarriers;
+}
+
+bool
+PhyProcessor::setNbOfCarriers (
+ const unsigned int nb_of_carriers)
+{
+ if ((PHY_CARRIER_NB < nb_of_carriers)
+ || (0 == nb_of_carriers))
+ {
+ errno = EINVAL;
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "number of carriers is out-of-range", errno);
+ }
+
+ mNbOfCarriers = nb_of_carriers;
+ return true;
+}
+
+const uint8_t *
+PhyProcessor::getTonemask () const
+{
+ if (NULL == mpTonemask)
+ {
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "tonemask pointer is NULL");
+ }
+
+ return mpTonemask;
+}
+
+void
+PhyProcessor::setTonemask (
+ const unsigned int length,
+ const uint8_t * p_tonemask)
+{
+ if (((PHY_CARRIER_NB+7)/8 != length)
+ || (NULL == p_tonemask))
+ {
+ errno = EINVAL;
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "tonemask length is incorrect and/or tonemask pointer is NULL",
+ errno);
+ }
+
+ /* If tonemask has already been set,
+ * delete it before setting the new one. */
+ if (NULL != mpTonemask)
+ {
+ maximus_log (LOG_INFO, "tonemask already set");
+ delete [] mpTonemask;
+ mpTonemask = NULL;
+ }
+
+ /* Allocate memory and set tonemask. */
+ mpTonemask = new uint8_t[length];
+ memcpy (mpTonemask, p_tonemask, length);
+}
+
+void
+PhyProcessor::schedule_next_zero_cross ()
+{
+ logFunction ();
+
+ if (ZeroCross_interval)
+ {
+ Network_Clock_Tick tickZeroCross =
+ p_scheduler->get_current_tick ()
+ + ZeroCross_interval;
+
+ p_scheduler->add_phy_event (
+ tickZeroCross, 0, 0, &PhySciMsg_ZeroCross);
+ }
+}
+
+inline void
+PhyProcessor::send_mpdu_and_noise (PhySciMsg &sci_payload)
+{
+ logFunction();
+
+ size_t noise_size = 0;
+ const Phy_Tx_Id phy_tx_id = sci_payload.get_phy_TxId ();
+ const Sci_Msg_Station_Id sta_id_sender =
+ sci_payload.get_sci_stationid ();
+
+ std::pair <Phy_Tx_Id, Sci_Msg_Station_Id> key;
+ key.first = phy_tx_id;
+ key.second = sta_id_sender;
+
+ /* Nobody want this payload message! */
+ if (rx_activated_list.count (key) == 0)
+ return;
+ maximus_log (LOG_INFO, "rx_activated_list.count (key) = "
+ << rx_activated_list.count (key));
+
+ rx_activated_list_t::iterator it;
+ std::pair <rx_activated_list_t::iterator,
+ rx_activated_list_t::iterator> range;
+ range = rx_activated_list.equal_range (key);
+
+ if (isChannelEnabled ())
+ noise_size = ((PHY_CARRIER_NB + MAC_MAX_SYMB_PER_MPDU)
+ * sizeof (phy_noise_energy_t));
+
+ PhySciMsg sci_noise (noise_size);
+ sci_noise.set_phy_type (PHY_TYPE_NOISE);
+ sci_noise.set_phy_TxId (phy_tx_id);
+ sci_noise.set_phy_flags (PHY_FLAG_CRC_OK);
+
+ for (it=range.first; it!=range.second; ++it)
+ {
+ const Sci_Msg_Station_Id dst_sta_id = it->second;
+
+ if (noise_size != 0)
+ getChannel()->addPerturbation (
+ sci_noise, sci_payload, sta_id_sender, dst_sta_id);
+
+ sci_noise.set_sci_stationid (sta_id_sender);
+
+ sci_payload.setup_and_send (sci_server, dst_sta_id);
+ sci_noise.setup_and_send (sci_server, dst_sta_id);
+ }
+
+ rx_activated_list.erase (key);
+}
+
+Network_Clock_Tick
+PhyProcessor::roll_die_next_interval () const
+{
+ logFunction();
+
+ /**
+ * Link about boost_random documentation.
+ * Website: http://www.boost.org
+ * URL: /doc/libs/1_46_1/doc/html/boost_random/tutorial.html
+ */
+
+ boost::normal_distribution <double> FalseAlarm_distribution (
+ FalseAlarm_avg_interval,
+ FalseAlarm_deviation);
+
+ boost::variate_generator
+ /* Normally boost::mt19937 should be a reference. */
+ <boost::mt19937,
+ boost::normal_distribution <double> > generator (
+ FalseAlarm_mersenne_twister,
+ FalseAlarm_distribution);
+
+ return static_cast <Network_Clock_Tick> (generator ());
+}
+
+bool
+PhyProcessor::scheduleNextWrongPre (
+ const Network_Clock_Tick next_interval)
+{
+ logFunction ();
+
+ /* XXX TODO : is should be getpid () ? */
+ Sci_Msg_Station_Id maximus_sta_id = 0;
+
+ Network_Clock_Tick tick =
+ p_scheduler->get_current_tick ()
+ + next_interval;
+
+ p_scheduler->add_phy_event (
+ tick, maximus_sta_id, 0, &PhySciMsg_WrongPre);
+
+ return true;
+}
diff --git a/cesar/maximus/processors/src/Processor.cpp b/cesar/maximus/processors/src/Processor.cpp
new file mode 100644
index 0000000000..66adf2c8e0
--- /dev/null
+++ b/cesar/maximus/processors/src/Processor.cpp
@@ -0,0 +1,31 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/src/Processor.cpp
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/processors/inc/Processor.h"
+#include "maximus/sci/inc/SciMsg.h"
+#include "maximus/sci/inc/SciServer.h"
+
+Processor::Processor (SciServer &ref1,
+ MaximusCallBack &ref2,
+ Sci_Msg_Type type):
+ processor_type (type),
+ sci_server (ref1),
+ maximus_cb (ref2),
+ p_scheduler (NULL)
+{
+ sci_server.register_processor (type, this);
+}
+
+Processor::~Processor ()
+{
+ sci_server.unregister_processor (processor_type);
+}
diff --git a/cesar/maximus/processors/src/SystemProcessor.cpp b/cesar/maximus/processors/src/SystemProcessor.cpp
new file mode 100644
index 0000000000..806fc33cb8
--- /dev/null
+++ b/cesar/maximus/processors/src/SystemProcessor.cpp
@@ -0,0 +1,123 @@
+/* Maximus project {{{
+ *
+ * Copyright (C) 2012 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus/processors/src/SystemProcessor.cpp
+ * \ingroup maximus_processors
+ *
+ */
+#include "maximus/processors/inc/Processor.h"
+#include "maximus/processors/inc/SystemProcessor.h"
+#include "maximus/interface/station/inc/Station.h"
+#include "maximus/sci/inc/SystemSciMsg.h"
+#include "maximus/utils/inc/Error.h"
+#include "maximus/utils/inc/Logger.h"
+#include <cstring>
+
+SystemProcessor::SystemProcessor (SciServer &ref1,
+ MaximusCallBack &ref2,
+ stations_list_t &ref3):
+ Processor (ref1, ref2, SCI_MSG_TYPE_SYSTEM),
+ sta_list (ref3)
+{
+ logFunction ();
+}
+
+SystemProcessor::~SystemProcessor ( )
+{
+ logFunction ();
+}
+
+SciMsg *
+SystemProcessor::create_sci_msg (
+ struct Sci_Msg_Header &header,
+ unsigned char *buffer)
+{
+ logFunction ();
+
+ return new SystemSciMsg (header, buffer);
+}
+
+void
+SystemProcessor::dispatchMsgProc (SciMsg *msg_rx)
+{
+ logFunction ();
+
+ SystemSciMsg &msg = static_cast <SystemSciMsg &> (*msg_rx);
+
+ if (SYSTEM_VERSION == msg.get_system_version ()
+ && SYSTEM_TYPE_IDLE == msg.get_system_type ())
+ {
+ Station *pStation = findStation (
+ msg.get_sci_stationid ());
+
+ if (pStation)
+ {
+ pStation->decrementStationIdleCounter ();
+
+ if ((0 == pStation->getStationIdleCounter ())
+ && (MAXIMUS_STATION_STATUS_DEACTIVATED
+ != pStation->getStationStatus ()))
+ {
+ pStation->setStationStatus (
+ MAXIMUS_STATION_STATUS_IDLE);
+ }
+ }
+ }
+
+ delete msg_rx;
+}
+
+void
+SystemProcessor::send_name (
+ const Station &sta)
+{
+ logFunction ();
+
+ std::string station_name = sta.get_station_name ();
+ SystemSciMsg msg (station_name.length () + 1);
+ unsigned char *data = msg.get_system_data_addr ();
+ strcpy ((char *)data, station_name.c_str());
+ msg.set_system_type (SYSTEM_TYPE_STATION_NAME);
+ msg.set_sci_stationid (sta.getStationId ());
+ msg.setup_and_send (sci_server);
+}
+
+Station *
+SystemProcessor::findStation (
+ const Sci_Msg_Station_Id station_id) const
+{
+ logFunction ();
+
+ Station *pStation = NULL;
+
+ stations_list_t::const_iterator it;
+ for (it = sta_list.begin ();
+ it != sta_list.end (); ++it)
+ {
+ if (*it
+ && (station_id == (*it)->getStationId ()) )
+ {
+ pStation = *it;
+ break;
+ }
+ }
+
+ if (NULL == pStation)
+ {
+ maximus_log (LOG_FATAL, "station with id "
+ << std::dec << station_id << " (0x"
+ << std::hex << station_id
+ << ") does not exist");;
+ errno = ENONET;
+ throw Error (
+ __PRETTY_FUNCTION__,
+ "station does not exist", errno);
+ }
+
+ return pStation;
+}