VOM fixes and logger improvements
[vpp.git] / src / vpp-api / vom / hw.hpp
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef __VOM_HW_H__
17 #define __VOM_HW_H__
18
19 #include <deque>
20 #include <map>
21 #include <sstream>
22 #include <string>
23 #include <thread>
24
25 #include "vom/connection.hpp"
26 #include "vom/types.hpp"
27
28 namespace VOM {
29
30 class cmd;
31 class HW
32 {
33 public:
34   /**
35    * A HW::item is data that is either to be written to or read from
36    * VPP/HW.
37    * The item is a pair of the data written/read and the result of that
38    * operation.
39    */
40   template <typename T>
41   class item
42   {
43   public:
44     /**
45      * Constructor
46      */
47     item(const T& data)
48       : item_data(data)
49       , item_rc(rc_t::NOOP)
50     {
51     }
52     /**
53      * Constructor
54      */
55     item()
56       : item_data()
57       , item_rc(rc_t::UNSET)
58     {
59     }
60
61     /**
62      * Constructor
63      */
64     item(rc_t rc)
65       : item_data()
66       , item_rc(rc)
67     {
68     }
69
70     /**
71      * Constructor
72      */
73     item(const T& data, rc_t rc)
74       : item_data(data)
75       , item_rc(rc)
76     {
77     }
78
79     /**
80      * Destructor
81      */
82     ~item() = default;
83
84     /**
85      * Comparison operator
86      */
87     bool operator==(const item<T>& i) const
88     {
89       return (item_data == i.item_data);
90     }
91
92     /**
93      * Copy assignment
94      */
95     item& operator=(const item& other)
96     {
97       item_data = other.item_data;
98       item_rc = other.item_rc;
99
100       return (*this);
101     }
102
103     /**
104      * Return the data read/written
105      */
106     T& data() { return (item_data); }
107
108     /**
109      * Const reference to the data
110      */
111     const T& data() const { return (item_data); }
112
113     /**
114      * Get the HW return code
115      */
116     rc_t rc() const { return (item_rc); }
117
118     /**
119      * Set the HW return code - should only be called from the
120      * family of Command objects
121      */
122     void set(const rc_t& rc) { item_rc = rc; }
123
124     /**
125      * Return true if the HW item is configred in HW
126      */
127     operator bool() const { return (rc_t::OK == item_rc); }
128
129     /**
130      * update the item to the desired state.
131      *  return true if a HW update is required
132      */
133     bool update(const item& desired)
134     {
135       bool need_hw_update = false;
136
137       /*
138        * if the deisred set is unset (i.e. defaulted, we've
139        * no update to make
140        */
141       if (rc_t::UNSET == desired.rc()) {
142         return (false);
143       }
144       /*
145        * A HW update is needed if thestate is different
146        * or the state is not yet in HW
147        */
148       need_hw_update = (item_data != desired.data() || rc_t::OK != rc());
149
150       item_data = desired.data();
151
152       return (need_hw_update);
153     }
154
155     /**
156      * convert to string format for debug purposes
157      */
158     std::string to_string() const
159     {
160       std::ostringstream os;
161
162       os << "hw-item:["
163          << "rc:" << item_rc.to_string() << " data:" << item_data.to_string()
164          << "]";
165
166       return (os.str());
167     }
168
169   private:
170     /**
171      * The data
172      */
173     T item_data;
174
175     /**
176      * The result when the item was written
177      */
178     rc_t item_rc;
179   };
180
181   /**
182    * The pipe to VPP into which we write the commands
183    */
184   class cmd_q
185   {
186   public:
187     /**
188      * Constructor
189      */
190     cmd_q();
191     /**
192      * Destructor
193      */
194     ~cmd_q();
195
196     /**
197      * Copy assignement - only used in UT
198      */
199     cmd_q& operator=(const cmd_q& f);
200
201     /**
202      * Enqueue a command into the Q.
203      */
204     virtual void enqueue(cmd* c);
205     /**
206      * Enqueue a command into the Q.
207      */
208     virtual void enqueue(std::shared_ptr<cmd> c);
209
210     /**
211      * Enqueue a set of commands
212      */
213     virtual void enqueue(std::queue<cmd*>& c);
214
215     /**
216      * dequeue a command from the Q.
217      */
218     virtual void dequeue(cmd* c);
219
220     /**
221      * dequeue a command from the Q.
222      */
223     virtual void dequeue(std::shared_ptr<cmd> c);
224
225     /**
226      * Write all the commands to HW
227      */
228     virtual rc_t write();
229
230     /**
231      * Blocking Connect to VPP - call once at bootup
232      */
233     void connect();
234
235     /**
236      * Disable the passing of commands to VPP. Whilst disabled all
237      * writes will be discarded. Use this during the reset phase.
238      */
239     void disable();
240
241     /**
242      * Enable the passing of commands to VPP - undoes the disable.
243      * The Q is enabled by default.
244      */
245     void enable();
246
247   private:
248     /**
249      * A queue of enqueued commands, ready to be written
250      */
251     std::deque<std::shared_ptr<cmd>> m_queue;
252
253     /**
254      * A map of issued, but uncompleted, commands.
255      *  i.e. those that we are waiting, async stylee,
256      * for VPP to complete
257      */
258     std::map<cmd*, std::shared_ptr<cmd>> m_pending;
259
260     /**
261      * VPP Q poll function
262      */
263     void rx_run();
264
265     /**
266      * The thread object running the poll/dispatch/connect thread
267      */
268     std::unique_ptr<std::thread> m_rx_thread;
269
270     /**
271      * A flag indicating the client has disabled the cmd Q.
272      */
273     bool m_enabled;
274
275     /**
276      * A flag for the thread to poll to see if the queue is still alive
277      */
278     bool m_connected;
279
280     /**
281      * The connection to VPP
282      */
283     connection m_conn;
284   };
285
286   /**
287    * Initialise the HW connection to VPP - the UT version passing
288    * a mock Q.
289    */
290   static void init(cmd_q* f);
291
292   /**
293    * Initialise the HW
294    */
295   static void init();
296
297   /**
298    * Enqueue A command for execution
299    */
300   static void enqueue(cmd* f);
301
302   /**
303    * Enqueue A command for execution
304    */
305   static void enqueue(std::shared_ptr<cmd> c);
306
307   /**
308    * Enqueue A set of commands for execution
309    */
310   static void enqueue(std::queue<cmd*>& c);
311
312   /**
313    * dequeue A command for execution
314    */
315   static void dequeue(cmd* f);
316
317   /**
318    * dequeue A command for execution
319    */
320   static void dequeue(std::shared_ptr<cmd> c);
321
322   /**
323    * Write/Execute all commands hitherto enqueued.
324    */
325   static rc_t write();
326
327   /**
328    * Blocking Connect to VPP
329    */
330   static void connect();
331
332   /**
333    * Blocking pool of the HW connection
334    */
335   static bool poll();
336
337 private:
338   /**
339    * The command Q toward HW
340    */
341   static cmd_q* m_cmdQ;
342
343   /**
344    * HW::item representing the connection state as determined by polling
345    */
346   static HW::item<bool> m_poll_state;
347
348   /**
349    * Disable the passing of commands to VPP. Whilst disabled all writes
350    * will be discarded. Use this during the reset phase.
351    */
352   static void disable();
353
354   /**
355    * Enable the passing of commands to VPP - undoes the disable.
356    * The Q is enabled by default.
357    */
358   static void enable();
359
360   /**
361    * Only the OM can enable/disable HW
362    */
363   friend class OM;
364 };
365
366 /**
367  * bool Specialisation for HW::item to_string
368  */
369 template <>
370 std::string HW::item<bool>::to_string() const;
371
372 /**
373  * uint Specialisation for HW::item to_string
374  */
375 template <>
376 std::string HW::item<unsigned int>::to_string() const;
377 };
378
379 /*
380  * fd.io coding-style-patch-verification: ON
381  *
382  * Local Variables:
383  * eval: (c-set-style "mozilla")
384  * End:
385  */
386
387 #endif