Vanetza
 
Loading...
Searching...
No Matches
osi_layer.hpp
1#ifndef OSI_LAYER_HPP_C4VTEZJP
2#define OSI_LAYER_HPP_C4VTEZJP
3
4#include <boost/range/iterator_range.hpp>
5#include <array>
6#include <cstdint>
7
8namespace vanetza
9{
10
11enum class OsiLayer : uint8_t
12{
13 Physical = 1,
14 Link = 2,
15 Network = 3,
16 Transport = 4,
17 Session = 5,
18 Presentation = 6,
19 Application = 7
20};
21
22constexpr OsiLayer min_osi_layer() { return OsiLayer::Physical; }
23constexpr OsiLayer max_osi_layer() { return OsiLayer::Application; }
24
25constexpr std::array<OsiLayer, 7> osi_layers {{
26 OsiLayer::Physical,
27 OsiLayer::Link,
28 OsiLayer::Network,
29 OsiLayer::Transport,
30 OsiLayer::Session,
31 OsiLayer::Presentation,
32 OsiLayer::Application
33}};
34
35/**
36 * Calculate distance between layers
37 * \param from start counting at this layer
38 * \param to stop counting here
39 * \return 0 if equal layers, positive if "to" is a higher layer, negative if "to" is below "from"
40 */
41constexpr int distance(OsiLayer from, OsiLayer to)
42{
43 return static_cast<int>(to) - static_cast<int>(from);
44}
45
46constexpr std::size_t num_osi_layers(OsiLayer from, OsiLayer to)
47{
48 return (from <= to ? distance(from, to) + 1 : 0);
49}
50
51template<OsiLayer FROM, OsiLayer TO>
52std::array<OsiLayer, num_osi_layers(FROM, TO)> osi_layer_range()
53{
54 static_assert(FROM <= TO, "FROM layer is above TO layer");
55 typedef typename std::underlying_type<OsiLayer>::type num_type;
56
57 num_type num = static_cast<num_type>(FROM);
58 std::array<OsiLayer, num_osi_layers(FROM, TO)> layers;
59 for (auto& layer : layers) {
60 layer = static_cast<OsiLayer>(num++);
61 }
62 return layers;
63}
64
65inline boost::iterator_range<decltype(osi_layers)::const_iterator>
66osi_layer_range(OsiLayer from, OsiLayer to)
67{
68 if (from <= to) {
69 auto begin = osi_layers.cbegin() + distance(min_osi_layer(), from);
70 auto end = osi_layers.cend() - distance(to, max_osi_layer());
71 return boost::make_iterator_range(begin, end);
72 } else {
73 return boost::make_iterator_range(osi_layers.cend(), osi_layers.cend());
74 }
75}
76
77} // namespace vanetza
78
79#endif /* OSI_LAYER_HPP_C4VTEZJP */
80