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