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 ePtr<iDVBFrontend> fe;
744 eDVBFrontendParametersTerrestrial parm;
745 m_ch_current->getDVBT(parm);
746 snprintf(sname, 255, "%d SID 0x%02x",
748 m_pmt_in_progress->first);
749 if (!m_channel->getFrontend(fe))
751 ePyObject tp_dict = PyDict_New();
752 fe->getTransponderData(tp_dict, false);
753 m_corrected_frequencys[m_chid_current] =
754 PyInt_AsLong(PyDict_GetItemString(tp_dict, "frequency"));
759 case iDVBFrontend::feCable:
761 eDVBFrontendParametersCable parm;
762 m_ch_current->getDVBC(parm);
763 snprintf(sname, 255, "%d SID 0x%02x",
765 m_pmt_in_progress->first);
769 SCAN_eDebug("name '%s', provider_name '%s'", sname, pname);
770 service->m_service_name = convertDVBUTF8(sname);
771 service->genSortName();
772 service->m_provider_name = convertDVBUTF8(pname);
775 if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) {
776 SCAN_eDebug("add not scrambled!");
777 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
778 m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
781 m_last_service = i.first;
782 m_event(evtNewService);
786 SCAN_eDebug("dont add... is scrambled!");
787 m_pmts_to_read.erase(m_pmt_in_progress++);
791 eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
793 addKnownGoodChannel(m_chid_current, m_ch_current);
795 m_ch_scanned.push_back(m_ch_current);
797 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
799 if (sameChannel(*i, m_ch_current))
801 SCAN_eDebug("remove dupe 2");
802 m_ch_toScan.erase(i++);
811 void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
815 m_ch_scanned.clear();
816 m_ch_unavailable.clear();
817 m_new_channels.clear();
818 m_new_services.clear();
819 m_last_service = m_new_services.end();
821 for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
824 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
826 if (sameChannel(*i, *ii, true))
833 m_ch_toScan.push_back(*i);
839 void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
841 if (m_flags & scanRemoveServices)
843 bool clearTerrestrial=false;
844 bool clearCable=false;
845 std::set<unsigned int> scanned_sat_positions;
847 std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
848 for (;it != m_ch_scanned.end(); ++it)
850 if (m_flags & scanDontRemoveUnscanned)
851 db->removeServices(&(*(*it)));
855 (*it)->getSystem(system);
858 case iDVBFrontend::feSatellite:
860 eDVBFrontendParametersSatellite sat_parm;
861 (*it)->getDVBS(sat_parm);
862 scanned_sat_positions.insert(sat_parm.orbital_position);
865 case iDVBFrontend::feTerrestrial:
867 clearTerrestrial=true;
870 case iDVBFrontend::feCable:
879 for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
881 if (m_flags & scanDontRemoveUnscanned)
882 db->removeServices(&(*(*it)));
886 (*it)->getSystem(system);
889 case iDVBFrontend::feSatellite:
891 eDVBFrontendParametersSatellite sat_parm;
892 (*it)->getDVBS(sat_parm);
893 scanned_sat_positions.insert(sat_parm.orbital_position);
896 case iDVBFrontend::feTerrestrial:
898 clearTerrestrial=true;
901 case iDVBFrontend::feCable:
910 if (clearTerrestrial)
913 chid.dvbnamespace=0xEEEE0000;
914 db->removeServices(chid);
919 chid.dvbnamespace=0xFFFF0000;
920 db->removeServices(chid);
922 for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
925 if (m_flags & scanDontRemoveFeeds)
926 chid.dvbnamespace = eDVBNamespace((*x)<<16);
927 // eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
928 db->removeServices(chid, *x);
932 for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator
933 ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
936 ch->second->getSystem(system);
937 if (system == iDVBFrontend::feTerrestrial)
939 std::map<eDVBChannelID, unsigned int>::iterator it = m_corrected_frequencys.find(ch->first);
940 if (it != m_corrected_frequencys.end())
942 eDVBFrontendParameters *p = (eDVBFrontendParameters*)&(*ch->second);
943 eDVBFrontendParametersTerrestrial parm;
945 eDebug("corrected freq for tsid %04x, onid %04x, ns %08x is %d, old was %d",
946 ch->first.transport_stream_id.get(), ch->first.original_network_id.get(),
947 ch->first.dvbnamespace.get(), it->second, parm.frequency);
948 parm.frequency = it->second;
950 m_corrected_frequencys.erase(it);
953 if (m_flags & scanOnlyFree)
955 eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
956 ptr->setFlags(iDVBFrontendParameters::flagOnlyFree);
958 db->addChannelToList(ch->first, ch->second);
961 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::const_iterator
962 service(m_new_services.begin()); service != m_new_services.end(); ++service)
964 ePtr<eDVBService> dvb_service;
965 if (!db->getService(service->first, dvb_service))
967 if (dvb_service->m_flags & eDVBService::dxNoSDT)
969 if (!(dvb_service->m_flags & eDVBService::dxHoldName))
971 dvb_service->m_service_name = service->second->m_service_name;
972 dvb_service->m_service_name_sort = service->second->m_service_name_sort;
974 dvb_service->m_provider_name = service->second->m_provider_name;
975 if (service->second->m_ca.size())
976 dvb_service->m_ca = service->second->m_ca;
977 if (!dontRemoveOldFlags) // do not remove new found flags when not wished
978 dvb_service->m_flags &= ~eDVBService::dxNewFound;
982 db->addService(service->first, service->second);
983 if (!(m_flags & scanRemoveServices))
984 service->second->m_flags |= eDVBService::dxNewFound;
989 RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt)
991 const ServiceDescriptionList &services = *sdt.getDescriptions();
992 SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
993 eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
995 /* save correct CHID for this channel */
996 m_chid_current = chid;
998 for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
1000 unsigned short service_id = (*s)->getServiceId();
1001 SCAN_eDebugNoNewLine("SID %04x: ", service_id);
1004 if (m_flags & scanOnlyFree)
1006 std::map<unsigned short, service>::iterator it =
1007 m_pmts_to_read.find(service_id);
1008 if (it != m_pmts_to_read.end())
1010 if (it->second.scrambled)
1012 SCAN_eDebug("is scrambled!");
1016 SCAN_eDebug("is free");
1019 SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!");
1026 eServiceReferenceDVB ref;
1027 ePtr<eDVBService> service = new eDVBService;
1030 ref.setServiceID(service_id);
1032 for (DescriptorConstIterator desc = (*s)->getDescriptors()->begin();
1033 desc != (*s)->getDescriptors()->end(); ++desc)
1035 switch ((*desc)->getTag())
1037 case SERVICE_DESCRIPTOR:
1039 ServiceDescriptor &d = (ServiceDescriptor&)**desc;
1040 ref.setServiceType(d.getServiceType());
1041 service->m_service_name = convertDVBUTF8(d.getServiceName());
1042 service->genSortName();
1044 service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
1045 SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
1048 case CA_IDENTIFIER_DESCRIPTOR:
1050 CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
1051 const CaSystemIdList &caids = *d.getCaSystemIds();
1052 SCAN_eDebugNoNewLine("CA ");
1053 for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i)
1055 SCAN_eDebugNoNewLine("%04x ", *i);
1056 service->m_ca.push_front(*i);
1062 SCAN_eDebug("descr<%x>", (*desc)->getTag());
1067 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
1068 m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
1072 m_last_service = i.first;
1073 m_event(evtNewService);
1076 if (m_pmt_running && m_pmt_in_progress->first == service_id)
1077 m_abort_current_pmt = true;
1079 m_pmts_to_read.erase(service_id);
1085 RESULT eDVBScan::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1087 connection = new eConnection(this, m_event.connect(event));
1091 void eDVBScan::getStats(int &transponders_done, int &transponders_total, int &services)
1093 transponders_done = m_ch_scanned.size() + m_ch_unavailable.size();
1094 transponders_total = m_ch_toScan.size() + transponders_done;
1095 services = m_new_services.size();
1098 void eDVBScan::getLastServiceName(std::string &last_service_name)
1100 if (m_last_service == m_new_services.end())
1101 last_service_name = "";
1103 last_service_name = m_last_service->second->m_service_name;
1106 RESULT eDVBScan::getFrontend(ePtr<iDVBFrontend> &fe)
1109 return m_channel->getFrontend(fe);
1114 RESULT eDVBScan::getCurrentTransponder(ePtr<iDVBFrontendParameters> &tp)