Packets documentation updates
[senf.git] / Packets / 80221Bundle / TLVPacket.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
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 TLVPacket public header */
25
26 #ifndef HH_SENF_Packets_80221Bundle_TLVPacket_
27 #define HH_SENF_Packets_80221Bundle_TLVPacket_ 1
28
29 // Custom includes
30 #include <algorithm>
31 #include "../../Packets/Packets.hh"
32
33 //#include "TLVPacket.mpp"
34 ///////////////////////////////hh.p////////////////////////////////////////
35
36 namespace senf {
37
38
39     struct TLVLengthException : public senf::Exception
40     { TLVLengthException() 
41           : senf::Exception("TLVLengthException"){} };
42
43     
44     class DynamicTLVLengthParser 
45         : public detail::packet::IntParserOps<DynamicTLVLengthParser, boost::uint32_t>,
46           public PacketParserBase
47     {
48     public:
49         DynamicTLVLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
50
51         typedef boost::uint32_t value_type;
52         static const size_type init_bytes = 1;
53         static value_type const min_value = 0;
54         static value_type const max_value = 4294967295u;
55
56         value_type value() const;
57         void value(value_type const & v);
58         
59         DynamicTLVLengthParser const & operator= (value_type other);
60         size_type bytes() const;
61         void init() const;
62
63 #       include SENF_PARSER()
64         SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1,  bool     );
65         SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field,   7,  unsigned );
66
67         void shrink();
68         void maxValue(DynamicTLVLengthParser::value_type v);
69     private:
70         void resize(size_type size);
71     };  
72         
73
74     /** \brief Base class for TLV-Packet-Parsers
75      
76          BaseTLVPacketParser is the abstract base class for TLV-Packet-Parsers. It defines the
77          \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a 
78          DynamicTLVLengthParser. The length field is read-only. 
79          
80          To create your own \c TLVParser you have to inherit from BaseTLVPacketParser (don't 
81          forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example 
82          the value is a vector of MacAddresses: 
83          \code
84          struct MacAddressesTLVParser : public BaseTLVPacketParser {
85          #   include SENF_PARSER()        
86              SENF_PARSER_INHERIT ( BaseTLVPacketParser );
87              SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
88              SENF_PARSER_FINALIZE( MacAddressesTLVParser );
89          };
90          
91          struct MacAddressesTLVPacketType : public PacketTypeBase {
92             typedef MacAddressesTLVParser parser;
93             ...
94             static void finalize(ConcretePacket<MacAddressesTLVPacketType> p) { 
95                 p->shrinkLength();
96             }
97          };
98          \endcode
99          
100          You have to adjust the maximum length value with the \ref maxLengthValue function 
101          before the length value is set. The default maximum value is 127. So, in the above
102          example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
103          if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before.
104          
105          \see DynamicTLVLengthParser \n
106            GenericTLVPacketParser \n
107      */
108     class BaseTLVPacketParser : public PacketParserBase
109     {
110     public:
111 #       include SENF_PARSER()
112         SENF_PARSER_FIELD    ( type,   UInt8Parser            );
113         SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser );
114         SENF_PARSER_FINALIZE ( BaseTLVPacketParser            );
115         
116         /** \brief set maximum value of length field
117     
118             The size of the length field will be increased if necessary.
119             \param v maximum value of length field
120          */
121         void maxLengthValue(DynamicTLVLengthParser::value_type v) const {
122             length_().maxValue(v);
123         }
124         
125         /** \brief shrink size of length field to minimum
126     
127             The size of the length field will be decreased to minimum necessary to hold
128             the current length value.
129          */
130         void shrinkLength() { 
131             length_().shrink(); 
132         };
133         
134     protected:
135         /// return size of length field
136         size_type length_bytes() const { return length_().bytes(); };
137         /// set length field to given value
138         void length(DynamicTLVLengthParser::value_type &v) { length_() = v; };
139         /// resize the Packet after the length field to given size
140         senf::safe_data_iterator resizeValue(DynamicTLVLengthParser::value_type size);
141     };
142
143         
144     /** \brief Parser for a generic TLV packet
145
146         \see GenericTLVPacketType
147      */
148     struct GenericTLVPacketParser : public BaseTLVPacketParser
149     {
150 #       include SENF_PARSER()        
151         SENF_PARSER_INHERIT  ( BaseTLVPacketParser    );
152         SENF_PARSER_SKIP     ( length(), 0            );
153         SENF_PARSER_FINALIZE ( GenericTLVPacketParser );
154         
155         SENF_PARSER_INIT() {
156             maxLengthValue( DynamicTLVLengthParser::max_value);
157         }
158         
159         senf::PacketInterpreterBase::range value() const;
160         
161         template <class ForwardReadableRange>
162         void value(ForwardReadableRange const &range);
163     };
164     
165     /** \brief Generic TLV packet
166
167         \par Packet type (typedef):
168             \ref GenericTLVPacket
169
170         \image html TLV.png
171         
172         \ingroup protocolbundle_80221
173      */
174     struct GenericTLVPacketType
175         : public PacketTypeBase,
176           public PacketTypeMixin<GenericTLVPacketType>
177     {
178 #ifndef DOXYGEN
179         typedef PacketTypeMixin<GenericTLVPacketType> mixin;
180 #endif
181         typedef ConcretePacket<GenericTLVPacketType> packet; ///< GenericTLV packet typedef
182         typedef GenericTLVPacketParser parser;               ///< typedef to the parser of GenericTLV packet
183
184         using mixin::nextPacketRange;
185         using mixin::init;
186         using mixin::initSize;
187         
188         /** \brief Dump given GenericTLVPacket in readable form to given output stream */
189         static void dump(packet p, std::ostream & os);  
190         static void finalize(packet p);  ///< Finalize packet.
191                                          /**< shrink size of length field to minimum 
192                                               \see BaseTLVPacketParser::shrinkLength() */
193         
194     };
195     
196     /** \brief GenericTLV packet typedef */
197     typedef ConcretePacket<GenericTLVPacketType> GenericTLVPacket;
198 }
199
200
201 ///////////////////////////////hh.e////////////////////////////////////////
202 //#include "TLVPacket.cci"
203 #include "TLVPacket.ct"
204 //#include "TLVPacket.cti"
205 #endif
206
207 \f
208 // Local Variables:
209 // mode: c++
210 // fill-column: 100
211 // c-file-style: "senf"
212 // indent-tabs-mode: nil
213 // ispell-local-dictionary: "american"
214 // compile-command: "scons -u test"
215 // comment-column: 40
216 // End: