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