summaryrefslogtreecommitdiffstats
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
parent67bcc46be09049d2ca65c0af2aa6a2fe0821eb04 (diff)
moved logic to the port class
also implemented the state machine for CP port
-rwxr-xr-xscripts/automation/trex_control_plane/console/trex_console.py3
-rw-r--r--src/gtest/rpc_test.cpp101
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp28
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp160
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h8
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.cpp3
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp143
-rw-r--r--src/stateless/cp/trex_stateless_port.h128
8 files changed, 468 insertions, 106 deletions
diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py
index a2c738ab..68050fc0 100755
--- a/scripts/automation/trex_control_plane/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/console/trex_console.py
@@ -778,6 +778,9 @@ class TRexConsole(cmd.Cmd):
return
else:
port_list = self.stateless_client.get_active_ports()
+ if not port_list:
+ print magenta("no active ports - operation aborted\n")
+ return
else:
port_list = self.extract_port_ids_from_line(line)
diff --git a/src/gtest/rpc_test.cpp b/src/gtest/rpc_test.cpp
index 6b8e3eff..34bb02a8 100644
--- a/src/gtest/rpc_test.cpp
+++ b/src/gtest/rpc_test.cpp
@@ -478,6 +478,7 @@ TEST_F(RpcTestOwned, add_remove_stream) {
create_request(request, "get_stream", 1, 1);
request["params"]["stream_id"] = 5;
+ request["params"]["get_pkt"] = true;
send_request(request, response);
@@ -501,6 +502,7 @@ TEST_F(RpcTestOwned, add_remove_stream) {
create_request(request, "get_stream", 1, 1);
request["params"]["stream_id"] = 5;
+ request["params"]["get_pkt"] = true;
send_request(request, response);
@@ -607,17 +609,21 @@ TEST_F(RpcTestOwned, start_stop_traffic) {
/* start port 1 */
create_request(request, "start_traffic", 1, 1);
+ request["params"]["mul"] = 1.0;
send_request(request, response);
+
EXPECT_EQ(response["result"], "ACK");
/* start port 3 */
create_request(request, "start_traffic", 1, 3);
+ request["params"]["mul"] = 1.0;
send_request(request, response);
EXPECT_EQ(response["result"], "ACK");
/* start not configured port */
create_request(request, "start_traffic", 1, 2);
+ request["params"]["mul"] = 1.0;
send_request(request, response);
EXPECT_EQ(response["error"]["code"], -32000);
@@ -633,11 +639,13 @@ TEST_F(RpcTestOwned, start_stop_traffic) {
/* start 1 again */
create_request(request, "start_traffic", 1, 1);
+ request["params"]["mul"] = 1.0;
send_request(request, response);
EXPECT_EQ(response["result"], "ACK");
/* start 1 twice (error) */
create_request(request, "start_traffic", 1, 1);
+ request["params"]["mul"] = 1.0;
send_request(request, response);
EXPECT_EQ(response["error"]["code"], -32000);
@@ -657,3 +665,96 @@ TEST_F(RpcTestOwned, start_stop_traffic) {
EXPECT_EQ(response["result"], "ACK");
}
+
+
+TEST_F(RpcTestOwned, states_check) {
+ Json::Value request;
+ Json::Value response;
+
+ /* add stream #1 */
+ create_request(request, "add_stream", 1, 1);
+ request["params"]["stream_id"] = 5;
+
+ Json::Value stream;
+ create_simple_stream(stream);
+
+ request["params"]["stream"] = stream;
+
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* start traffic */
+ create_request(request, "start_traffic", 1, 1);
+ request["params"]["mul"] = 1.0;
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* now we cannot add streams */
+ create_request(request, "add_stream", 1, 1);
+ request["params"]["stream_id"] = 15;
+
+ create_simple_stream(stream);
+
+ request["params"]["stream"] = stream;
+
+ send_request(request, response);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+ /* we cannot remove streams */
+ create_request(request, "remove_stream", 1, 1);
+ request["params"]["stream_id"] = 15;
+ send_request(request, response);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+ /* cannot start again */
+ create_request(request, "start_traffic", 1, 1);
+ request["params"]["mul"] = 1.0;
+ send_request(request, response);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+ /* we can stop and add stream / remove */
+
+ create_request(request, "stop_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ create_request(request, "add_stream", 1, 1);
+ request["params"]["stream_id"] = 328;
+
+ create_simple_stream(stream);
+
+ request["params"]["stream"] = stream;
+
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+
+ create_request(request, "remove_stream", 1, 1);
+ request["params"]["stream_id"] = 15;
+ send_request(request, response);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+ /* we cannot pause now */
+ create_request(request, "pause_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["error"]["code"], -32000);
+
+
+ /* start */
+ create_request(request, "start_traffic", 1, 1);
+ request["params"]["mul"] = 1.0;
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* now can pause */
+ create_request(request, "pause_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+ /* also we can resume*/
+ create_request(request, "resume_traffic", 1, 1);
+ send_request(request, response);
+ EXPECT_EQ(response["result"], "ACK");
+
+
+}
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index b40e996f..b6d06cfc 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -222,12 +222,12 @@ TrexRpcCmdAcquire::_run(const Json::Value &params, Json::Value &result) {
/* if not free and not you and not force - fail */
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- if ( (!port->is_free_to_aquire()) && (port->get_owner() != new_owner) && (!force)) {
- generate_execute_err(result, "port is already taken by '" + port->get_owner() + "'");
+ try {
+ port->acquire(new_owner, force);
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
}
- port->set_owner(new_owner);
-
result["result"] = port->get_owner_handler();
return (TREX_RPC_CMD_OK);
@@ -244,12 +244,12 @@ TrexRpcCmdRelease::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- if (port->get_state() == TrexStatelessPort::PORT_STATE_TRANSMITTING) {
- generate_execute_err(result, "cannot release a port during transmission");
+ try {
+ port->release();
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
}
- port->clear_owner();
-
result["result"] = "ACK";
return (TREX_RPC_CMD_OK);
@@ -266,13 +266,13 @@ TrexRpcCmdGetPortStats::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- if (port->get_state() == TrexStatelessPort::PORT_STATE_DOWN) {
- generate_execute_err(result, "cannot get stats - port is down");
- }
-
result["result"]["status"] = port->get_state_as_string();
- port->encode_stats(result["result"]);
+ try {
+ port->encode_stats(result["result"]);
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
return (TREX_RPC_CMD_OK);
}
@@ -303,7 +303,7 @@ TrexRpcCmdSyncUser::_run(const Json::Value &params, Json::Value &result) {
owned_port["streams"] = Json::arrayValue;
std::vector <TrexStream *> streams;
- port->get_stream_table()->get_object_list(streams);
+ port->get_object_list(streams);
for (auto stream : streams) {
owned_port["streams"].append(stream->get_stream_json());
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index 4fa0956d..fffc800a 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -115,7 +115,12 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
validate_stream(stream, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
- port->get_stream_table()->add_stream(stream);
+
+ try {
+ port->add_stream(stream);
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
result["result"] = "ACK";
@@ -293,7 +298,7 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu
TrexStatelessPort * port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
/* does such a stream exists ? */
- if (port->get_stream_table()->get_stream_by_id(stream->m_stream_id)) {
+ if (port->get_stream_by_id(stream->m_stream_id)) {
std::stringstream ss;
ss << "stream " << stream->m_stream_id << " already exists";
delete stream;
@@ -319,7 +324,7 @@ TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
}
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- TrexStream *stream = port->get_stream_table()->get_stream_by_id(stream_id);
+ TrexStream *stream = port->get_stream_by_id(stream_id);
if (!stream) {
std::stringstream ss;
@@ -327,7 +332,12 @@ TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
generate_execute_err(result, ss.str());
}
- port->get_stream_table()->remove_stream(stream);
+ try {
+ port->remove_stream(stream);
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
+
delete stream;
result["result"] = "ACK";
@@ -350,12 +360,18 @@ TrexRpcCmdRemoveAllStreams::_run(const Json::Value &params, Json::Value &result)
generate_execute_err(result, ss.str());
}
- TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- port->get_stream_table()->remove_and_delete_all_streams();
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- result["result"] = "ACK";
+ try {
+ port->remove_and_delete_all_streams();
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
- return (TREX_RPC_CMD_OK);
+
+ result["result"] = "ACK";
+
+ return (TREX_RPC_CMD_OK);
}
/***************************
@@ -377,7 +393,7 @@ TrexRpcCmdGetStreamList::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- port->get_stream_table()->get_id_list(stream_list);
+ port->get_id_list(stream_list);
Json::Value json_list = Json::arrayValue;
@@ -409,7 +425,7 @@ TrexRpcCmdGetStream::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- TrexStream *stream = port->get_stream_table()->get_stream_by_id(stream_id);
+ TrexStream *stream = port->get_stream_by_id(stream_id);
if (!stream) {
std::stringstream ss;
@@ -447,32 +463,19 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- TrexStatelessPort::rc_e rc = port->start_traffic(mul);
-
- if (rc == TrexStatelessPort::RC_OK) {
- result["result"] = "ACK";
- } else {
- std::stringstream ss;
- switch (rc) {
- case TrexStatelessPort::RC_ERR_BAD_STATE_FOR_OP:
- ss << "bad state for operations: port is either transmitting traffic or down";
- break;
- case TrexStatelessPort::RC_ERR_NO_STREAMS:
- ss << "no active streams on that port";
- break;
- default:
- ss << "failed to start traffic";
- break;
- }
-
- generate_execute_err(result, ss.str());
+ try {
+ port->start_traffic(mul);
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
}
- return (TREX_RPC_CMD_OK);
+ result["result"] = "ACK";
+
+ return (TREX_RPC_CMD_OK);
}
/***************************
- * start traffic on port
+ * stop traffic on port
*
**************************/
trex_rpc_cmd_rc_e
@@ -487,7 +490,12 @@ TrexRpcCmdStopTraffic::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- port->stop_traffic();
+ try {
+ port->stop_traffic();
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
+
result["result"] = "ACK";
return (TREX_RPC_CMD_OK);
@@ -511,7 +519,7 @@ TrexRpcCmdGetAllStreams::_run(const Json::Value &params, Json::Value &result) {
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
std::vector <TrexStream *> streams;
- port->get_stream_table()->get_object_list(streams);
+ port->get_object_list(streams);
Json::Value streams_json = Json::objectValue;
for (auto stream : streams) {
@@ -533,3 +541,89 @@ TrexRpcCmdGetAllStreams::_run(const Json::Value &params, Json::Value &result) {
return (TREX_RPC_CMD_OK);
}
+
+/***************************
+ * pause traffic
+ *
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdPauseTraffic::_run(const Json::Value &params, Json::Value &result) {
+
+ uint8_t port_id = parse_byte(params, "port_id", result);
+
+ if (port_id >= get_stateless_obj()->get_port_count()) {
+ std::stringstream ss;
+ ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
+ generate_execute_err(result, ss.str());
+ }
+
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+
+ try {
+ port->pause_traffic();
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
+
+ result["result"] = "ACK";
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/***************************
+ * resume traffic
+ *
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdResumeTraffic::_run(const Json::Value &params, Json::Value &result) {
+
+ uint8_t port_id = parse_byte(params, "port_id", result);
+
+ if (port_id >= get_stateless_obj()->get_port_count()) {
+ std::stringstream ss;
+ ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
+ generate_execute_err(result, ss.str());
+ }
+
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+
+ try {
+ port->resume_traffic();
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
+
+ result["result"] = "ACK";
+
+ return (TREX_RPC_CMD_OK);
+}
+
+/***************************
+ * update traffic
+ *
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdUpdateTraffic::_run(const Json::Value &params, Json::Value &result) {
+
+ uint8_t port_id = parse_byte(params, "port_id", result);
+ double mul = parse_double(params, "mul", result);
+
+ if (port_id >= get_stateless_obj()->get_port_count()) {
+ std::stringstream ss;
+ ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
+ generate_execute_err(result, ss.str());
+ }
+
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+
+ try {
+ port->update_traffic(mul);
+ } catch (const TrexRpcException &ex) {
+ generate_execute_err(result, ex.what());
+ }
+
+ result["result"] = "ACK";
+
+ return (TREX_RPC_CMD_OK);
+}
+
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index a604d9a1..8b173cb9 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -105,8 +105,12 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStream, "get_stream", 3, true);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 2, true);
-TREX_RPC_CMD_DEFINE(TrexRpcCmdStopTraffic, "stop_traffic", 1, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdStartTraffic, "start_traffic", 2, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdStopTraffic, "stop_traffic", 1, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdPauseTraffic, "pause_traffic", 1, true);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdResumeTraffic, "resume_traffic", 1, true);
+
+TREX_RPC_CMD_DEFINE(TrexRpcCmdUpdateTraffic, "update_traffic", 1, true);
TREX_RPC_CMD_DEFINE(TrexRpcCmdSyncUser, "sync_user", 2, false);
diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp
index e3bd7848..f38b4df4 100644
--- a/src/rpc-server/trex_rpc_cmds_table.cpp
+++ b/src/rpc-server/trex_rpc_cmds_table.cpp
@@ -51,8 +51,11 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() {
register_command(new TrexRpcCmdGetStreamList());
register_command(new TrexRpcCmdGetStream());
register_command(new TrexRpcCmdGetAllStreams());
+
register_command(new TrexRpcCmdStartTraffic());
register_command(new TrexRpcCmdStopTraffic());
+ register_command(new TrexRpcCmdPauseTraffic());
+ register_command(new TrexRpcCmdResumeTraffic());
}
TrexRpcCommandsTable::~TrexRpcCommandsTable() {
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();