workaround for transponder with same tsid/onid on hotbird (11470V, 11258H)
[vuplus_dvbapp] / lib / dvb / scan.cpp
1 #include <lib/dvb/idvb.h>
2 #include <dvbsi++/descriptor_tag.h>
3 #include <dvbsi++/service_descriptor.h>
4 #include <dvbsi++/satellite_delivery_system_descriptor.h>
5 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
6 #include <dvbsi++/cable_delivery_system_descriptor.h>
7 #include <dvbsi++/ca_identifier_descriptor.h>
8 #include <lib/dvb/specs.h>
9 #include <lib/dvb/esection.h>
10 #include <lib/dvb/scan.h>
11 #include <lib/dvb/frontend.h>
12 #include <lib/base/eerror.h>
13 #include <lib/base/estring.h>
14 #include <errno.h>
15
16 #define SCAN_eDebug(x...) do { if (m_scan_debug) eDebug(x); } while(0)
17 #define SCAN_eDebugNoNewLine(x...) do { if (m_scan_debug) eDebugNoNewLine(x); } while(0)
18
19 DEFINE_REF(eDVBScan);
20
21 eDVBScan::eDVBScan(iDVBChannel *channel, bool usePAT, bool debug)
22         :m_channel(channel), m_channel_state(iDVBChannel::state_idle)
23         ,m_ready(0), m_ready_all(usePAT ? (readySDT|readyPAT) : readySDT)
24         ,m_pmt_running(false), m_abort_current_pmt(false), m_flags(0)
25         ,m_usePAT(usePAT), m_scan_debug(debug)
26 {
27         if (m_channel->getDemux(m_demux))
28                 SCAN_eDebug("scan: failed to allocate demux!");
29         m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection);
30 }
31
32 eDVBScan::~eDVBScan()
33 {
34 }
35
36 int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTransportStreamID tsid)
37 {
38         switch (onid.get())
39         {
40         case 0:
41         case 0x1111:
42                 return 0;
43         case 0x13E:  // workaround for 11258H and 11470V on hotbird with same ONID/TSID (0x13E/0x578)
44                 return orbital_position != 130 || tsid != 0x578;
45         case 1:
46                 return orbital_position == 192;
47         case 0x00B1:
48                 return tsid != 0x00B0;
49         case 0x0002:
50                 return abs(orbital_position-282) < 6;
51         default:
52                 return onid.get() < 0xFF00;
53         }
54 }
55
56 eDVBNamespace eDVBScan::buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash)
57 {
58                 // on valid ONIDs, ignore frequency ("sub network") part
59         if (isValidONIDTSID((hash >> 16) & 0xFFFF, onid, tsid))
60                 hash &= ~0xFFFF;
61         return eDVBNamespace(hash);
62 }
63
64 void eDVBScan::stateChange(iDVBChannel *ch)
65 {
66         int state;
67         if (ch->getState(state))
68                 return;
69         if (m_channel_state == state)
70                 return;
71         
72         if (state == iDVBChannel::state_ok)
73         {
74                 startFilter();
75                 m_channel_state = state;
76         } else if (state == iDVBChannel::state_failed)
77         {
78                 m_ch_unavailable.push_back(m_ch_current);
79                 nextChannel();
80         }
81                         /* unavailable will timeout, anyway. */
82 }
83
84 RESULT eDVBScan::nextChannel()
85 {
86         ePtr<iDVBFrontend> fe;
87
88         m_SDT = 0; m_PAT = 0; m_BAT = 0; m_NIT = 0, m_PMT = 0;
89
90         m_ready = 0;
91
92         m_pat_tsid = eTransportStreamID();
93
94                 /* check what we need */
95         m_ready_all = readySDT;
96         
97         if (m_flags & scanNetworkSearch)
98                 m_ready_all |= readyNIT;
99         
100         if (m_flags & scanSearchBAT)
101                 m_ready_all |= readyBAT;
102
103         if (m_usePAT)
104                 m_ready_all |= readyPAT;
105
106         if (m_ch_toScan.empty())
107         {
108                 SCAN_eDebug("no channels left to scan.");
109                 SCAN_eDebug("%d channels scanned, %d were unavailable.", 
110                                 m_ch_scanned.size(), m_ch_unavailable.size());
111                 SCAN_eDebug("%d channels in database.", m_new_channels.size());
112                 m_event(evtFinish);
113                 return -ENOENT;
114         }
115         
116         m_ch_current = m_ch_toScan.front();
117         
118         m_ch_toScan.pop_front();
119         
120         if (m_channel->getFrontend(fe))
121         {
122                 m_event(evtFail);
123                 return -ENOTSUP;
124         }
125
126         m_chid_current = eDVBChannelID();
127
128         m_channel_state = iDVBChannel::state_idle;
129
130         if (fe->tune(*m_ch_current))
131                 return nextChannel();
132
133         m_event(evtUpdate);
134         return 0;
135 }
136
137 RESULT eDVBScan::startFilter()
138 {
139         bool startSDT=true;
140         assert(m_demux);
141
142                         /* only start required filters filter */
143
144         if (m_ready_all & readyPAT)
145                 startSDT = m_ready & readyPAT;
146
147         // m_ch_current is not set, when eDVBScan is just used for a SDT update
148         if (!m_ch_current)
149         {
150                 unsigned int channelFlags;
151                 m_channel->getCurrentFrontendParameters(m_ch_current);
152                 m_ch_current->getFlags(channelFlags);
153                 if (channelFlags & iDVBFrontendParameters::flagOnlyFree)
154                         m_flags |= scanOnlyFree;
155         }
156
157         m_SDT = 0;
158         if (startSDT && (m_ready_all & readySDT))
159         {
160                 m_SDT = new eTable<ServiceDescriptionSection>(m_scan_debug);
161                 int tsid=-1;
162                 if (m_ready & readyPAT && m_ready & validPAT)
163                 {
164                         std::vector<ProgramAssociationSection*>::const_iterator i =
165                                 m_PAT->getSections().begin();
166                         assert(i != m_PAT->getSections().end());
167                         tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id
168                         m_pat_tsid = eTransportStreamID(tsid);
169                         for (; i != m_PAT->getSections().end(); ++i)
170                         {
171                                 const ProgramAssociationSection &pat = **i;
172                                 ProgramAssociationConstIterator program = pat.getPrograms()->begin();
173                                 for (; program != pat.getPrograms()->end(); ++program)
174                                         m_pmts_to_read.insert(std::pair<unsigned short, service>((*program)->getProgramNumber(), service((*program)->getProgramMapPid())));
175                         }
176                         m_PMT = new eTable<ProgramMapSection>(m_scan_debug);
177                         CONNECT(m_PMT->tableReady, eDVBScan::PMTready);
178                         PMTready(-2);
179                         // KabelBW HACK ... on 618Mhz and 626Mhz the transport stream id in PAT and SDT is different
180
181                         {
182                                 int type;
183                                 m_ch_current->getSystem(type);
184                                 if (type == iDVBFrontend::feCable)
185                                 {
186                                         eDVBFrontendParametersCable parm;
187                                         m_ch_current->getDVBC(parm);
188                                         if ((tsid == 0x00d7 && abs(parm.frequency-618000) < 2000) ||
189                                                 (tsid == 0x00d8 && abs(parm.frequency-626000) < 2000))
190                                                 tsid = -1;
191                                 }
192                         }
193                 }
194                 if (tsid == -1)
195                 {
196                         if (m_SDT->start(m_demux, eDVBSDTSpec()))
197                                 return -1;
198                 }
199                 else if (m_SDT->start(m_demux, eDVBSDTSpec(tsid, true)))
200                         return -1;
201                 CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
202         }
203
204         if (!(m_ready & readyPAT))
205         {
206                 m_PAT = 0;
207                 if (m_ready_all & readyPAT)
208                 {
209                         m_PAT = new eTable<ProgramAssociationSection>(m_scan_debug);
210                         if (m_PAT->start(m_demux, eDVBPATSpec(4000)))
211                                 return -1;
212                         CONNECT(m_PAT->tableReady, eDVBScan::PATready);
213                 }
214
215                 m_NIT = 0;
216                 if (m_ready_all & readyNIT)
217                 {
218                         m_NIT = new eTable<NetworkInformationSection>(m_scan_debug);
219                         if (m_NIT->start(m_demux, eDVBNITSpec()))
220                                 return -1;
221                         CONNECT(m_NIT->tableReady, eDVBScan::NITready);
222                 }
223
224                 m_BAT = 0;
225                 if (m_ready_all & readyBAT)
226                 {
227                         m_BAT = new eTable<BouquetAssociationSection>(m_scan_debug);
228                         if (m_BAT->start(m_demux, eDVBBATSpec()))
229                                 return -1;
230                         CONNECT(m_BAT->tableReady, eDVBScan::BATready);
231                 }
232         }
233         return 0;
234 }
235
236 void eDVBScan::SDTready(int err)
237 {
238         SCAN_eDebug("got sdt %d", err);
239         m_ready |= readySDT;
240         if (!err)
241                 m_ready |= validSDT;
242         channelDone();
243 }
244
245 void eDVBScan::NITready(int err)
246 {
247         SCAN_eDebug("got nit, err %d", err);
248         m_ready |= readyNIT;
249         if (!err)
250                 m_ready |= validNIT;
251         channelDone();
252 }
253
254 void eDVBScan::BATready(int err)
255 {
256         SCAN_eDebug("got bat");
257         m_ready |= readyBAT;
258         if (!err)
259                 m_ready |= validBAT;
260         channelDone();
261 }
262
263 void eDVBScan::PATready(int err)
264 {
265         SCAN_eDebug("got pat");
266         m_ready |= readyPAT;
267         if (!err)
268                 m_ready |= validPAT;
269         startFilter(); // for starting the SDT filter
270 }
271
272 void eDVBScan::PMTready(int err)
273 {
274         SCAN_eDebug("got pmt %d", err);
275         if (!err)
276         {
277                 bool scrambled = false;
278                 bool have_audio = false;
279                 bool have_video = false;
280                 unsigned short pcrpid = 0xFFFF;
281                 std::vector<ProgramMapSection*>::const_iterator i;
282                 for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i)
283                 {
284                         const ProgramMapSection &pmt = **i;
285                         if (pcrpid == 0xFFFF)
286                                 pcrpid = pmt.getPcrPid();
287                         else
288                                 SCAN_eDebug("already have a pcrpid %04x %04x", pcrpid, pmt.getPcrPid());
289                         ElementaryStreamInfoConstIterator es;
290                         for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
291                         {
292                                 int isaudio = 0, isvideo = 0, is_scrambled = 0;
293                                 switch ((*es)->getType())
294                                 {
295                                 case 0x1b: // AVC Video Stream (MPEG4 H264)
296                                 case 0x01: // MPEG 1 video
297                                 case 0x02: // MPEG 2 video
298                                         isvideo = 1;
299                                         //break; fall through !!!
300                                 case 0x03: // MPEG 1 audio
301                                 case 0x04: // MPEG 2 audio:
302                                         if (!isvideo)
303                                                 isaudio = 1;
304                                         //break; fall through !!!
305                                 case 0x06: // PES Private
306                                 case 0x81: // user private
307                                                 /* PES private can contain AC-3, DTS or lots of other stuff.
308                                                    check descriptors to get the exact type. */
309                                         for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
310                                                         desc != (*es)->getDescriptors()->end(); ++desc)
311                                         {
312                                                 uint8_t tag = (*desc)->getTag();
313                                                 if (!isaudio && !isvideo)
314                                                 {
315                                                         switch (tag)
316                                                         {
317                                                         case DTS_DESCRIPTOR:
318                                                         case AAC_DESCRIPTOR:
319                                                         case AC3_DESCRIPTOR:
320                                                                 isaudio = 1;
321                                                                 break;
322                                                         case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
323                                                         {
324                                                                         /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
325                                                                 if ((*desc)->getLength() != 4)
326                                                                         break;
327                                                                 unsigned char descr[6];
328                                                                 (*desc)->writeToBuffer(descr);
329                                                                 int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
330                                                                 switch (format_identifier)
331                                                                 {
332                                                                 case 0x41432d33:
333                                                                         isaudio = 1;
334                                                                 default:
335                                                                         break;
336                                                                 }
337                                                                 break;
338                                                         }
339                                                         }
340                                                 }
341                                                 if (tag == CA_DESCRIPTOR)
342                                                         is_scrambled = 1;
343                                         }
344                                         break;
345                                 }
346                                 if (isaudio)
347                                         have_audio = true;
348                                 else if (isvideo)
349                                         have_video = true;
350                                 else
351                                         continue;
352                                 if (is_scrambled)
353                                         scrambled = true;
354                         }
355                         for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
356                                 desc != pmt.getDescriptors()->end(); ++desc)
357                         {
358                                 if ((*desc)->getTag() == CA_DESCRIPTOR)
359                                         scrambled = true;
360                         }
361                 }
362                 m_pmt_in_progress->second.scrambled = scrambled;
363                 if ( have_video )
364                         m_pmt_in_progress->second.serviceType = 1;
365                 else if ( have_audio )
366                         m_pmt_in_progress->second.serviceType = 2;
367                 else
368                         m_pmt_in_progress->second.serviceType = 100;
369         }
370         if (err == -1) // timeout or removed by sdt
371                 m_pmts_to_read.erase(m_pmt_in_progress++);
372         else if (m_pmt_running)
373                 ++m_pmt_in_progress;
374         else
375         {
376                 m_pmt_in_progress = m_pmts_to_read.begin();
377                 m_pmt_running = true;
378         }
379
380         if (m_pmt_in_progress != m_pmts_to_read.end())
381                 m_PMT->start(m_demux, eDVBPMTSpec(m_pmt_in_progress->second.pmtPid, m_pmt_in_progress->first, 4000));
382         else
383         {
384                 m_PMT = 0;
385                 m_pmt_running = false;
386                 channelDone();
387         }
388 }
389
390
391 void eDVBScan::addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
392 {
393                 /* add it to the list of known channels. */
394         if (chid)
395                 m_new_channels.insert(std::pair<eDVBChannelID,ePtr<iDVBFrontendParameters> >(chid, feparm));
396 }
397
398 void eDVBScan::addChannelToScan(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
399 {
400                 /* check if we don't already have that channel ... */
401
402         int type;
403         feparm->getSystem(type);
404
405         switch(type)
406         {
407         case iDVBFrontend::feSatellite:
408         {
409                 eDVBFrontendParametersSatellite parm;
410                 feparm->getDVBS(parm);
411                 SCAN_eDebug("try to add %d %d %d %d %d %d",
412                         parm.orbital_position, parm.frequency, parm.symbol_rate, parm.polarisation, parm.fec, parm.modulation);
413                 break;
414         }
415         case iDVBFrontend::feCable:
416         {
417                 eDVBFrontendParametersCable parm;
418                 feparm->getDVBC(parm);
419                 SCAN_eDebug("try to add %d %d %d %d",
420                         parm.frequency, parm.symbol_rate, parm.modulation, parm.fec_inner);
421                 break;
422         }
423         case iDVBFrontend::feTerrestrial:
424         {
425                 eDVBFrontendParametersTerrestrial parm;
426                 feparm->getDVBT(parm);
427                 SCAN_eDebug("try to add %d %d %d %d %d %d %d %d",
428                         parm.frequency, parm.modulation, parm.transmission_mode, parm.hierarchy,
429                         parm.guard_interval, parm.code_rate_LP, parm.code_rate_HP, parm.bandwidth);
430                 break;
431         }
432         }
433
434         int found_count=0;
435                 /* ... in the list of channels to scan */
436         for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
437         {
438                 if (sameChannel(*i, feparm))
439                 {
440                         if (!found_count)
441                         {
442                                 *i = feparm;  // update
443                                 SCAN_eDebug("update");
444                         }
445                         else
446                         {
447                                 SCAN_eDebug("remove dupe");
448                                 m_ch_toScan.erase(i++);
449                                 continue;
450                         }
451                         ++found_count;
452                 }
453                 ++i;
454         }
455
456         if (found_count > 0)
457         {
458                 SCAN_eDebug("already in todo list");
459                 return;
460         }
461
462                 /* ... in the list of successfully scanned channels */
463         for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_scanned.begin()); i != m_ch_scanned.end(); ++i)
464                 if (sameChannel(*i, feparm))
465                 {
466                         SCAN_eDebug("successfully scanned");
467                         return;
468                 }
469
470                 /* ... in the list of unavailable channels */
471         for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_unavailable.begin()); i != m_ch_unavailable.end(); ++i)
472                 if (sameChannel(*i, feparm, true))
473                 {
474                         SCAN_eDebug("scanned but not available");
475                         return;
476                 }
477
478                 /* ... on the current channel */
479         if (sameChannel(m_ch_current, feparm))
480         {
481                 SCAN_eDebug("is current");
482                 return;
483         }
484
485         SCAN_eDebug("really add");
486                 /* otherwise, add it to the todo list. */
487         m_ch_toScan.push_front(feparm); // better.. then the rotor not turning wild from east to west :)
488 }
489
490 int eDVBScan::sameChannel(iDVBFrontendParameters *ch1, iDVBFrontendParameters *ch2, bool exact) const
491 {
492         int diff;
493         if (ch1->calculateDifference(ch2, diff, exact))
494                 return 0;
495         if (diff < 4000) // more than 4mhz difference?
496                 return 1;
497         return 0;
498 }
499
500 void eDVBScan::channelDone()
501 {
502         if (m_ready & validSDT && (!(m_flags & scanOnlyFree) || !m_pmt_running))
503         {
504                 unsigned long hash = 0;
505
506                 m_ch_current->getHash(hash);
507                 
508                 eDVBNamespace dvbnamespace = buildNamespace(
509                         (**m_SDT->getSections().begin()).getOriginalNetworkId(),
510                         (**m_SDT->getSections().begin()).getTransportStreamId(),
511                         hash);
512                 
513                 SCAN_eDebug("SDT: ");
514                 std::vector<ServiceDescriptionSection*>::const_iterator i;
515                 for (i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
516                         processSDT(dvbnamespace, **i);
517                 m_ready &= ~validSDT;
518         }
519         
520         if (m_ready & validNIT)
521         {
522                 int system;
523                 std::list<ePtr<iDVBFrontendParameters> > m_ch_toScan_backup;
524                 m_ch_current->getSystem(system);
525                 SCAN_eDebug("dumping NIT");
526                 if (m_flags & clearToScanOnFirstNIT)
527                 {
528                         m_ch_toScan_backup = m_ch_toScan;
529                         m_ch_toScan.clear();
530                 }
531                 std::vector<NetworkInformationSection*>::const_iterator i;
532                 for (i = m_NIT->getSections().begin(); i != m_NIT->getSections().end(); ++i)
533                 {
534                         const TransportStreamInfoList &tsinfovec = *(*i)->getTsInfo();
535                         
536                         for (TransportStreamInfoConstIterator tsinfo(tsinfovec.begin()); 
537                                 tsinfo != tsinfovec.end(); ++tsinfo)
538                         {
539                                 SCAN_eDebug("TSID: %04x ONID: %04x", (*tsinfo)->getTransportStreamId(),
540                                         (*tsinfo)->getOriginalNetworkId());
541                                 
542                                 eOriginalNetworkID onid = (*tsinfo)->getOriginalNetworkId();
543                                 eTransportStreamID tsid = (*tsinfo)->getTransportStreamId();
544                                 
545                                 for (DescriptorConstIterator desc = (*tsinfo)->getDescriptors()->begin();
546                                                 desc != (*tsinfo)->getDescriptors()->end(); ++desc)
547                                 {
548                                         switch ((*desc)->getTag())
549                                         {
550                                         case CABLE_DELIVERY_SYSTEM_DESCRIPTOR:
551                                         {
552                                                 if (system != iDVBFrontend::feCable)
553                                                         break; // when current locked transponder is no cable transponder ignore this descriptor
554                                                 CableDeliverySystemDescriptor &d = (CableDeliverySystemDescriptor&)**desc;
555                                                 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
556                                                 eDVBFrontendParametersCable cable;
557                                                 cable.set(d);
558                                                 feparm->setDVBC(cable);
559
560                                                 unsigned long hash=0;
561                                                 feparm->getHash(hash);
562                                                 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
563
564                                                 addChannelToScan(
565                                                         eDVBChannelID(ns, tsid, onid),
566                                                         feparm);
567                                                 break;
568                                         }
569                                         case TERRESTRIAL_DELIVERY_SYSTEM_DESCRIPTOR:
570                                         {
571                                                 if (system != iDVBFrontend::feTerrestrial)
572                                                         break; // when current locked transponder is no terrestrial transponder ignore this descriptor
573                                                 TerrestrialDeliverySystemDescriptor &d = (TerrestrialDeliverySystemDescriptor&)**desc;
574                                                 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
575                                                 eDVBFrontendParametersTerrestrial terr;
576                                                 terr.set(d);
577                                                 feparm->setDVBT(terr);
578
579                                                 unsigned long hash=0;
580                                                 feparm->getHash(hash);
581                                                 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
582
583                                                 addChannelToScan(
584                                                         eDVBChannelID(ns, tsid, onid),
585                                                         feparm);
586                                                 break;
587                                         }
588                                         case SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR:
589                                         {
590                                                 if (system != iDVBFrontend::feSatellite)
591                                                         break; // when current locked transponder is no satellite transponder ignore this descriptor
592
593                                                 SatelliteDeliverySystemDescriptor &d = (SatelliteDeliverySystemDescriptor&)**desc;
594                                                 if (d.getFrequency() < 10000)
595                                                         break;
596                                                 
597                                                 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
598                                                 eDVBFrontendParametersSatellite sat;
599                                                 sat.set(d);
600
601                                                 eDVBFrontendParametersSatellite p;
602                                                 m_ch_current->getDVBS(p);
603
604                                                 if ( abs(p.orbital_position - sat.orbital_position) < 5 )
605                                                         sat.orbital_position = p.orbital_position;
606
607                                                 if ( abs(abs(3600 - p.orbital_position) - sat.orbital_position) < 5 )
608                                                 {
609                                                         SCAN_eDebug("found transponder with incorrect west/east flag ... correct this");
610                                                         sat.orbital_position = p.orbital_position;
611                                                 }
612
613                                                 feparm->setDVBS(sat);
614
615                                                 if ( p.orbital_position != sat.orbital_position)
616                                                         SCAN_eDebug("dropping this transponder, it's on another satellite.");
617                                                 else
618                                                 {
619                                                         unsigned long hash=0;
620                                                         feparm->getHash(hash);
621                                                         addChannelToScan(
622                                                                         eDVBChannelID(buildNamespace(onid, tsid, hash), tsid, onid),
623                                                                         feparm);
624                                                 }
625                                                 break;
626                                         }
627                                         default:
628                                                 SCAN_eDebug("descr<%x>", (*desc)->getTag());
629                                                 break;
630                                         }
631                                 }
632                         }
633                         
634                 }
635
636                         /* a pitfall is to have the clearToScanOnFirstNIT-flag set, and having channels which have
637                            no or invalid NIT. this code will not erase the toScan list unless at least one valid entry
638                            has been found.
639
640                            This is not a perfect solution, as the channel could contain a partial NIT. Life's bad.
641                         */
642                 if (m_flags & clearToScanOnFirstNIT)
643                 {
644                         if (m_ch_toScan.empty())
645                         {
646                                 eWarning("clearToScanOnFirstNIT was set, but NIT is invalid. Refusing to stop scan.");
647                                 m_ch_toScan = m_ch_toScan_backup;
648                         } else
649                                 m_flags &= ~clearToScanOnFirstNIT;
650                 }
651                 m_ready &= ~validNIT;
652         }
653
654         if (m_pmt_running || (m_ready & m_ready_all) != m_ready_all)
655         {
656                 if (m_abort_current_pmt)
657                 {
658                         m_abort_current_pmt = false;
659                         PMTready(-1);
660                 }
661                 return;
662         }
663
664         SCAN_eDebug("channel done!");
665         
666                 /* if we had services on this channel, we declare
667                    this channels as "known good". add it.
668                    
669                    (TODO: not yet implemented)
670                    a NIT entry could have possible overridden
671                    our frontend data with more exact data.
672                    
673                    (TODO: not yet implemented)
674                    the tuning process could have lead to more
675                    exact data than the user entered.
676                    
677                    The channel id was probably corrected
678                    by the data written in the SDT. this is
679                    important, as "initial transponder lists"
680                    usually don't have valid CHIDs (and that's
681                    good).
682                    
683                    These are the reasons for adding the transponder
684                    here, and not before.
685                 */
686
687         for (m_pmt_in_progress = m_pmts_to_read.begin(); m_pmt_in_progress != m_pmts_to_read.end();)
688         {
689                 int type;
690                 eServiceReferenceDVB ref;
691                 ePtr<eDVBService> service = new eDVBService;
692
693                 if (!m_chid_current)
694                 {
695                         unsigned long hash = 0;
696
697                         m_ch_current->getHash(hash);
698
699                         m_chid_current = eDVBChannelID(
700                                 buildNamespace(eOriginalNetworkID(0), m_pat_tsid, hash),
701                                 m_pat_tsid, eOriginalNetworkID(0));
702                 }
703
704                 if (m_pmt_in_progress->second.serviceType == 1)
705                         SCAN_eDebug("SID %04x is VIDEO", m_pmt_in_progress->first);
706                 else if (m_pmt_in_progress->second.serviceType == 2)
707                         SCAN_eDebug("SID %04x is AUDIO", m_pmt_in_progress->first);
708                 else
709                         SCAN_eDebug("SID %04x is DATA", m_pmt_in_progress->first);
710
711                 ref.set(m_chid_current);
712                 ref.setServiceID(m_pmt_in_progress->first);
713                 ref.setServiceType(m_pmt_in_progress->second.serviceType);
714
715                 if (!m_ch_current->getSystem(type))
716                 {
717                         char sname[255];
718                         char pname[255];
719                         memset(pname, 0, sizeof(pname));
720                         memset(sname, 0, sizeof(sname));
721                         switch(type)
722                         {
723                                 case iDVBFrontend::feSatellite:
724                                 {
725                                         eDVBFrontendParametersSatellite parm;
726                                         m_ch_current->getDVBS(parm);
727                                         snprintf(sname, 255, "%d%c SID 0x%02x",
728                                                         parm.frequency/1000,
729                                                         parm.polarisation ? 'V' : 'H',
730                                                         m_pmt_in_progress->first);
731                                         snprintf(pname, 255, "%s %s %d%c %d.%d°%c",
732                                                 parm.system ? "DVB-S2" : "DVB-S",
733                                                 parm.modulation == 1 ? "QPSK" : "8PSK",
734                                                 parm.frequency/1000,
735                                                 parm.polarisation ? 'V' : 'H',
736                                                 parm.orbital_position/10,
737                                                 parm.orbital_position%10,
738                                                 parm.orbital_position > 0 ? 'E' : 'W');
739                                         break;
740                                 }
741                                 case iDVBFrontend::feTerrestrial:
742                                 {
743                                         eDVBFrontendParametersTerrestrial parm;
744                                         m_ch_current->getDVBT(parm);
745                                         snprintf(sname, 255, "%d SID 0x%02x",
746                                                 parm.frequency/1000,
747                                                 m_pmt_in_progress->first);
748                                         break;
749                                 }
750                                 case iDVBFrontend::feCable:
751                                 {
752                                         eDVBFrontendParametersCable parm;
753                                         m_ch_current->getDVBC(parm);
754                                         snprintf(sname, 255, "%d SID 0x%02x",
755                                                 parm.frequency/1000,
756                                                 m_pmt_in_progress->first);
757                                         break;
758                                 }
759                         }
760                         SCAN_eDebug("name '%s', provider_name '%s'", sname, pname);
761                         service->m_service_name = convertDVBUTF8(sname);
762                         service->genSortName();
763                         service->m_provider_name = convertDVBUTF8(pname);
764                 }
765
766                 if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) {
767                         SCAN_eDebug("add not scrambled!");
768                         std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
769                         if (i.second)
770                         {
771                                 m_last_service = i.first;
772                                 m_event(evtNewService);
773                         }
774                 }
775                 else
776                         SCAN_eDebug("dont add... is scrambled!");
777                 m_pmts_to_read.erase(m_pmt_in_progress++);
778         }
779
780         if (!m_chid_current)
781                 eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
782         else
783                 addKnownGoodChannel(m_chid_current, m_ch_current);
784         
785         m_ch_scanned.push_back(m_ch_current);
786         
787         for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
788         {
789                 if (sameChannel(*i, m_ch_current))
790                 {
791                         SCAN_eDebug("remove dupe 2");
792                         m_ch_toScan.erase(i++);
793                         continue;
794                 }
795                 ++i;
796         }
797         
798         nextChannel();
799 }
800
801 void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
802 {
803         m_flags = flags;
804         m_ch_toScan.clear();
805         m_ch_scanned.clear();
806         m_ch_unavailable.clear();
807         m_new_channels.clear();
808         m_new_services.clear();
809         m_last_service = m_new_services.end();
810
811         for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
812         {
813                 bool exist=false;
814                 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
815                 {
816                         if (sameChannel(*i, *ii, true))
817                         {
818                                 exist=true;
819                                 break;
820                         }
821                 }
822                 if (!exist)
823                         m_ch_toScan.push_back(*i);
824         }
825
826         nextChannel();
827 }
828
829 void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
830 {
831         if (m_flags & scanRemoveServices)
832         {
833                 bool clearTerrestrial=false;
834                 bool clearCable=false;
835                 std::set<unsigned int> scanned_sat_positions;
836                 
837                 std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
838                 for (;it != m_ch_scanned.end(); ++it)
839                 {
840                         if (m_flags & scanDontRemoveUnscanned)
841                                 db->removeServices(&(*(*it)));
842                         else
843                         {
844                                 int system;
845                                 (*it)->getSystem(system);
846                                 switch(system)
847                                 {
848                                         case iDVBFrontend::feSatellite:
849                                         {
850                                                 eDVBFrontendParametersSatellite sat_parm;
851                                                 (*it)->getDVBS(sat_parm);
852                                                 scanned_sat_positions.insert(sat_parm.orbital_position);
853                                                 break;
854                                         }
855                                         case iDVBFrontend::feTerrestrial:
856                                         {
857                                                 clearTerrestrial=true;
858                                                 break;
859                                         }
860                                         case iDVBFrontend::feCable:
861                                         {
862                                                 clearCable=true;
863                                                 break;
864                                         }
865                                 }
866                         }
867                 }
868
869                 for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
870                 {
871                         if (m_flags & scanDontRemoveUnscanned)
872                                 db->removeServices(&(*(*it)));
873                         else
874                         {
875                                 int system;
876                                 (*it)->getSystem(system);
877                                 switch(system)
878                                 {
879                                         case iDVBFrontend::feSatellite:
880                                         {
881                                                 eDVBFrontendParametersSatellite sat_parm;
882                                                 (*it)->getDVBS(sat_parm);
883                                                 scanned_sat_positions.insert(sat_parm.orbital_position);
884                                                 break;
885                                         }
886                                         case iDVBFrontend::feTerrestrial:
887                                         {
888                                                 clearTerrestrial=true;
889                                                 break;
890                                         }
891                                         case iDVBFrontend::feCable:
892                                         {
893                                                 clearCable=true;
894                                                 break;
895                                         }
896                                 }
897                         }
898                 }
899
900                 if (clearTerrestrial)
901                 {
902                         eDVBChannelID chid;
903                         chid.dvbnamespace=0xEEEE0000;
904                         db->removeServices(chid);
905                 }
906                 if (clearCable)
907                 {
908                         eDVBChannelID chid;
909                         chid.dvbnamespace=0xFFFF0000;
910                         db->removeServices(chid);
911                 }
912                 for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
913                 {
914                         eDVBChannelID chid;
915                         if (m_flags & scanDontRemoveFeeds)
916                                 chid.dvbnamespace = eDVBNamespace((*x)<<16);
917 //                      eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
918                         db->removeServices(chid, *x);
919                 }
920         }
921
922         for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator 
923                         ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
924         {
925                 if (m_flags & scanOnlyFree)
926                 {
927                         eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
928                         ptr->setFlags(iDVBFrontendParameters::flagOnlyFree);
929                 }
930                 db->addChannelToList(ch->first, ch->second);
931         }
932
933         for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::const_iterator
934                 service(m_new_services.begin()); service != m_new_services.end(); ++service)
935         {
936                 ePtr<eDVBService> dvb_service;
937                 if (!db->getService(service->first, dvb_service))
938                 {
939                         if (dvb_service->m_flags & eDVBService::dxNoSDT)
940                                 continue;
941                         if (!(dvb_service->m_flags & eDVBService::dxHoldName))
942                         {
943                                 dvb_service->m_service_name = service->second->m_service_name;
944                                 dvb_service->m_service_name_sort = service->second->m_service_name_sort;
945                         }
946                         dvb_service->m_provider_name = service->second->m_provider_name;
947                         if (service->second->m_ca.size())
948                                 dvb_service->m_ca = service->second->m_ca;
949                         if (!dontRemoveOldFlags) // do not remove new found flags when not wished
950                                 dvb_service->m_flags &= ~eDVBService::dxNewFound;
951                 }
952                 else
953                 {
954                         db->addService(service->first, service->second);
955                         if (!(m_flags & scanRemoveServices))
956                                 service->second->m_flags |= eDVBService::dxNewFound;
957                 }
958         }
959 }
960
961 RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt)
962 {
963         const ServiceDescriptionList &services = *sdt.getDescriptions();
964         SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
965         eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
966         
967         /* save correct CHID for this channel */
968         m_chid_current = chid;
969
970         for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
971         {
972                 unsigned short service_id = (*s)->getServiceId();
973                 SCAN_eDebugNoNewLine("SID %04x: ", service_id);
974                 bool add = true;
975
976                 if (m_flags & scanOnlyFree)
977                 {
978                         std::map<unsigned short, service>::iterator it =
979                                 m_pmts_to_read.find(service_id);
980                         if (it != m_pmts_to_read.end())
981                         {
982                                 if (it->second.scrambled)
983                                 {
984                                         SCAN_eDebug("is scrambled!");
985                                         add = false;
986                                 }
987                                 else
988                                         SCAN_eDebug("is free");
989                         }
990                         else {
991                                 SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!");
992                                 add = false;
993                         }
994                 }
995
996                 if (add)
997                 {
998                         eServiceReferenceDVB ref;
999                         ePtr<eDVBService> service = new eDVBService;
1000
1001                         ref.set(chid);
1002                         ref.setServiceID(service_id);
1003
1004                         for (DescriptorConstIterator desc = (*s)->getDescriptors()->begin();
1005                                         desc != (*s)->getDescriptors()->end(); ++desc)
1006                         {
1007                                 switch ((*desc)->getTag())
1008                                 {
1009                                 case SERVICE_DESCRIPTOR:
1010                                 {
1011                                         ServiceDescriptor &d = (ServiceDescriptor&)**desc;
1012                                         ref.setServiceType(d.getServiceType());
1013                                         service->m_service_name = convertDVBUTF8(d.getServiceName());
1014                                         service->genSortName();
1015
1016                                         service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
1017                                         SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
1018                                         break;
1019                                 }
1020                                 case CA_IDENTIFIER_DESCRIPTOR:
1021                                 {
1022                                         CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
1023                                         const CaSystemIdList &caids = *d.getCaSystemIds();
1024                                         SCAN_eDebugNoNewLine("CA ");
1025                                         for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i)
1026                                         {
1027                                                 SCAN_eDebugNoNewLine("%04x ", *i);
1028                                                 service->m_ca.push_front(*i);
1029                                         }
1030                                         SCAN_eDebug("");
1031                                         break;
1032                                 }
1033                                 default:
1034                                         SCAN_eDebug("descr<%x>", (*desc)->getTag());
1035                                         break;
1036                                 }
1037                         }
1038
1039                         std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
1040
1041                         if (i.second)
1042                         {
1043                                 m_last_service = i.first;
1044                                 m_event(evtNewService);
1045                         }
1046                 }
1047                 if (m_pmt_running && m_pmt_in_progress->first == service_id)
1048                         m_abort_current_pmt = true;
1049                 else
1050                         m_pmts_to_read.erase(service_id);
1051         }
1052
1053         return 0;
1054 }
1055
1056 RESULT eDVBScan::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1057 {
1058         connection = new eConnection(this, m_event.connect(event));
1059         return 0;
1060 }
1061
1062 void eDVBScan::getStats(int &transponders_done, int &transponders_total, int &services)
1063 {
1064         transponders_done = m_ch_scanned.size() + m_ch_unavailable.size();
1065         transponders_total = m_ch_toScan.size() + transponders_done;
1066         services = m_new_services.size();
1067 }
1068
1069 void eDVBScan::getLastServiceName(std::string &last_service_name)
1070 {
1071         if (m_last_service == m_new_services.end())
1072                 last_service_name = "";
1073         else
1074                 last_service_name = m_last_service->second->m_service_name;
1075 }
1076
1077 RESULT eDVBScan::getFrontend(ePtr<iDVBFrontend> &fe)
1078 {
1079         if (m_channel)
1080                 return m_channel->getFrontend(fe);
1081         fe = 0;
1082         return -1;
1083 }
1084
1085 RESULT eDVBScan::getCurrentTransponder(ePtr<iDVBFrontendParameters> &tp)
1086 {
1087         if (m_ch_current)
1088         {
1089                 tp = m_ch_current;
1090                 return 0;
1091         }
1092         tp = 0;
1093         return -1;
1094 }