Fix SCons 1.2.0 build failure
[senf.git] / senf / Packets / 80221Bundle / MIHPacket.hh
1 // $Id$
2 //
3 // Copyright (C) 2009
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Thorsten Horstmann <tho@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief MIH protocol public header */
25
26 #ifndef HH_SENF_Packets_80221Bundle_MIHPacket_
27 #define HH_SENF_Packets_80221Bundle_MIHPacket_ 1
28
29 // Custom includes
30 #include "../../Packets/Packets.hh"
31 #include "../../Socket/Protocols/Raw/MACAddress.hh"
32 #include "../../Socket/Protocols/INet/INet4Address.hh"
33 #include "../../Socket/Protocols/INet/INet6Address.hh"
34 #include "TLVPacket.hh"
35 #include <boost/function_output_iterator.hpp>
36 #include <boost/iterator/filter_iterator.hpp>
37 #include "boost/variant.hpp"
38
39
40 //#include "MIHPacket.mpp"
41 ///////////////////////////////hh.p////////////////////////////////////////
42
43 namespace senf {
44
45     struct MIHMessageRegistry {
46         // MIH messages registry
47         typedef boost::uint16_t key_t;
48     };
49
50 #   define SENF_MIH_PACKET_REGISTRY_REGISTER( packet )                    \
51         SENF_PACKET_REGISTRY_REGISTER(                                    \
52             senf::MIHMessageRegistry, packet::type::MESSAGE_ID, packet )
53     
54     class MIHFId 
55         : public boost::variant< boost::blank, senf::MACAddress, senf::INet4Address, 
56                 senf::INet6Address, std::string, senf::EUI64 >,
57           public boost::less_than_comparable<MIHFId>,
58           public boost::equality_comparable<MIHFId>
59     {
60     public:
61         enum Type { Empty, MACAddress, INet4Address, INet6Address, String, EUI64 };
62       
63         MIHFId();
64         MIHFId(senf::MACAddress const & addr);
65         MIHFId(senf::INet4Address const & addr);
66         MIHFId(senf::INet6Address const & addr);
67         MIHFId(std::string const & addr);
68         MIHFId(senf::EUI64 const & addr);
69         
70         Type type() const;
71         bool operator==(MIHFId const & other) const;
72         bool operator<(MIHFId const & other) const; 
73         
74     private:
75         struct GetTypeVisitor : public boost::static_visitor<Type> {
76             Type operator()(boost::blank const &) const { return Empty; }
77             Type operator()(senf::MACAddress const &) const { return MACAddress; }
78             Type operator()(senf::INet4Address const &) const { return INet4Address; }
79             Type operator()(senf::INet6Address const &) const { return INet6Address; }
80             Type operator()(std::string const & ) const { return String; }
81             Type operator()(senf::EUI64 const &) const { return EUI64; }
82         };
83         struct EqualsVisitor : public boost::static_visitor<bool> {
84             template <typename T, typename U>
85             bool operator()(T const &, U const &) const {
86                 return false;
87             }
88             template <typename T>
89             bool operator()( const T & lhs, const T & rhs ) const {
90                 return lhs == rhs;
91             }
92         };
93         struct LessThanVisitor : public boost::static_visitor<bool> {
94             template <typename T, typename U>
95             bool operator()(T const &, U const &) const {
96                 return false;
97             }
98             template <typename T>
99             bool operator()( const T & lhs, const T & rhs ) const {
100                 return lhs < rhs;
101             }
102         };
103     };
104     
105     
106     /** \brief Parse a MIHF_ID
107
108          the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
109          we could set maxLengthValue in init(), but for the most MIHF_IDs the default
110          maximum length of 127 should be enough.
111          
112          \note you must call mihfIdPacket.maxLengthValue( 253) *before*
113          setting longer MIHF_IDs values.
114     */
115     class MIHFId_TLVParser : public BaseTLVPacketParser
116     {
117     #   include SENF_PARSER()
118         SENF_PARSER_INHERIT  ( BaseTLVPacketParser );
119         SENF_PARSER_SKIP     ( length(), 0         );
120         SENF_PARSER_FINALIZE ( MIHFId_TLVParser    );
121
122         std::string asString() const;
123         void setString(std::string const &id);
124
125         senf::MACAddress asMACAddress() const;
126         void setMACAddress(senf::MACAddress const &mac);
127
128         senf::INet4Address asINet4Address() const;
129         void setINet4Address(senf::INet4Address const &addr);
130
131         senf::INet6Address asINet6Address() const;
132         void setINet6Address(senf::INet6Address const &addr);
133         
134         senf::EUI64 asEUI64() const;
135         void setEUI64(senf::EUI64 const &addr);
136
137         MIHFId valueAs(MIHFId::Type type) const;
138         
139     private:
140         template <class OutputIterator>
141         struct binaryNAIEncoder {
142             binaryNAIEncoder(OutputIterator &i) : i_(i) {}
143             void operator()(const boost::uint8_t &v) const {
144                 *i_++ = '\\';
145                 *i_++ = v;
146             }
147             OutputIterator &i_;
148         };
149         template <class OutputIterator>
150         static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> > getNAIEncodedOutputIterator(OutputIterator i) {
151             return boost::make_function_output_iterator(binaryNAIEncoder<OutputIterator>(i));
152         }
153
154         struct binaryNAIDecoder {
155             binaryNAIDecoder() : readNextByte_(true) {}
156             bool operator()(const boost::uint8_t &v) {
157                 readNextByte_ = readNextByte_ ? false : true;
158                 return readNextByte_;
159             }
160             bool readNextByte_;
161         };
162         template <class Iterator>
163         static boost::filter_iterator<binaryNAIDecoder, Iterator> getNAIDecodedIterator(Iterator begin, Iterator end) {
164             return boost::make_filter_iterator<binaryNAIDecoder>(begin, end);
165         }
166     };
167  
168     /** \brief Parse a MIH packet
169
170         Parser implementing the MIH header. The fields implemented are:
171         \image html MIHPacket.png
172
173         \see MIHPacketType
174      */
175     struct MIHPacketParser : public PacketParserBase
176     {
177     #   include SENF_PARSER()
178
179         SENF_PARSER_BITFIELD_RO ( version,       4,  unsigned );
180         SENF_PARSER_BITFIELD    ( ackRequest,    1,  bool     );
181         SENF_PARSER_BITFIELD    ( ackResponse,   1,  bool     );
182         SENF_PARSER_BITFIELD    ( uir,           1,  bool     );
183         SENF_PARSER_BITFIELD    ( moreFragment,  1,  bool     );
184         SENF_PARSER_BITFIELD    ( fragmentNr,    7,  unsigned );
185         SENF_PARSER_SKIP_BITS   ( 1                           );
186
187         // MIH message ID (MID)
188         SENF_PARSER_FIELD    ( messageId, UInt16Parser ); //<pkgdraw:hide
189         SENF_PARSER_GOTO     ( messageId               );
190         SENF_PARSER_BITFIELD ( sid,     4,  unsigned   );
191         SENF_PARSER_BITFIELD ( opcode,  2,  unsigned   );
192         SENF_PARSER_BITFIELD ( aid,    10,  unsigned   );
193         
194         SENF_PARSER_SKIP_BITS ( 4                           );
195         SENF_PARSER_BITFIELD  ( transactionId, 12, unsigned );
196         SENF_PARSER_FIELD_RO  ( payloadLength, UInt16Parser );
197         
198         SENF_PARSER_GOTO_OFFSET( 8, 8); // just to limit the offset calculation
199         
200         // Source MIHF Id
201         SENF_PARSER_FIELD ( src_mihfId, MIHFId_TLVParser );
202         // Destination MIHF Id
203         SENF_PARSER_FIELD ( dst_mihfId, MIHFId_TLVParser );
204
205         SENF_PARSER_FINALIZE ( MIHPacketParser );
206
207         SENF_PARSER_INIT() {
208             version_() = 1;
209             src_mihfId().type() = 1;
210             dst_mihfId().type() = 2;
211         }
212
213         friend class MIHPacketType;
214     };
215
216     /** \brief MIH packet
217
218         \par Packet type (typedef):
219             \ref MIHPacket
220
221         \par Fields:
222             \ref MIHPacketParser
223
224         \ingroup protocolbundle_80221
225      */
226     struct MIHPacketType
227         : public PacketTypeBase,
228           public PacketTypeMixin<MIHPacketType, MIHMessageRegistry>
229     {
230 #ifndef DOXYGEN
231         typedef PacketTypeMixin<MIHPacketType, MIHMessageRegistry> mixin;
232 #endif
233         typedef ConcretePacket<MIHPacketType> packet; ///< MIH packet typedef
234         typedef MIHPacketParser parser;               ///< typedef to the parser of MIH packet
235
236         using mixin::nextPacketRange;
237         using mixin::init;
238         using mixin::initSize;
239
240         /** \brief Dump given MIH packet in readable form to given output stream */
241         static void dump(packet p, std::ostream &os);
242         static void finalize(packet p);
243         static factory_t nextPacketType(packet p);
244     };
245
246     /** \brief MIH packet typedef */
247     typedef ConcretePacket<MIHPacketType> MIHPacket;
248
249
250     struct MIHPayloadPacketParser : public PacketParserBase
251     {
252     #   include SENF_PARSER()
253         SENF_PARSER_LIST ( tlv_list, packetSize(), GenericTLVPacketParser );
254
255         SENF_PARSER_FINALIZE ( MIHPayloadPacketParser );
256     };
257
258     struct MIHPayloadPacketType
259         : public PacketTypeBase,
260           public PacketTypeMixin<MIHPayloadPacketType>
261     {
262 #ifndef DOXYGEN
263         typedef PacketTypeMixin<MIHPayloadPacketType> mixin;
264 #endif
265         typedef ConcretePacket<MIHPayloadPacketType> packet; ///< MIH Payload packet typedef
266         typedef MIHPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet
267
268         using mixin::nextPacketRange;
269         using mixin::init;
270         using mixin::initSize;
271
272         /** \brief Dump given MIHPayload in readable form to given output stream */
273         static void dump(packet p, std::ostream &os);
274     };
275
276      /** \brief MIH Payload packet typedef */
277     typedef ConcretePacket<MIHPayloadPacketType> MIHPayloadPacket;
278 }
279
280
281 ///////////////////////////////hh.e////////////////////////////////////////
282 #include "MIHPacket.cci"
283 //#include "MIHPacket.ct"
284 //#include "MIHPacket.cti"
285 #endif
286
287
288 \f
289 // Local Variables:
290 // mode: c++
291 // fill-column: 100
292 // c-file-style: "senf"
293 // indent-tabs-mode: nil
294 // ispell-local-dictionary: "american"
295 // compile-command: "scons -u test"
296 // comment-column: 40
297 // End: