summaryrefslogtreecommitdiffstats
path: root/extras/vom/vom/hw.hpp
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2018-04-25 19:11:15 +0200
committerNeale Ranns <nranns@cisco.com>2018-04-27 11:35:07 +0000
commit164e5f8c63652028ecb9c3570e1ea8618b163071 (patch)
tree7423f5abbc61b761df9a679c7974f17613736020 /extras/vom/vom/hw.hpp
parentaa682a39b76ee043f65313f23e134bf18fe7a47e (diff)
Move VOM to extras/vom
Change-Id: Iea174f03dfba3bd06024db0f0cc373532300dcae Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'extras/vom/vom/hw.hpp')
-rw-r--r--extras/vom/vom/hw.hpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/extras/vom/vom/hw.hpp b/extras/vom/vom/hw.hpp
new file mode 100644
index 00000000000..9ba47505619
--- /dev/null
+++ b/extras/vom/vom/hw.hpp
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VOM_HW_H__
+#define __VOM_HW_H__
+
+#include <deque>
+#include <map>
+#include <queue>
+#include <sstream>
+#include <string>
+#include <thread>
+
+#include "vom/cmd.hpp"
+#include "vom/connection.hpp"
+#include "vom/types.hpp"
+
+namespace VOM {
+
+class cmd;
+class HW
+{
+public:
+ /**
+ * A HW::item is data that is either to be written to or read from
+ * VPP/HW.
+ * The item is a pair of the data written/read and the result of that
+ * operation.
+ */
+ template <typename T>
+ class item
+ {
+ public:
+ /**
+ * Constructor
+ */
+ item(const T& data)
+ : item_data(data)
+ , item_rc(rc_t::NOOP)
+ {
+ }
+ /**
+ * Constructor
+ */
+ item()
+ : item_data()
+ , item_rc(rc_t::UNSET)
+ {
+ }
+
+ /**
+ * Constructor
+ */
+ item(rc_t rc)
+ : item_data()
+ , item_rc(rc)
+ {
+ }
+
+ /**
+ * Constructor
+ */
+ item(const T& data, rc_t rc)
+ : item_data(data)
+ , item_rc(rc)
+ {
+ }
+
+ /**
+ * Destructor
+ */
+ ~item() = default;
+
+ /**
+ * Comparison operator
+ */
+ bool operator==(const item<T>& i) const
+ {
+ return (item_data == i.item_data);
+ }
+
+ /**
+ * Copy assignment
+ */
+ item& operator=(const item& other)
+ {
+ item_data = other.item_data;
+ item_rc = other.item_rc;
+
+ return (*this);
+ }
+
+ /**
+ * Return the data read/written
+ */
+ T& data() { return (item_data); }
+
+ /**
+ * Const reference to the data
+ */
+ const T& data() const { return (item_data); }
+
+ /**
+ * Get the HW return code
+ */
+ rc_t rc() const { return (item_rc); }
+
+ /**
+ * Set the HW return code - should only be called from the
+ * family of Command objects
+ */
+ void set(const rc_t& rc) { item_rc = rc; }
+
+ /**
+ * Return true if the HW item is configred in HW
+ */
+ operator bool() const { return (rc_t::OK == item_rc); }
+
+ /**
+ * update the item to the desired state.
+ * return true if a HW update is required
+ */
+ bool update(const item& desired)
+ {
+ bool need_hw_update = false;
+
+ /*
+ * if the deisred set is unset (i.e. defaulted, we've
+ * no update to make
+ */
+ if (rc_t::UNSET == desired.rc()) {
+ return (false);
+ }
+ /*
+ * A HW update is needed if thestate is different
+ * or the state is not yet in HW
+ */
+ need_hw_update = (item_data != desired.data() || rc_t::OK != rc());
+
+ item_data = desired.data();
+
+ return (need_hw_update);
+ }
+
+ /**
+ * convert to string format for debug purposes
+ */
+ std::string to_string() const
+ {
+ std::ostringstream os;
+
+ os << "hw-item:["
+ << "rc:" << item_rc.to_string() << " data:" << item_data.to_string()
+ << "]";
+
+ return (os.str());
+ }
+
+ private:
+ /**
+ * The data
+ */
+ T item_data;
+
+ /**
+ * The result when the item was written
+ */
+ rc_t item_rc;
+ };
+
+ /**
+ * The pipe to VPP into which we write the commands
+ */
+ class cmd_q
+ {
+ public:
+ /**
+ * Constructor
+ */
+ cmd_q();
+ /**
+ * Destructor
+ */
+ ~cmd_q();
+
+ /**
+ * Copy assignement - only used in UT
+ */
+ cmd_q& operator=(const cmd_q& f);
+
+ /**
+ * Enqueue a command into the Q.
+ */
+ virtual void enqueue(cmd* c);
+ /**
+ * Enqueue a command into the Q.
+ */
+ virtual void enqueue(std::shared_ptr<cmd> c);
+
+ /**
+ * Enqueue a set of commands
+ */
+ virtual void enqueue(std::queue<cmd*>& c);
+
+ /**
+ * Write all the commands to HW
+ */
+ virtual rc_t write();
+
+ /**
+ * Blocking Connect to VPP - call once at bootup
+ */
+ virtual bool connect();
+
+ /**
+ * Disconnect to VPP
+ */
+ virtual void disconnect();
+
+ /**
+ * Disable the passing of commands to VPP. Whilst disabled all
+ * writes will be discarded. Use this during the reset phase.
+ */
+ void disable();
+
+ /**
+ * Enable the passing of commands to VPP - undoes the disable.
+ * The Q is enabled by default.
+ */
+ void enable();
+
+ private:
+ /**
+ * A queue of enqueued commands, ready to be written
+ */
+ std::deque<std::shared_ptr<cmd>> m_queue;
+
+ /**
+ * A map of issued, but uncompleted, commands.
+ * i.e. those that we are waiting, async stylee,
+ * for VPP to complete
+ */
+ std::map<cmd*, std::shared_ptr<cmd>> m_pending;
+
+ /**
+ * VPP Q poll function
+ */
+ void rx_run();
+
+ /**
+ * The thread object running the poll/dispatch/connect thread
+ */
+ std::unique_ptr<std::thread> m_rx_thread;
+
+ /**
+ * A flag indicating the client has disabled the cmd Q.
+ */
+ bool m_enabled;
+
+ /**
+ * A flag for the thread to poll to see if the queue is still alive
+ */
+ bool m_connected;
+
+ /**
+ * The connection to VPP
+ */
+ connection m_conn;
+ };
+
+ /**
+ * Initialise the HW connection to VPP - the UT version passing
+ * a mock Q.
+ */
+ static void init(cmd_q* f);
+
+ /**
+ * Initialise the HW
+ */
+ static void init();
+
+ /**
+ * Enqueue A command for execution
+ */
+ static void enqueue(cmd* f);
+
+ /**
+ * Enqueue A command for execution
+ */
+ static void enqueue(std::shared_ptr<cmd> c);
+
+ /**
+ * Enqueue A set of commands for execution
+ */
+ static void enqueue(std::queue<cmd*>& c);
+
+ /**
+ * Write/Execute all commands hitherto enqueued.
+ */
+ static rc_t write();
+
+ /**
+ * Blocking Connect to VPP
+ */
+ static bool connect();
+
+ /**
+ * Disconnect to VPP
+ */
+ static void disconnect();
+
+ /**
+ * Blocking pool of the HW connection
+ */
+ static bool poll();
+
+private:
+ /**
+ * The command Q toward HW
+ */
+ static cmd_q* m_cmdQ;
+
+ /**
+ * HW::item representing the connection state as determined by polling
+ */
+ static HW::item<bool> m_poll_state;
+
+ /**
+ * Disable the passing of commands to VPP. Whilst disabled all writes
+ * will be discarded. Use this during the reset phase.
+ */
+ static void disable();
+
+ /**
+ * Enable the passing of commands to VPP - undoes the disable.
+ * The Q is enabled by default.
+ */
+ static void enable();
+
+ /**
+ * Only the OM can enable/disable HW
+ */
+ friend class OM;
+};
+
+/**
+ * bool Specialisation for HW::item to_string
+ */
+template <>
+std::string HW::item<bool>::to_string() const;
+
+/**
+ * uint Specialisation for HW::item to_string
+ */
+template <>
+std::string HW::item<unsigned int>::to_string() const;
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
+
+#endif