blob: 3cd5d214454cbeb24ca8612cd243fef2018d8bab [file] [log] [blame]
Vernon Mauery08a70aa2018-11-07 09:36:22 -08001/**
2 * Copyright © 2018 Intel Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17#include <algorithm>
18#include <boost/callable_traits.hpp>
19#include <cstdint>
20#include <ipmid/api.hpp>
21#include <ipmid/message.hpp>
22#include <memory>
23#include <tuple>
24#include <utility>
25
26namespace ipmi
27{
28
29using FilterFunction = ipmi::Cc(ipmi::message::Request::ptr);
30
31/**
32 * @brief Filter base class for dealing with IPMI request/response
33 *
34 * The subclasses are all templated so they can provide access to any type of
35 * command callback functions.
36 */
37class FilterBase
38{
39 public:
40 using ptr = std::shared_ptr<FilterBase>;
41
42 virtual ipmi::Cc call(message::Request::ptr request) = 0;
43};
44
45/**
46 * @brief filter concrete class
47 *
48 * This is the base template that ipmi filters will resolve into. This is
49 * essentially just a wrapper to hold the filter callback so it can be stored in
50 * the filter list.
51 *
52 * Filters are called with a ipmi::message::Request shared_ptr on all IPMI
53 * commands in priority order and each filter has the opportunity to reject the
54 * command (by returning an IPMI error competion code.) If all the filters
55 * return success, the actual IPMI command will be executed. Filters can reject
56 * the command for any reason, based on system state, the context, the command
57 * payload, etc.
58 */
59template <typename Filter>
60class IpmiFilter : public FilterBase
61{
62 public:
63 IpmiFilter(Filter&& filter) : filter_(std::move(filter))
64 {
65 }
66
67 ipmi::Cc call(message::Request::ptr request) override
68 {
69 return filter_(request);
70 }
71
72 private:
73 Filter filter_;
74};
75
76/**
77 * @brief helper function to construct a filter object
78 *
79 * This is called internally by the ipmi::registerFilter function.
80 */
81template <typename Filter>
82static inline auto makeFilter(Filter&& filter)
83{
84 FilterBase::ptr ptr(new IpmiFilter<Filter>(std::forward<Filter>(filter)));
85 return ptr;
86}
87template <typename Filter>
88static inline auto makeFilter(const Filter& filter)
89{
90 Filter lFilter = filter;
91 return makeFilter(std::forward<Filter>(lFilter));
92}
93
94} // namespace ipmi