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