Merge branch 'master' of /home/tmbinc/enigma2-git
[enigma2.git] / 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                                         ePtr<iDVBFrontend> fe;
744                                         eDVBFrontendParametersTerrestrial parm;
745                                         m_ch_current->getDVBT(parm);
746                                         snprintf(sname, 255, "%d SID 0x%02x",
747                                                 parm.frequency/1000,
748                                                 m_pmt_in_progress->first);
749                                         if (!m_channel->getFrontend(fe))
750                                         {
751                                                 ePyObject tp_dict = PyDict_New();
752                                                 fe->getTransponderData(tp_dict, false);
753                                                 m_corrected_frequencys[m_chid_current] =
754                                                         PyInt_AsLong(PyDict_GetItemString(tp_dict, "frequency"));
755                                                 Py_DECREF(tp_dict);
756                                         }
757                                         break;
758                                 }
759                                 case iDVBFrontend::feCable:
760                                 {
761                                         eDVBFrontendParametersCable parm;
762                                         m_ch_current->getDVBC(parm);
763                                         snprintf(sname, 255, "%d SID 0x%02x",
764                                                 parm.frequency/1000,
765                                                 m_pmt_in_progress->first);
766                                         break;
767                                 }
768                         }
769                         SCAN_eDebug("name '%s', provider_name '%s'", sname, pname);
770                         service->m_service_name = convertDVBUTF8(sname);
771                         service->genSortName();
772                         service->m_provider_name = convertDVBUTF8(pname);
773                 }
774
775                 if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) {
776                         SCAN_eDebug("add not scrambled!");
777                         std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
778                                 m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
779                         if (i.second)
780                         {
781                                 m_last_service = i.first;
782                                 m_event(evtNewService);
783                         }
784                 }
785                 else
786                         SCAN_eDebug("dont add... is scrambled!");
787                 m_pmts_to_read.erase(m_pmt_in_progress++);
788         }
789
790         if (!m_chid_current)
791                 eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
792         else
793                 addKnownGoodChannel(m_chid_current, m_ch_current);
794         
795         m_ch_scanned.push_back(m_ch_current);
796         
797         for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
798         {
799                 if (sameChannel(*i, m_ch_current))
800                 {
801                         SCAN_eDebug("remove dupe 2");
802                         m_ch_toScan.erase(i++);
803                         continue;
804                 }
805                 ++i;
806         }
807         
808         nextChannel();
809 }
810
811 void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
812 {
813         m_flags = flags;
814         m_ch_toScan.clear();
815         m_ch_scanned.clear();
816         m_ch_unavailable.clear();
817         m_new_channels.clear();
818         m_new_services.clear();
819         m_last_service = m_new_services.end();
820
821         for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
822         {
823                 bool exist=false;
824                 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
825                 {
826                         if (sameChannel(*i, *ii, true))
827                         {
828                                 exist=true;
829                                 break;
830                         }
831                 }
832                 if (!exist)
833                         m_ch_toScan.push_back(*i);
834         }
835
836         nextChannel();
837 }
838
839 void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
840 {
841         if (m_flags & scanRemoveServices)
842         {
843                 bool clearTerrestrial=false;
844                 bool clearCable=false;
845                 std::set<unsigned int> scanned_sat_positions;
846                 
847                 std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
848                 for (;it != m_ch_scanned.end(); ++it)
849                 {
850                         if (m_flags & scanDontRemoveUnscanned)
851                                 db->removeServices(&(*(*it)));
852                         else
853                         {
854                                 int system;
855                                 (*it)->getSystem(system);
856                                 switch(system)
857                                 {
858                                         case iDVBFrontend::feSatellite:
859                                         {
860                                                 eDVBFrontendParametersSatellite sat_parm;
861                                                 (*it)->getDVBS(sat_parm);
862                                                 scanned_sat_positions.insert(sat_parm.orbital_position);
863                                                 break;
864                                         }
865                                         case iDVBFrontend::feTerrestrial:
866                                         {
867                                                 clearTerrestrial=true;
868                                                 break;
869                                         }
870                                         case iDVBFrontend::feCable:
871                                         {
872                                                 clearCable=true;
873                                                 break;
874                                         }
875                                 }
876                         }
877                 }
878
879                 for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
880                 {
881                         if (m_flags & scanDontRemoveUnscanned)
882                                 db->removeServices(&(*(*it)));
883                         else
884                         {
885                                 int system;
886                                 (*it)->getSystem(system);
887                                 switch(system)
888                                 {
889                                         case iDVBFrontend::feSatellite:
890                                         {
891                                                 eDVBFrontendParametersSatellite sat_parm;
892                                                 (*it)->getDVBS(sat_parm);
893                                                 scanned_sat_positions.insert(sat_parm.orbital_position);
894                                                 break;
895                                         }
896                                         case iDVBFrontend::feTerrestrial:
897                                         {
898                                                 clearTerrestrial=true;
899                                                 break;
900                                         }
901                                         case iDVBFrontend::feCable:
902                                         {
903                                                 clearCable=true;
904                                                 break;
905                                         }
906                                 }
907                         }
908                 }
909
910                 if (clearTerrestrial)
911                 {
912                         eDVBChannelID chid;
913                         chid.dvbnamespace=0xEEEE0000;
914                         db->removeServices(chid);
915                 }
916                 if (clearCable)
917                 {
918                         eDVBChannelID chid;
919                         chid.dvbnamespace=0xFFFF0000;
920                         db->removeServices(chid);
921                 }
922                 for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
923                 {
924                         eDVBChannelID chid;
925                         if (m_flags & scanDontRemoveFeeds)
926                                 chid.dvbnamespace = eDVBNamespace((*x)<<16);
927 //                      eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
928                         db->removeServices(chid, *x);
929                 }
930         }
931
932         for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator 
933                         ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
934         {
935                 int system;
936                 ch->second->getSystem(system);
937                 if (system == iDVBFrontend::feTerrestrial)
938                 {
939                         std::map<eDVBChannelID, unsigned int>::iterator it = m_corrected_frequencys.find(ch->first);
940                         if (it != m_corrected_frequencys.end())
941                         {
942                                 eDVBFrontendParameters *p = (eDVBFrontendParameters*)&(*ch->second);
943                                 eDVBFrontendParametersTerrestrial parm;
944                                 p->getDVBT(parm);
945                                 eDebug("corrected freq for tsid %04x, onid %04x, ns %08x is %d, old was %d",
946                                         ch->first.transport_stream_id.get(), ch->first.original_network_id.get(),
947                                         ch->first.dvbnamespace.get(), it->second, parm.frequency);
948                                 parm.frequency = it->second;
949                                 p->setDVBT(parm);
950                                 m_corrected_frequencys.erase(it);
951                         }
952                 }
953                 if (m_flags & scanOnlyFree)
954                 {
955                         eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
956                         ptr->setFlags(iDVBFrontendParameters::flagOnlyFree);
957                 }
958                 db->addChannelToList(ch->first, ch->second);
959         }
960
961         for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::const_iterator
962                 service(m_new_services.begin()); service != m_new_services.end(); ++service)
963         {
964                 ePtr<eDVBService> dvb_service;
965                 if (!db->getService(service->first, dvb_service))
966                 {
967                         if (dvb_service->m_flags & eDVBService::dxNoSDT)
968                                 continue;
969                         if (!(dvb_service->m_flags & eDVBService::dxHoldName))
970                         {
971                                 dvb_service->m_service_name = service->second->m_service_name;
972                                 dvb_service->m_service_name_sort = service->second->m_service_name_sort;
973                         }
974                         dvb_service->m_provider_name = service->second->m_provider_name;
975                         if (service->second->m_ca.size())
976                                 dvb_service->m_ca = service->second->m_ca;
977                         if (!dontRemoveOldFlags) // do not remove new found flags when not wished
978                                 dvb_service->m_flags &= ~eDVBService::dxNewFound;
979                 }
980                 else
981                 {
982                         db->addService(service->first, service->second);
983                         if (!(m_flags & scanRemoveServices))
984                                 service->second->m_flags |= eDVBService::dxNewFound;
985                 }
986         }
987 }
988
989 RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt)
990 {
991         const ServiceDescriptionList &services = *sdt.getDescriptions();
992         SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
993         eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
994         
995         /* save correct CHID for this channel */
996         m_chid_current = chid;
997
998         for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
999         {
1000                 unsigned short service_id = (*s)->getServiceId();
1001                 SCAN_eDebugNoNewLine("SID %04x: ", service_id);
1002                 bool add = true;
1003
1004                 if (m_flags & scanOnlyFree)
1005                 {
1006                         std::map<unsigned short, service>::iterator it =
1007                                 m_pmts_to_read.find(service_id);
1008                         if (it != m_pmts_to_read.end())
1009                         {
1010                                 if (it->second.scrambled)
1011                                 {
1012                                         SCAN_eDebug("is scrambled!");
1013                                         add = false;
1014                                 }
1015                                 else
1016                                         SCAN_eDebug("is free");
1017                         }
1018                         else {
1019                                 SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!");
1020                                 add = false;
1021                         }
1022                 }
1023
1024                 if (add)
1025                 {
1026                         eServiceReferenceDVB ref;
1027                         ePtr<eDVBService> service = new eDVBService;
1028
1029                         ref.set(chid);
1030                         ref.setServiceID(service_id);
1031
1032                         for (DescriptorConstIterator desc = (*s)->getDescriptors()->begin();
1033                                         desc != (*s)->getDescriptors()->end(); ++desc)
1034                         {
1035                                 switch ((*desc)->getTag())
1036                                 {
1037                                 case SERVICE_DESCRIPTOR:
1038                                 {
1039                                         ServiceDescriptor &d = (ServiceDescriptor&)**desc;
1040                                         ref.setServiceType(d.getServiceType());
1041                                         service->m_service_name = convertDVBUTF8(d.getServiceName());
1042                                         service->genSortName();
1043
1044                                         service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
1045                                         SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
1046                                         break;
1047                                 }
1048                                 case CA_IDENTIFIER_DESCRIPTOR:
1049                                 {
1050                                         CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
1051                                         const CaSystemIdList &caids = *d.getCaSystemIds();
1052                                         SCAN_eDebugNoNewLine("CA ");
1053                                         for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i)
1054                                         {
1055                                                 SCAN_eDebugNoNewLine("%04x ", *i);
1056                                                 service->m_ca.push_front(*i);
1057                                         }
1058                                         SCAN_eDebug("");
1059                                         break;
1060                                 }
1061                                 default:
1062                                         SCAN_eDebug("descr<%x>", (*desc)->getTag());
1063                                         break;
1064                                 }
1065                         }
1066
1067                         std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
1068                                 m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
1069
1070                         if (i.second)
1071                         {
1072                                 m_last_service = i.first;
1073                                 m_event(evtNewService);
1074                         }
1075                 }
1076                 if (m_pmt_running && m_pmt_in_progress->first == service_id)
1077                         m_abort_current_pmt = true;
1078                 else
1079                         m_pmts_to_read.erase(service_id);
1080         }
1081
1082         return 0;
1083 }
1084
1085 RESULT eDVBScan::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1086 {
1087         connection = new eConnection(this, m_event.connect(event));
1088         return 0;
1089 }
1090
1091 void eDVBScan::getStats(int &transponders_done, int &transponders_total, int &services)
1092 {
1093         transponders_done = m_ch_scanned.size() + m_ch_unavailable.size();
1094         transponders_total = m_ch_toScan.size() + transponders_done;
1095         services = m_new_services.size();
1096 }
1097
1098 void eDVBScan::getLastServiceName(std::string &last_service_name)
1099 {
1100         if (m_last_service == m_new_services.end())
1101                 last_service_name = "";
1102         else
1103                 last_service_name = m_last_service->second->m_service_name;
1104 }
1105
1106 RESULT eDVBScan::getFrontend(ePtr<iDVBFrontend> &fe)
1107 {
1108         if (m_channel)
1109                 return m_channel->getFrontend(fe);
1110         fe = 0;
1111         return -1;
1112 }
1113
1114 RESULT eDVBScan::getCurrentTransponder(ePtr<iDVBFrontendParameters> &tp)
1115 {
1116         if (m_ch_current)
1117         {
1118                 tp = m_ch_current;
1119                 return 0;
1120         }
1121         tp = 0;
1122         return -1;
1123 }