added some documentation for PacketData
[senf.git] / Examples / DVBAdapter / ULEdec.cc
index 609a5c9..a732b96 100644 (file)
 #include "Packets/PacketData.hh"
 #include "Packets/ParseInt.hh"
 
+#include "ULEdec.hh"
+
 #define PID 271
 #define TS_SYNC 0x47
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-namespace {
-
-    static const unsigned BLOCK_SIZE = 16;
-
-    template <class Iterator>
-    void hexdump(Iterator i, Iterator const & i_end, std::ostream& stream)
-    {
-        unsigned offset (0);
-        std::string ascii;
-        for (; i != i_end; ++i, ++offset) {
-            switch (offset % BLOCK_SIZE) {
-            case 0:
-                if (!ascii.empty()) {
-                    stream << "  " << ascii << "\n";
-                    ascii = "";
-                }
-                stream << "  "
-                          << std::hex << std::setw(4) << std::setfill('0')
-                          << offset << ' ';
-                break;
-            case BLOCK_SIZE/2:
-                stream << " ";
-                ascii += ' ';
-                break;
+template <class Iterator>
+void ULEdec::hexdump(Iterator i, Iterator const & i_end, std::ostream& stream)
+{
+    unsigned offset (0);
+    std::string ascii;
+    for (; i != i_end; ++i, ++offset) {
+        switch (offset % BLOCK_SIZE) {
+        case 0:
+            if (!ascii.empty()) {
+                stream << "  " << ascii << "\n";
+                ascii = "";
             }
-            stream << ' ' << std::hex << std::setw(2) << std::setfill('0')
-                      << unsigned(*i);
-            ascii += (*i >= ' ' && *i < 126) ? *i : '.';
+            stream << "  "
+                      << std::hex << std::setw(4) << std::setfill('0')
+                      << offset << ' ';
+            break;
+        case BLOCK_SIZE/2:
+            stream << " ";
+            ascii += ' ';
+            break;
         }
-        if (!ascii.empty()) {
-            for (; (offset % BLOCK_SIZE) != 0; ++offset) {
-                if ((offset % BLOCK_SIZE) == BLOCK_SIZE/2)
-                    stream << " ";
-                stream << "   ";
-            }
-            stream << "  " << ascii << "\n";
+        stream << ' ' << std::hex << std::setw(2) << std::setfill('0')
+                  << unsigned(*i);
+        ascii += (*i >= ' ' && *i < 126) ? *i : '.';
+    }
+    if (!ascii.empty()) {
+        for (; (offset % BLOCK_SIZE) != 0; ++offset) {
+            if ((offset % BLOCK_SIZE) == BLOCK_SIZE/2)
+                stream << " ";
+            stream << "   ";
         }
-        stream << std::dec;
+        stream << "  " << ascii << "\n";
     }
+    stream << std::dec;
 }
 
 
-class ULEdec
+ULEdec::ULEdec()
 {
-    senf::DVBDemuxPESHandle demuxHandle;
-    senf::DVBDvrHandle dvrHandle;
+    struct dmx_pes_filter_params pes_filter;
+    memset(&pes_filter, 0, sizeof (struct dmx_pes_filter_params));
+    pes_filter.pid = PID;
+    pes_filter.input  = DMX_IN_FRONTEND;
+    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(&ULEdec::handleEvent, this));
     
-    unsigned char receiver_state;
-    unsigned char priv_tscc;
-public:
-    ULEdec()
+    this->receiver_state = 1; // Idle
+}
+
+void ULEdec::handleEvent(senf::FileHandle, senf::Scheduler::EventId event)
+{
+    senf::TransportPacket ts_packet (
+            senf::TransportPacket::create(188, senf::TransportPacket::noinit));
+    dvrHandle.read( ts_packet.data() );
+   
+    // Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control.
+    if ( (ts_packet->sync_byte() != TS_SYNC) || 
+         (ts_packet->transport_error_indicator() == true) || 
+         (ts_packet->transport_scrmbl_ctrl() != 0)) 
     {
-        struct dmx_pes_filter_params pes_filter;
-        memset(&pes_filter, 0, sizeof (struct dmx_pes_filter_params));
-        pes_filter.pid = PID;
-        pes_filter.input  = DMX_IN_FRONTEND;
-        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(&ULEdec::handlePacket, this));
-        
-        receiver_state = 1; // Idle
+        std::cerr << "invalid ts packet\n";
+        // drop partly decoded SNDU, reset state, resync on PUSI.
+        return;
     }
+    
+    handleTSPacket(ts_packet);
+}
+    
+void ULEdec::handleTSPacket(senf::TransportPacket ts_packet)
+{
+    unsigned char payload_pointer;
 
-private:
-    void handlePacket(senf::FileHandle, senf::Scheduler::EventId event)
-    {
-        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);
+    senf::PacketData &ts_payload (ts_packet.next().data());
+    BOOST_ASSERT( ts_payload.size() == 184 );
+    
+    switch (this->receiver_state) {
+    case 1: { // Idle State
+        // resync on PUSI
+        if (ts_packet->pusi() == 0) 
+            return; // skip packet
         
-        // 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.
+        // Synchronize continuity counter
+        this->priv_tscc = ts_packet->continuity_counter();
+
+        // a PUSI value of 1 indicates the presence of a Payload Pointer.
+        payload_pointer = ts_payload[0];
+        if (payload_pointer>181) {
+            std::cerr << "invalid payload_pointer\n";
             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;
+        payload_pointer++;
+        
+        bool dbit = false;
+        senf::Packet::size_type sndu_length;
+        while (payload_pointer < 184) {
+            sndu_length = ts_payload[payload_pointer] << 8 | ts_payload[payload_pointer+1];
+            if (sndu_length & 0x8000) {
+                sndu_length &= 0x7FFF;
+                dbit = true;
             }
+            this->snduPacket = senf::SNDUPacket::create(sndu_length+2);
+            this->snduPacket->d_bit() = dbit;
+            this->snduPacket->length() = sndu_length;
+
+            return;
+            
+            payload_pointer += 2;
+            
             
-            // 
-            break;
-        case 2:  // Reassembly State
-            break;
         }
+        
+        
+        
+        // 
+        break;
     }
-};
+    case 2: { // Reassembly State
+        break;
+    }
+    }
+}
+
 
 int main(int argc, char const * argv[])
 {