#include "Scheduler/Scheduler.hh"
#include "Packets/DefaultBundle/EthernetPacket.hh"
#include "Packets/MPEGDVBBundle/TransportPacket.hh"
+#include "Packets/MPEGDVBBundle/SNDUPacket.hh"
#include "Utils/membind.hh"
#include "Socket/Protocols/DVB/DVBDemuxHandles.hh"
#include "Packets/ParseInt.hh"
#include "Packets/Packet.hh"
#include "Packets/PacketData.hh"
+#include "Packets/ParseInt.hh"
#define PID 271
+#define TS_SYNC 0x47
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
}
-class MySniffer
+class ULEdec
{
senf::DVBDemuxPESHandle demuxHandle;
senf::DVBDvrHandle dvrHandle;
-
+
+ unsigned char receiver_state;
+ unsigned char priv_tscc;
public:
- MySniffer()
+ ULEdec()
{
struct dmx_pes_filter_params pes_filter;
memset(&pes_filter, 0, sizeof (struct dmx_pes_filter_params));
pes_filter.output = DMX_OUT_TS_TAP;
pes_filter.pes_type = DMX_PES_OTHER;
pes_filter.flags = DMX_IMMEDIATE_START;
-
demuxHandle.protocol().setPESFilter( &pes_filter );
senf::Scheduler::instance().add(
- dvrHandle, senf::membind(&MySniffer::dumpSection, this));
+ dvrHandle, senf::membind(&ULEdec::handlePacket, this));
+
+ receiver_state = 1; // Idle
}
private:
- void dumpSection(senf::FileHandle /* ignored */, senf::Scheduler::EventId event)
+ void handlePacket(senf::FileHandle, senf::Scheduler::EventId event)
{
- std::string data (dvrHandle.read());
- senf::TransportPacket packet (senf::TransportPacket::create(data));
- packet.dump(std::cout);
- senf::PacketData & packetData (packet.last().data());
- hexdump(packetData.begin(), packetData.end(), std::cout);
+ char ts_data[188];
+ dvrHandle.read(&ts_data[0], &ts_data[188]);
+ senf::TransportPacket tsPacket (
+ senf::TransportPacket::create( boost::begin(ts_data) ));
+// packet.dump(std::cout);
+// senf::PacketData & packetData (packet.last().data());
+// hexdump(packetData.begin(), packetData.end(), std::cout);
+
+ // Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control.
+ if ( (tsPacket->sync_byte() != TS_SYNC) ||
+ (tsPacket->transport_error_indicator() == true) ||
+ (tsPacket->transport_scrmbl_ctrl() != 0))
+ {
+ std::cerr << "invalid ts packet\n";
+ // drop partly decoded SNDU, reset state, resync on PUSI.
+ return;
+ }
+
+ unsigned char payload_pointer;
+ switch (receiver_state) {
+ case 1: // Idle State
+ // resync on PUSI
+ if (tsPacket->pusi() == 0)
+ return; // skip packet
+ // Synchronize continuity counter
+ priv_tscc = tsPacket->continuity_counter();
+ // a PUSI value of 1 indicates the presence of a Payload Pointer.
+ payload_pointer = ts_data[4];
+ if (payload_pointer>181) {
+ std::cerr << "invalid payload_pointer\n";
+ return;
+ }
+
+ //
+ break;
+ case 2: // Reassembly State
+ break;
+ }
}
};
int main(int argc, char const * argv[])
{
try {
- MySniffer sniffer;
+ ULEdec decoder;
senf::Scheduler::instance().process();
}
catch (std::exception const & ex) {
# else
- Parse_Version version();
- Parse_IHL ihl();
- Parse_8bit tos();
- Parse_16bit length();
- Parse_16bit identifier();
- Parse_R reserved();
- Parse_DF df();
- Parse_MF mf();
- Parse_Frag frag();
- Parse_8bit ttl();
- Parse_8bit protocol();
- Parse_16bit crc();
- Parse_32bit source();
- Parse_32bit destination();
+ Parse_Version version() const;
+ Parse_IHL ihl() const;
+ Parse_8bit tos() const;
+ Parse_16bit length() const;
+ Parse_16bit identifier() const;
+ Parse_R reserved() const;
+ Parse_DF df() const;
+ Parse_MF mf() const;
+ Parse_Frag frag() const;
+ Parse_8bit ttl() const;
+ Parse_8bit protocol() const;
+ Parse_16bit crc() const;
+ Parse_32bit source() const;
+ Parse_32bit destination() const;
# endif
# else
- Parse_Version version();
- Parse_Class trafficClass();
- Parse_FlowLabel flowLabel();
- Parse_16bit length();
- Parse_8bit nextHeader();
- Parse_8bit hopLimit();
- Parse_Addr source();
- Parse_Addr destination();
+ Parse_Version version() const;
+ Parse_Class trafficClass() const;
+ Parse_FlowLabel flowLabel() const;
+ Parse_16bit length() const;
+ Parse_8bit nextHeader() const;
+ Parse_8bit hopLimit() const;
+ Parse_Addr source() const;
+ Parse_Addr destination() const;
# endif
#include <algorithm>
#include "Packets/PacketType.hh"
#include "Packets/ParseInt.hh"
-#include "Packets/PacketRegistry.hh"
#include "Packets/PacketParser.hh"
//#include "DSMCCSection.mpp"
namespace senf {
- ///\addtogroup protocolbundle_mpegdvb
- ///@{
-
+ /** \brief Parse a DSMCC Section
+
+ Parser implementing the header of a DSMCC Section
+
+ \see DSMCCSectionType
+ */
struct Parse_DSMCCSection : public PacketParserBase
{
- SENF_PACKET_PARSER_INIT(Parse_DSMCCSection);
-
- ///////////////////////////////////////////////////////////////////////////
-
typedef Parse_UInt8 Parse_table_id;
typedef Parse_Flag < 0 > Parse_ssi; // section_syntax_indicator
typedef Parse_Flag < 1 > Parse_pi; // private_indicator
typedef Parse_UIntField < 0, 2 > Parse_reserved_2;
typedef Parse_UIntField < 2, 7 > Parse_version_num;
typedef Parse_Flag < 7 > Parse_curr_next_indicator;
-
+
+# ifndef DOXYGEN
+
+ SENF_PACKET_PARSER_INIT(Parse_DSMCCSection);
+
SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(
((Field ) ( table_id, Parse_table_id ))
((OverlayField) ( ssi, Parse_ssi ))
((Field ) ( last_sec_num, Parse_UInt8 ))
);
+# else
+
+ Parse_table_id table_id() const;
+ Parse_ssi ssi() const;
+ Parse_pi pi() const;
+ Parse_reserved_1 reserved_1() const;
+ Parse_sec_length sec_length const;
+ Parse_UInt16 tabel_id_extension() const;
+ Parse_reserved_2 reserved_2() const;
+ Parse_version_num version_num() const;
+ Parse_curr_next_indicator curr_next_indicator() const;
+ Parse_UInt8 sec_num() const;
+ Parse_UInt8 last_sec_num() const;
+
+# endif
+
Parse_UInt32 crc() const { return parse<Parse_UInt32>( data().size()-4 ); }
};
+
+ /** \brief DSMCC Section
+
+ \par Packet type (typedef):
+ \ref DSMCCSection
+ \par Fields:
+ \ref Parse_DSMCCSection
+
+ \ingroup protocolbundle_mpegdvb
+ */
struct DSMCCSectionType
: public PacketTypeBase,
public PacketTypeMixin<DSMCCSectionType>
};
typedef DSMCCSectionType::packet DSMCCSection;
-
- ///@}
}
namespace senf {
- ///\addtogroup protocolbundle_mpegdvb
- ///@{
-
+ /** \brief Parse a Datagram Section
+
+ Parser implementing the Datagram Section.
+
+ \see DatagramSectionType
+ */
struct Parse_DatagramSection : public Parse_DSMCCSection
{
- //SENF_PACKET_PARSER_NO_INIT(Parse_DatagramSection);
Parse_DatagramSection(data_iterator i, state_type s) : senf::Parse_DSMCCSection(i,s) {}
- ///////////////////////////////////////////////////////////////////////////
-
typedef Parse_UIntField < 2, 4 > Parse_payload_scrmbl_ctrl;
typedef Parse_UIntField < 4, 6 > Parse_addr_scrmbl_ctrl;
typedef Parse_Flag < 6 > Parse_llc_snap_flag;
+# ifndef DOXYGEN
+
SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(Parse_DSMCCSection::fixed_bytes,
((Field ) ( mac_addr_4, Parse_UInt8 ))
((Field ) ( mac_addr_3, Parse_UInt8 ))
((Field ) ( mac_addr_1, Parse_UInt8 ))
);
+# else
+
+ Parse_UInt8 mac_addr_4() const;
+ Parse_UInt8 mac_addr_3() const;
+ Parse_UInt8 mac_addr_2() const;
+ Parse_UInt8 mac_addr_1() const;
+
+# endif
+
Parse_UInt8 mac_addr_6() const { return parse<Parse_UInt8>( 3 ); }
Parse_UInt8 mac_addr_5() const { return parse<Parse_UInt8>( 4 ); }
Parse_payload_scrmbl_ctrl payload_scrmbl_ctrl() const {
}
};
+ /** \brief Datagram Section
+
+ \par Packet type (typedef):
+ \ref DatagramSection
+
+ \par Fields:
+ \ref Parse_DatagramSection
+
+ \ingroup protocolbundle_mpegdvb
+ */
struct DatagramSectionType
: public DSMCCSectionType,
public PacketTypeMixin<DatagramSectionType>
};
typedef DatagramSectionType::packet DatagramSection;
-
- ///@}
}
--- /dev/null
+// $Id: DSMCCSection.cc 350 2007-07-25 08:26:41Z g0dil $
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief DSMCCSection non-inline non-template implementation */
+
+#include "SNDUPacket.hh"
+//#include "SNDUPacket.ih"
+
+// Custom includes
+#include <iomanip>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+//namespace {
+// senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::EthVLanPacketType>
+// registerEthVLanPacket(0x8100);
+//}
+
+
+prefix_ senf::PacketParserBase::size_type senf::Parse_SNDUPacket::bytes()
+ const
+{
+ if ( d_bit() )
+ return 2 + 2 + 4; // D-Bit + 15 bits length + 16 bits type field + 32 bits crc
+ else
+ return 2 + 2 + 4 + 6; // + 6 Byte NPA destination address
+}
+
+prefix_ void senf::SNDUPacketType::dump(packet p, std::ostream & os)
+{
+ os << "SNDUPacket:\n";
+}
+
+prefix_ senf::PacketParserBase::size_type senf::SNDUPacketType::initSize()
+{
+ return 2 + 2 + 4; // D-Bit + 15 bits length + 16 bits type field + 32 bits crc
+}
+
+prefix_ senf::PacketParserBase::size_type senf::SNDUPacketType::initHeadSize()
+{
+ return 2 + 2; // D-Bit + 15 bits length + 16 bits type field
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
--- /dev/null
+// $Id:DSMCCSection.hh 327 2007-07-20 10:03:44Z tho $
+//
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief SNDUPacket public header */
+
+#ifndef HH_SNDUPacket_
+#define HH_SNDUPacket_ 1
+
+// Custom includes
+#include <algorithm>
+#include "Packets/PacketType.hh"
+#include "Packets/ParseInt.hh"
+#include "Packets/PacketRegistry.hh"
+#include "Packets/PacketParser.hh"
+#include "Packets/DefaultBundle/EthernetPacket.hh"
+
+//#include "SNDUPacket.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+ /** \brief parse ULE SNDU Packet
+
+ Parser implementing the header and trailer of a ULE SNDU Packet
+
+ \see SNDUPacketType
+ */
+ struct Parse_SNDUPacket : public PacketParserBase
+ {
+# ifndef DOXYGEN
+
+ SENF_PACKET_PARSER_INIT(Parse_SNDUPacket);
+
+# endif
+
+ typedef Parse_Flag < 0 > Parse_daaf; // Destination Address Absent Field
+ typedef Parse_UIntField < 1, 16 > Parse_length;
+
+ Parse_daaf d_bit() const {
+ return parse<Parse_daaf>( 0 );
+ }
+ Parse_length length() const {
+ return parse<Parse_length>( 0 );
+ }
+ Parse_UInt16 type() const {
+ return parse<Parse_UInt16>( 2 );
+ }
+ Parse_MAC destination() const {
+ BOOST_ASSERT( ! d_bit() );
+ return parse<Parse_MAC>( 4 );
+ }
+ Parse_UInt32 crc() const {
+ return parse<Parse_UInt32>( data().size()-4 );
+ }
+
+ PacketParserBase::size_type bytes() const;
+
+ static const size_type init_bytes = 2+2+4; // D-Bit + 15 bits length + 16 bits type field + 32 bits crc
+ };
+
+ /** \brief ULE SNDU Packet
+
+ \par Packet type (typedef):
+ \ref SNDUPacket
+
+ \par Fields:
+ \ref Parse_SNDUPacket
+
+ \ingroup protocolbundle_mpegdvb
+ */
+ struct SNDUPacketType
+ : public PacketTypeBase,
+ public PacketTypeMixin<SNDUPacketType>
+ {
+ typedef PacketTypeMixin<SNDUPacketType> mixin;
+ typedef ConcretePacket<SNDUPacketType> packet;
+ typedef Parse_SNDUPacket parser;
+
+ using mixin::nextPacketRange;
+// using mixin::nextPacketType;
+ using mixin::init;
+
+ static void dump(packet p, std::ostream & os);
+
+ static PacketParserBase::size_type initSize();
+ static PacketParserBase::size_type initHeadSize();
+ };
+
+ typedef SNDUPacketType::packet SNDUPacket;
+
+ /*!
+ \def ULE_END_INDICATOR
+ ULE End Indicator; indicates to the Receiver that there are no
+ further SNDUs present within the current TS Packet.
+ */
+# define ULE_END_INDICATOR 0xffff
+}
+
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "SNDUPacket.cci"
+//#include "SNDUPacket.ct"
+//#include "SNDUPacket.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
namespace senf {
- /** \brief Parse a UDP packet
+ /** \brief Parse a Transport Stream packet
Parser implementing the header of a MPEG Transport Stream Packet.
/** \brief Parser Base class
- Parsers come in two favors: fixed and dynamically sized parsers. A <em>fixed size
+ Parsers come in two flavors: fixed and dynamically sized parsers. A <em>fixed size
parser</em> has a constant size, it will always parse a fixed number of bytes. The low-level
'final' parsers (like the integer parsers) are fixed size parsers as are composite parsers
built up only of fixed-size fields.
using these macros has the following form (This is a concrete example from the definition of
the ethernet packet in <tt>DefaultBundle/EthernetPacket.hh</tt>)
- \dontinclude EthernetPacket.hh
- \skipline struct Parse_EthVLan : public PacketParserBase
- \until };
-
+ \code
+ struct Parse_EthVLan : public PacketParserBase
+ {
+ typedef Parse_UIntField < 0, 3 > Parse_Priority;
+ typedef Parse_Flag < 3 > Parse_CFI;
+ typedef Parse_UIntField < 4, 16 > Parse_VLanId;
+ typedef Parse_UInt16 Parse_Type;
+
+ SENF_PACKET_PARSER_INIT(Parse_EthVLan);
+
+ SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS(
+ ((OverlayField)( priority, Parse_Priority ))
+ ((OverlayField)( cfi, Parse_CFI ))
+ ((Field )( vlanId, Parse_VLanId ))
+ ((Field )( type, Parse_Type )) );
+ };
+ \endcode
+
The macros take care of the following:
\li They define the accessor functions returning parsers of the given type.
\li They automatically calculate the offset of the fields from the preceding fields.