switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / 80221Bundle / TLVParser.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Thorsten Horstmann <tho@berlios.de>
27
28 /** \file
29     \brief TLVParser non-inline non-template implementation */
30
31 #include "TLVParser.hh"
32 //#include "TLVParser.ih"
33
34 // Custom includes
35 #include <senf/Utils/hexdump.hh>
36 #include <senf/Utils/Format.hh>
37 #include "Exceptions.hh"
38
39 #define prefix_
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41
42 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFSrcIdTLVParser );
43 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFDstIdTLVParser );
44 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHStatusTLVParser );
45 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHValidTimeIntervalTLVParser );
46
47 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48 // MIHBaseTLVParser
49
50 prefix_ void senf::MIHBaseTLVParser::validateType(boost::uint8_t expectedType)
51     const
52 {
53     if (! check( 1 + senf::bytes(length_()) + length()) )
54         throw InvalidMIHPacketException("truncated TLV.") << " Type: " << unsigned(type());
55     if (type() != expectedType)
56         throw InvalidMIHPacketException("wrong TLV type. expected ") << unsigned(expectedType) << " got " << unsigned(type());
57 }
58
59 prefix_ void senf::MIHBaseTLVParser::validateTypeLength(boost::uint8_t expectedType, MIHTLVLengthParser::value_type expectedLength)
60     const
61 {
62     validateType( expectedType);
63     if (length() != expectedLength)
64         throw InvalidMIHPacketException("invalid length in TLV.") << " Type: " << unsigned(type());
65 }
66
67 //-/////////////////////////////////////////////////////////////////////////////////////////////////
68 // senf::MIHBaseListTLVParser
69
70 prefix_ void senf::MIHBaseListTLVParser::maxListSize(MIHTLVLengthParser::value_type maxl)
71     const
72 {
73     protect(), listSize_().capacity( maxl);
74     maxLength( maxl + senf::bytes(listSize_()));
75 }
76
77 //-/////////////////////////////////////////////////////////////////////////////////////////////////
78 // senf::MIHFIdTLVParser
79
80 prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
81     const
82 {
83     senf::format::IndentHelper indent;
84     os << indent << "type:   " << unsigned (type()) << std::endl
85        << indent << "length: " << unsigned (length()) << std::endl
86        << indent << "value:\n";
87     std::string src_mihfId (valueAsString());
88     hexdump(src_mihfId.begin(), src_mihfId.end(), os);
89 }
90
91 prefix_ void senf::MIHFIdTLVParser::finalize()
92 {
93     protect(), idLength_().finalize();
94     length_() << idLength() + senf::bytes(idLength_());
95     MIHBaseTLVParser::finalize();
96 }
97
98 prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxl)
99     const
100 {
101     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
102     if (maxl > 253)
103         throw std::length_error("maximum length of a MIHF_ID is 253 octets");
104     protect(), idLength_().capacity( maxl);
105     maxLength( maxl + senf::bytes(idLength_()));
106 }
107
108 prefix_ senf::safe_data_iterator senf::MIHFIdTLVParser::resizeValueField(
109         MIHTLVLengthParser::value_type size)
110 {
111     MIHTLVLengthParser::value_type current_length ( idLength());
112     idLength_() << size;
113     length_() << size + idLength_().bytes();
114
115     safe_data_iterator si (data(), valueBegin());
116     if (current_length > size)
117         data().erase( si, boost::next(si, current_length-size));
118     else
119         data().insert( si, size-current_length, 0);
120     return si;
121 }
122
123 prefix_ void senf::MIHFIdTLVParser::value(std::string const & id)
124 {
125     size_type str_size (id.size());
126     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
127     if (str_size > 253)
128         throw std::length_error("maximum length of a MIHF_ID is 253 octets");
129     safe_data_iterator si = resizeValueField( str_size);
130     std::copy( id.begin(), id.end(), si);
131 }
132
133 prefix_ void senf::MIHFIdTLVParser::value(senf::MACAddress const & addr)
134 {
135     safe_data_iterator si = resizeValueField(6*2);
136     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
137 }
138
139 prefix_ void senf::MIHFIdTLVParser::value(senf::INet4Address const & addr)
140 {
141     safe_data_iterator si = resizeValueField(4*2);
142     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
143 }
144
145 prefix_ void senf::MIHFIdTLVParser::value(senf::INet6Address const & addr)
146 {
147     safe_data_iterator si = resizeValueField(16*2);
148     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
149 }
150
151 prefix_ void senf::MIHFIdTLVParser::value(senf::EUI64 const & addr)
152 {
153     safe_data_iterator si = resizeValueField(8*2);
154     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
155 }
156
157 prefix_ void senf::MIHFIdTLVParser::value( MIHFId const & id)
158 {
159     boost::apply_visitor( ValueSetterVisitor(*this), id);
160 }
161
162 prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type)
163     const
164 {
165     if (length() == 0) return MIHFId();
166     switch (type) {
167     case MIHFId::MulticastType:
168         return MIHFId();
169     case MIHFId::MACAddress:
170         return MIHFId( valueAsMACAddress());
171     case MIHFId::INet4Address:
172         return MIHFId( valueAsINet4Address());
173     case MIHFId::INet6Address:
174         return MIHFId( valueAsINet6Address());
175     case MIHFId::String:
176         return MIHFId( valueAsString());
177     case MIHFId::EUI64:
178         return MIHFId( valueAsEUI64());
179     }
180     return MIHFId();
181 }
182
183
184 //-/////////////////////////////////////////////////////////////////////////////////////////////////
185 // senf::MIHFSrcIdTLVParser
186
187 prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os)
188     const
189 {
190     senf::format::IndentHelper indent;
191     os << indent << "source MIHF_Id TLV:\n";
192     MIHFIdTLVParser::dump(os);
193 }
194
195 prefix_ void senf::MIHFSrcIdTLVParser::validate()
196     const
197 {
198     validateType( typeId);
199 }
200
201
202 //-/////////////////////////////////////////////////////////////////////////////////////////////////
203 // senf::MIHFDstIdTLVParser
204
205 prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os)
206     const
207 {
208     senf::format::IndentHelper indent;
209     os << indent << "destination MIHF_Id TLV:\n";
210     MIHFIdTLVParser::dump(os);
211 }
212
213 prefix_ void senf::MIHFDstIdTLVParser::validate()
214     const
215 {
216     validateType( typeId);
217 }
218
219 //-/////////////////////////////////////////////////////////////////////////////////////////////////
220 // senf::MIHStatusTLVParser
221
222 prefix_ void senf::MIHStatusTLVParser::dump(std::ostream & os)
223     const
224 {
225     senf::format::IndentHelper indent;
226     os << indent << "Status TLV:" << std::endl;
227     indent.increase();
228     os << indent <<   "type:   " << unsigned( type()) << std::endl
229        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
230        << indent <<   "value:  " << unsigned( value());
231     switch (value()) {
232     case Success:
233         os << " (Success)" << std::endl;
234         return;
235     case UnspecifiedFailure:
236         os << " (Unspecified Failure)" << std::endl;
237         return;
238     case Rejected:
239         os << " (Rejected)" << std::endl;
240         return;
241     case AuthorizationFailure:
242         os << " (Authorization Failure)" << std::endl;
243         return;
244     case NetworkError:
245         os << " (Network Error)" << std::endl;
246         return;
247     }
248     os << " (???; invalid value!)" << std::endl;
249 }
250
251 prefix_ void senf::MIHStatusTLVParser::validate()
252     const
253 {
254     validateTypeLength( typeId, 1);
255     if (value() >= 4)
256         throw InvalidMIHPacketException("invalid value in MIHStatusTLV ") << unsigned( value());
257 }
258
259 //-/////////////////////////////////////////////////////////////////////////////////////////////////
260 // senf::MIHRegisterReqCodeTLVParser
261
262 prefix_ void senf::MIHRegisterReqCodeTLVParser::dump(std::ostream & os)
263     const
264 {
265     senf::format::IndentHelper indent;
266     os << indent << "Register Request Code TLV:" << std::endl;
267     indent.increase();
268     os << indent <<   "type:   " << unsigned( type()) << std::endl
269        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
270        << indent <<   "value:  " << unsigned( value());
271     switch (value()) {
272     case Registration:
273         os << " (Registration)" << std::endl;
274         return;
275     case ReRegistration:
276         os << " (Re-Registration)" << std::endl;
277         return;
278     }
279     os << " (???; invalid value!)" << std::endl;
280 }
281
282 prefix_ void senf::MIHRegisterReqCodeTLVParser::validate()
283     const
284 {
285     validateTypeLength( typeId, 1);
286     if (value() >= 2)
287         throw InvalidMIHPacketException("invalid value in MIHRegisterReqCodeTLV ") << unsigned( value());
288 }
289
290 //-/////////////////////////////////////////////////////////////////////////////////////////////////
291 // senf::MIHValidTimeIntervalTLVParser
292
293 prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os)
294     const
295 {
296     senf::format::IndentHelper indent;
297     os << indent << "Valid Time Interval TLV:" << std::endl;
298     indent.increase();
299     os << indent <<   "type:   " << unsigned( type()) << std::endl
300        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
301        << indent <<   "value:  " << unsigned( value())
302        << ( value()==0 ? " (infinite)" : " seconds") << std::endl;
303 }
304
305 prefix_ void senf::MIHValidTimeIntervalTLVParser::validate()
306     const
307 {
308     validateTypeLength( typeId, 4);
309 }
310
311 //-/////////////////////////////////////////////////////////////////////////////////////////////////
312 // senf::MIHTLVLengthParser
313
314 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const
315 {
316     switch (bytes() ) {
317     case 1:
318         return length_field().value();
319     case 2:
320         return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
321     case 3:
322         return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
323     case 4:
324         return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
325     case 5:
326         return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
327     default:
328         throw( MIHTLVLengthException());
329     };
330 }
331
332 prefix_ void senf::MIHTLVLengthParser::value(value_type const & v)
333 {
334     switch (bytes() ) {
335     case 1:
336         if (v > 128) throw( MIHTLVLengthException());
337         length_field() = v;
338         return;
339     case 2:
340         if (v > UInt8Parser::max_value + 128) throw( MIHTLVLengthException());
341         parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
342         break;
343     case 3:
344         if (v > UInt16Parser::max_value + 128) throw( MIHTLVLengthException());
345         parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
346         break;;
347     case 4:
348         if (v > UInt24Parser::max_value + 128) throw( MIHTLVLengthException());
349         parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
350         break;
351     case 5:
352         parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
353         break;
354     default:
355         throw( MIHTLVLengthException());
356     };
357     underflow_flag() = (v <= 128);
358 }
359
360 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::capacity()
361     const
362 {
363     switch (bytes() ) {
364     case 1:
365         return 128;
366     case 2:
367         return UInt8Parser::max_value + 128;
368     case 3:
369         return UInt16Parser::max_value + 128;
370     case 4:
371         return UInt24Parser::max_value + 128;
372     case 5:
373         return UInt32Parser::max_value;
374     default:
375         throw( MIHTLVLengthException());
376     };
377 }
378
379 prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other)
380 {
381     value(other);
382     return *this;
383 }
384
385 prefix_ void senf::MIHTLVLengthParser::init() const
386 {
387     defaultInit();
388     extended_length_flag() = false;
389 }
390
391 prefix_ void senf::MIHTLVLengthParser::finalize()
392 {
393     value_type v = value();
394     size_type b = bytes();
395     if (v <= 128) {
396         if (b != 1) resize_(1);
397         return;
398     }
399     if (v <= UInt8Parser::max_value + 128) {
400         if (b != 2) resize_(2);
401         return;
402     }
403     if (v <= UInt16Parser::max_value + 128) {
404         if (b != 3) resize_(3);
405         return;
406     }
407     if (v <= UInt24Parser::max_value + 128 ) {
408         if (b != 4) resize_(4);
409         return;
410     }
411     if (b != 5) resize_(5);
412 }
413
414 prefix_ void senf::MIHTLVLengthParser::capacity(MIHTLVLengthParser::value_type v)
415 {
416     if (v <= 128)
417         return;
418     size_type b = bytes();
419     if (v <= UInt8Parser::max_value + 128) {
420         if (b < 2) resize_(2);
421         return;
422     }
423     if (v <= UInt16Parser::max_value + 128) {
424         if (b < 3) resize_(3);
425         return;
426     }
427     if (v <= UInt24Parser::max_value + 128) {
428         if (b < 4) resize_(4);
429         return;
430     }
431     if (b < 5) resize_(5);
432 }
433
434 prefix_ void senf::MIHTLVLengthParser::resize_(size_type size)
435 {
436     value_type v = value();
437     resize(bytes(), size);
438     if (size > 1) {
439         extended_length_flag() = true;
440         fixed_length_field() = size - 1;
441     } else {
442         extended_length_flag() = false;
443     }
444     value(v);
445 }
446
447
448 //-/////////////////////////////////////////////////////////////////////////////////////////////////
449 #undef prefix_
450
451 \f
452 // Local Variables:
453 // mode: c++
454 // fill-column: 100
455 // c-file-style: "senf"
456 // indent-tabs-mode: nil
457 // ispell-local-dictionary: "american"
458 // compile-command: "scons -u test"
459 // comment-column: 40
460 // End: