renaming
[senf.git] / Packets / MPEGDVBBundle / DTCPPacket.hh
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum NETwork research (NET)
4 //     David Wagner <david.wagner@fokus.fraunhofer.de>
5 //
6 #ifndef DTCPPACKET_HH_
7 #define DTCPPACKET_HH_
8
9 #include "../../Packets/Packets.hh"
10 #include "../../Packets/DefaultBundle/IpV4Packet.hh"
11 #include "../../Packets/DefaultBundle/IpV6Packet.hh"
12
13 namespace senf {
14     
15     //first we have to define some helpers
16     struct DTCPIpV4AddressListParser : public PacketParserBase {
17 #       include SENF_PARSER()        
18         SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, Parse_UInt8 );
19         SENF_PARSER_PRIVATE_FIELD ( reserved ,    Parse_UInt8 );   //must be zero 
20         SENF_PARSER_VEC_N         ( fbiplist,     num_of_fbips, Parse_INet4Address );
21
22         SENF_PARSER_FINALIZE(DTCPIpV4AddressListParser);
23     };
24         
25     struct DTCPIpV6AddressListParser : public PacketParserBase {
26 #       include SENF_PARSER()        
27         SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, Parse_UInt8 );
28         SENF_PARSER_PRIVATE_FIELD ( reserved,     Parse_UInt8 );   //must be zero 
29         SENF_PARSER_VEC_N         ( fbiplist,     num_of_fbips, Parse_INet6Address );
30
31         SENF_PARSER_FINALIZE(DTCPIpV6AddressListParser);
32     };
33
34     /** \brief Parse a DTCP packet
35
36         Parser implementing the DTCP packet according to RFC 3077
37         
38         \see DTCPPacketType
39      */
40     struct Parse_DTCPPacket : public PacketParserBase
41     {
42 #       include SENF_PARSER()
43
44         SENF_PARSER_BITFIELD         ( version_number,       4, unsigned );  // =1 according to rfc3077
45         SENF_PARSER_BITFIELD         ( command,              4, unsigned );  // 1=JOIN 2=LEAVE
46         SENF_PARSER_FIELD            ( interval,             Parse_UInt8 );  // 5 according to rfc3077
47         SENF_PARSER_FIELD            ( sequence_number,      Parse_UInt16 );
48         SENF_PARSER_PRIVATE_BITFIELD ( reserved,             3, unsigned );
49         SENF_PARSER_BITFIELD         ( receive_capable_feed, 1, bool );      // 0=send only, 1=receive_capable_feed
50         SENF_PARSER_BITFIELD         ( ip_version,           4, unsigned );  // 4=IPv4, 6=IPv6
51         SENF_PARSER_FIELD            ( tunnel_protocol,      Parse_UInt8 ); 
52                 /* Please consider the following comments on the implementation given in this class: 
53                  * 1. you could think of simply using SENF_PARSER_PRIVATE_VARIANT and List / Vectorparser like this:
54                  * SENF_PARSER_PRIVATE_VARIANT  ( fbiplist,             ip_version,
55          *                                                       (senf::VoidPacketParser) //ip_version=0
56          *                                                       (senf::VoidPacketParser) //1
57          *                                                       (senf::VoidPacketParser) //2
58          *                                                       (senf::VoidPacketParser) //3
59          *                                                       (senf::Parse_ListB< IpV4Packet, num_of_fbips>) //4 
60          *                                                       (senf::VoidPacketParser) //5
61          *                                                       (senf::Parse_ListB< IpV6Packet, num_of_fbips>) ); //6
62          * This can't work for two reasons: 
63          *              -SENF_PARSER_PRIVATE_VARIANT only accepts 6 templates in types but you have to start from 0.
64          *              -you NEVER can use templated Parsers in these macros since the macro-preprocessor won't recognize the <> brackets and will
65          *                      interpret the ","
66          * 
67          * The first problem is solved by using (actually inventing)  SENF_PARSER_VARIANT_TRANS which has the same limitations 
68          *              concerning the number of types but isn't limited to the values used. This is achieved by a translating function 
69          *              as you can see. 
70          * The second problem is solved by introducing Helper-Parser which cover both the list and the number field. By that no 
71          *              templates have to be used. 
72                 */
73
74                 struct ip_version_translator {
75                     static unsigned fromChooser(ip_version_t::value_type in) {
76                         switch (in) { 
77                         case 4: return 0;
78                         case 6: return 1;
79                         }
80                     }
81                     static ip_version_t::value_type toChooser(unsigned in) {
82                         switch (in) {
83                             case 0: return 4;
84                             case 1: return 6; 
85                         }
86                     }
87                 };
88     
89         SENF_PARSER_VARIANT_TRANS    ( fbiplist,             ip_version, ip_version_translator,
90                                                                  (senf::DTCPIpV4AddressListParser)        //IPv4 
91                                                                  (senf::DTCPIpV6AddressListParser) );     //IPv6
92
93         SENF_PARSER_FINALIZE(Parse_DTCPPacket);
94     };
95     
96     /** \brief DTCP packet
97         
98         \par Packet type (typedef):
99             \ref DTCPPacket
100
101         \par Fields:
102             \ref Parse_DTCPPacket
103
104         \ingroup protocolbundle_mpegdvb
105      */
106     struct DTCPPacketType
107         : public PacketTypeBase,
108           public PacketTypeMixin<DTCPPacketType>
109     {
110         typedef PacketTypeMixin<DTCPPacketType> mixin;
111         typedef ConcretePacket<DTCPPacketType> packet;
112         typedef Parse_DTCPPacket parser;
113     
114         using mixin::nextPacketRange;
115         using mixin::init;
116         using mixin::initSize;
117         
118         static void dump(packet p, std::ostream & os);
119     };
120     
121     /** \brief DTCP packet typedef */
122     typedef DTCPPacketType::packet DTCPPacket;
123 }
124
125 #endif /*DTCPPACKET_HH_*/