summaryrefslogtreecommitdiff
path: root/cesar/maximus/python/src/interface_module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/maximus/python/src/interface_module.cpp')
-rw-r--r--cesar/maximus/python/src/interface_module.cpp745
1 files changed, 745 insertions, 0 deletions
diff --git a/cesar/maximus/python/src/interface_module.cpp b/cesar/maximus/python/src/interface_module.cpp
new file mode 100644
index 0000000000..7890989579
--- /dev/null
+++ b/cesar/maximus/python/src/interface_module.cpp
@@ -0,0 +1,745 @@
+
+#include <boost/python.hpp>
+#include <boost/python/class.hpp>
+#include <boost/python/module.hpp>
+#include <boost/python/call.hpp>
+#include <boost/python/call_method.hpp>
+
+#include <boost/python/return_value_policy.hpp>
+#include <boost/python/copy_non_const_reference.hpp>
+#include <boost/python/return_internal_reference.hpp>
+
+#include <boost/python/detail/api_placeholder.hpp>
+
+#include "maximus/common/interfaces/Maximus.h"
+#include "maximus/common/interfaces/Sta.h"
+#include "maximus/common/interfaces/Msg.h"
+
+#include "ISystem.h"
+#include "IFunctionCall.h"
+#include "PhySciMsgMpdu.h"
+#include "PhySciMsgFc.h"
+#include "EtherSciMsg.h"
+
+#include "Logger.h"
+
+using namespace std;
+using namespace boost::python;
+
+// For unitary tests
+extern bool UNITTEST;
+extern string stationTest;
+
+// For Maximus log
+extern Logger logger;
+
+// To catch signals
+extern Maximus * pMaximus;
+
+// To log Ether SCI messages
+File_Descriptor etherLogFileDescriptor = -1;
+
+typedef std::multimap<Function_Call_Msg_Id, object, compareMsgId> CbsList;
+CbsList listOfCbs;
+
+typedef struct rx_param_phy
+{
+ object create_pb;
+ object cb;
+ bool activated;
+} rx_param_phy_t;
+rx_param_phy_t phy_rx_param;
+
+typedef struct rx_param_ether
+{
+ object create_eth;
+ object create_mme;
+ object create_buffer;
+ object create_sniffer;
+ object cb;
+ bool activated;
+} rx_param__ether_t;
+rx_param__ether_t ether_rx_param;
+
+
+void log_ether ( EtherSciMsg & ether )
+{
+ logFunction();
+
+ if (-1 != etherLogFileDescriptor)
+ {
+ /* Write the Ether SCI message into the Ether log file. */
+ int length = 0;
+ int totalLength = 0;
+ while(totalLength < (int)ether.getSpecializedSciMsgDataLength())
+ {
+ length = write(etherLogFileDescriptor, ether.getSpecializedSciMsgData() + totalLength, ether.getSpecializedSciMsgDataLength() - totalLength);
+ if(length < 0)
+ {
+ if (EAGAIN != errno)
+ {
+ Error e(__PRETTY_FUNCTION__, "write Ether SCI message failed", errno);
+ e.display();
+ throw e;
+ }
+ else
+ {
+ length = 0;
+ }
+ }
+ totalLength += length;
+ }
+ }
+}
+
+
+void set_fcall_cb ( const Msg & msg, object user_cb )
+{
+ listOfCbs.insert(CbsList::value_type(msg.get_tx_msg_id(), user_cb));
+}
+
+
+void remove_fcall_cb ( const Msg & msg )
+{
+ for (CbsList::const_iterator it = listOfCbs.begin(); it != listOfCbs.end(); ++it)
+ {
+ if (msg.get_tx_msg_id() == it->first)
+ {
+ listOfCbs.erase(it->first);
+ break;
+ }
+ }
+}
+
+
+void recv_fcall_cb ( Msg & msg )
+{
+ for (CbsList::const_iterator it = listOfCbs.begin(); it != listOfCbs.end(); ++it)
+ {
+ if (msg.get_rx_msg_id() == it->first)
+ {
+ (it->second)(msg);
+ listOfCbs.erase(it->first);
+ break;
+ }
+ }
+}
+
+
+void recv_phy_mpdu_cb ( PhySciMsgMpdu & mpdu )
+{
+ logFunction();
+
+ if (phy_rx_param.activated)
+ {
+ // Create a new MPDU Python object (PB)
+ object rx_mpdu = phy_rx_param.create_pb();
+
+ // Get PHY SCI message MPDU attributes
+ // and set the MPDU object attributes
+ // (FC 1.0, FC AV and MPDU payload)
+ string payload((char *)mpdu.getSpecializedSciMsgData(), mpdu.getSpecializedSciMsgDataLength());
+ rx_mpdu.attr("set_mpdu_attr")(mpdu.getFc10(),
+ make_tuple(mpdu.getFcAv()[0], mpdu.getFcAv()[1], mpdu.getFcAv()[2], mpdu.getFcAv()[3]),
+ payload);
+
+ // Call the Python reception callback
+ phy_rx_param.activated = !phy_rx_param.cb(rx_mpdu);
+ }
+}
+
+
+void recv_ether_cb ( EtherSciMsg & ether )
+{
+ logFunction();
+
+ // Log the received Ether SCI message
+ log_ether(ether);
+
+ if ( ether_rx_param.activated
+ || (ETHERNET_TYPE_BUFFER_RELEASED == ether.getSpecializedSciMsgType()) )
+ {
+ // Get Ethernet SCI message attributes
+ string payload((char *)ether.getSpecializedSciMsgData(), ether.getSpecializedSciMsgDataLength());
+
+ // Create a new MSDU Python object (Eth, MME, Buffer or Sniffer)
+ object rx_msdu;
+ if (ETHERNET_TYPE_DATA == ether.getSpecializedSciMsgType())
+ {
+ rx_msdu = ether_rx_param.create_eth();
+ }
+ else if (ETHERNET_TYPE_MME == ether.getSpecializedSciMsgType())
+ {
+ rx_msdu = ether_rx_param.create_mme();
+ }
+ else if (ETHERNET_TYPE_BUFFER_RELEASED == ether.getSpecializedSciMsgType())
+ {
+ rx_msdu = ether_rx_param.create_buffer();
+ }
+ else if (ETHERNET_TYPE_SNIFFER == ether.getSpecializedSciMsgType())
+ {
+ /* Read flags. */
+ // way
+ bool way = (ETHERNET_FLAG_WAY == (ether.getFlags() & ETHERNET_FLAG_WAY));
+ // encryption
+ bool encryption = (ETHERNET_FLAG_ENCRYPTED == (ether.getFlags() & ETHERNET_FLAG_ENCRYPTED));
+
+ rx_msdu = ether_rx_param.create_sniffer(way, encryption, ether.getSnifferType());
+ }
+ else
+ {
+ errno = ENOMSG;
+ Error e(__PRETTY_FUNCTION__, "receive an Ether SCI message with a bad type (should be DATA, MME, BUFFER_RELEASED or SNIFFER)", errno);
+ e.display();
+ throw e;
+ }
+
+ if (ETHERNET_TYPE_BUFFER_RELEASED == ether.getSpecializedSciMsgType())
+ {
+ // Reallocate a buffer if requested by user
+ rx_msdu.attr("realloc")(ether.getSciMsgStationId(), payload);
+ }
+
+ // Set the MSDU object attributes (payload)
+ rx_msdu.attr("set_msdu_attr")(payload);
+
+ if (ether_rx_param.activated)
+ {
+ // Call the Python reception callback
+ ether_rx_param.activated = !ether_rx_param.cb(rx_msdu);
+ }
+ }
+}
+
+/*
+void init_wrap ( Maximus & m, const int argc, const string args )
+{
+ size_t previous = 0;
+ size_t found = 0;
+ char * argv[argc];
+ int i = 0;
+
+ do
+ {
+ found = args.find(' ', previous);
+ string temp = args.substr(previous, found-previous);
+ argv[i] = new char[temp.size()+1];
+ strcpy(argv[i], temp.c_str());
+ previous = found+1;
+ i++;
+ }
+ while ((found != string::npos) && (i<argc));
+
+ m.init(argc,argv);
+
+ for (i=0; i<argc; i++)
+ {
+ delete [] argv[i];
+ }
+}
+*/
+
+void init_wrap ( Maximus & m, object args )
+{
+ int argc = len (args);
+ /* std::string.c_str() returns a const, need a temporary storage because
+ * of getopt. */
+ std::vector<char> args_copy[argc];
+ char *argv[argc];
+ /* Make the argv array. */
+ for (int i = 0; i < argc; i++)
+ {
+ const std::string s = extract<std::string> (args[i]);
+ args_copy[i].insert (args_copy[i].end (), s.c_str (),
+ s.c_str () + s.size () + 1);
+ argv[i] = &args_copy[i][0];
+ }
+ /* Call the real function. */
+ m.init (argc, argv);
+
+ phy_rx_param.activated = false;
+ ether_rx_param.activated = false;
+ m.init_phy (&recv_phy_mpdu_cb);
+ etherLogFileDescriptor = m.init_ether (&recv_ether_cb);
+}
+
+
+PyObject * create_sta_wrapx1 ( Maximus & m )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Sta &>::type converter;
+ return converter(m.create_sta());
+}
+
+
+PyObject * create_sta_wrapx2 ( Maximus & m, const string & station_executable )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Sta &>::type converter;
+ return converter(m.create_sta(station_executable));
+}
+
+
+PyObject * create_fcall_wrap ( Maximus & m, const string name )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Msg &>::type converter;
+ return converter(m.create_fc(name));
+}
+
+
+PyObject * create_probe_wrap ( Maximus & m )
+{
+ return_internal_reference<1, Maximus>::result_converter::apply<Msg &>::type converter;
+ return converter(m.create_probe());
+}
+
+
+void send_phy ( Maximus & m, object mpdu )
+{
+ /* Create a PHY SCI message MPDU. */
+ PhySciMsgMpdu * pMpdu = m.create_mpdu();
+
+ /* Extract MPDU object attributes
+ * and set the PHY SCI message MPDU attributes. */
+
+ // Extract and set FC 1.0
+ uint32_t fc_10 = extract<uint32_t>(mpdu.attr("fc_10"));
+ if (0 != fc_10)
+ {
+ pMpdu->setFc10(fc_10);
+ }
+
+ // Extract and set FC AV
+ uint32_t fc_av[4];
+ for (int i=0; i<4; i++)
+ {
+ fc_av[i] = extract<uint32_t>(mpdu.attr("fc_av")[i]);
+ }
+ pMpdu->setFcAv(fc_av);
+
+ // Extract MPDU payload and set MPDU payload length and MPDU payload
+ string payload = extract<string>(mpdu.attr("payload"));
+ pMpdu->setMpdu((unsigned long)payload.length(), (unsigned char *)payload.c_str());
+
+ // Set MPDU format
+ // HomePlug AV specs => delimiter type (DT_AV) is described by bits 0-2 of first fc_av octet:
+ // 000 Beacon
+ // 001 SOF
+ // 010 SACK
+ // 011 RTS/CTS
+ // 100 SOUND
+ // 101 RSOF
+ pMpdu->setMpduFormat((Phy_Mpdu_Format)((fc_av[0] & 0x07) + 1)); // +1 to have the correspondance with our own MPDU format definition (of 'phy_types.h')
+
+ // Extract and set FC mode
+ int fc_mode = extract<int>(mpdu.attr("fc_mode"));
+ if ( PHY_FC_MODE_NONE == (Phy_Fc_Mode)fc_mode )
+ {
+ if (0 == fc_10)
+ {
+ fc_mode = PHY_FC_MODE_AV_1;
+ }
+ else
+ {
+ fc_mode = PHY_FC_MODE_HYBRID_1;
+ }
+ }
+ pMpdu->setFcMode((Phy_Fc_Mode)fc_mode);
+
+ // Extract and set short PPDU
+ pMpdu->setShortPpdu((Phy_Short_Ppdu)extract<int>(mpdu.attr("short_ppdu")));
+
+ // Set default flags
+ pMpdu->setFlags(PHY_FLAG_CRC_OK);
+
+ if (!pMpdu->getShortPpdu())
+ {
+ // Extract and set modulation
+ int mod = extract<int>(mpdu.attr("mod"));
+ if (PHY_MOD_TM == (Phy_Mod)mod)
+ {
+ errno = EINVAL;
+ Error e(__PRETTY_FUNCTION__, "modulation cannot be set to PHY_MOD_TM", errno);
+ e.display();
+ throw e;
+ }
+ else if ((PHY_MOD_NONE == (Phy_Mod)mod) && (MAC_PB136_BYTES >= payload.length()))
+ {
+ mod = PHY_MOD_MINI_ROBO;
+ }
+ else if ((PHY_MOD_NONE == (Phy_Mod)mod) && (MAC_PB136_BYTES < payload.length()))
+ {
+ mod = PHY_MOD_ROBO;
+ }
+ pMpdu->setMod((Phy_Mod)mod);
+
+ // Set default FEC rate
+ pMpdu->setFecrate(PHY_FEC_RATE_1_2);
+
+ if (PHY_MOD_MINI_ROBO == pMpdu->getMod())
+ {
+ // Set default Guard Interval
+ pMpdu->setGil(PHY_GIL_567);
+ // Set default PB size
+ pMpdu->setPbSize(MAC_PB136_BYTES);
+ }
+ else
+ {
+ // Set default Guard Interval
+ pMpdu->setGil(PHY_GIL_417);
+ // Set default PB size
+ pMpdu->setPbSize(MAC_PB520_BYTES);
+ // Set default flags
+ pMpdu->setFlags(PHY_FLAG_CRC_OK+PHY_FLAG_PB512);
+ }
+ }
+
+ // Extract and set PB Header
+ uint32_t pbHeader = extract<uint32_t>(mpdu.attr("first_pb_header"));
+ if (0 != pbHeader)
+ {
+ unsigned short int mfboCounter = 1;
+ unsigned long mfbo = extract<unsigned long>(mpdu.attr("mfbo")[mfboCounter]);
+ for (unsigned short int n=0; n<MAC_MAX_PB_PER_MPDU; n++)
+ {
+ if (0 != n)
+ {
+ while ( (0 != mfbo) && (mfbo < (unsigned long)(n * pMpdu->getPbSize())) )
+ {
+ // increment MFBO counter
+ mfboCounter++;
+ // extract MFBO
+ mfbo = extract<unsigned long>(mpdu.attr("mfbo")[mfboCounter]);
+ }
+
+ // extract MFBO
+ if ( (0 != mfbo) && (mfbo < (unsigned long)((n + 1) * pMpdu->getPbSize())) )
+ {
+ // set MFBF
+ pbHeader |= (1 << 27);
+ // set MFB0
+ pbHeader += ((mfbo % pMpdu->getPbSize()) << 16);
+ }
+ }
+
+ // set PBs Headers
+ pMpdu->setPbsHeaders(n, pbHeader);
+
+ // reset MFBF and MFBO, and increment SSN
+ if (0xFFFF > (pbHeader & 0xFFFF))
+ {
+ pbHeader = (pbHeader & 0xF600FFFF) + 1;
+ }
+ else
+ {
+ pbHeader &= 0xF6000000;
+ }
+ }
+ }
+
+ /* Send the PHY SCI message MPDU. */
+ m.send_mpdu(pMpdu);
+ while (!pMpdu->isSent())
+ {
+ m.process();
+ }
+
+ /* Delete the PHY SCI message MPDU. */
+ if (NULL != pMpdu)
+ {
+ delete (pMpdu);
+ pMpdu = NULL;
+ }
+}
+
+
+void set_phy_rx ( Maximus & m, object user_cb, object create_pb_function )
+{
+ phy_rx_param.cb = user_cb;
+ phy_rx_param.create_pb = create_pb_function;
+ phy_rx_param.activated = true;
+}
+
+
+void send_ether ( Maximus & m, object msdu, int station_id )
+{
+ /* Create an Ether SCI message. */
+ EtherSciMsg * pEther = m.create_ether();
+
+ /* Set the Ether SCI message attributes. */
+
+ // Extract MSDU payload and set Ether SCI message payload length and Ether SCI message payload
+ string payload = extract<string>(msdu.attr("get")());
+ pEther->setSpecializedSciMsgDataLength((unsigned long)payload.length());
+ pEther->setSpecializedSciMsgData((unsigned char *)payload.c_str());
+
+ // Set Ether SCI message type
+ int type = extract<int>(msdu.attr("get_ether_type")());
+ pEther->setSpecializedSciMsgType(static_cast<Ethernet_Type>(type));
+
+ // Set station ID
+ pEther->setSciMsgStationId(static_cast<Sci_Msg_Station_Id>(station_id));
+
+ /* Log the Ether SCI message to send. */
+ log_ether(*pEther);
+
+ /* Send the Ether SCI message. */
+ m.send_ether(*pEther);
+
+ /* Delete the Ether SCI message. */
+ if (NULL != pEther)
+ {
+ delete (pEther);
+ pEther = NULL;
+ }
+}
+
+
+void set_ether_rx ( Maximus & m,
+ object user_cb,
+ object create_eth_function,
+ object create_mme_function,
+ object create_buffer_function,
+ object create_sniffer_function )
+{
+ ether_rx_param.cb = user_cb;
+ ether_rx_param.create_eth = create_eth_function;
+ ether_rx_param.create_mme = create_mme_function;
+ ether_rx_param.create_buffer = create_buffer_function;
+ ether_rx_param.create_sniffer = create_sniffer_function;
+ ether_rx_param.activated = true;
+}
+
+
+PyObject * add_param_bool ( Msg & msg, const string name, const bool value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param<bool>(name, value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_uchar ( Msg & msg, const string name, const unsigned char value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param(name, sizeof(unsigned char), &value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_ushort ( Msg & msg, const string name, const unsigned short int value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param<unsigned short int>(name, value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_ulong ( Msg & msg, const string name, const unsigned long int value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ msg.add_param<unsigned long int>(name, value);
+ return converter(msg);
+}
+
+
+PyObject * add_param_n_u8 ( Msg & msg, const string name, tuple value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ unsigned long length = (unsigned long)len(value);
+ unsigned char param[length];
+ for (unsigned long i=0; i<length; i++)
+ {
+ param[i] = extract<unsigned char>(value[i]);
+ }
+ msg.add_param(name, length*sizeof(unsigned char), param);
+ return converter(msg);
+}
+
+
+PyObject * add_param_n_u16 ( Msg & msg, const string name, tuple value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ unsigned long length = (unsigned long)len(value);
+ unsigned short int param[length];
+ for (unsigned long i=0; i<length; i++)
+ {
+ param[i] = htons(extract<unsigned short int>(value[i]));
+ }
+ msg.add_param(name, length*sizeof(unsigned short int), (unsigned char *)&param);
+ return converter(msg);
+}
+
+
+PyObject * add_param_n_u32 ( Msg & msg, const string name, tuple value )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ unsigned long length = (unsigned long)len(value);
+ unsigned long int param[length];
+ for (unsigned long i=0; i<length; i++)
+ {
+ param[i] = htonl(extract<unsigned long int>(value[i]));
+ }
+ msg.add_param(name, length*sizeof(unsigned long int), (unsigned char *)&param);
+ return converter(msg);
+}
+
+
+PyObject * set_cb_wrap ( Msg & msg, object user_cb )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ remove_fcall_cb(msg);
+ set_fcall_cb(msg, user_cb);
+ msg.set_cb(&recv_fcall_cb);
+ return converter(msg);
+}
+
+
+PyObject * remove_cb_wrap ( Msg & msg )
+{
+ copy_non_const_reference::apply<Msg &>::type converter;
+ remove_fcall_cb(msg);
+ msg.remove_cb();
+ return converter(msg);
+}
+
+
+string bind_param ( Msg & msg, const string name )
+{
+ string str;
+ unsigned long ulLength = FUNCTION_CALL_PARAM_MAX_SIZE;
+ unsigned char ucValue[ulLength];
+ if (NULL != msg.bind_param(name, ulLength, ucValue))
+ {
+ str.assign((char *)ucValue, ulLength);
+ }
+ return str;
+}
+
+
+string bind_param_string ( Msg & msg, const string name )
+{
+ string str(bind_param(msg, name));
+ if ( (0 < str.length()) && ('\0' == str[str.length()-1]) )
+ {
+ str.erase(str.length()-1);
+ }
+ return str;
+}
+
+
+bool bind_param_bool ( Msg & msg, const string name )
+{
+ return msg.bind_param<bool>(name);
+}
+
+
+unsigned short int bind_param_ushort ( Msg & msg, const string name )
+{
+ return msg.bind_param<unsigned short int>(name);
+}
+
+
+unsigned long int bind_param_ulong ( Msg & msg, const string name )
+{
+ return msg.bind_param<unsigned long int>(name);
+}
+
+
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(disturb_channel_overloads, Maximus::disturb_channel, 0, 1)
+
+BOOST_PYTHON_MODULE(interface)
+{
+ /* class Maximus */
+
+ void (Maximus::*waitx1)(const tick_t) = &Maximus::wait;
+ void (Maximus::*waitx2)(void) = &Maximus::wait;
+
+ void (Maximus::*set_snrx1)(const float) = &Maximus::set_snr;
+ void (Maximus::*set_snrx2)(const string &) = &Maximus::set_snr;
+ void (Maximus::*set_snr_from_srcx1)(const float, const Sta &, const bool) = &Maximus::set_snr_from_src;
+ void (Maximus::*set_snr_from_srcx2)(const string &, const Sta &, const bool) = &Maximus::set_snr_from_src;
+ void (Maximus::*set_snr_to_dstx1)(const float, const Sta &, const bool) = &Maximus::set_snr_to_dst;
+ void (Maximus::*set_snr_to_dstx2)(const string &, const Sta &, const bool) = &Maximus::set_snr_to_dst;
+ void (Maximus::*set_snr_from_src_to_dstx1)(const float, const Sta &, const Sta &, const bool) = &Maximus::set_snr_from_src_to_dst;
+ void (Maximus::*set_snr_from_src_to_dstx2)(const string &, const Sta &, const Sta &, const bool) = &Maximus::set_snr_from_src_to_dst;
+
+ class_<Maximus, boost::noncopyable>("Maximus")
+ .def("init", init_wrap)
+ .def("process", &Maximus::process)
+ .def("create_sta", create_sta_wrapx1) // create a station with the default station executable (from command line arguments)
+ .def("create_sta", create_sta_wrapx2) // create a station with an explicit station executable
+ .def("create_fcall", create_fcall_wrap)
+ .def("create_probe", create_probe_wrap)
+ .def("send_mpdu", send_phy)
+ .def("set_mpdu_rx", set_phy_rx)
+ .def("send_msdu", send_ether)
+ .def("set_msdu_rx", set_ether_rx)
+ .def("wait", waitx1)
+ .def("wait", waitx2)
+ .def("disturb_channel", &Maximus::disturb_channel, disturb_channel_overloads())
+ .def("get_date", &Maximus::get_date)
+ .def("set_freq", &Maximus::set_freq)
+ .def("get_freq", &Maximus::get_freq)
+ .def("set_snr", set_snrx1)
+ .def("set_snr", set_snrx2)
+ .def("set_snr_from_src", set_snr_from_srcx1)
+ .def("set_snr_from_src", set_snr_from_srcx2)
+ .def("set_snr_to_dst", set_snr_to_dstx1)
+ .def("set_snr_to_dst", set_snr_to_dstx2)
+ .def("set_snr_from_src_to_dst", set_snr_from_src_to_dstx1)
+ .def("set_snr_from_src_to_dst", set_snr_from_src_to_dstx2)
+ .def("activate_false_alarm", &Maximus::activate_false_alarm)
+ .def("deactivate_false_alarm", &Maximus::deactivate_false_alarm)
+ .def("is_station_idle", &Maximus::is_station_idle)
+ ;
+
+ /* class Sta */
+
+ class_<Sta>("Sta", init< Maximus *, ISystem *, const string & >())
+ .def("remove", &Sta::remove)
+ .def("deactivate", &Sta::deactivate)
+ .def("activate", &Sta::activate)
+ .def("debug", &Sta::debug)
+ .def("is_idle", &Sta::is_idle)
+ .def("get_station_id", &Sta::getStationId)
+ .def("set_name", &Sta::set_name)
+ ;
+
+ /* class Msg */
+
+ Msg & (Msg::*add_paramx1)(const string &) = &Msg::add_param;
+ Msg & (Msg::*add_paramx2)(const string &, const string &) = &Msg::add_param;
+
+ void (Msg::*send_asyncx1)(void) = &Msg::send_async;
+ void (Msg::*send_asyncx2)(Sta &) = &Msg::send_async;
+
+ Msg & (Msg::*sendx1)(void) = &Msg::send;
+ Msg & (Msg::*sendx2)(Sta &) = &Msg::send;
+
+ class_<Msg>("Msg", init< Maximus *, IFunctionCall *, ISystem *, optional<const string &> >())
+ .def("add_param", add_paramx1, return_value_policy<copy_non_const_reference>())
+ .def("add_param", add_paramx2, return_value_policy<copy_non_const_reference>())
+ .def("add_param_bool", add_param_bool)
+ .def("add_param_uchar", add_param_uchar)
+ .def("add_param_ushort", add_param_ushort)
+ .def("add_param_ulong", add_param_ulong)
+ .def("add_param_n_u8", add_param_n_u8)
+ .def("add_param_n_u16", add_param_n_u16)
+ .def("add_param_n_u32", add_param_n_u32)
+ .def("remove_param", &Msg::remove_param, return_value_policy<copy_non_const_reference>())
+ .def("set_cb", set_cb_wrap)
+ .def("remove_cb", remove_cb_wrap)
+ .def("set_sta", &Msg::set_sta, return_value_policy<copy_non_const_reference>())
+ .def("send_async", send_asyncx1)
+ .def("send_async", send_asyncx2)
+ .def("send", sendx1, return_value_policy<copy_non_const_reference>())
+ .def("send", sendx2, return_value_policy<copy_non_const_reference>())
+ .def("is_param", &Msg::is_param)
+ .def("bind_param", bind_param)
+ .def("bind_param_string", bind_param_string)
+ .def("bind_param_bool", bind_param_bool)
+ .def("bind_param_ushort", bind_param_ushort)
+ .def("bind_param_ulong", bind_param_ulong)
+ ;
+
+}
+