...draft...
authorimarom <[email protected]>
Mon, 31 Aug 2015 14:26:08 +0000 (17:26 +0300)
committerimarom <[email protected]>
Mon, 31 Aug 2015 14:26:08 +0000 (17:26 +0300)
src/rpc-server/commands/trex_rpc_cmd_general.cpp
src/rpc-server/commands/trex_rpc_cmd_stream.cpp
src/rpc-server/commands/trex_rpc_cmd_test.cpp
src/rpc-server/commands/trex_rpc_cmds.h
src/rpc-server/trex_rpc_cmd.cpp
src/rpc-server/trex_rpc_cmd_api.h
src/rpc-server/trex_rpc_cmds_table.cpp
src/rpc-server/trex_rpc_jsonrpc_v2_parser.cpp
src/stateless/trex_stream.cpp
src/stateless/trex_stream_api.h

index 484cd2b..6b765ac 100644 (file)
@@ -34,9 +34,6 @@ using namespace std;
 trex_rpc_cmd_rc_e
 TrexRpcCmdGetStatus::_run(const Json::Value &params, Json::Value &result) {
 
-    /* validate count */
-    check_param_count(params, 0, result);
-
     Json::Value &section = result["result"];
 
     #ifndef TREX_RPC_MOCK_SERVER
index fcd91ab..25dee50 100644 (file)
@@ -35,65 +35,148 @@ using namespace std;
 trex_rpc_cmd_rc_e
 TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
 
-    TrexStream *stream;
-
-    check_param_count(params, 1, result);
-
     const Json::Value &section = parse_object(params, "stream", result);
 
     /* get the type of the stream */
     const Json::Value &mode = parse_object(section, "mode", result);
     string type = parse_string(mode, "type", result);
 
+    TrexStream *stream = allocate_new_stream(section, result);
+
+    /* create a new steram and populate it */
+   
+    stream->m_isg_usec  = parse_double(section, "Is", result);
+
+    stream->m_next_stream_id = parse_int(section, "next_stream_id", result);
+    stream->m_loop_count     = parse_int(section, "loop_count", result);
+
+    const Json::Value &pkt = parse_array(section, "packet", result);
+
+    /* fetch the packet from the message */
+
+    stream->m_pkt_len = pkt.size();
+    stream->m_pkt = new uint8_t[pkt.size()];
+    if (!stream->m_pkt) {
+        generate_internal_err(result, "unable to allocate memory");
+    }
+
+    for (int i = 0; i < pkt.size(); i++) {
+        stream->m_pkt[i] = parse_byte(pkt, i, result);
+    }
+
+    /* make sure this is a valid stream to add */
+    validate_stream(stream, result);
+
+    TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(stream->m_port_id);
+    port->get_stream_table()->add_stream(stream);
+
+    result["result"] = "ACK";
+
+    return (TREX_RPC_CMD_OK);
+}
+
+
+
+TrexStream *
+TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, Json::Value &result) {
+
+    uint8_t  port_id    = parse_int(section, "port_id", result);
+    uint32_t stream_id  = parse_int(section, "stream_id", result);
+
+    TrexStream *stream;
+
+    const Json::Value &mode = parse_object(section, "mode", result);
+    std::string type = parse_string(mode, "type", result);
+
     if (type == "continuous") {
-        stream = new TrexStreamContinuous();
+
+        uint32_t pps = parse_int(mode, "pps", result);
+        stream = new TrexStreamContinuous(port_id, stream_id, pps);
+
     } else if (type == "single_burst") {
-        stream = new TrexStreamSingleBurst();
+
+        uint32_t pps = parse_int(mode, "pps", result);
+        uint32_t packets = parse_int(type, "packets", result);
+
+        stream = new TrexStreamSingleBurst(port_id, stream_id, pps, packets);
+
     } else if (type == "multi_burst") {
-        stream = new TrexStreamMultiBurst();
+
+        uint32_t  pps           = parse_int(mode, "pps", result);
+        double    ibg_usec      = parse_double(mode, "ibg", result);
+        uint32_t  num_bursts    = parse_int(mode, "number_of_bursts", result);
+        uint32_t  pkt_per_burst = parse_int(mode, "pkt_per_burst", result);
+
+        stream = new TrexStreamMultiBurst(port_id, stream_id, pps, ibg_usec, num_bursts, pkt_per_burst);
+        
+
     } else {
-        generate_err(result, "bad stream type provided: '" + type + "'");
+        generate_parse_err(result, "bad stream type provided: '" + type + "'");
     }
 
     if (!stream) {
         generate_internal_err(result, "unable to allocate memory");
     }
 
-    /* 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);
+    return (stream);
 
-    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);
+void
+TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, 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"); 
+    /* check packet size */
+    if ( (stream->m_pkt_len < TrexStream::MIN_PKT_SIZE_BYTES) || (stream->m_pkt_len > TrexStream::MAX_PKT_SIZE_BYTES) ) {
+        std::stringstream ss;
+        ss << "bad packet size provided: should be between " << TrexStream::MIN_PKT_SIZE_BYTES << " and " << TrexStream::MAX_PKT_SIZE_BYTES;
+        delete stream;
+        generate_execute_err(result, ss.str()); 
     }
 
-    stream->pkt = new uint8_t[pkt.size()];
-    if (!stream->pkt) {
-        generate_internal_err(result, "unable to allocate memory");
+    /* port id should be between 0 and count - 1 */
+    if (stream->m_port_id >= get_trex_stateless()->get_port_count()) {
+        std::stringstream ss;
+        ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+        delete stream;
+        generate_execute_err(result, ss.str());
     }
 
-    for (int i = 0; i < pkt.size(); i++) {
-        stream->pkt[i] = parse_byte(pkt, i, result);
+     /* add the stream to the port's stream table */
+    TrexStatelessPort * port = get_trex_stateless()->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)) {
+        std::stringstream ss;
+        ss << "stream " << stream->m_stream_id << " already exists";
+        delete stream;
+        generate_execute_err(result, ss.str());
     }
 
-    /* register the stream to the port */
+}
+
+trex_rpc_cmd_rc_e
+TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
+    uint8_t  port_id = parse_byte(params, "port_id", result);
+    uint32_t stream_id = parse_int(params, "stream_id", result);
+
 
