--- /dev/null
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum NETwork research (NET)
+// David Wagner <david.wagner@fokus.fraunhofer.de>
+//
+#ifndef DTCPPACKET_HH_
+#define DTCPPACKET_HH_
+
+#include "../../Packets/Packets.hh"
+#include "../../Packets/DefaultBundle/IpV4Packet.hh"
+#include "../../Packets/DefaultBundle/IpV6Packet.hh"
+
+namespace senf {
+
+ //first we have to define some helpers
+ struct DTCPIpV4AddressListParser : public PacketParserBase {
+# include SENF_PARSER()
+ SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, Parse_UInt8 );
+ SENF_PARSER_PRIVATE_FIELD ( reserved , Parse_UInt8 ); //must be zero
+ SENF_PARSER_VEC_N ( fbiplist, num_of_fbips, Parse_INet4Address );
+
+ SENF_PARSER_FINALIZE(DTCPIpV4AddressListParser);
+ };
+
+ struct DTCPIpV6AddressListParser : public PacketParserBase {
+# include SENF_PARSER()
+ SENF_PARSER_PRIVATE_FIELD ( num_of_fbips, Parse_UInt8 );
+ SENF_PARSER_PRIVATE_FIELD ( reserved, Parse_UInt8 ); //must be zero
+ SENF_PARSER_VEC_N ( fbiplist, num_of_fbips, Parse_INet6Address );
+
+ SENF_PARSER_FINALIZE(DTCPIpV6AddressListParser);
+ };
+
+ /** \brief Parse a DTCP packet
+
+ Parser implementing the DTCP packet according to RFC 3077
+
+ \see DTCPPacketType
+ */
+ struct Parse_DTCPPacket : public PacketParserBase
+ {
+# include SENF_PARSER()
+
+ SENF_PARSER_BITFIELD ( version_number, 4, unsigned ); // =1 according to rfc3077
+ SENF_PARSER_BITFIELD ( command, 4, unsigned ); // 1=JOIN 2=LEAVE
+ SENF_PARSER_FIELD ( interval, Parse_UInt8 ); // 5 according to rfc3077
+ SENF_PARSER_FIELD ( sequence_number, Parse_UInt16 );
+ SENF_PARSER_PRIVATE_BITFIELD ( reserved, 3, unsigned );
+ SENF_PARSER_BITFIELD ( receive_capable_feed, 1, bool ); // 0=send only, 1=receive_capable_feed
+ SENF_PARSER_BITFIELD ( ip_version, 4, unsigned ); // 4=IPv4, 6=IPv6
+ SENF_PARSER_FIELD ( tunnel_protocol, Parse_UInt8 );
+ /* Please consider the following comments on the implementation given in this class:
+ * 1. you could think of simply using SENF_PARSER_PRIVATE_VARIANT and List / Vectorparser like this:
+ * SENF_PARSER_PRIVATE_VARIANT ( fbiplist, ip_version,
+ * (senf::VoidPacketParser) //ip_version=0
+ * (senf::VoidPacketParser) //1
+ * (senf::VoidPacketParser) //2
+ * (senf::VoidPacketParser) //3
+ * (senf::Parse_ListB< IpV4Packet, num_of_fbips>) //4
+ * (senf::VoidPacketParser) //5
+ * (senf::Parse_ListB< IpV6Packet, num_of_fbips>) ); //6
+ * This can't work for two reasons:
+ * -SENF_PARSER_PRIVATE_VARIANT only accepts 6 templates in types but you have to start from 0.
+ * -you NEVER can use templated Parsers in these macros since the macro-preprocessor won't recognize the <> brackets and will
+ * interpret the ","
+ *
+ * The first problem is solved by using (actually inventing) SENF_PARSER_VARIANT_TRANS which has the same limitations
+ * concerning the number of types but isn't limited to the values used. This is achieved by a translating function
+ * as you can see.
+ * The second problem is solved by introducing Helper-Parser which cover both the list and the number field. By that no
+ * templates have to be used.
+ */
+
+ struct ip_version_translator {
+ static unsigned fromChooser(ip_version_t::value_type in) {
+ switch (in) {
+ case 4: return 0;
+ case 6: return 1;
+ }
+ }
+ static ip_version_t::value_type toChooser(unsigned in) {
+ switch (in) {
+ case 0: return 4;
+ case 1: return 6;
+ }
+ }
+ };
+
+ SENF_PARSER_VARIANT_TRANS ( fbiplist, ip_version, ip_version_translator,
+ (senf::DTCPIpV4AddressListParser) //IPv4
+ (senf::DTCPIpV6AddressListParser) ); //IPv6
+
+ SENF_PARSER_FINALIZE(Parse_DTCPPacket);
+ };
+
+ /** \brief DTCP packet
+
+ \par Packet type (typedef):
+ \ref DTCPPacket
+
+ \par Fields:
+ \ref Parse_DTCPPacket
+
+ \ingroup protocolbundle_mpegdvb
+ */
+ struct DTCPPacketType
+ : public PacketTypeBase,
+ public PacketTypeMixin<DTCPPacketType>
+ {
+ typedef PacketTypeMixin<DTCPPacketType> mixin;
+ typedef ConcretePacket<DTCPPacketType> packet;
+ typedef Parse_DTCPPacket parser;
+
+ using mixin::nextPacketRange;
+ using mixin::init;
+ using mixin::initSize;
+
+ static void dump(packet p, std::ostream & os);
+ };
+
+ /** \brief DTCP packet typedef */
+ typedef DTCPPacketType::packet DTCPPacket;
+}
+
+#endif /*DTCPPACKET_HH_*/