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>
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)
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)
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);
36 int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTransportStreamID tsid)
43 case 0x13E: // workaround for 11258H and 11470V on hotbird with same ONID/TSID (0x13E/0x578)
44 return orbital_position != 130 || tsid != 0x578;
46 return orbital_position == 192;
48 return tsid != 0x00B0;
50 return abs(orbital_position-282) < 6;
52 return onid.get() < 0xFF00;
56 eDVBNamespace eDVBScan::buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash)
58 // on valid ONIDs, ignore frequency ("sub network") part
59 if (isValidONIDTSID((hash >> 16) & 0xFFFF, onid, tsid))
61 return eDVBNamespace(hash);
64 void eDVBScan::stateChange(iDVBChannel *ch)
67 if (ch->getState(state))
69 if (m_channel_state == state)
72 if (state == iDVBChannel::state_ok)
75 m_channel_state = state;
76 } else if (state == iDVBChannel::state_failed)
78 m_ch_unavailable.push_back(m_ch_current);
81 /* unavailable will timeout, anyway. */
84 RESULT eDVBScan::nextChannel()
86 ePtr<iDVBFrontend> fe;
88 m_SDT = 0; m_PAT = 0; m_BAT = 0; m_NIT = 0, m_PMT = 0;
92 m_pat_tsid = eTransportStreamID();
94 /* check what we need */
95 m_ready_all = readySDT;
97 if (m_flags & scanNetworkSearch)
98 m_ready_all |= readyNIT;
100 if (m_flags & scanSearchBAT)
101 m_ready_all |= readyBAT;
104 m_ready_all |= readyPAT;
106 if (m_ch_toScan.empty())
108 SCAN_eDebug("no channels left to scan.");
109 SCAN_eDebug("%d channels scanned, %d were unavailable.",
110 m_ch_scanned.size(), m_ch_unavailable.size());
111 SCAN_eDebug("%d channels in database.", m_new_channels.size());
116 m_ch_current = m_ch_toScan.front();
118 m_ch_toScan.pop_front();
120 if (m_channel->getFrontend(fe))
126 m_chid_current = eDVBChannelID();
128 m_channel_state = iDVBChannel::state_idle;
130 if (fe->tune(*m_ch_current))
131 return nextChannel();
137 RESULT eDVBScan::startFilter()
142 /* only start required filters filter */
144 if (m_ready_all & readyPAT)
145 startSDT = m_ready & readyPAT;
147 // m_ch_current is not set, when eDVBScan is just used for a SDT update
150 unsigned int channelFlags;
151 m_channel->getCurrentFrontendParameters(m_ch_current);
152 m_ch_current->getFlags(channelFlags);
153 if (channelFlags & iDVBFrontendParameters::flagOnlyFree)
154 m_flags |= scanOnlyFree;
158 if (startSDT && (m_ready_all & readySDT))
160 m_SDT = new eTable<ServiceDescriptionSection>(m_scan_debug);
162 if (m_ready & readyPAT && m_ready & validPAT)
164 std::vector<ProgramAssociationSection*>::const_iterator i =
165 m_PAT->getSections().begin();
166 assert(i != m_PAT->getSections().end());
167 tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id
168 m_pat_tsid = eTransportStreamID(tsid);
169 for (; i != m_PAT->getSections().end(); ++i)
171 const ProgramAssociationSection &pat = **i;
172 ProgramAssociationConstIterator program = pat.getPrograms()->begin();
173 for (; program != pat.getPrograms()->end(); ++program)
174 m_pmts_to_read.insert(std::pair<unsigned short, service>((*program)->getProgramNumber(), service((*program)->getProgramMapPid())));
176 m_PMT = new eTable<ProgramMapSection>(m_scan_debug);
177 CONNECT(m_PMT->tableReady, eDVBScan::PMTready);
179 // KabelBW HACK ... on 618Mhz and 626Mhz the transport stream id in PAT and SDT is different
183 m_ch_current->getSystem(type);
184 if (type == iDVBFrontend::feCable)
186 eDVBFrontendParametersCable parm;
187 m_ch_current->getDVBC(parm);
188 if ((tsid == 0x00d7 && abs(parm.frequency-618000) < 2000) ||
189 (tsid == 0x00d8 && abs(parm.frequency-626000) < 2000))
196 if (m_SDT->start(m_demux, eDVBSDTSpec()))
199 else if (m_SDT->start(m_demux, eDVBSDTSpec(tsid, true)))
201 CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
204 if (!(m_ready & readyPAT))
207 if (m_ready_all & readyPAT)
209 m_PAT = new eTable<ProgramAssociationSection>(m_scan_debug);
210 if (m_PAT->start(m_demux, eDVBPATSpec(4000)))
212 CONNECT(m_PAT->tableReady, eDVBScan::PATready);
216 if (m_ready_all & readyNIT)
218 m_NIT = new eTable<NetworkInformationSection>(m_scan_debug);
219 if (m_NIT->start(m_demux, eDVBNITSpec()))
221 CONNECT(m_NIT->tableReady, eDVBScan::NITready);
225 if (m_ready_all & readyBAT)
227 m_BAT = new eTable<BouquetAssociationSection>(m_scan_debug);
228 if (m_BAT->start(m_demux, eDVBBATSpec()))
230 CONNECT(m_BAT->tableReady, eDVBScan::BATready);
236 void eDVBScan::SDTready(int err)
238 SCAN_eDebug("got sdt %d", err);
245 void eDVBScan::NITready(int err)
247 SCAN_eDebug("got nit, err %d", err);
254 void eDVBScan::BATready(int err)
256 SCAN_eDebug("got bat");
263 void eDVBScan::PATready(int err)
265 SCAN_eDebug("got pat");
269 startFilter(); // for starting the SDT filter
272 void eDVBScan::PMTready(int err)
274 SCAN_eDebug("got pmt %d", err);
277 bool scrambled = false;
278 bool have_audio = false;
279 bool have_video = false;
280 unsigned short pcrpid = 0xFFFF;
281 std::vector<ProgramMapSection*>::const_iterator i;
282 for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i)
284 const ProgramMapSection &pmt = **i;
285 if (pcrpid == 0xFFFF)
286 pcrpid = pmt.getPcrPid();
288 SCAN_eDebug("already have a pcrpid %04x %04x", pcrpid, pmt.getPcrPid());
289 ElementaryStreamInfoConstIterator es;
290 for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
292 int isaudio = 0, isvideo = 0, is_scrambled = 0;
293 switch ((*es)->getType())
295 case 0x1b: // AVC Video Stream (MPEG4 H264)
296 case 0x01: // MPEG 1 video
297 case 0x02: // MPEG 2 video
299 //break; fall through !!!
300 case 0x03: // MPEG 1 audio
301 case 0x04: // MPEG 2 audio:
304 //break; fall through !!!
305 case 0x06: // PES Private
306 case 0x81: // user private
307 /* PES private can contain AC-3, DTS or lots of other stuff.
308 check descriptors to get the exact type. */
309 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
310 desc != (*es)->getDescriptors()->end(); ++desc)
312 uint8_t tag = (*desc)->getTag();
313 if (!isaudio && !isvideo)
322 case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
324 /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
325 if ((*desc)->getLength() != 4)
327 unsigned char descr[6];
328 (*desc)->writeToBuffer(descr);
329 int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
330 switch (format_identifier)
341 if (tag == CA_DESCRIPTOR)
355 for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
356 desc != pmt.getDescriptors()->end(); ++desc)
358 if ((*desc)->getTag() == CA_DESCRIPTOR)
362 m_pmt_in_progress->second.scrambled = scrambled;
364 m_pmt_in_progress->second.serviceType = 1;
365 else if ( have_audio )
366 m_pmt_in_progress->second.serviceType = 2;
368 m_pmt_in_progress->second.serviceType = 100;
370 if (err == -1) // timeout or removed by sdt
371 m_pmts_to_read.erase(m_pmt_in_progress++);
372 else if (m_pmt_running)
376 m_pmt_in_progress = m_pmts_to_read.begin();
377 m_pmt_running = true;
380 if (m_pmt_in_progress != m_pmts_to_read.end())
381 m_PMT->start(m_demux, eDVBPMTSpec(m_pmt_in_progress->second.pmtPid, m_pmt_in_progress->first, 4000));
385 m_pmt_running = false;
391 void eDVBScan::addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
393 /* add it to the list of known channels. */
395 m_new_channels.insert(std::pair<eDVBChannelID,ePtr<iDVBFrontendParameters> >(chid, feparm));
398 void eDVBScan::addChannelToScan(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
400 /* check if we don't already have that channel ... */
403 feparm->getSystem(type);
407 case iDVBFrontend::feSatellite:
409 eDVBFrontendParametersSatellite parm;
410 feparm->getDVBS(parm);
411 SCAN_eDebug("try to add %d %d %d %d %d %d",
412 parm.orbital_position, parm.frequency, parm.symbol_rate, parm.polarisation, parm.fec, parm.modulation);
415 case iDVBFrontend::feCable:
417 eDVBFrontendParametersCable parm;
418 feparm->getDVBC(parm);
419 SCAN_eDebug("try to add %d %d %d %d",
420 parm.frequency, parm.symbol_rate, parm.modulation, parm.fec_inner);
423 case iDVBFrontend::feTerrestrial:
425 eDVBFrontendParametersTerrestrial parm;
426 feparm->getDVBT(parm);
427 SCAN_eDebug("try to add %d %d %d %d %d %d %d %d",
428 parm.frequency, parm.modulation, parm.transmission_mode, parm.hierarchy,
429 parm.guard_interval, parm.code_rate_LP, parm.code_rate_HP, parm.bandwidth);
435 /* ... in the list of channels to scan */
436 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
438 if (sameChannel(*i, feparm))
442 *i = feparm; // update
443 SCAN_eDebug("update");
447 SCAN_eDebug("remove dupe");
448 m_ch_toScan.erase(i++);
458 SCAN_eDebug("already in todo list");
462 /* ... in the list of successfully scanned channels */
463 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_scanned.begin()); i != m_ch_scanned.end(); ++i)
464 if (sameChannel(*i, feparm))
466 SCAN_eDebug("successfully scanned");
470 /* ... in the list of unavailable channels */
471 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_unavailable.begin()); i != m_ch_unavailable.end(); ++i)
472 if (sameChannel(*i, feparm, true))
474 SCAN_eDebug("scanned but not available");
478 /* ... on the current channel */
479 if (sameChannel(m_ch_current, feparm))
481 SCAN_eDebug("is current");
485 SCAN_eDebug("really add");
486 /* otherwise, add it to the todo list. */
487 m_ch_toScan.push_front(feparm); // better.. then the rotor not turning wild from east to west :)
490 int eDVBScan::sameChannel(iDVBFrontendParameters *ch1, iDVBFrontendParameters *ch2, bool exact) const
493 if (ch1->calculateDifference(ch2, diff, exact))
495 if (diff < 4000) // more than 4mhz difference?
500 void eDVBScan::channelDone()
502 if (m_ready & validSDT && (!(m_flags & scanOnlyFree) || !m_pmt_running))
504 unsigned long hash = 0;
506 m_ch_current->getHash(hash);
508 eDVBNamespace dvbnamespace = buildNamespace(
509 (**m_SDT->getSections().begin()).getOriginalNetworkId(),
510 (**m_SDT->getSections().begin()).getTransportStreamId(),
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;
520 if (m_ready & validNIT)
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)
528 m_ch_toScan_backup = m_ch_toScan;
531 std::vector<NetworkInformationSection*>::const_iterator i;
532 for (i = m_NIT->getSections().begin(); i != m_NIT->getSections().end(); ++i)
534 const TransportStreamInfoList &tsinfovec = *(*i)->getTsInfo();
536 for (TransportStreamInfoConstIterator tsinfo(tsinfovec.begin());
537 tsinfo != tsinfovec.end(); ++tsinfo)
539 SCAN_eDebug("TSID: %04x ONID: %04x", (*tsinfo)->getTransportStreamId(),
540 (*tsinfo)->getOriginalNetworkId());
542 eOriginalNetworkID onid = (*tsinfo)->getOriginalNetworkId();
543 eTransportStreamID tsid = (*tsinfo)->getTransportStreamId();
545 for (DescriptorConstIterator desc = (*tsinfo)->getDescriptors()->begin();
546 desc != (*tsinfo)->getDescriptors()->end(); ++desc)
548 switch ((*desc)->getTag())
550 case CABLE_DELIVERY_SYSTEM_DESCRIPTOR:
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;
558 feparm->setDVBC(cable);
560 unsigned long hash=0;
561 feparm->getHash(hash);
562 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
565 eDVBChannelID(ns, tsid, onid),
569 case TERRESTRIAL_DELIVERY_SYSTEM_DESCRIPTOR:
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;
577 feparm->setDVBT(terr);
579 unsigned long hash=0;
580 feparm->getHash(hash);
581 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
584 eDVBChannelID(ns, tsid, onid),
588 case SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR:
590 if (system != iDVBFrontend::feSatellite)
591 break; // when current locked transponder is no satellite transponder ignore this descriptor
593 SatelliteDeliverySystemDescriptor &d = (SatelliteDeliverySystemDescriptor&)**desc;
594 if (d.getFrequency() < 10000)
597 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
598 eDVBFrontendParametersSatellite sat;
601 eDVBFrontendParametersSatellite p;
602 m_ch_current->getDVBS(p);
604 if ( abs(p.orbital_position - sat.orbital_position) < 5 )
605 sat.orbital_position = p.orbital_position;
607 if ( abs(abs(3600 - p.orbital_position) - sat.orbital_position) < 5 )
609 SCAN_eDebug("found transponder with incorrect west/east flag ... correct this");
610 sat.orbital_position = p.orbital_position;
613 feparm->setDVBS(sat);
615 if ( p.orbital_position != sat.orbital_position)
616 SCAN_eDebug("dropping this transponder, it's on another satellite.");
619 unsigned long hash=0;
620 feparm->getHash(hash);
622 eDVBChannelID(buildNamespace(onid, tsid, hash), tsid, onid),
628 SCAN_eDebug("descr<%x>", (*desc)->getTag());
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
640 This is not a perfect solution, as the channel could contain a partial NIT. Life's bad.
642 if (m_flags & clearToScanOnFirstNIT)
644 if (m_ch_toScan.empty())
646 eWarning("clearToScanOnFirstNIT was set, but NIT is invalid. Refusing to stop scan.");
647 m_ch_toScan = m_ch_toScan_backup;
649 m_flags &= ~clearToScanOnFirstNIT;
651 m_ready &= ~validNIT;
654 if (m_pmt_running || (m_ready & m_ready_all) != m_ready_all)
656 if (m_abort_current_pmt)
658 m_abort_current_pmt = false;
664 SCAN_eDebug("channel done!");
666 /* if we had services on this channel, we declare
667 this channels as "known good". add it.
669 (TODO: not yet implemented)
670 a NIT entry could have possible overridden
671 our frontend data with more exact data.
673 (TODO: not yet implemented)
674 the tuning process could have lead to more
675 exact data than the user entered.
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
683 These are the reasons for adding the transponder
684 here, and not before.
687 for (m_pmt_in_progress = m_pmts_to_read.begin(); m_pmt_in_progress != m_pmts_to_read.end();)
690 eServiceReferenceDVB ref;
691 ePtr<eDVBService> service = new eDVBService;
695 unsigned long hash = 0;
697 m_ch_current->getHash(hash);
699 m_chid_current = eDVBChannelID(
700 buildNamespace(eOriginalNetworkID(0), m_pat_tsid, hash),
701 m_pat_tsid, eOriginalNetworkID(0));
704 if (m_pmt_in_progress->second.serviceType == 1)
705 SCAN_eDebug("SID %04x is VIDEO", m_pmt_in_progress->first);
706 else if (m_pmt_in_progress->second.serviceType == 2)
707 SCAN_eDebug("SID %04x is AUDIO", m_pmt_in_progress->first);
709 SCAN_eDebug("SID %04x is DATA", m_pmt_in_progress->first);
711 ref.set(m_chid_current);
712 ref.setServiceID(m_pmt_in_progress->first);
713 ref.setServiceType(m_pmt_in_progress->second.serviceType);
715 if (!m_ch_current->getSystem(type))
719 memset(pname, 0, sizeof(pname));
720 memset(sname, 0, sizeof(sname));
723 case iDVBFrontend::feSatellite:
725 eDVBFrontendParametersSatellite parm;
726 m_ch_current->getDVBS(parm);
727 snprintf(sname, 255, "%d%c SID 0x%02x",
729 parm.polarisation ? 'V' : 'H',
730 m_pmt_in_progress->first);
731 snprintf(pname, 255, "%s %s %d%c %d.%d°%c",
732 parm.system ? "DVB-S2" : "DVB-S",
733 parm.modulation == 1 ? "QPSK" : "8PSK",
735 parm.polarisation ? 'V' : 'H',
736 parm.orbital_position/10,
737 parm.orbital_position%10,
738 parm.orbital_position > 0 ? 'E' : 'W');
741 case iDVBFrontend::feTerrestrial:
743 eDVBFrontendParametersTerrestrial parm;
744 m_ch_current->getDVBT(parm);
745 snprintf(sname, 255, "%d SID 0x%02x",
747 m_pmt_in_progress->first);
750 case iDVBFrontend::feCable:
752 eDVBFrontendParametersCable parm;
753 m_ch_current->getDVBC(parm);
754 snprintf(sname, 255, "%d SID 0x%02x",
756 m_pmt_in_progress->first);
760 SCAN_eDebug("name '%s', provider_name '%s'", sname, pname);
761 service->m_service_name = convertDVBUTF8(sname);
762 service->genSortName();
763 service->m_provider_name = convertDVBUTF8(pname);
766 if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) {
767 SCAN_eDebug("add not scrambled!");
768 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
771 m_last_service = i.first;
772 m_event(evtNewService);
776 SCAN_eDebug("dont add... is scrambled!");
777 m_pmts_to_read.erase(m_pmt_in_progress++);
781 eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
783 addKnownGoodChannel(m_chid_current, m_ch_current);
785 m_ch_scanned.push_back(m_ch_current);
787 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
789 if (sameChannel(*i, m_ch_current))
791 SCAN_eDebug("remove dupe 2");
792 m_ch_toScan.erase(i++);
801 void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
805 m_ch_scanned.clear();
806 m_ch_unavailable.clear();
807 m_new_channels.clear();
808 m_new_services.clear();
809 m_last_service = m_new_services.end();
811 for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
814 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
816 if (sameChannel(*i, *ii, true))
823 m_ch_toScan.push_back(*i);
829 void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
831 if (m_flags & scanRemoveServices)
833 bool clearTerrestrial=false;
834 bool clearCable=false;
835 std::set<unsigned int> scanned_sat_positions;
837 std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
838 for (;it != m_ch_scanned.end(); ++it)
840 if (m_flags & scanDontRemoveUnscanned)
841 db->removeServices(&(*(*it)));
845 (*it)->getSystem(system);
848 case iDVBFrontend::feSatellite:
850 eDVBFrontendParametersSatellite sat_parm;
851 (*it)->getDVBS(sat_parm);
852 scanned_sat_positions.insert(sat_parm.orbital_position);
855 case iDVBFrontend::feTerrestrial:
857 clearTerrestrial=true;
860 case iDVBFrontend::feCable:
869 for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
871 if (m_flags & scanDontRemoveUnscanned)
872 db->removeServices(&(*(*it)));
876 (*it)->getSystem(system);
879 case iDVBFrontend::feSatellite:
881 eDVBFrontendParametersSatellite sat_parm;
882 (*it)->getDVBS(sat_parm);
883 scanned_sat_positions.insert(sat_parm.orbital_position);
886 case iDVBFrontend::feTerrestrial:
888 clearTerrestrial=true;
891 case iDVBFrontend::feCable:
900 if (clearTerrestrial)
903 chid.dvbnamespace=0xEEEE0000;
904 db->removeServices(chid);
909 chid.dvbnamespace=0xFFFF0000;
910 db->removeServices(chid);
912 for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
915 if (m_flags & scanDontRemoveFeeds)
916 chid.dvbnamespace = eDVBNamespace((*x)<<16);
917 // eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
918 db->removeServices(chid, *x);
922 for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator
923 ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
925 if (m_flags & scanOnlyFree)
927 eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
928 ptr->setFlags(iDVBFrontendParameters::flagOnlyFree);
930 db->addChannelToList(ch->first, ch->second);
933 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::const_iterator
934 service(m_new_services.begin()); service != m_new_services.end(); ++service)
936 ePtr<eDVBService> dvb_service;
937 if (!db->getService(service->first, dvb_service))
939 if (dvb_service->m_flags & eDVBService::dxNoSDT)
941 if (!(dvb_service->m_flags & eDVBService::dxHoldName))
943 dvb_service->m_service_name = service->second->m_service_name;
944 dvb_service->m_service_name_sort = service->second->m_service_name_sort;
946 dvb_service->m_provider_name = service->second->m_provider_name;
947 if (service->second->m_ca.size())
948 dvb_service->m_ca = service->second->m_ca;
949 if (!dontRemoveOldFlags) // do not remove new found flags when not wished
950 dvb_service->m_flags &= ~eDVBService::dxNewFound;
954 db->addService(service->first, service->second);
955 if (!(m_flags & scanRemoveServices))
956 service->second->m_flags |= eDVBService::dxNewFound;
961 RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt)
963 const ServiceDescriptionList &services = *sdt.getDescriptions();
964 SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
965 eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
967 /* save correct CHID for this channel */
968 m_chid_current = chid;
970 for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
972 unsigned short service_id = (*s)->getServiceId();
973 SCAN_eDebugNoNewLine("SID %04x: ", service_id);
976 if (m_flags & scanOnlyFree)
978 std::map<unsigned short, service>::iterator it =
979 m_pmts_to_read.find(service_id);
980 if (it != m_pmts_to_read.end())
982 if (it->second.scrambled)
984 SCAN_eDebug("is scrambled!");
988 SCAN_eDebug("is free");
991 SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!");
998 eServiceReferenceDVB ref;
999 ePtr<eDVBService> service = new eDVBService;
1002 ref.setServiceID(service_id);
1004 for (DescriptorConstIterator desc = (*s)->getDescriptors()->begin();
1005 desc != (*s)->getDescriptors()->end(); ++desc)
1007 switch ((*desc)->getTag())
1009 case SERVICE_DESCRIPTOR:
1011 ServiceDescriptor &d = (ServiceDescriptor&)**desc;
1012 ref.setServiceType(d.getServiceType());
1013 service->m_service_name = convertDVBUTF8(d.getServiceName());
1014 service->genSortName();
1016 service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
1017 SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
1020 case CA_IDENTIFIER_DESCRIPTOR:
1022 CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
1023 const CaSystemIdList &caids = *d.getCaSystemIds();
1024 SCAN_eDebugNoNewLine("CA ");
1025 for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i)
1027 SCAN_eDebugNoNewLine("%04x ", *i);
1028 service->m_ca.push_front(*i);
1034 SCAN_eDebug("descr<%x>", (*desc)->getTag());
1039 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
1043 m_last_service = i.first;
1044 m_event(evtNewService);
1047 if (m_pmt_running && m_pmt_in_progress->first == service_id)
1048 m_abort_current_pmt = true;
1050 m_pmts_to_read.erase(service_id);
1056 RESULT eDVBScan::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1058 connection = new eConnection(this, m_event.connect(event));
1062 void eDVBScan::getStats(int &transponders_done, int &transponders_total, int &services)
1064 transponders_done = m_ch_scanned.size() + m_ch_unavailable.size();
1065 transponders_total = m_ch_toScan.size() + transponders_done;
1066 services = m_new_services.size();
1069 void eDVBScan::getLastServiceName(std::string &last_service_name)
1071 if (m_last_service == m_new_services.end())
1072 last_service_name = "";
1074 last_service_name = m_last_service->second->m_service_name;
1077 RESULT eDVBScan::getFrontend(ePtr<iDVBFrontend> &fe)
1080 return m_channel->getFrontend(fe);
1085 RESULT eDVBScan::getCurrentTransponder(ePtr<iDVBFrontendParameters> &tp)