Packets/80221Bundle: added more MIH-TLVs
[senf.git] / senf / Packets / 80221Bundle / TLVParser.cc
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 TLVParser non-inline non-template implementation */
25
26 #include "TLVParser.hh"
27 //#include "TLVParser.ih"
28
29 // Custom includes
30 #include <iomanip>
31 #include <senf/Utils/hexdump.hh>
32 #include <senf/Utils/Format.hh>
33
34 #define prefix_
35 ///////////////////////////////cc.p////////////////////////////////////////
36
37 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFSrcIdTLVParser );
38 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFDstIdTLVParser );
39 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHStatusTLVParser );
40 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHValidTimeIntervalTLVParser );
41
42 ///////////////////////////////////////////////////////////////////////////
43 // senf::MIHFIdTLVParser
44
45 prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
46     const
47 {
48     senf::format::IndentHelper indent;
49     os << indent << "type:   " << unsigned (type()) << std::endl
50        << indent << "length: " << unsigned (length()) << std::endl
51        << indent << "value:\n";
52     std::string src_mihfId (asString());
53     hexdump(src_mihfId.begin(), src_mihfId.end(), os);
54 }
55
56 prefix_ void senf::MIHFIdTLVParser::setString(std::string const &id)
57 {
58     size_type str_size (id.size());
59     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
60     if (str_size > 253) 
61         throw std::length_error("maximum length of a MIHF_ID is 253 octets");
62     safe_data_iterator si = resizeValueField( str_size);   
63     std::copy( id.begin(), id.end(), si);
64 }
65
66 prefix_ void senf::MIHFIdTLVParser::setMACAddress(senf::MACAddress const &mac)
67 {
68     safe_data_iterator si = resizeValueField(12);
69     std::copy( mac.begin(), mac.end(), getNAIEncodedOutputIterator(si));
70 }
71
72 prefix_ void senf::MIHFIdTLVParser::setINet4Address(senf::INet4Address const &addr)
73 {
74     safe_data_iterator si = resizeValueField(8);
75     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
76 }
77
78 prefix_ void senf::MIHFIdTLVParser::setINet6Address(senf::INet6Address const &addr)
79 {
80     safe_data_iterator si = resizeValueField(32);
81     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
82 }
83
84 prefix_ void senf::MIHFIdTLVParser::setEUI64(senf::EUI64 const &addr)
85 {
86     safe_data_iterator si = resizeValueField(16);
87     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
88 }
89
90 prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type)
91     const
92 {
93     if (length() == 0) return MIHFId();
94     switch (type) {
95     case MIHFId::Empty:
96         return MIHFId();
97     case MIHFId::MACAddress:
98         return MIHFId( asMACAddress());
99     case MIHFId::INet4Address:
100         return MIHFId( asINet4Address());
101     case MIHFId::INet6Address:
102         return MIHFId( asINet6Address());
103     case MIHFId::String:
104         return MIHFId( asINet6Address());
105     case MIHFId::EUI64:
106         return MIHFId( asINet6Address());
107     }
108     return MIHFId();
109 }
110
111
112 ///////////////////////////////////////////////////////////////////////////
113 // senf::MIHFSrcIdTLVParser
114
115 prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os)
116     const
117 {
118     senf::format::IndentHelper indent;
119     os << indent << "source MIHF_Id TLV:\n";
120     MIHFIdTLVParser::dump(os);
121 }
122
123 ///////////////////////////////////////////////////////////////////////////
124 // senf::MIHFDstIdTLVParser
125
126 prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os)
127     const
128 {
129     senf::format::IndentHelper indent;
130     os << indent << "destination MIHF_Id TLV:\n";
131     MIHFIdTLVParser::dump(os);
132 }
133
134 ///////////////////////////////////////////////////////////////////////////
135 // senf::MIHStatusTLVParser
136
137 prefix_ void senf::MIHStatusTLVParser::dump(std::ostream & os)
138     const
139 {
140     senf::format::IndentHelper indent;
141     os << indent << "Status TLV:" << std::endl;
142     indent.increase();
143     os << indent <<   "type:   " << unsigned( type()) << std::endl
144        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
145        << indent <<   "value:  " << unsigned( value());
146     switch (value()) {
147     case Success:
148         os << " (Success)" << std::endl;
149         return;
150     case UnspecifiedFailure:  
151         os << " (Unspecified Failure)" << std::endl;
152         return;
153     case Rejected:
154         os << " (Rejected)" << std::endl;
155         return;
156     case AuthorizationFailure:
157         os << " (Authorization Failure)" << std::endl;
158         return;
159     case NetworkError:
160         os << " (Network Error)" << std::endl;
161         return;
162     }
163     os << " (???; invalid value!)" << std::endl;
164 }
165
166 ///////////////////////////////////////////////////////////////////////////
167 // senf::MIHRegisterReqCodeTLVParser
168
169 prefix_ void senf::MIHRegisterReqCodeTLVParser::dump(std::ostream & os)
170     const
171 {
172     senf::format::IndentHelper indent;
173     os << indent << "Register Request Code TLV:" << std::endl;
174     indent.increase();
175     os << indent <<   "type:   " << unsigned( type()) << std::endl
176        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
177        << indent <<   "value:  " << unsigned( value());
178     switch (value()) {
179     case Registration:
180         os << " (Registration)" << std::endl;
181         return;
182     case ReRegistration:
183         os << " (Re-Registration)" << std::endl;
184         return;
185     }
186     os << " (???; invalid value!)" << std::endl;
187 }
188
189 ///////////////////////////////////////////////////////////////////////////
190 // senf::MIHValidTimeIntervalTLVParser
191
192 prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os)
193     const
194 {
195     senf::format::IndentHelper indent;
196     os << indent << "Valid Time Interval TLV:" << std::endl;
197     indent.increase();
198     os << indent <<   "type:   " << unsigned( type()) << std::endl
199        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
200        << indent <<   "value:  " << unsigned( value())
201        << ( value()==0 ? " (infinite)" : " seconds") << std::endl;
202 }
203
204
205 ///////////////////////////////////////////////////////////////////////////
206 // senf::MIHBaseTLVParser
207
208 prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
209         MIHTLVLengthParser::value_type size) 
210 {
211     MIHTLVLengthParser::value_type current_length ( length());
212     length_() << size;
213
214     safe_data_iterator si (data(), boost::next(i(), 1 + length_().bytes() ));
215     if (current_length > size)
216         data().erase( si, boost::next(si, current_length-size));
217     else
218         data().insert( si, size-current_length, 0);
219     return si;
220 }
221
222
223 ///////////////////////////////////////////////////////////////////////////
224 // senf::MIHTLVLengthParser
225
226 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const 
227 {
228     switch (bytes() ) {
229     case 1:
230         return length_field().value();
231     case 2:
232         return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
233     case 3:
234         return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
235     case 4:
236         return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
237     case 5:
238         return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
239     default:
240         throw( MIHTLVLengthException());
241     };
242 }
243
244 prefix_ void senf::MIHTLVLengthParser::value(value_type const & v) 
245 {
246     switch (bytes() ) {
247     case 1:
248         if (v > 128) throw( MIHTLVLengthException());
249         length_field() = v;
250         return;
251     case 2:
252         if (v > UInt8Parser::max_value + 128) throw( MIHTLVLengthException());
253         parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
254         break;
255     case 3:
256         if (v > UInt16Parser::max_value + 128) throw( MIHTLVLengthException());
257         parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
258         break;;
259     case 4:
260         if (v > UInt24Parser::max_value + 128) throw( MIHTLVLengthException());
261         parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
262         break;
263     case 5:
264         parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
265         break;
266     default:
267         throw( MIHTLVLengthException());
268     };
269     underflow_flag() = (v <= 128);
270 }
271
272 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue()
273     const
274 {
275     switch (bytes() ) {
276     case 1:
277         return 128;
278     case 2:
279         return UInt8Parser::max_value + 128;
280     case 3:
281         return UInt16Parser::max_value + 128;
282     case 4:
283         return UInt24Parser::max_value + 128;
284     case 5:
285         return UInt32Parser::max_value; 
286     default:
287         throw( MIHTLVLengthException());
288     };
289 }
290
291 prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other) 
292 {
293     value(other);
294     return *this; 
295 }
296
297 prefix_ void senf::MIHTLVLengthParser::init() const 
298 {
299     defaultInit();
300     extended_length_flag() = false;
301 }
302
303 prefix_ void senf::MIHTLVLengthParser::finalize()
304 {
305     value_type v = value();
306     size_type b = bytes();
307     if (v <= 128) {
308         if (b != 1) resize_(1);
309         return;
310     }
311     if (v <= UInt8Parser::max_value + 128) {
312         if (b != 2) resize_(2);
313         return;
314     }
315     if (v <= UInt16Parser::max_value + 128) {
316         if (b != 3) resize_(3);
317         return;
318     }
319     if (v <= UInt24Parser::max_value + 128 ) {
320         if (b != 4) resize_(4);
321         return;
322     }
323     if (b != 5) resize_(5);
324 }
325
326 prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v)
327 {
328     if (v <= 128)
329         return;
330     size_type b = bytes();
331     if (v <= UInt8Parser::max_value + 128) {
332         if (b < 2) resize_(2);
333         return;
334     }
335     if (v <= UInt16Parser::max_value + 128) {
336         if (b < 3) resize_(3);
337         return;
338     }
339     if (v <= UInt24Parser::max_value + 128) {
340         if (b < 4) resize_(4);
341         return;
342     }
343     if (b < 5) resize_(5);
344 }
345
346 prefix_ void senf::MIHTLVLengthParser::resize_(size_type size)
347 {
348     value_type v = value();
349     resize(bytes(), size);
350     if (size > 1) {
351         extended_length_flag() = true;
352         fixed_length_field() = size - 1;
353     } else {
354         extended_length_flag() = false;
355     }
356     value(v);
357 }
358
359
360 ///////////////////////////////cc.e////////////////////////////////////////
361 #undef prefix_
362
363 \f
364 // Local Variables:
365 // mode: c++
366 // fill-column: 100
367 // c-file-style: "senf"
368 // indent-tabs-mode: nil
369 // ispell-local-dictionary: "american"
370 // compile-command: "scons -u test"
371 // comment-column: 40
372 // End: