GBP: add allowed ethertypes to contracts
[vpp.git] / extras / vom / vom / hw.cpp
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 #include "vom/hw.hpp"
17 #include "vom/hw_cmds.hpp"
18 #include "vom/logger.hpp"
19 #include "vom/stat_reader.hpp"
20
21 namespace VOM {
22 HW::cmd_q::cmd_q()
23   : m_enabled(true)
24   , m_connected(false)
25   , m_conn()
26 {
27 }
28
29 HW::cmd_q::~cmd_q()
30 {
31 }
32
33 HW::cmd_q&
34 HW::cmd_q::operator=(const HW::cmd_q& f)
35 {
36   return (*this);
37 }
38
39 /**
40  * Run the connect/dispatch thread.
41  */
42 void
43 HW::cmd_q::rx_run()
44 {
45   while (m_connected) {
46     m_conn.ctx().dispatch();
47   }
48 }
49
50 void
51 HW::cmd_q::enqueue(cmd* c)
52 {
53   std::shared_ptr<cmd> sp(c);
54
55   m_queue.push_back(sp);
56 }
57
58 void
59 HW::cmd_q::enqueue(std::shared_ptr<cmd> c)
60 {
61   m_queue.push_back(c);
62 }
63
64 void
65 HW::cmd_q::enqueue(std::queue<cmd*>& cmds)
66 {
67   while (cmds.size()) {
68     std::shared_ptr<cmd> sp(cmds.front());
69
70     m_queue.push_back(sp);
71     cmds.pop();
72   }
73 }
74
75 bool
76 HW::cmd_q::connect()
77 {
78   if (m_connected)
79     return m_connected;
80
81   if (0 == m_conn.connect()) {
82     m_connected = true;
83     m_rx_thread.reset(new std::thread(&HW::cmd_q::rx_run, this));
84   }
85   return (m_connected);
86 }
87
88 void
89 HW::cmd_q::disconnect()
90 {
91
92   if (!m_connected)
93     return;
94
95   m_connected = false;
96
97   if (m_rx_thread && m_rx_thread->joinable()) {
98     m_rx_thread->join();
99   }
100
101   m_conn.disconnect();
102 }
103
104 void
105 HW::cmd_q::enable()
106 {
107   m_enabled = true;
108 }
109
110 void
111 HW::cmd_q::disable()
112 {
113   m_enabled = false;
114 }
115
116 rc_t
117 HW::cmd_q::write()
118 {
119   rc_t rc = rc_t::OK;
120
121   /*
122    * The queue is enabled, Execute each command in the queue.
123    * If one execution fails, abort the rest
124    */
125   auto it = m_queue.begin();
126
127   while (it != m_queue.end()) {
128     std::shared_ptr<cmd> c = *it;
129
130     VOM_LOG(log_level_t::DEBUG) << *c;
131
132     if (m_enabled) {
133       /*
134        * before we issue the command we must move it to the pending
135        * store
136        * ince a async event can be recieved before the command
137        * completes
138        */
139       rc = c->issue(m_conn);
140
141       if (rc_t::OK == rc) {
142         /*
143          * move to the next
144          */
145       } else {
146         /*
147          * barf out without issuing the rest
148          */
149         VOM_LOG(log_level_t::ERROR) << "Failed to execute: " << c->to_string();
150         break;
151       }
152     } else {
153       /*
154        * The HW is disabled, so set each command as succeeded
155        */
156       c->succeeded();
157     }
158
159     ++it;
160   }
161
162   /*
163    * erase all objects in the queue
164    */
165   m_queue.erase(m_queue.begin(), m_queue.end());
166
167   return (rc);
168 }
169
170 /*
171  * The single Command Queue
172  */
173 HW::cmd_q* HW::m_cmdQ;
174
175 /*
176  * single stat reader
177  */
178 stat_reader* HW::m_statReader;
179 HW::item<bool> HW::m_poll_state;
180
181 /**
182  * Initialse the connection to VPP
183  */
184 void
185 HW::init(HW::cmd_q* f)
186 {
187   m_cmdQ = f;
188   m_statReader = new stat_reader();
189 }
190
191 /**
192  * Initialse the connection to VPP
193  */
194 void
195 HW::init(HW::cmd_q* f, stat_reader* s)
196 {
197   m_cmdQ = f;
198   m_statReader = s;
199 }
200
201 /**
202  * Initialse the connection to VPP
203  */
204 void
205 HW::init()
206 {
207   m_cmdQ = new cmd_q();
208   m_statReader = new stat_reader();
209 }
210
211 void
212 HW::enqueue(cmd* cmd)
213 {
214   m_cmdQ->enqueue(cmd);
215 }
216
217 void
218 HW::enqueue(std::shared_ptr<cmd> cmd)
219 {
220   m_cmdQ->enqueue(cmd);
221 }
222
223 void
224 HW::enqueue(std::queue<cmd*>& cmds)
225 {
226   m_cmdQ->enqueue(cmds);
227 }
228
229 bool
230 HW::connect()
231 {
232   return (m_cmdQ->connect() && m_statReader->connect());
233 }
234
235 void
236 HW::disconnect()
237 {
238   m_statReader->disconnect();
239   m_cmdQ->disconnect();
240 }
241
242 void
243 HW::enable()
244 {
245   m_cmdQ->enable();
246 }
247
248 void
249 HW::disable()
250 {
251   m_cmdQ->disable();
252 }
253
254 rc_t
255 HW::write()
256 {
257   return (m_cmdQ->write());
258 }
259
260 bool
261 HW::poll()
262 {
263   std::shared_ptr<cmd> poll(new hw_cmds::poll(m_poll_state));
264
265   HW::enqueue(poll);
266   HW::write();
267
268   return (m_poll_state);
269 }
270
271 void
272 HW::read_stats()
273 {
274   m_statReader->read();
275 }
276
277 template <>
278 std::string
279 HW::item<bool>::to_string() const
280 {
281   std::ostringstream os;
282
283   os << "hw-item:["
284      << "rc:" << item_rc.to_string() << " data:" << item_data << "]";
285   return (os.str());
286 }
287
288 template <>
289 std::string
290 HW::item<unsigned int>::to_string() const
291 {
292   std::ostringstream os;
293
294   os << "hw-item:["
295      << "rc:" << item_rc.to_string() << " data:" << item_data << "]";
296   return (os.str());
297 }
298 }
299
300 /*
301  * fd.io coding-style-patch-verification: ON
302  *
303  * Local Variables:
304  * eval: (c-set-style "mozilla")
305  * End:
306  */