4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 // Definition of non-inline non-template functions
27 #include "Packets/PacketData.hh"
28 #include "Utils/hexdump.hh"
29 #include "Utils/membind.hh"
35 ///////////////////////////////cc.p////////////////////////////////////////
40 struct dmx_pes_filter_params pes_filter;
41 memset(&pes_filter, 0, sizeof (struct dmx_pes_filter_params));
43 pes_filter.input = DMX_IN_FRONTEND;
44 pes_filter.output = DMX_OUT_TS_TAP;
45 pes_filter.pes_type = DMX_PES_OTHER;
46 pes_filter.flags = DMX_IMMEDIATE_START;
47 demuxHandle.protocol().setPESFilter( &pes_filter );
49 senf::Scheduler::instance().add(
50 dvrHandle, senf::membind(&ULEdec::handleEvent, this));
52 this->receiver_state = Idle;
53 this->priv_sndu_type_1 = false;
56 void ULEdec::handleEvent(senf::FileHandle, senf::Scheduler::EventId event)
58 senf::TransportPacket ts_packet (
59 senf::TransportPacket::create(188, senf::TransportPacket::noinit));
60 dvrHandle.read( ts_packet.data() );
62 // Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control.
63 if ( (ts_packet->sync_byte() != TS_SYNC) ||
64 (ts_packet->transport_error_indicator() == true) ||
65 (ts_packet->transport_scrmbl_ctrl() != 0))
67 std::cerr << "invalid ts packet\n";
68 // drop partly decoded SNDU, reset state, resync on PUSI.
72 handleTSPacket(ts_packet);
75 void ULEdec::handleTSPacket(senf::TransportPacket ts_packet)
77 senf::PacketData & payloadData (ts_packet.next().data());
78 iterator payload_iter = payloadData.begin();
79 iterator payload_end = payloadData.end();
81 std::cout << "New TS Packet:\n"
82 << "----------------------------------------------------------------------------\n";
83 senf::hexdump(payload_iter, payload_end, std::cout);
84 std::cout << "----------------------------------------------------------------------------\n";
86 // Synchronize continuity counter
87 this->priv_tscc = ts_packet->continuity_counter();
89 switch (ts_packet->pusi()) {
91 switch (this->receiver_state) {
95 payload_iter = readContSNDUPacket( payload_iter, payload_end );
96 if (isSDNUPacketComplete()) {
97 this->receiver_state = Idle;
100 } catch (ULEdecException const & ex) {
101 std::cerr << ex.what() << "\n";
104 switch (std::distance( payload_iter, payload_end ))
109 if ( (*payload_iter++ << 8 | *payload_iter++) != ULE_END_INDICATOR )
110 std::cerr << "delimiting error 1\n";
112 BOOST_ASSERT( std::distance( payload_iter, payload_end ) == 0 );
118 // a PUSI value of 1 indicates the presence of a Payload Pointer.
119 unsigned char payload_pointer = *payload_iter++;
120 if (payload_pointer > 181) {
121 std::cerr << "invalid payload_pointer\n";
122 this->receiver_state = Idle;
125 switch (this->receiver_state) {
127 std::advance(payload_iter, payload_pointer);
130 // Reassembly Payload Pointer Checking
131 if (snduPacketBytesLeft() != payload_pointer) {
133 std::cerr << "delimiting error 2\n";
134 std::advance(payload_iter, payload_pointer);
136 payload_iter = readContSNDUPacket( payload_iter, payload_end );
137 BOOST_ASSERT( isSDNUPacketComplete() );
140 } catch (ULEdecException const & ex) {
141 std::cerr << ex.what() << "\n";
142 this->receiver_state = Idle;
147 this->receiver_state = Idle;
150 payload_iter = readNewSNDUPacket( payload_iter, payload_end );
151 if (! isSDNUPacketComplete()) {
152 BOOST_ASSERT( std::distance( payload_iter, payload_end ) == 0 );
153 this->receiver_state = Reassembly;
157 } while (std::distance(payload_iter, payload_end) < 2 );
159 catch (ULEdecException const & ex) {
160 std::cerr << ex.what() << "\n";
169 ULEdec::iterator ULEdec::readContSNDUPacket(iterator i, iterator const i_end)
171 if (priv_sndu_type_1) {
172 this->snduPacket->type() |= *i++;
174 return readRawSNDUPacketData(i, i_end);
178 ULEdec::iterator ULEdec::readNewSNDUPacket(iterator i, iterator const i_end)
181 senf::Packet::size_type sndu_length = *i++ << 8 | *i++;
182 if (sndu_length & 0x8000) {
183 sndu_length &= 0x7FFF;
186 if (sndu_length < 5 || sndu_length == 0xffff) {
187 throw ULEdecException("SNDU length error");
189 this->snduPacket = senf::SNDUPacket::create(sndu_length+4);
190 this->snduPacket->d_bit() = dbit;
191 this->snduPacket->length() = sndu_length;
192 this->snduPacketData_iter = boost::next(this->snduPacket.data().begin(), 2);
193 this->priv_sndu_type_1 = false;
195 switch (std::distance(i, i_end)) {
197 this->priv_sndu_type_1 = true;
198 this->snduPacket->type() = *i++ << 8;
199 this->snduPacketData_iter++;
204 this->snduPacket->type() = *i++ << 8 | *i++;
205 std::advance(this->snduPacketData_iter, 2);
206 i = readRawSNDUPacketData(i, i_end);
213 ULEdec::iterator ULEdec::readRawSNDUPacketData(iterator i, iterator i_end)
215 unsigned char how_much = std::min(
216 snduPacketBytesLeft(), std::distance(i, i_end) );
217 copy_n(i, how_much, this->snduPacketData_iter);
218 std::advance(i, how_much);
219 std::advance(this->snduPacketData_iter, how_much);
224 void ULEdec::handleSNDUPacket()
226 this->snduPacket.dump(std::cout);
227 std::cout << "----------------------------------------------------------------------------\n\n";
228 if (this->snduPacket->crc() != this->snduPacket->calcCrc()) {
229 throw ULEdecException("CRC Error");
231 // senf::Packet nextPacket = this->snduPacket.next();
233 // nextPacket.data().begin(),
234 // nextPacket.data().end(),
240 inline bool ULEdec::isSDNUPacketComplete()
242 return this->snduPacketData_iter == this->snduPacket.data().end();
245 inline ULEdec::iterator::difference_type ULEdec::snduPacketBytesLeft()
247 return std::distance( this->snduPacketData_iter, this->snduPacket.data().end() );
251 int main(int argc, char const * argv[])
255 senf::Scheduler::instance().process();
257 catch (std::exception const & ex) {
258 std::cerr << senf::prettyName(typeid(ex)) << ": " << ex.what() << "\n";
264 ///////////////////////////////cc.e////////////////////////////////////////
271 // c-file-style: "senf"
272 // indent-tabs-mode: nil
273 // ispell-local-dictionary: "american"
274 // compile-command: "scons -u test"
275 // comment-column: 40