summaryrefslogtreecommitdiffstats
path: root/src/stateless/cp
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2015-11-09 17:10:24 +0200
committerimarom <imarom@cisco.com>2015-11-09 17:10:24 +0200
commit9c32c36b6006d2a81e1a5658a1fb1616eff650f3 (patch)
tree6c768596aedd26eea82ec22cb61a04da7d8a3304 /src/stateless/cp
parent67bcc46be09049d2ca65c0af2aa6a2fe0821eb04 (diff)
moved logic to the port class
also implemented the state machine for CP port
Diffstat (limited to 'src/stateless/cp')
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp143
-rw-r--r--src/stateless/cp/trex_stateless_port.h128
2 files changed, 214 insertions, 57 deletions
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index cb6fcc0e..b9206775 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -53,29 +53,47 @@ using namespace std;
*
**************************/
TrexStatelessPort::TrexStatelessPort(uint8_t port_id) : m_port_id(port_id) {
- m_port_state = PORT_STATE_UP_IDLE;
+ m_port_state = PORT_STATE_IDLE;
clear_owner();
}
/**
+ * acquire the port
+ *
+ * @author imarom (09-Nov-15)
+ *
+ * @param user
+ * @param force
+ */
+void
+TrexStatelessPort::acquire(const std::string &user, bool force) {
+ if ( (!is_free_to_aquire()) && (get_owner() != user) && (!force)) {
+ throw TrexRpcException("port is already taken by '" + get_owner() + "'");
+ }
+
+ set_owner(user);
+}
+
+void
+TrexStatelessPort::release(void) {
+ verify_state( ~(PORT_STATE_TX | PORT_STATE_PAUSE) );
+ clear_owner();
+}
+
+/**
* starts the traffic on the port
*
*/
-TrexStatelessPort::rc_e
+void
TrexStatelessPort::start_traffic(double mul) {
- if (m_port_state != PORT_STATE_UP_IDLE) {
- return (RC_ERR_BAD_STATE_FOR_OP);
- }
-
- if (get_stream_table()->size() == 0) {
- return (RC_ERR_NO_STREAMS);
- }
+ /* command allowed only on state stream */
+ verify_state(PORT_STATE_STREAMS);
/* fetch all the streams from the table */
vector<TrexStream *> streams;
- get_stream_table()->get_object_list(streams);
+ get_object_list(streams);
/* compiler it */
TrexStreamsCompiler compiler;
@@ -83,7 +101,7 @@ TrexStatelessPort::start_traffic(double mul) {
bool rc = compiler.compile(streams, *compiled_obj);
if (!rc) {
- return (RC_ERR_FAILED_TO_COMPILE_STREAMS);
+ throw TrexRpcException("Failed to compile streams");
}
/* generate a message to all the relevant DP cores to start transmitting */
@@ -91,51 +109,94 @@ TrexStatelessPort::start_traffic(double mul) {
send_message_to_dp(start_msg);
- /* move the state to transmiting */
- m_port_state = PORT_STATE_TRANSMITTING;
-
- return (RC_OK);
+ change_state(PORT_STATE_TX);
}
-TrexStatelessPort::rc_e
+/**
+ * stop traffic on port
+ *
+ * @author imarom (09-Nov-15)
+ *
+ * @return TrexStatelessPort::rc_e
+ */
+void
TrexStatelessPort::stop_traffic(void) {
- /* real code goes here */
- if (m_port_state != PORT_STATE_TRANSMITTING) {
- return (RC_ERR_BAD_STATE_FOR_OP);
- }
+ verify_state(PORT_STATE_TX);
/* generate a message to all the relevant DP cores to start transmitting */
TrexStatelessCpToDpMsgBase *stop_msg = new TrexStatelessDpStop(m_port_id);
send_message_to_dp(stop_msg);
- m_port_state = PORT_STATE_UP_IDLE;
+ change_state(PORT_STATE_STREAMS);
+}
+
+void
+TrexStatelessPort::pause_traffic(void) {
+
+ verify_state(PORT_STATE_TX);
+
+ #if 0
+ /* generate a message to all the relevant DP cores to start transmitting */
+ TrexStatelessCpToDpMsgBase *stop_msg = new TrexStatelessDpStop(m_port_id);
- return (RC_OK);
+ send_message_to_dp(stop_msg);
+
+ m_port_state = PORT_STATE_UP_IDLE;
+ #endif
+ change_state(PORT_STATE_PAUSE);
}
-/**
-* access the stream table
-*
-*/
-TrexStreamTable * TrexStatelessPort::get_stream_table() {
- return &m_stream_table;
+void
+TrexStatelessPort::resume_traffic(void) {
+
+ verify_state(PORT_STATE_PAUSE);
+
+ #if 0
+ /* generate a message to all the relevant DP cores to start transmitting */
+ TrexStatelessCpToDpMsgBase *stop_msg = new TrexStatelessDpStop(m_port_id);
+
+ send_message_to_dp(stop_msg);
+
+ m_port_state = PORT_STATE_UP_IDLE;
+ #endif
+ change_state(PORT_STATE_TX);
}
+void
+TrexStatelessPort::update_traffic(double mul) {
+
+ verify_state(PORT_STATE_STREAMS | PORT_STATE_TX | PORT_STATE_PAUSE);
+
+ #if 0
+ /* generate a message to all the relevant DP cores to start transmitting */
+ TrexStatelessCpToDpMsgBase *stop_msg = new TrexStatelessDpStop(m_port_id);
+
+ send_message_to_dp(stop_msg);
+
+ m_port_state = PORT_STATE_UP_IDLE;
+ #endif
+}
std::string
-TrexStatelessPort::get_state_as_string() {
+TrexStatelessPort::get_state_as_string() const {
switch (get_state()) {
case PORT_STATE_DOWN:
return "down";
- case PORT_STATE_UP_IDLE:
- return "idle";
+ case PORT_STATE_IDLE:
+ return "no streams";
+
+ case PORT_STATE_STREAMS:
+ return "with streams, idle";
- case PORT_STATE_TRANSMITTING:
+ case PORT_STATE_TX:
return "transmitting";
+
+ case PORT_STATE_PAUSE:
+ return "paused";
}
return "unknown";
@@ -149,6 +210,24 @@ TrexStatelessPort::get_properties(string &driver, string &speed) {
speed = "1 Gbps";
}
+bool
+TrexStatelessPort::verify_state(int state, bool should_throw) const {
+ if ( (state & m_port_state) == 0 ) {
+ if (should_throw) {
+ throw TrexRpcException("command cannot be executed on current state: '" + get_state_as_string() + "'");
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+TrexStatelessPort::change_state(port_state_e new_state) {
+
+ m_port_state = new_state;
+}
/**
* generate a random connection handler
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index 09183768..90bf936e 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -37,9 +37,11 @@ public:
* port state
*/
enum port_state_e {
- PORT_STATE_DOWN,
- PORT_STATE_UP_IDLE,
- PORT_STATE_TRANSMITTING
+ PORT_STATE_DOWN = 0x1,
+ PORT_STATE_IDLE = 0x2,
+ PORT_STATE_STREAMS = 0x4,
+ PORT_STATE_TX = 0x8,
+ PORT_STATE_PAUSE = 0x10,
};
/**
@@ -53,30 +55,54 @@ public:
};
TrexStatelessPort(uint8_t port_id);
+
+ /**
+ * acquire port
+ * throws TrexException in case of an error
+ */
+ void acquire(const std::string &user, bool force = false);
+
+ /**
+ * release the port from the current user
+ * throws TrexException in case of an error
+ */
+ void release(void);
/**
* start traffic
- *
+ * throws TrexException in case of an error
*/
- rc_e start_traffic(double mul);
+ void start_traffic(double mul);
/**
* stop traffic
- *
+ * throws TrexException in case of an error
+ */
+ void stop_traffic(void);
+
+ /**
+ * pause traffic
+ * throws TrexException in case of an error
*/
- rc_e stop_traffic(void);
+ void pause_traffic(void);
/**
- * access the stream table
+ * resume traffic
+ * throws TrexException in case of an error
+ */
+ void resume_traffic(void);
+
+ /**
+ * update current traffic on port
*
*/
- TrexStreamTable *get_stream_table();
+ void update_traffic(double mul);
/**
* get the port state
*
*/
- port_state_e get_state() {
+ port_state_e get_state() const {
return m_port_state;
}
@@ -84,7 +110,7 @@ public:
* port state as string
*
*/
- std::string get_state_as_string();
+ std::string get_state_as_string() const;
/**
* fill up properties of the port
@@ -96,6 +122,7 @@ public:
*/
void get_properties(std::string &driver, std::string &speed);
+
/**
* query for ownership
*
@@ -113,11 +140,70 @@ public:
return m_owner_handler;
}
- bool is_free_to_aquire() {
- return (m_owner == "none");
+
+ bool verify_owner_handler(const std::string &handler) {
+
+ return ( (m_owner != "none") && (m_owner_handler == handler) );
+
}
/**
+ * encode stats as JSON
+ */
+ void encode_stats(Json::Value &port);
+
+ uint8_t get_port_id() {
+ return m_port_id;
+ }
+
+ /**
+ * delegators
+ *
+ */
+
+ void add_stream(TrexStream *stream) {
+ verify_state(PORT_STATE_IDLE | PORT_STATE_STREAMS);
+
+ m_stream_table.add_stream(stream);
+
+ change_state(PORT_STATE_STREAMS);
+ }
+
+ void remove_stream(TrexStream *stream) {
+ verify_state(PORT_STATE_STREAMS);
+
+ m_stream_table.remove_stream(stream);
+
+ if (m_stream_table.size() == 0) {
+ change_state(PORT_STATE_IDLE);
+ }
+ }
+
+ void remove_and_delete_all_streams() {
+ verify_state(PORT_STATE_IDLE | PORT_STATE_STREAMS);
+
+ m_stream_table.remove_and_delete_all_streams();
+
+ change_state(PORT_STATE_IDLE);
+ }
+
+ TrexStream * get_stream_by_id(uint32_t stream_id) {
+ return m_stream_table.get_stream_by_id(stream_id);
+ }
+
+ void get_id_list(std::vector<uint32_t> &id_list) {
+ m_stream_table.get_id_list(id_list);
+ }
+
+ void get_object_list(std::vector<TrexStream *> &object_list) {
+ m_stream_table.get_object_list(object_list);
+ }
+
+private:
+
+
+
+ /**
* take ownership of the server array
* this is static
* ownership is total
@@ -133,22 +219,14 @@ public:
m_owner_handler = "";
}
- bool verify_owner_handler(const std::string &handler) {
-
- return ( (m_owner != "none") && (m_owner_handler == handler) );
-
+ bool is_free_to_aquire() {
+ return (m_owner == "none");
}
- /**
- * encode stats as JSON
- */
- void encode_stats(Json::Value &port);
- uint8_t get_port_id() {
- return m_port_id;
- }
+ bool verify_state(int state, bool should_throw = true) const;
-private:
+ void change_state(port_state_e new_state);
std::string generate_handler();