summaryrefslogtreecommitdiffstats
path: root/include/ipmid/filter.hpp
blob: 3cd5d214454cbeb24ca8612cd243fef2018d8bab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
 * Copyright © 2018 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once
#include <algorithm>
#include <boost/callable_traits.hpp>
#include <cstdint>
#include <ipmid/api.hpp>
#include <ipmid/message.hpp>
#include <memory>
#include <tuple>
#include <utility>

namespace ipmi
{

using FilterFunction = ipmi::Cc(ipmi::message::Request::ptr);

/**
 * @brief Filter base class for dealing with IPMI request/response
 *
 * The subclasses are all templated so they can provide access to any type of
 * command callback functions.
 */
class FilterBase
{
  public:
    using ptr = std::shared_ptr<FilterBase>;

    virtual ipmi::Cc call(message::Request::ptr request) = 0;
};

/**
 * @brief filter concrete class
 *
 * This is the base template that ipmi filters will resolve into. This is
 * essentially just a wrapper to hold the filter callback so it can be stored in
 * the filter list.
 *
 * Filters are called with a ipmi::message::Request shared_ptr on all IPMI
 * commands in priority order and each filter has the opportunity to reject the
 * command (by returning an IPMI error competion code.) If all the filters
 * return success, the actual IPMI command will be executed. Filters can reject
 * the command for any reason, based on system state, the context, the command
 * payload, etc.
 */
template <typename Filter>
class IpmiFilter : public FilterBase
{
  public:
    IpmiFilter(Filter&& filter) : filter_(std::move(filter))
    {
    }

    ipmi::Cc call(message::Request::ptr request) override
    {
        return filter_(request);
    }

  private:
    Filter filter_;
};

/**
 * @brief helper function to construct a filter object
 *
 * This is called internally by the ipmi::registerFilter function.
 */
template <typename Filter>
static inline auto makeFilter(Filter&& filter)
{
    FilterBase::ptr ptr(new IpmiFilter<Filter>(std::forward<Filter>(filter)));
    return ptr;
}
template <typename Filter>
static inline auto makeFilter(const Filter& filter)
{
    Filter lFilter = filter;
    return makeFilter(std::forward<Filter>(lFilter));
}

} // namespace ipmi
OpenPOWER on IntegriCloud