Packets/80221Bundle: MIHFIdTLVParser API clean up
[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 (valueAsString());
53     hexdump(src_mihfId.begin(), src_mihfId.end(), os);
54 }
55
56 prefix_ void senf::MIHFIdTLVParser::value(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::value(senf::MACAddress const & addr)
67 {
68     safe_data_iterator si = resizeValueField(12);
69     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
70 }
71
72 prefix_ void senf::MIHFIdTLVParser::value(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::value(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::value(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_ void senf::MIHFIdTLVParser::value( MIHFId const & id)
91 {
92     boost::apply_visitor( ValueSetterVisitor(*this), id);
93 }
94
95 prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type)
96     const
97 {
98     if (length() == 0) return MIHFId();
99     switch (type) {
100     case MIHFId::Empty:
101         return MIHFId();
102     case MIHFId::MACAddress:
103         return MIHFId( valueAsMACAddress());
104     case MIHFId::INet4Address:
105         return MIHFId( valueAsINet4Address());
106     case MIHFId::INet6Address:
107         return MIHFId( valueAsINet6Address());
108     case MIHFId::String:
109         return MIHFId( valueAsString());
110     case MIHFId::EUI64:
111         return MIHFId( valueAsEUI64());
112     }
113     return MIHFId();
114 }
115
116
117 ///////////////////////////////////////////////////////////////////////////
118 // senf::MIHFSrcIdTLVParser
119
120 prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os)
121     const
122 {
123     senf::format::IndentHelper indent;
124     os << indent << "source MIHF_Id TLV:\n";
125     MIHFIdTLVParser::dump(os);
126 }
127
128 ///////////////////////////////////////////////////////////////////////////
129 // senf::MIHFDstIdTLVParser
130
131 prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os)
132     const
133 {
134     senf::format::IndentHelper indent;
135     os << indent << "destination MIHF_Id TLV:\n";
136     MIHFIdTLVParser::dump(os);
137 }
138
139 ///////////////////////////////////////////////////////////////////////////
140 // senf::MIHStatusTLVParser
141
142 prefix_ void senf::MIHStatusTLVParser::dump(std::ostream & os)
143     const
144 {
145     senf::format::IndentHelper indent;
146     os << indent << "Status TLV:" << std::endl;
147     indent.increase();
148     os << indent <<   "type:   " << unsigned( type()) << std::endl
149        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
150        << indent <<   "value:  " << unsigned( value());
151     switch (value()) {
152     case Success:
153         os << " (Success)" << std::endl;
154         return;
155     case UnspecifiedFailure:  
156         os << " (Unspecified Failure)" << std::endl;
157         return;
158     case Rejected:
159         os << " (Rejected)" << std::endl;
160         return;
161     case AuthorizationFailure:
162         os << " (Authorization Failure)" << std::endl;
163         return;
164     case NetworkError:
165         os << " (Network Error)" << std::endl;
166         return;
167     }
168     os << " (???; invalid value!)" << std::endl;
169 }
170
171 ///////////////////////////////////////////////////////////////////////////
172 // senf::MIHRegisterReqCodeTLVParser
173
174 prefix_ void senf::MIHRegisterReqCodeTLVParser::dump(std::ostream & os)
175     const
176 {
177     senf::format::IndentHelper indent;
178     os << indent << "Register Request Code TLV:" << std::endl;
179     indent.increase();
180     os << indent <<   "type:   " << unsigned( type()) << std::endl
181        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
182        << indent <<   "value:  " << unsigned( value());
183     switch (value()) {
184     case Registration:
185         os << " (Registration)" << std::endl;
186         return;
187     case ReRegistration:
188         os << " (Re-Registration)" << std::endl;
189         return;
190     }
191     os << " (???; invalid value!)" << std::endl;
192 }
193
194 ///////////////////////////////////////////////////////////////////////////
195 // senf::MIHValidTimeIntervalTLVParser
196
197 prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os)
198     const
199 {
200     senf::format::IndentHelper indent;
201     os << indent << "Valid Time Interval TLV:" << std::endl;
202     indent.increase();
203     os << indent <<   "type:   " << unsigned( type()) << std::endl
204        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
205        << indent <<   "value:  " << unsigned( value())
206        << ( value()==0 ? " (infinite)" : " seconds") << std::endl;
207 }
208
209
210 ///////////////////////////////////////////////////////////////////////////
211 // senf::MIHBaseTLVParser
212
213 prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
214         MIHTLVLengthParser::value_type size) 
215 {
216     MIHTLVLengthParser::value_type current_length ( length());
217     length_() << size;
218
219     safe_data_iterator si (data(), boost::next(i(), 1 + length_().bytes() ));
220     if (current_length > size)
221         data().erase( si, boost::next(si, current_length-size));
222     else
223         data().insert( si, size-current_length, 0);
224     return si;
225 }
226
227
228 ///////////////////////////////////////////////////////////////////////////
229 // senf::MIHTLVLengthParser
230
231 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const 
232 {
233     switch (bytes() ) {
234     case 1:
235         return length_field().value();
236     case 2:
237         return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
238     case 3:
239         return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
240     case 4:
241         return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
242     case 5:
243         return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
244     default:
245         throw( MIHTLVLengthException());
246     };
247 }
248
249 prefix_ void senf::MIHTLVLengthParser::value(value_type const & v) 
250 {
251     switch (bytes() ) {
252     case 1:
253         if (v > 128) throw( MIHTLVLengthException());
254         length_field() = v;
255         return;
256     case 2:
257         if (v > UInt8Parser::max_value + 128) throw( MIHTLVLengthException());
258         parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
259         break;
260     case 3:
261         if (v > UInt16Parser::max_value + 128) throw( MIHTLVLengthException());
262         parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
263         break;;
264     case 4:
265         if (v > UInt24Parser::max_value + 128) throw( MIHTLVLengthException());
266         parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
267         break;
268     case 5:
269         parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
270         break;
271     default:
272         throw( MIHTLVLengthException());
273     };
274     underflow_flag() = (v <= 128);
275 }
276
277 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue()
278     const
279 {
280     switch (bytes() ) {
281     case 1:
282         return 128;
283     case 2:
284         return UInt8Parser::max_value + 128;
285     case 3:
286         return UInt16Parser::max_value + 128;
287     case 4:
288         return UInt24Parser::max_value + 128;
289     case 5:
290         return UInt32Parser::max_value; 
291     default:
292         throw( MIHTLVLengthException());
293     };
294 }
295
296 prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other) 
297 {
298     value(other);
299     return *this; 
300 }
301
302 prefix_ void senf::MIHTLVLengthParser::init() const 
303 {
304     defaultInit();
305     extended_length_flag() = false;
306 }
307
308 prefix_ void senf::MIHTLVLengthParser::finalize()
309 {
310     value_type v = value();
311     size_type b = bytes();
312     if (v <= 128) {
313         if (b != 1) resize_(1);
314         return;
315     }
316     if (v <= UInt8Parser::max_value + 128) {
317         if (b != 2) resize_(2);
318         return;
319     }
320     if (v <= UInt16Parser::max_value + 128) {
321         if (b != 3) resize_(3);
322         return;
323     }
324     if (v <= UInt24Parser::max_value + 128 ) {
325         if (b != 4) resize_(4);
326         return;
327     }
328     if (b != 5) resize_(5);
329 }
330
331 prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v)
332 {
333     if (v <= 128)
334         return;
335     size_type b = bytes();
336     if (v <= UInt8Parser::max_value + 128) {
337         if (b < 2) resize_(2);
338         return;
339     }
340     if (v <= UInt16Parser::max_value + 128) {
341         if (b < 3) resize_(3);
342         return;
343     }
344     if (v <= UInt24Parser::max_value + 128) {
345         if (b < 4) resize_(4);
346         return;
347     }
348     if (b < 5) resize_(5);
349 }
350
351 prefix_ void senf::MIHTLVLengthParser::resize_(size_type size)
352 {
353     value_type v = value();
354     resize(bytes(), size);
355     if (size > 1) {
356         extended_length_flag() = true;
357         fixed_length_field() = size - 1;
358     } else {
359         extended_length_flag() = false;
360     }
361     value(v);
362 }
363
364
365 ///////////////////////////////cc.e////////////////////////////////////////
366 #undef prefix_
367
368 \f
369 // Local Variables:
370 // mode: c++
371 // fill-column: 100
372 // c-file-style: "senf"
373 // indent-tabs-mode: nil
374 // ispell-local-dictionary: "american"
375 // compile-command: "scons -u test"
376 // comment-column: 40
377 // End: