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