switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / 80221Bundle / TLVParser.test.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 unit tests */
30
31 //#include "TLVParser.test.hh"
32 //#include "TLVParser.test.ih"
33
34 // Custom includes
35 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
36 #include "TLVParser.hh"
37 #include "Exceptions.hh"
38
39 #include <senf/Utils/auto_unit_test.hh>
40 #include <boost/test/test_tools.hpp>
41
42 #define prefix_
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44
45 using namespace senf;
46
47 namespace {
48     struct VoidPacket : public PacketTypeBase
49     {};
50 }
51
52 #define CHECK_TLVParser(tlvParser, ptype, plength)                          \
53 {                                                                           \
54     BOOST_CHECK_EQUAL( tlvParser.type(),         ptype   );                 \
55     BOOST_CHECK_EQUAL( tlvParser.length(),       plength );                 \
56     BOOST_CHECK_EQUAL( tlvParser.value().size(), int(plength) );            \
57     senf::PacketData::iterator dataIterator (tlvParser.value().begin());    \
58     for (unsigned i=0; i<plength; i++) {                                    \
59         BOOST_CHECK_EQUAL( *dataIterator, i );                              \
60         dataIterator++;                                                     \
61     }                                                                       \
62 }
63
64
65 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_simple_length)
66 {
67     PacketInterpreterBase::byte data[] = {
68         0x01, // type
69         0x0A, // first bit not set, length=10
70         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
71     };
72     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
73     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
74     CHECK_TLVParser( tlvParser, 0x01, 0x0Au );
75 }
76
77
78 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_extended_length)
79 {
80     PacketInterpreterBase::byte data[] = {
81         0x01, // type
82         0x81, // first and last bit set => one byte length following
83         0x0A, // length (10 = 138 bytes value follows)
84         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
85         0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
86         0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
87         0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
88         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
89         0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
90         0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
91         0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
92         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
93         0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
94         0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
95         0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
96         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81,
97         0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89
98     };
99     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
100     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
101     CHECK_TLVParser( tlvParser, 0x01, 0x8au );
102 }
103
104
105 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_simple_length)
106 {
107     PacketInterpreterBase::byte value[] = {
108            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
109     };
110     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(
111             senf::PacketInterpreterBase::size_type(2u)));
112     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
113     tlvParser.type() = 42u;
114     tlvParser.value( value);
115     tlvParser.finalize();
116
117     CHECK_TLVParser( tlvParser, 42u, 0x0Au );
118
119     PacketInterpreterBase::byte data[] = {
120         0x2a, // type
121         0x0A, // first bit not set, length=10
122         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
123     };
124     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
125             p->data().begin(), p->data().end() );
126 }
127
128
129 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length)
130 {
131     PacketInterpreterBase::byte value[255];
132     for (unsigned i=0; i<sizeof(value); i++)
133         value[i] = i;
134     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(
135             senf::PacketInterpreterBase::size_type(2u)));
136     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
137     tlvParser.maxLength( MIHTLVLengthParser::max_value);
138     tlvParser.type() = 42u;
139     tlvParser.value( value);
140     tlvParser.finalize();
141
142     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
143
144     PacketInterpreterBase::byte data[] = {
145         0x2a, // type
146         0x81, // first and last bit set => one byte length following
147         0x7f, // length (127 = 255 bytes value)
148         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value
149     };
150     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
151             p->data().begin(), boost::next( p->data().begin(), sizeof(data)) );
152 }
153
154
155 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid)
156 {
157     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(
158             senf::PacketInterpreterBase::size_type(2u)));
159     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
160     tlvParser.type() = 42u;
161     tlvParser.finalize();
162
163     PacketInterpreterBase::byte value[255];
164     for (unsigned i=0; i<sizeof(value); i++)
165         value[i] = i;
166
167     BOOST_CHECK_THROW( tlvParser.value( value), MIHTLVLengthException);
168     tlvParser.maxLength( sizeof(value));
169     tlvParser.value( value);
170     tlvParser.finalize();
171     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
172 }
173
174
175 namespace {
176
177     struct TestMacAddressTLVPacketParser : public MIHBaseTLVParser
178     {
179     #   include SENF_PARSER()
180         SENF_PARSER_INHERIT ( MIHBaseTLVParser );
181         SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
182         SENF_PARSER_FINALIZE( TestMacAddressTLVPacketParser );
183     };
184
185     struct TestMacAddressTLVPacketType
186         : public PacketTypeBase,
187           public PacketTypeMixin<TestMacAddressTLVPacketType>
188     {
189         typedef PacketTypeMixin<TestMacAddressTLVPacketType> mixin;
190         typedef TestMacAddressTLVPacketParser parser;
191
192         using mixin::nextPacketRange;
193         using mixin::init;
194         using mixin::initSize;
195
196         static void finalize(ConcretePacket<TestMacAddressTLVPacketType> p) {
197             p->finalize();
198         }
199     };
200     typedef ConcretePacket<TestMacAddressTLVPacketType> TestMacAddressTLVPacket;
201 }
202
203 SENF_AUTO_UNIT_TEST(TestMacAddressTLVPacket_create)
204 {
205     TestMacAddressTLVPacket tlvPacket (TestMacAddressTLVPacket::create());
206     tlvPacket->type() = 42;
207     tlvPacket->value().push_back( senf::MACAddress::from_string("01:23:45:67:89:ab") );
208     tlvPacket->value().push_back( senf::MACAddress::from_string("cd:ef:01:23:45:67") );
209     tlvPacket.finalizeThis();
210
211     unsigned char data[] = {
212         0x2a, // type
213         0x0c, // length
214         0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67  // value
215     };
216     SENF_CHECK_EQUAL_COLLECTIONS(
217             data, data+sizeof(data), tlvPacket.data().begin(), tlvPacket.data().end() );
218 }
219
220
221 //-/////////////////////////////////////////////////////////////////////////////////////////////////
222 #undef prefix_
223
224 \f
225 // Local Variables:
226 // mode: c++
227 // fill-column: 100
228 // c-file-style: "senf"
229 // indent-tabs-mode: nil
230 // ispell-local-dictionary: "american"
231 // compile-command: "scons -u test"
232 // comment-column: 40
233 // End: