diff options
Diffstat (limited to 'src/vpp-api/vom/hw.hpp')
-rw-r--r-- | src/vpp-api/vom/hw.hpp | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/src/vpp-api/vom/hw.hpp b/src/vpp-api/vom/hw.hpp new file mode 100644 index 00000000000..00ab2d647f1 --- /dev/null +++ b/src/vpp-api/vom/hw.hpp @@ -0,0 +1,408 @@ +/* + * 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 <sstream> +#include <string> +#include <thread> + +#include <vapi/vapi.hpp> +#include <vapi/vpe.api.vapi.hpp> + +#include "vom/connection.hpp" +#include "vom/rpc_cmd.hpp" + +namespace VOM { +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_rc(rc_t::UNSET) + { + } + + /** + * Constructor + */ + item(rc_t rc) + : item_rc(rc) + { + } + + /** + * Constructor + */ + item(const T& data, rc_t rc) + : item_data(data) + , item_rc(rc) + { + } + + /** + * 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); + + /** + * dequeue a command from the Q. + */ + virtual void dequeue(cmd* c); + + /** + * dequeue a command from the Q. + */ + virtual void dequeue(std::shared_ptr<cmd> c); + + /** + * Write all the commands to HW + */ + virtual rc_t write(); + + /** + * Blocking Connect to VPP - call once at bootup + */ + void connect(); + + /** + * 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); + + /** + * dequeue A command for execution + */ + static void dequeue(cmd* f); + + /** + * dequeue A command for execution + */ + static void dequeue(std::shared_ptr<cmd> c); + + /** + * Write/Execute all commands hitherto enqueued. + */ + static rc_t write(); + + /** + * Blocking Connect to VPP + */ + static void connect(); + + /** + * 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; + + /** + * A command pool the HW for liveness + */ + class Poll : public rpc_cmd<HW::item<bool>, rc_t, vapi::Control_ping> + { + public: + /** + * Constructor taking the HW::item to update + */ + Poll(HW::item<bool>& item); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Comparison operator - only used for UT + */ + bool operator==(const Poll& i) const; + }; +}; + +/** + * 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 |