-    /* port id should be between 0 and count - 1 */
-    if (stream->port_id >= get_trex_stateless()->get_port_count()) {
+    if (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());
+        ss << "invalid port id - should be between 0 and " << (int)get_trex_stateless()->get_port_count() - 1;
+        generate_execute_err(result, ss.str());
     }
 
-    TrexStatelessPort * port = get_trex_stateless()->get_port_by_id(stream->port_id);
-    port->get_stream_table()->add_stream(stream);
+    TrexStatelessPort *port = get_trex_stateless()->get_port_by_id(port_id);
+    TrexStream *stream  = port->get_stream_table()->get_stream_by_id(stream_id);
 
-    return (TREX_RPC_CMD_OK);
+    if (!stream) {
+        std::stringstream ss;
+        ss << "stream " << stream_id << " does not exists";
+        generate_execute_err(result, ss.str());
+    }
+
+    port->get_stream_table()->remove_stream(stream);
+
+    result["result"] = "ACK";
 }
 
index 473cbb7..382279b 100644 (file)
@@ -35,8 +35,6 @@ TrexRpcCmdTestAdd::_run(const Json::Value &params, Json::Value &result) {
     const Json::Value &x = params["x"];
     const Json::Value &y = params["y"];
     
-    check_param_count(params, 2, result);
-
     result["result"] = parse_int(params, "x", result) + parse_int(params, "y", result);
 
     return (TREX_RPC_CMD_OK);
@@ -53,8 +51,6 @@ TrexRpcCmdTestSub::_run(const Json::Value &params, Json::Value &result) {
     const Json::Value &x = params["x"];
     const Json::Value &y = params["y"];
         
-    check_param_count(params, 2, result);
-
     result["result"] = parse_int(params, "x", result) - parse_int(params, "y", result);
 
     return (TREX_RPC_CMD_OK);
@@ -66,9 +62,6 @@ TrexRpcCmdTestSub::_run(const Json::Value &params, Json::Value &result) {
 trex_rpc_cmd_rc_e 
 TrexRpcCmdPing::_run(const Json::Value &params, Json::Value &result) {
 
-    /* validate count */
-    check_param_count(params, 0, result);
-
     result["result"] = "ACK";
     return (TREX_RPC_CMD_OK);
 }
@@ -80,9 +73,6 @@ trex_rpc_cmd_rc_e
 TrexRpcCmdGetReg::_run(const Json::Value &params, Json::Value &result) {
     vector<string> cmds;
 
-    /* validate count */
-    check_param_count(params, 0, result);
-
     TrexRpcCommandsTable::get_instance().query(cmds);
 
     Json::Value test = Json::arrayValue;
index 5c42585..7ec8aba 100644 (file)
@@ -25,6 +25,8 @@ limitations under the License.
 #include <trex_rpc_cmd_api.h>
 #include <json/json.h>
 
+class TrexStream;
+
 /* all the RPC commands decl. goes here */
 
 /******************* test section ************/
@@ -32,31 +34,43 @@ limitations under the License.
 /**
  * syntactic sugar for creating a simple command
  */
-#define TREX_RPC_CMD_DEFINE(class_name, cmd_name)                                       \
-    class class_name : public TrexRpcCommand {                                          \
-    public:                                                                             \
-        class_name () : TrexRpcCommand(cmd_name) {}                                     \
-    protected:                                                                          \
-        virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result); \
+
+#define TREX_RPC_CMD_DEFINE_EXTENED(class_name, cmd_name, param_count, ext)                               \
+    class class_name : public TrexRpcCommand {                                                            \
+    public:                                                                                               \
+        class_name () : TrexRpcCommand(cmd_name, param_count) {}                                          \
+    protected:                                                                                            \
+        virtual trex_rpc_cmd_rc_e _run(const Json::Value &params, Json::Value &result);                   \
+        ext                                                                                               \
     }
 
+#define TREX_RPC_CMD_DEFINE(class_name, cmd_name, param_count) TREX_RPC_CMD_DEFINE_EXTENED(class_name, cmd_name, param_count, ;)
 
 /**
  * test cmds
  */
-TREX_RPC_CMD_DEFINE(TrexRpcCmdTestAdd,    "test_add");
-TREX_RPC_CMD_DEFINE(TrexRpcCmdTestSub,    "test_sub");
+TREX_RPC_CMD_DEFINE(TrexRpcCmdTestAdd,    "test_add", 2);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdTestSub,    "test_sub", 2);
 
 /**
  * general cmds
  */
-TREX_RPC_CMD_DEFINE(TrexRpcCmdPing,       "ping");
-TREX_RPC_CMD_DEFINE(TrexRpcCmdGetReg,     "get_reg_cmds");
-TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStatus,  "get_status");
+TREX_RPC_CMD_DEFINE(TrexRpcCmdPing,       "ping",            0);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetReg,     "get_reg_cmds",    0);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdGetStatus,  "get_status",      0);
 
 /**
  * stream cmds
  */
-TREX_RPC_CMD_DEFINE(TrexRpcCmdAddStream,  "add_stream");
+TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream,   "remove_stream",   2);
+
+TREX_RPC_CMD_DEFINE_EXTENED(TrexRpcCmdAddStream, "add_stream", 1,
+
+/* extended part */
+TrexStream * allocate_new_stream(const Json::Value &section, Json::Value &result);
+void validate_stream(const TrexStream *stream, Json::Value &result);
+
+);
+
 
 #endif /* __TREX_RPC_CMD_H__ */
index 1ba36e3..6988cba 100644 (file)
@@ -26,6 +26,7 @@ TrexRpcCommand::run(const Json::Value &params, Json::Value &result) {
 
     /* the internal run can throw a parser error / other error */
     try {
+        check_param_count(params, m_param_count, result);
         rc = _run(params, result);
     } catch (TrexRpcCommandException &e) {
         return e.get_rc();
@@ -40,7 +41,7 @@ TrexRpcCommand::check_param_count(const Json::Value &params, int expected, Json:
     if (params.size() != expected) {
         std::stringstream ss;
         ss << "method expects '" << expected << "' paramteres, '" << params.size() << "' provided";
-        generate_err(result, ss.str());
+        generate_parse_err(result, ss.str());
     }
 }
 
@@ -177,7 +178,7 @@ TrexRpcCommand::check_field_type_common(const Json::Value &field, const std::str
     /* first check if field exists */
     if (field == Json::Value::null) {
         ss << "field '" << name << "' is missing";
-        generate_err(result, ss.str());
+        generate_parse_err(result, ss.str());
     }
 
     bool rc = true;
@@ -232,15 +233,15 @@ TrexRpcCommand::check_field_type_common(const Json::Value &field, const std::str
     }
     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());
+        generate_parse_err(result, ss.str());
     }
 
 }
 
 void 
-TrexRpcCommand::generate_err(Json::Value &result, const std::string &msg) {
+TrexRpcCommand::generate_parse_err(Json::Value &result, const std::string &msg) {
     result["specific_err"] = msg;
-    throw (TrexRpcCommandException(TREX_RPC_CMD_PARAM_PARSE_ERR));
+    throw (TrexRpcCommandException(TREX_RPC_CMD_PARSE_ERR));
 }
 
 void 
@@ -249,3 +250,9 @@ TrexRpcCommand::generate_internal_err(Json::Value &result, const std::string &ms
     throw (TrexRpcCommandException(TREX_RPC_CMD_INTERNAL_ERR));
 }
 
+void 
+TrexRpcCommand::generate_execute_err(Json::Value &result, const std::string &msg) {
+    result["specific_err"] = msg;
+    throw (TrexRpcCommandException(TREX_RPC_CMD_EXECUTE_ERR));
+}
+
index 40f839d..da89580 100644 (file)
@@ -32,8 +32,8 @@ limitations under the License.
  */
 typedef enum trex_rpc_cmd_rc_ {
     TREX_RPC_CMD_OK,
-    TREX_RPC_CMD_PARAM_COUNT_ERR = 1,
-    TREX_RPC_CMD_PARAM_PARSE_ERR,
+    TREX_RPC_CMD_PARSE_ERR,
+    TREX_RPC_CMD_EXECUTE_ERR,
     TREX_RPC_CMD_INTERNAL_ERR
 } trex_rpc_cmd_rc_e;
 
@@ -68,7 +68,7 @@ public:
     /**
      * method name and params
      */
-    TrexRpcCommand(const std::string &method_name) : m_name(method_name) {
+    TrexRpcCommand(const std::string &method_name, int param_count) : m_name(method_name), m_param_count(param_count) {
 
     }
 
@@ -142,15 +142,22 @@ protected:
      * error generating functions
      * 
      */
-    void generate_err(Json::Value &result, const std::string &msg);
+    void generate_parse_err(Json::Value &result, const std::string &msg);
 
 
+    /**
+     * method execute error
+     * 
+     */
+    void generate_execute_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
      * 
@@ -164,7 +171,8 @@ protected:
     const char * json_type_to_name(const Json::Value &value);
 
     /* RPC command name */
-    std::string m_name;
+    std::string   m_name;
+    int           m_param_count;
 };
 
 #endif /* __TREX_RPC_CMD_API_H__ */
index ac419bf..e586c3d 100644 (file)
@@ -36,6 +36,7 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() {
 
     /* stream commands */
     register_command(new TrexRpcCmdAddStream());
+    register_command(new TrexRpcCmdRemoveStream());
 }
 
 TrexRpcCommandsTable::~TrexRpcCommandsTable() {
index bf6056d..3831bb3 100644 (file)
@@ -37,7 +37,10 @@ enum {
     JSONRPC_V2_ERR_INVALID_REQ        = -32600,
     JSONRPC_V2_ERR_METHOD_NOT_FOUND   = -32601,
     JSONRPC_V2_ERR_INVALID_PARAMS     = -32602,
-    JSONRPC_V2_ERR_INTERNAL_ERROR     = -32603
+    JSONRPC_V2_ERR_INTERNAL_ERROR     = -32603,
+
+    /* specific server errors */
+    JSONRPC_V2_ERR_EXECUTE_ERROR      = -32000,
 };
 
 
@@ -78,13 +81,18 @@ public:
             response["result"] = result["result"];
             break;
 
-        case TREX_RPC_CMD_PARAM_COUNT_ERR:
-        case TREX_RPC_CMD_PARAM_PARSE_ERR:
+        case TREX_RPC_CMD_PARSE_ERR:
             response["error"]["code"]          = JSONRPC_V2_ERR_INVALID_PARAMS;
             response["error"]["message"]       = "Bad paramters for method";
             response["error"]["specific_err"]  = result["specific_err"];
             break;
 
+        case TREX_RPC_CMD_EXECUTE_ERR:
+            response["error"]["code"]          = JSONRPC_V2_ERR_EXECUTE_ERROR;
+            response["error"]["message"]       = "Failed To Execute Method";
+            response["error"]["specific_err"]  = result["specific_err"];
+            break;
+
         case TREX_RPC_CMD_INTERNAL_ERR:
             response["error"]["code"]          = JSONRPC_V2_ERR_INTERNAL_ERROR;
             response["error"]["message"]       = "Internal Server Error";
index 09d2b66..1a78ab3 100644 (file)
@@ -24,13 +24,25 @@ limitations under the License.
 /**************************************
  * stream
  *************************************/
-TrexStream::TrexStream() {
-    pkt = NULL;
+TrexStream::TrexStream(uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) {
+
+    /* default values */
+    m_isg_usec = 0;
+    m_next_stream_id = -1;
+    m_loop_count = 0;
+    m_enable = false;
+    m_start = false;
+
+    m_pkt = NULL;
+    m_pkt_len = 0;
+
+    m_rx_check.m_enable = false;
+
 }
 
 TrexStream::~TrexStream() {
-    if (pkt) {
-        delete [] pkt;
+    if (m_pkt) {
+        delete [] m_pkt;
     }
 }
 
@@ -48,17 +60,17 @@ TrexStreamTable::~TrexStreamTable() {
 }
 
 void TrexStreamTable::add_stream(TrexStream *stream) {
-    TrexStream *old_stream = get_stream_by_id(stream->stream_id);
+    TrexStream *old_stream = get_stream_by_id(stream->m_stream_id);
     if (old_stream) {
         remove_stream(old_stream);
         delete old_stream;
     }
 
-    m_stream_table[stream->stream_id] = stream;
+    m_stream_table[stream->m_stream_id] = stream;
 }                                           
 
 void TrexStreamTable::remove_stream(TrexStream *stream) {
-    m_stream_table.erase(stream->stream_id);
+    m_stream_table.erase(stream->m_stream_id);
 }
 
 TrexStream * TrexStreamTable::get_stream_by_id(uint32_t stream_id) {
index ab7a8f2..7ae25c6 100644 (file)
@@ -36,38 +36,41 @@ class TrexStream {
     friend class TrexStreamTable;
 
 public:
-    TrexStream();
+    TrexStream(uint8_t port_id, uint32_t stream_id);
     virtual ~TrexStream() = 0;
 
-    static const uint32_t MIN_PKT_SIZE_BYTES = 64;
+    static const uint32_t MIN_PKT_SIZE_BYTES = 1;
     static const uint32_t MAX_PKT_SIZE_BYTES = 9000;
 
 private:
-    /* config */
-    uint32_t      stream_id;
-    uint8_t       port_id;
-    double        isg_usec;
-    uint32_t      next_stream_id;
-    uint32_t      loop_count;
+    /* basic */
+    uint8_t       m_port_id;
+    uint32_t      m_stream_id;
+    
+
+    /* config fields */
+    double        m_isg_usec;
+    uint32_t      m_next_stream_id;
+    uint32_t      m_loop_count;
 
     /* indicators */
-    bool          enable;
-    bool          start;
+    bool          m_enable;
+    bool          m_start;
     
     /* pkt */
-    uint8_t      *pkt;
-    uint16_t      pkt_len;
+    uint8_t      *m_pkt;
+    uint16_t      m_pkt_len;
 
     /* VM */
 
     /* RX check */
     struct {
-        bool      enable;
-        bool      seq_enable;
-        bool      latency;
-        uint32_t  stream_id;
+        bool      m_enable;
+        bool      m_seq_enable;
+        bool      m_latency;
+        uint32_t  m_stream_id;
 
-    } rx_check;
+    } m_rx_check;
 
 };
 
@@ -76,8 +79,11 @@ private:
  * 
  */
 class TrexStreamContinuous : public TrexStream {
+public:
+    TrexStreamContinuous(uint8_t port_id, uint32_t stream_id, uint32_t pps) : TrexStream(port_id, stream_id), m_pps(pps) {
+    }
 protected:
-    uint32_t pps;
+    uint32_t m_pps;
 };
 
 /**
@@ -85,9 +91,13 @@ protected:
  * 
  */
 class TrexStreamSingleBurst : public TrexStream {
+public:
+    TrexStreamSingleBurst(uint8_t port_id, uint32_t stream_id, uint32_t packets, uint32_t pps) : TrexStream(port_id, stream_id), m_pps(pps), m_packets(packets) {
+    }
 protected:
-    uint32_t packets;
-    uint32_t pps;
+    uint32_t m_pps;
+    uint32_t m_packets;
+    
 };
 
 /**
@@ -95,11 +105,20 @@ protected:
  * 
  */
 class TrexStreamMultiBurst : public TrexStream {
+public:
+    TrexStreamMultiBurst(uint8_t port_id,
+                         uint32_t stream_id,
+                         uint32_t pps,
+                         double   ibg_usec,
+                         uint32_t pkts_per_burst,
+                         uint32_t num_bursts) : TrexStream(port_id, stream_id), m_pps(pps), m_ibg_usec(ibg_usec), m_num_bursts(num_bursts), m_pkts_per_burst(pkts_per_burst) {
+
+    }
 protected:
-    uint32_t pps;
-    double   ibg_usec;
-    uint32_t number_of_bursts;
-    uint32_t pkts_per_burst;
+    uint32_t m_pps;
+    double   m_ibg_usec;
+    uint32_t m_num_bursts;
+    uint32_t m_pkts_per_burst;
 };
 
 /**