diff options
author | imarom <imarom@cisco.com> | 2015-08-31 13:42:03 +0300 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2015-08-31 13:42:03 +0300 |
commit | 499b4d6221c023d656663fe441bbf5d194886efb (patch) | |
tree | 971c0738a56adfd9d39790b843ef1d1a83b88229 /src/rpc-server | |
parent | c9381643e7bf9b3dc690bf3e012ad6176ee32b8c (diff) |
SOOO DRAFT....
Diffstat (limited to 'src/rpc-server')
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_general.cpp | 17 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 160 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_test.cpp | 10 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_cmd.cpp | 115 | ||||
-rw-r--r-- | src/rpc-server/trex_rpc_cmd_api.h | 33 |
5 files changed, 210 insertions, 125 deletions
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index ac35babf..484cd2b9 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -19,9 +19,12 @@ See the License for the specific language governing permissions and limitations under the License. */ #include "trex_rpc_cmds.h" -#include <../linux_dpdk/version.h> #include <trex_rpc_server_api.h> +#ifndef TREX_RPC_MOCK_SERVER + #include <../linux_dpdk/version.h> +#endif + using namespace std; /** @@ -36,12 +39,24 @@ TrexRpcCmdGetStatus::_run(const Json::Value ¶ms, Json::Value &result) { Json::Value §ion = result["result"]; + #ifndef TREX_RPC_MOCK_SERVER + section["general"]["version"] = VERSION_BUILD_NUM; section["general"]["build_date"] = get_build_date(); section["general"]["build_time"] = get_build_time(); section["general"]["version_user"] = VERSION_USER; section["general"]["uptime"] = TrexRpcServer::get_server_uptime(); + #else + + section["general"]["version"] = "v0.0"; + section["general"]["build_date"] = __DATE__; + section["general"]["build_time"] = __TIME__; + section["general"]["version_user"] = "MOCK"; + section["general"]["uptime"] = TrexRpcServer::get_server_uptime(); + + #endif + return (TREX_RPC_CMD_OK); } diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 58226a6b..fcd91ab7 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -21,134 +21,78 @@ limitations under the License. #include "trex_rpc_cmds.h" #include <../linux_dpdk/version.h> #include <trex_rpc_server_api.h> +#include <trex_stream_api.h> +#include <trex_stateless_api.h> -using namespace std; +#include <iostream> -/** - * Stateless stream mode - * abstract class - */ -class TrexStreamMode { -public: - enum mode_e { - CONTINUOUS, - SINGLE_BURST, - MULTI_BURST - }; - - virtual mode_e get_runtime_type() = 0; - virtual ~TrexStreamMode() {} -}; +using namespace std; /** - * stream mode continuous + * add new stream * - * @author imarom (30-Aug-15) */ -class TrexStreamModeContinuous : public TrexStreamMode { -public: - mode_e get_runtime_type() { - return (CONTINUOUS); - } -private: - uint32_t pps; -}; +trex_rpc_cmd_rc_e +TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { -/** - * single burst mode - * - */ -class TrexStreamModeSingleBurst : public TrexStreamMode { -public: - mode_e get_runtime_type() { - return (SINGLE_BURST); - } -private: + TrexStream *stream; - uint32_t packets; - uint32_t pps; -}; + check_param_count(params, 1, result); + + const Json::Value §ion = parse_object(params, "stream", result); -class TrexStreamModeMultiBurst : public TrexStreamMode { -public: + /* get the type of the stream */ + const Json::Value &mode = parse_object(section, "mode", result); + string type = parse_string(mode, "type", result); + + if (type == "continuous") { + stream = new TrexStreamContinuous(); + } else if (type == "single_burst") { + stream = new TrexStreamSingleBurst(); + } else if (type == "multi_burst") { + stream = new TrexStreamMultiBurst(); + } else { + generate_err(result, "bad stream type provided: '" + type + "'"); + } - mode_e get_runtime_type() { - return (MULTI_BURST); + if (!stream) { + generate_internal_err(result, "unable to allocate memory"); } -private: + /* create a new steram and populate it */ + stream->stream_id = parse_int(section, "stream_id", result); + stream->port_id = parse_int(section, "port_id", result); + stream->isg_usec = parse_double(section, "Is", result); - uint32_t pps; - double ibg_usec; - uint32_t number_of_bursts; - uint32_t pkts_per_burst; -}; + stream->next_stream_id = parse_int(section, "next_stream_id", result); + stream->loop_count = parse_int(section, "loop_count", result); + const Json::Value &pkt = parse_array(section, "packet", result); -/** - * Stateless Stream - * - */ -class TrexStatelessStream { - friend class TrexRpcCmdAddStream; - -public: - -private: - /* config */ - uint32_t stream_id; - uint8_t port_id; - double isg_usec; - uint32_t next_stream_id; - uint32_t loop_count; - - /* indicators */ - bool enable; - bool start; - - /* pkt */ - uint8_t *pkt; - uint16_t pkt_len; - - /* stream mode */ - TrexStreamMode *mode; - - /* VM */ - - /* RX check */ - struct { - bool enable; - bool seq_enable; - bool latency; - uint32_t stream_id; - - } rx_check; - -}; -/** - * add new stream - * - */ -trex_rpc_cmd_rc_e -TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { + if ( (pkt.size() < TrexStream::MIN_PKT_SIZE_BYTES) || (pkt.size() > TrexStream::MAX_PKT_SIZE_BYTES) ) { + generate_err(result, "bad packet size provided: should be between 64B and 9K"); + } - TrexStatelessStream stream; + stream->pkt = new uint8_t[pkt.size()]; + if (!stream->pkt) { + generate_internal_err(result, "unable to allocate memory"); + } - check_param_count(params, 1, result); - check_field_type(params, "stream", FIELD_TYPE_OBJ, result); + for (int i = 0; i < pkt.size(); i++) { + stream->pkt[i] = parse_byte(pkt, i, result); + } - Json::Value §ion = result["stream"]; - - /* create a new steram and populate it */ - - check_field_type(section, "stream_id", FIELD_TYPE_INT, result); - stream.stream_id = section["stream_id"].asInt(); + /* register the stream to the port */ - check_field_type(section, "port_id", FIELD_TYPE_INT, result); - stream.port_id = section["port_id"].asInt(); + /* port id should be between 0 and count - 1 */ + if (stream->port_id >= get_trex_stateless()->get_port_count()) { + std::stringstream ss; + ss << "invalid port id - should be between 0 and " << get_trex_stateless()->get_port_count(); + generate_err(result, ss.str()); + } - check_field_type(section, "Is", FIELD_TYPE_DOUBLE, result); - stream.isg_usec = section["Is"].asDouble(); + TrexStatelessPort * port = get_trex_stateless()->get_port_by_id(stream->port_id); + port->get_stream_table()->add_stream(stream); return (TREX_RPC_CMD_OK); } diff --git a/src/rpc-server/commands/trex_rpc_cmd_test.cpp b/src/rpc-server/commands/trex_rpc_cmd_test.cpp index e67de286..473cbb70 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_test.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_test.cpp @@ -36,10 +36,9 @@ TrexRpcCmdTestAdd::_run(const Json::Value ¶ms, Json::Value &result) { const Json::Value &y = params["y"]; check_param_count(params, 2, result); - check_field_type(params, "x", FIELD_TYPE_INT, result); - check_field_type(params, "y", FIELD_TYPE_INT, result); - result["result"] = x.asInt() + y.asInt(); + result["result"] = parse_int(params, "x", result) + parse_int(params, "y", result); + return (TREX_RPC_CMD_OK); } @@ -55,10 +54,9 @@ TrexRpcCmdTestSub::_run(const Json::Value ¶ms, Json::Value &result) { const Json::Value &y = params["y"]; check_param_count(params, 2, result); - check_field_type(params, "x", TrexRpcCommand::FIELD_TYPE_INT, result); - check_field_type(params, "y", TrexRpcCommand::FIELD_TYPE_INT, result); - result["result"] = x.asInt() - y.asInt(); + result["result"] = parse_int(params, "x", result) - parse_int(params, "y", result); + return (TREX_RPC_CMD_OK); } diff --git a/src/rpc-server/trex_rpc_cmd.cpp b/src/rpc-server/trex_rpc_cmd.cpp index 1ad94fb5..1ba36e32 100644 --- a/src/rpc-server/trex_rpc_cmd.cpp +++ b/src/rpc-server/trex_rpc_cmd.cpp @@ -41,13 +41,14 @@ TrexRpcCommand::check_param_count(const Json::Value ¶ms, int expected, Json: std::stringstream ss; ss << "method expects '" << expected << "' paramteres, '" << params.size() << "' provided"; generate_err(result, ss.str()); - throw TrexRpcCommandException(TREX_RPC_CMD_PARAM_COUNT_ERR); } } const char * TrexRpcCommand::type_to_str(field_type_e type) { switch (type) { + case FIELD_TYPE_BYTE: + return "byte"; case FIELD_TYPE_BOOL: return "bool"; case FIELD_TYPE_INT: @@ -58,7 +59,7 @@ TrexRpcCommand::type_to_str(field_type_e type) { return "object"; case FIELD_TYPE_STR: return "string"; - case FILED_TYPE_ARRAY: + case FIELD_TYPE_ARRAY: return "array"; default: @@ -72,6 +73,8 @@ TrexRpcCommand::json_type_to_name(const Json::Value &value) { switch(value.type()) { case Json::nullValue: return "null"; + case Json::intValue: + return "int"; case Json::uintValue: return "uint"; case Json::realValue: @@ -90,23 +93,102 @@ TrexRpcCommand::json_type_to_name(const Json::Value &value) { } } + +uint8_t +TrexRpcCommand::parse_byte(const Json::Value &parent, const std::string &name, Json::Value &result) { + check_field_type(parent, name, FIELD_TYPE_BYTE, result); + return parent[name].asUInt(); +} + +uint8_t +TrexRpcCommand::parse_byte(const Json::Value &parent, int index, Json::Value &result) { + check_field_type(parent, index, FIELD_TYPE_BYTE, result); + return parent[index].asUInt(); +} + +int +TrexRpcCommand::parse_int(const Json::Value &parent, const std::string &name, Json::Value &result) { + check_field_type(parent, name, FIELD_TYPE_INT, result); + return parent[name].asInt(); +} + +bool +TrexRpcCommand::parse_bool(const Json::Value &parent, const std::string &name, Json::Value &result) { + check_field_type(parent, name, FIELD_TYPE_BOOL, result); + return parent[name].asBool(); +} + +double +TrexRpcCommand::parse_double(const Json::Value &parent, const std::string &name, Json::Value &result) { + check_field_type(parent, name, FIELD_TYPE_DOUBLE, result); + return parent[name].asDouble(); +} + +const std::string +TrexRpcCommand::parse_string(const Json::Value &parent, const std::string &name, Json::Value &result) { + check_field_type(parent, name, FIELD_TYPE_STR, result); + return parent[name].asString(); +} + +const Json::Value & +TrexRpcCommand::parse_object(const Json::Value &parent, const std::string &name, Json::Value &result) { + check_field_type(parent, name, FIELD_TYPE_OBJ, result); + return parent[name]; +} + +const Json::Value & +TrexRpcCommand::parse_array(const Json::Value &parent, const std::string &name, Json::Value &result) { + check_field_type(parent, name, FIELD_TYPE_ARRAY, result); + return parent[name]; +} + +/** + * for index element (array) + */ void -TrexRpcCommand::check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result) { +TrexRpcCommand::check_field_type(const Json::Value &parent, int index, field_type_e type, Json::Value &result) { + + /* should never get here without parent being array */ + if (!parent.isArray()) { + throw TrexRpcException("internal parsing error"); + } + + const Json::Value &field = parent[index]; + std::stringstream ss; + ss << "array element: " << (index + 1) << " "; + check_field_type_common(field, ss.str(), type, result); +} + +void +TrexRpcCommand::check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result) { + /* should never get here without parent being object */ + if (!parent.isObject()) { + throw TrexRpcException("internal parsing error"); + } - /* check if field exists , does not add the field because its const */ const Json::Value &field = parent[name]; + check_field_type_common(field, name, type, result); +} +void +TrexRpcCommand::check_field_type_common(const Json::Value &field, const std::string &name, field_type_e type, Json::Value &result) { + std::stringstream ss; /* first check if field exists */ if (field == Json::Value::null) { - ss << "field '" << name << "' missing"; + ss << "field '" << name << "' is missing"; generate_err(result, ss.str()); - throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR)); } bool rc = true; switch (type) { + case FIELD_TYPE_BYTE: + if ( (!field.isUInt()) || (field.asInt() > 0xFF)) { + rc = false; + } + break; + case FIELD_TYPE_BOOL: if (!field.isBool()) { rc = false; @@ -136,12 +218,21 @@ TrexRpcCommand::check_field_type(const Json::Value &parent, const std::string &n rc = false; } break; - } + case FIELD_TYPE_ARRAY: + if (!field.isArray()) { + rc = false; + } + break; + + default: + throw TrexRpcException("unhandled type"); + break; + + } if (!rc) { ss << "error at offset: " << field.getOffsetStart() << " - '" << name << "' is '" << json_type_to_name(field) << "', expecting '" << type_to_str(type) << "'"; generate_err(result, ss.str()); - throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR)); } } @@ -149,4 +240,12 @@ TrexRpcCommand::check_field_type(const Json::Value &parent, const std::string &n void TrexRpcCommand::generate_err(Json::Value &result, const std::string &msg) { result["specific_err"] = msg; + throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR)); +} + +void +TrexRpcCommand::generate_internal_err(Json::Value &result, const std::string &msg) { + result["specific_err"] = msg; + throw (TrexRpcCommandException(TREX_RPC_CMD_INTERNAL_ERR)); } + diff --git a/src/rpc-server/trex_rpc_cmd_api.h b/src/rpc-server/trex_rpc_cmd_api.h index 34e6ba0a..40f839df 100644 --- a/src/rpc-server/trex_rpc_cmd_api.h +++ b/src/rpc-server/trex_rpc_cmd_api.h @@ -90,12 +90,13 @@ protected: * different types of fields */ enum field_type_e { + FIELD_TYPE_BYTE, FIELD_TYPE_INT, FIELD_TYPE_DOUBLE, FIELD_TYPE_BOOL, FIELD_TYPE_STR, FIELD_TYPE_OBJ, - FILED_TYPE_ARRAY + FIELD_TYPE_ARRAY }; /** @@ -110,11 +111,32 @@ protected: void check_param_count(const Json::Value ¶ms, int expected, Json::Value &result); /** + * parse functions + * + */ + uint8_t parse_byte(const Json::Value &parent, const std::string &name, Json::Value &result); + int parse_int(const Json::Value &parent, const std::string &name, Json::Value &result); + double parse_double(const Json::Value &parent, const std::string &name, Json::Value &result); + bool parse_bool(const Json::Value &parent, const std::string &name, Json::Value &result); + const std::string parse_string(const Json::Value &parent, const std::string &name, Json::Value &result); + const Json::Value & parse_object(const Json::Value &parent, const std::string &name, Json::Value &result); + const Json::Value & parse_array(const Json::Value &parent, const std::string &name, Json::Value &result); + + uint8_t parse_byte(const Json::Value &parent, int index, Json::Value &result); + int parse_int(const Json::Value &parent, int index, Json::Value &result); + double parse_double(const Json::Value &parent, int index, Json::Value &result); + bool parse_bool(const Json::Value &parent, int index, Json::Value &result); + const std::string parse_string(const Json::Value &parent, int index, Json::Value &result); + const Json::Value & parse_object(const Json::Value &parent, int index, Json::Value &result); + const Json::Value & parse_array(const Json::Value &parent, int index, Json::Value &result); + + /** * check field type * */ - //void check_field_type(const Json::Value &field, field_type_e type, Json::Value &result); void check_field_type(const Json::Value &parent, const std::string &name, field_type_e type, Json::Value &result); + void check_field_type(const Json::Value &parent, int index, field_type_e type, Json::Value &result); + void check_field_type_common(const Json::Value &field, const std::string &name, field_type_e type, Json::Value &result); /** * error generating functions @@ -122,6 +144,13 @@ protected: */ void generate_err(Json::Value &result, const std::string &msg); + + /** + * internal error + * + */ + void generate_internal_err(Json::Value &result, const std::string &msg); + /** * translate enum to string * |