pax_global_header00006660000000000000000000000064152015440570014515gustar00rootroot0000000000000052 comment=56956e9379aba57f16a104895c9bf904076704f8 wirbel-at-vdr-portal-wirbelscan-dev-eebef12/000077500000000000000000000000001520154405700211515ustar00rootroot00000000000000wirbel-at-vdr-portal-wirbelscan-dev-eebef12/.gitignore000066400000000000000000000010111520154405700231320ustar00rootroot00000000000000# Prerequisites *.d .dependencies # Compiled Object files *.lo *.o *.obj *.mo # Compiled Dynamic libraries *.so *.so.* *.dylib *.dll # Compiled Static libraries *.la *.a *.lib # Executables *.out # not part of package. README.md *.pot # texts, logs, patches *.diff *.patch *.txt *.text *.log #/****************************************************************************** # * Packages # *****************************************************************************/ *.7z *.tgz *.tar.gz *.tar.bz2 *.tar.xz *.zip wirbel-at-vdr-portal-wirbelscan-dev-eebef12/COPYING000066400000000000000000000431061520154405700222100ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. wirbel-at-vdr-portal-wirbelscan-dev-eebef12/HISTORY000066400000000000000000000524551520154405700222500ustar00rootroot00000000000000VDR Plugin 'wirbelscan' Revision History ---------------------------------------- 2006-10-28: Version 0.0.1 ------------------------------------------------------------------------------- - Initial revision. Alpha Status up to now. 2006-12-01: Version 0.0.2 ------------------------------------------------------------------------------- - removed unused header from common.c - added missing setup property 'logfile' in setup (menusetup.c) - added some internationalization (i18n.c) - fixed compiler warning in satfrequencies.c and frequencies.c - setting liveView=true if dvb card used is not free; either the only card or receiving/recording. (scanner.c) - moved "memset(&frontend_status,0, sizeof(frontend_status));" into GetStatus(void) (scanner.c) to be shure that frontend_status is *always* resetted. - while scanning now the channels.conf is cleared (and refilled after last scan with the old channel data) - Added EITScanner.ForceScan(); at the End of dvb scans to enshure Adding channels. - now switching to all new transponders after last scan - changed transponder scan routines in scanner.c - now tuning (by purpose!) to a invalid transponder before tuning to other data; this should enshure that tuning is successful. - slightly changed cUpdateThread::Action() - osd: remains now open while scanning - osd: removed inversion setting dvb-c - osd: added symbolrate setting dvb-c - osd: added stop scan button - speed up dvb-t scan - speed up dvb-s scan - fixed d(const int level, const char *fmt, ...) for syslog - still Alpha Status. 2006-12-XX: Version 0.0.2a ------------------------------------------------------------------------------- - now deleting transponders Searchlist in AfterScan(void) - fixed osd handling during scan (OK, Back) - scanning not possible if recordings are running. - added Channels.SetModified() in AfterScan to avoid duplicate channels. -> has to be checked. 2007-02-XX: Version 0.0.2b ------------------------------------------------------------------------------- - first SVDRP support: S_TERR, S_CABL, S_SAT, S_PVR, S_STOP 2007-09-03: Version 0.0.3-20070903 ------------------------------------------------------------------------------- - changed device handling to lowlevel functions - new SVDRP functions: M_AUTO, M64, M128, M256, SR_AUTO, SR6900, SR6875 - started Internationalization with xgettext as in VDR>=1.5.7 - fixed compiling on vdr-1.5.x - started freq offset support for DVB-T (france) - changes to frequency tables (see above and cSatFreqlist) - fixed wrong message in cTerrScanner "C %d has lock.." into "T %d has lock.." - fixed wrong internationalization "PVR x50 scan done" - PVR x50 support for external input scan - new function stopScanners - new functions DoScan and DoStop for SVDRP support - DVB-C added missing Symbolrate 6111 (only manual mode) - now using Skins.QueueMessage instead of Skins.Message 2008-05-12: Version 0.0.4-20080512 ------------------------------------------------------------------------------- - added some Copyright Remark to README as proposed from Debian VDR Packaging Team - removed PAL SE1 105250/107500 see http://de.wikipedia.org/wiki/Kabelfernsehen: "Der Sonderkanal S01 kann wegen der Überschneidung mit dem UKW-Radio-Frequenzband nicht genutzt werden" - added 73.00 MHz for DVB-C PAL - italian translations (Diego Pierotto ) - removed obsolete ptv plugin option - minor changes to osd - now start searching dvb devices at highest device number (often first device at dvb-c is a full-featured card -> QAM256 problems). 2008-09-10ff: version 0.0.5-preXX ------------------------------------------------------------------------------- - applied updated italian translations (thanks to Diego Pierotto), renamed "Gringo" to Diego's real name - completely restructured dvb scanners - no longer deleting channel list during scan, but rather applying receiver - added pat, pmt, nit, nit_other, sdt filters (adapted versions of VDRs own scan filters, see /{pat,nit,sdt}.c) - scans are now handled with state machine which is initialized from transponder lists - new dvb wrapper for easier following dvb/vdr variants next versions (not complete up to now) (multiproto jusst, multiproto stoth, vdr-1.6 vs. vdr-1.7, channel syntax vdr-1.7.0 vs vdr-1.7.1, multiproto-wrapper, whatever..) - added support for channel names on pvr-x50 channels using VBI network readout (needs libzbvi, which is part of Zapper) - support for new pvrinput syntax - added cx88_blackbird analogue scan support + input names (still under test) - new patch for disabling libzvbi support, if not available/not needed (see sub folder patches) - updated satellite lists, now including system and modulation_type - new files vbi.{h,c}, scanfilter.{h,c}, dvb_wrapper.{h,c}, statemachine.{h,c}, caDescriptor.{h,c} - remove about dlg - compiling on 1.7.13, 1.7.14, 1.4.7 - check compiling 1.4.7 *) 1.6.0 1.7.2 .. 1.7.14 *) support may be dropped sometime - add: DVB-C SRates 5156, 5483, Finland add QAM128 - add: preliminary ATSC support - add missing default switches - fix unsigned vs signed - fix floating point comparisons - DVB-C scan: FEC_NONE, fix: setting Inversion - DVB-T scan: UK changed from TM_2k to TM_8k, fix check DVB-T Bandwidth - pvrinput syntax adaption (may change further depending on development of pvrinput) - remove files vbi.{h,c} and related autotools setup (zvbi introduced more problems than usability :-( ) - update README - add: S97W0 telstar5, S160E0 Optus D1 - upd: S30W0 Hispasat 1C/1D - upd. S23E5 Astra 1E/1G/3A - improve human readability of log output - GetFrontendStrength: 'value' is now uint16_t - pvrinput syntax changes, remove pvrinput syntax choice - improve storing of setup - fix color keys on setup page - cMenuScanning::SetStr: fix displayed value - enhAC3 Tag adds now DPids - during scan: update also existing channels, no longer skip those. - decrease verbosity on LinkageChannels. - gcc-4.5 fix (Edgar Hucek ) - add wirbelscan service API && add SERVICES.html - improve SVDRP interface - added descriptors STREAMTYPE_13818_AUDIO_ADTS, STREAMTYPE_14496_AUDIO_LATM - vdr-1.7.15 changed SetPid: add Atypes, Dtypes - 0.0.5-pre12b - service interface: * add user transponder scan (SUser) * status: add SUser version - 0.0.5-pre12c - improve setup storage key handling - move hexdump to common - move SwReceiver to ttext - pvrinput: * scan channel names from cni && teletext (needs pvrinput from 09/2010 and enabling teletext) * add external inputs (svideo, composite,...) - 0.0.5-pre12d - bugfix counting queued transponders - bugfix dvb-c auto symbolrates stopped at sr 6900 - ttext: timeout counter in seconds. - 0.0.5-pre12d == version 0.0.5 - 0.0.5-1 - bugfix: segfault on vdr-1.6.0 - 0.0.5-2 - bugfix: reading dvb capability flags - improved receiver handling in statemachine.c to avoid loosing control of receiving device - simplified eit scanner && deadlock fix. - throw compilation warning on outdated dvb api 3.2 - throw compilation error on unsupported/outdated dvb api 3.3 - 0.0.5-3 - cleanup && cosmetics - update README 2011-02-06: version 0.0.6 ------------------------------------------------------------------------------- - whitespace && minor code cleanups. - don't throw error on start scan if timers on schedule; check wether next timer is at least 2hours in future and of the same type as the scan requested. - pvrinput scan: move channel check for pvrinput into IsPvrinput and fix misuse of sscanf (old plugin param patch only) - remove wrong "fuzzy" translations 2011-03-24: version 0.0.7 ------------------------------------------------------------------------------- - 0.0.7-pre01 - fix memory leak: ext_math.c:112 - fix memory leak: scanner.c:609 - remove unused #include videodev.h from countries.c (file used by w_scan and wirbelscan) - replace DeleteAndNull by DELETENULL (defined in ) - replace all remaining 'delete' by 'DELETENULL' - check return value of asprintf in cPluginWirbelscan::Service - countries.c: remove octals. - common.c: change inititialization of char arrays to avoid memset - common.c: hexdump, check for buf != NULL - update S41E9 + rename to S42E0 - fix compiling vdr-1.6.0-2 - fix SetTerrTransponderDataFromDVB to set DVB-T Bandwidth for VDR > 10712 correctly. - 0.0.7-pre02 - don't set shortname and provider on analog channels anymore - wirbelscan_services: cast for Bandwidth to avoid float to int conversion, increase service user version to 0002 - common.c: FileExists(), dont cast arg1 of stat() to char * (unsafe conversion losses 'const' attribute) - scanfilter.c: cast to unsigned in switch(d->getDescriptorTag()) - move setup class 'cWirbelscan' to common.{c,h} and rename to 'wSetup' - move defines from menusetup.h to common.h - disable now pvrinput support by default, enabling needs new command line option '--use-pvrinput'. - disable unused DVB Types in settings menu. Only DVB types with matching devices (pvrinput similar) are now visible in settings menu. This should help newbees finding their settings. - SERVICE and SVDRP connections will now reject DVB/pvrinput without devices; in case of pvrinput also if not explicitly enabled by command line option. - skip support of VDR Versions before 1.6.0; remove po2i18n.pl, i18n.h, i18n-template.c - remove clean_code folder from dist package - update Makefile; now using LDFLAGS, Make.global and -O3 optimisation, force permissions on make dist. - GetPreferredDevice: dont stop if Device(i) doesnt exist, continue up to MAXDEVICES (was: MAXDVBDEVICES and stopping if Device(i) missed) - 0.0.7 - 0.0.7 == 0.0.7-pre02 2016-xx-xx ------------------------------------------------------------------------------- * pvrinput support is removed, as no analog channels available anymore. * build using VDRs Makefile is no longer used by me. It may work or not. Feel free to edit the Makefile stub. * version numbering is now YYYY.MM.DD * new version dont care about vdr before 2.3 as the changes in VDRs core are too large to keep compat. If using old VDR, use old plugin. * also plugin interface changed a bit - considered broken at the moment. * now trying to avoid cChannel and cString VDR classes - too deep changes in vdr core. * avoid as much as possible vdrs global lists (Channels, Timers, etc.) This one has consequences for the whole plugin - the scan algorithm changed and updates (new channels counting etc.) are not possible any longer during scan. * T2: add scan loop 2018-11-04 ------------------------------------------------------------------------------- * fix possible segfault, if remotely controlled (thanks to Luca Olivetti) * allow operation from positioner (thanks to Luca Olivetti) * silence a few useless vdr warnings during scan: "ERROR: channel data results in invalid ID!"; as a channel scanner doesnt have any valid channel IDs at the beginning of its work. 2020-05-03 ------------------------------------------------------------------------------- * plugin maintainance after a few years * check for compat with vdr-2.4.1 * changes in core VDR 2.4.1 cause now segfaults together with wirbelscan together with rofafors SAT>IP plugin. -> Solution: no longer try to query device information in case of SAT>IP. Otherwise, complete Astra-19.2E is scanned using SAT>IP in 8 minutes, 15 seconds. Not that bad for an very old dtv scanner inside VDR's jail, using an emulated dvb device. :) 2020-05-03 ------------------------------------------------------------------------------- * simplify InitSystems 2020-12-06/2020-12-13 ------------------------------------------------------------------------------- * add channel export feature to wirbelscan_services for w_scan_cpp support * fix bugs if cDevice* casted c-Style to cDvbDevice* Thanks to MarkusE @ vdr-portal.de * fix error messages if cast to cDvbDevice failed and device coulnt be opened. Thanks to MarkusE @ vdr-portal.de * remove a few DVB-T/T2 freqs in DE (700M Band) * scan plp 0..3 for T2 (not an real fix, but should work good enough) * move {VERSION,DESCRIPTION,MAINMENUENTRY} to WIRBELSCAN_* * enable SAT>IP for C/T(2) * fix bug introduced by wrong packaging Thanks to MarkusE @ vdr-portal.de 2020-12-17 ------------------------------------------------------------------------------- * dynamite support broke satip support :(, fixed by removing dvb dev check. 2020-12-22 ------------------------------------------------------------------------------- * add PMT Pid to TChannel - no change if used as a VDR Plugin. 2021-02-18 ------------------------------------------------------------------------------- * scanfilter.c: - modify message for SatelliteDeliverySystemDescriptor from wrong satellites to be more readable and remove superfluous newline - report PAT timeout, if 3 secs no data from PAT * statemachine.c: - if PAT scanner exits without data, set it to NULL and clear PmtData. Otherwise next PatScanners are not created. - add line numbers for {New,Scanned}Transponders.Add for debug - move ScannedTransponders.Add from eAddChannels to eTune, to catch any retuning to the same tp in case of broken NIT and updated tp - remove commented code in statemachine.c * increase version to 2021.02.18 2021-03-07 ------------------------------------------------------------------------------- * countries.c: - reorder DVBC_QAM frequencies, thanks for pointing out issue to Michael Kaufmann * countries.c: - swap sequence of DVB-C modulations, now preferring QAM256 to QAM64 * scanner.c: - skip DVB-C loops after first one, if card has QAM_AUTO support. * increase version to 2021.03.07 * feed several files tru dos2unix - fixing line end. Why did it happen..? 2021-07-14 ------------------------------------------------------------------------------- * common.c: - hexdump to stderr instead of stdout 2021-10-09 ------------------------------------------------------------------------------- * review whole plugin after many years in service: - update contact address and homepage, outdated on a few files. - build system: change from VDR style *.c file names to *.cpp - build system: sort includes to be bare minimum - build system: prefer c++ includes to c includes (stdint.h -> cstdint) - review code formatting and indentation - replace NULL by c++ style nullptr - replace any unistd or BSD-style integers by standard integers - replace any *sleep functions by mSleep(), which uses C++11 - replace DELETENULL by DeleteNullptr(), to get rid of macro style - remove as much as possible *printf and sscanf style and logging * remove dvb_wrapper.{h,c} and move remains to common.{h,cpp} * wirbelscan_services.h - remove deprecated entry Satsystem. * tlist.h: - replace VDR's cMutex by std::lock_guard * statemachine.{h,cpp} - add ThreadBase.h from easyvdr and series plugin. - change cStateMachine's base class to ThreadBase, to get rid of VDR's class cThread - change cScanReceiver's base class to ThreadBase, to get rid of VDR's class cThread * scanner.{h,cpp} - replace TThread by ThreadBase - replace BCD2INT() by BCDtoDecimal() - remove vdr/tools.h - simplify satellites.dat lookup * scanfilter.{h,cpp} - replace TThread by ThreadBase - remove pthread.h - replace BCD2INT() by BCDtoDecimal() - fix rounding of frequencies - is_different_transponder_deep_scan(): disable rolloff comparison - is_different_transponder_deep_scan(): prefer lambda instead of C Macro. * satellites.{h,cpp} - move SAT_TRANSPONDER_COUNT and SAT_COUNT to cpp src - adapt to newer dat version * countries.{h,cpp} - remove COUNTRY_COUNT - convert get_user_country() to c++ style - move country_t, offset_type_t and SKIP_CHANNEL to countries.cpp * common.{h,cpp} - remove FREENULL macro. - remove struct satellite_transponder - remove struct tuning_parameters - add BCDtoDecimal template - add IntToStr(), IntToHex(), FloatToStr() - remove va_*, vsnprint and remove cstdarg - remove HEXDUMP() macro, used in two places only * wirbelscan.cpp - convert as much as possible to std::string, std::stringstream - bump version 2021-11-28 ------------------------------------------------------------------------------- * wirbelscan.cpp - found old bug: invalid country or satellite settings in setup.conf could crash the plugin, if used inside VDR, but not inside w_scan_cpp. - apply range checks to setup.conf stored variables. - replace atoi by std::sto{i,l,ll} * menusetup.cpp - convert SatNames and CountryNames to std::vector, this avoids duplicating those const char *, while opening the menu. - convert DVB_Types, logfiles, Symbolrates, Qams, inversions, atsc_types to std::array * wirbelscan.cpp, common.cpp, menusetup.cpp - wSetup.logFile == 0 was used in the past to turn off logging, but was different in common.c/cpp. Restore it. Similarly, wSetup.logFile == 3 is logging to stderr, make it avail from GUI. - remove uppercase() and split() and use librepfunc * menusetup.cpp - in cMenuScanning::SetStatus(), protect st using constrain * satellites.dat - regen with updated generator on LFS, now 152 sats. * scanner.cpp - now choose the first sat device, which supports any item in scanlist. Otherwise, with mixed Ku-band and C-band items in list, no device may be found. * statemachine.cpp - show signal strength also for satip, no longer assuming lock = 100%. The satip plugin added signal strength long time ago. * common.{h,cpp} - TChannel::ValidSatIf() takes care of spectral inversion case - hexdump() is now a wrapper to librepfunc's HexDump() - FileExists(), IntToStr(), IntToHex(), FloatToStr(), mSleep(), BCDtoDecimal() have been moved to librepfunc (https://github.com/wirbel-at-vdr-portal/librepfunc) * ThreadBase.h - delete file and use librepfunc * Makefile - check availability and version of librepfunc and link to it. * New: preferred device per scan type, ie. sat, cable,.. * bump version. 2021-12-11 ------------------------------------------------------------------------------- * scanner.cpp - satellite fix: ValidSatIf() needs source to be set 2022-01-05 ------------------------------------------------------------------------------- * scanner.cpp - modify preferred device search messages * countries.cpp - revise countries * scanner.cpp - fix terr device search * scanner.cpp - fix DVB-T only loop for non T2 devices 2022-10-15 ------------------------------------------------------------------------------- * fix typos * Update README.md * remove unused func/variable 2022-10-16 ------------------------------------------------------------------------------- * fix typos 2022-12-31 ------------------------------------------------------------------------------- * countries.{h,cpp} - provide currently selected Alpha-3 - add Alpha-3 to cCountry * countries.cpp - restore DVB-T* for France * si_ext.h - add private_data_specifier values 2022-01-21 ------------------------------------------------------------------------------- * prepare for private descriptors, outside of 300468 v1.15 * use more distinct initialisation * Add notice about private descriptors * add parts of logical channel numbering * LogicalChannel doesnt need pure virtual * store current status: V2 to be modified * renamed loop member * add LCNs to TNitData * now we need #include * v2023.01.21 2023-02-19 ------------------------------------------------------------------------------- * new setup option ParseLCN * preserve current state * debug, add unknown descriptors id * convert lcn list to global * add comparison operators * add new setup option parsing * remove duplicate LCNs * LCN assignment function * assign LCN to TChannel * ease LCN to service match * improve debug output * bump version 2023-06-04 ------------------------------------------------------------------------------- * add to countries.h, thanks to Manuel Reimer for pinging me * bump version 2023-10-15 ------------------------------------------------------------------------------- * use std::atomic for scanfilters instead of bool * move {active,isActive} to end of scanfilters Action() * early delete and set to nullptr any of the scanfilters in statemachine.cpp (less memory required) * detach aReceiver from dev, before deleting it * bump version 2024-09-15 ------------------------------------------------------------------------------- * added configuration for signal wait time and lock timeout. * bumped service version for get/set setup, GetSetup#XXXX/SetSetup#XXXX; plugins using the wirbelscan service interface member 'setup' should be recompiled with the current version of wirbelscan_services.h. Otherwise, any call to bool cPluginWirbelscan::Service(const char* id, void* Data) with id = GetSetup or SetSetup will fail. Ideally, their sources should be also touched, such that the new members of cWirbelscanScanSetup named SignalWaitTime and LockTimeout are available in the controlling plugin. * TP update on S19E2 * fixed the case when a language descriptor is empty (random incorrect lang) * removed cSectionSyncer::Sync(), the plugin needs now at least vdr-2.5.2 2024-xx-xx ------------------------------------------------------------------------------- * update .gitignore * get rid of VDR-2.5.2 requirement by VDR-2.7.1 deprecating features, by adding a local copy of the old cSectionSyncer, the new class cPatScanner::PatSync. The plugin requires now 2.3.1+ only again, instead of 2.5.2+. wirbel-at-vdr-portal-wirbelscan-dev-eebef12/Makefile000066400000000000000000000127071520154405700226200ustar00rootroot00000000000000# # IMPORTANT NOTICE: # !! This Makefile is no longer in use by me and i consider it obsolete. # !! It *may* or *may not* build/install this plugin. # #/****************************************************************************** # * if you prefer verbose non-coloured build messages, remove the '@' here: # *****************************************************************************/ Q = @ CC ?= gcc CXX ?= g++ PWD = $(shell pwd) PLUGIN = $(shell basename $(PWD) | cut -d- -f1) CPPSRC = $(wildcard *.cpp) OBJS = $(CPPSRC:%.cpp=%.o) LDFLAGS?= #/****************************************************************************** # * dependencies, add variables here, and checks in target check_dependencies # *****************************************************************************/ LIBREPFUNC=librepfunc LIBREPFUNC_MINVERSION=1.0.0 # /* require either PKG_CONFIG_PATH to be set, or, a working pkg-config */ HAVE_LIBREPFUNC =$(shell if pkg-config --exists $(LIBREPFUNC); then echo "1"; else echo "0"; fi ) HAVE_LIBREPFUNC_MINVERSION=$(shell if pkg-config --atleast-version=$(LIBREPFUNC_MINVERSION) $(LIBREPFUNC); then echo "1"; else echo "0"; fi ) DISTFILES = $(CPPSRC) $(wildcard *.h) $(wildcard *.dat) po DISTFILES+= build COPYING HISTORY Makefile README SERVICES.html ### The version number of this plugin (taken from the main source file): VERSION = $(shell grep 'const char\* WIRBELSCAN_VERSION *= ' wirbelscan.cpp | awk '{ print $$5 }' | sed -e 's/[";]//g') ### The directory environment: # Use package data if installed...otherwise assume we're under the VDR source directory: PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr)) LIBDIR = $(call PKGCFG,libdir) LOCDIR = $(call PKGCFG,locdir) PLGCFG = $(call PKGCFG,plgcfg) # TMPDIR ?= /tmp ### The compiler options: export CFLAGS = $(call PKGCFG,cflags) export CXXFLAGS = $(call PKGCFG,cxxflags) ### The version number of VDR's plugin API: APIVERSION = $(call PKGCFG,apiversion) ### Allow user defined options to overwrite defaults: -include $(PLGCFG) ### The name of the distribution archive: ARCHIVE = $(PLUGIN)-$(VERSION) PACKAGE = vdr-$(ARCHIVE) ### The name of the shared object file: SOFILE = libvdr-$(PLUGIN).so ### Includes and Defines (add further entries here): INCLUDES += $(shell pkg-config --cflags $(LIBREPFUNC)) DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' LDFLAGS += $(shell pkg-config --libs $(LIBREPFUNC)) ### The main target: all: check_dependencies $(SOFILE) i18n #/****************************************************************************** # * color definitions, RST=reset, CY=cyan, MG=magenta, BL=blue, (..) # *****************************************************************************/ RST=\e[0m CY=\e[1;36m MG=\e[1;35m BL=\e[1;34m YE=\e[1;33m RD=\e[1;31m GN=\e[1;32m #/****************************************************************************** # * Implicit rules # *****************************************************************************/ %.o: %.c ifeq ($(Q),@) @echo -e "${CY} CXX $@${RST}" endif $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< %.o: %.cpp ifeq ($(Q),@) @echo -e "${BL} CXX $@${RST}" endif $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< ### Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile @$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(CPPSRC) > $@ -include $(DEPFILE) ### Internationalization (I18N): PODIR = po I18Npo = $(wildcard $(PODIR)/*.po) I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file)))) I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po @msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.cpp) @xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` %.po: $(I18Npot) @msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo install -D -m644 $< $@ .PHONY: i18n check_dependencies i18n: $(I18Nmo) $(I18Npot) install-i18n: $(I18Nmsgs) ### Targets: $(SOFILE): $(OBJS) ifeq ($(Q),@) @echo -e "${GN} LINK $(SOFILE)${RST}" endif $(Q)$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ $(LDFLAGS) install-lib: $(SOFILE) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install: install-lib install-i18n dist: $(I18Npo) clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a $(DISTFILES) $(TMPDIR)/$(ARCHIVE) @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) @echo Distribution package created as $(PACKAGE).tgz clean: @-rm -f $(SOFILE) $(SOFILE).$(APIVERSION) @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ #/****************************************************************************** # * dependencies, check them here and provide message to user. # *****************************************************************************/ check_dependencies: ifeq ($(HAVE_LIBREPFUNC),0) @echo "ERROR: not found: $(LIBREPFUNC) >= $(LIBREPFUNC_MINVERSION)" exit 1 endif ifeq ($(HAVE_LIBREPFUNC_MINVERSION),0) @echo "ERROR: dependency $(LIBREPFUNC) older than $(LIBREPFUNC_MINVERSION)" exit 1 endif wirbel-at-vdr-portal-wirbelscan-dev-eebef12/README000066400000000000000000000072311520154405700220340ustar00rootroot00000000000000This is a "plugin" for the Video Disk Recorder (VDR). Copyright (C) 2007-2021 Winfried Koehler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ------------------------------------------------------------------------ Written by: Winfried Koehler Project's homepage: https://www.gen2vdr.de/wirbel/wirbelscan/index2.html Latest version: see Projects homepage See the file COPYING for further license information. Description: ------------------------------------------------------------------------ This plugin performs channel scans for digital tv cards. Requirements: ------------------------------------------------------------------------ - VDR Version >= 1.7.x for wirbelscan <= 2023.10.15 - VDR Version >= 2.5.2 for wirbelscan > 2023.10.15 - librepfunc >= 1.0.0 (https://github.com/wirbel-at-vdr-portal/librepfunc) Installation: ------------------------------------------------------------------------ Install this plugin: unpack it into VDRs Plugin source folder and compile it as usual. Replace $VERSION with the actual plugins version like '0.0.1' and $SOURCEDIR with your path to the sources, usually /usr/src or similar: cp vdr-wirbelscan-$VERSION.tgz $SOURCEDIR/vdr-1.7.16/PLUGINS cd $SOURCEDIR/VDR/PLUGINS tar xfz vdr-wirbelscan-$VERSION.tgz ln -s wirbelscan-$VERSION wirbelscan cd $SOURCEDIR/VDR make plugins How To Use ------------------------------------------------------------------------ #0 open plugins setup menu page #1 adjust your country #2 define the search in the field 'Source Type' #3 MAKE SHURE, THAT YOU DONT HAVE TIMERS ON SCHEDULE. Otherwise you may loose them. #4 Start the scan with the GREEN key and wait. This will take some time, up to 30 min. Specific Problems: ------------------------------------------------------------------------ - On some dvb cards, the I/Q inversion needs to be explicitly switched on or off. If you find cards *only* working with INVERSION = ON, please report those as *bug* to the linux-media dvb driver mailing list. - Hint: For experts: setting symbolrate and modulation to well known values will speed up the scan. Nevertheless - with wrong settings some or even all transponders will be lost. Some words of warning and information: ------------------------------------------------------------------------ * Reporting Bugs: - please send me a full log from the plugin with Verbosity = 5 setting from beginning of scan up to the point where your problem occurs - please include hardware details of your system and VDR's setup.conf * Version Numbering: - versions with 'X.Y.Z-pre-XX' are to be understood as Version before the version X.Y.Z; so 0.0.5-pre1 is *older* as 0.0.5 - there is no stable version up to now. * do NOT scan if you have some recording on your schedule. This plugin will steel you the dvb card, regardless wether your recording will break. * the plugin will add new channels - as vdr everytime does - at the end of the channels list, so if you have a timer on schedule it may cause problems. -wirbel wirbel-at-vdr-portal-wirbelscan-dev-eebef12/README.md000066400000000000000000000011401520154405700224240ustar00rootroot00000000000000# wirbelscan-dev This is a "plugin" for the Video Disk Recorder (VDR). This is my **test** wirbelscan repo. *No pull requests/issues/bugs here, use contact given in **README**.* For further details on wirbelscan, see it's [Homepage](https://www.gen2vdr.de/wirbel/wirbelscan/index2.html) and see file 'README'. This one is my workbench only. It serves as backup for my local changes, which may or may not show up in future releases. Often, those changes may be rolled back, replaced by other approaches and so on, break function or FTBC. A pure development branch, not to be seen as a 'peak of package'. wirbel-at-vdr-portal-wirbelscan-dev-eebef12/SERVICES.html000066400000000000000000000151201520154405700232610ustar00rootroot00000000000000 Using the Service Interface

Wirbelscan service interface


Introduction

Do you want to talk with me?

wirbelscan implements, starting from version 0.0.5-pre12, a service interface, allowing other plugins to communicate with or control wirbelscan. The service interface can be implemented by including wirbelscans service header. You may also provide a copy of this header file in your source code, but pointing to wirbelscan is the preferred solution.

#include "../wirbelscan/wirbelscan_services.h"
using namespace WIRBELSCAN_SERVICE;

virtual bool Service(const char *Id, void *Data = NULL);

Id is a unique identification string that identifies the plugin, the requested service and its protocol version number. A service id for wirbelscan looks like this: "wirbelscan_<SERVICE>#<VERSION>". At the moment of writing this, its assumed that higher versions will stay backward compatible, but in general, a plugin using the interface should use services only with matching service version.

NOTE: The function service returns true for any service id string it handles, and false otherwise.

The following services are available:

  • GetVersion, query wirbelscan plugin version and its service api
  • GetStatus, query wirbelscans status
  • DoCmd, execute commands
  • GetSetup, query actual setup parameters
  • SetSetup, change actual setup parameters
  • GetCountry, query list of country IDs and corresponding names
  • GetSat, query list of satellite IDs and corresponding names

    Data is a pointer to a data structure, depending on the service used. If Data is set to NULL and wirbelscan supports this service it will return true. You may use this as a 'service supported' check.


    GetVersion

    Query plugin and api, will work with every wirbelscan version supporting the interface.

    Id = "wirbelscan_GetVersion".
    Data is a pointer of type cWirbelscanInfo.


    GetStatus

    Query actual status.

    Id = "wirbelscan_GetStatus#<VERSION>".
    Data is a pointer of type cWirbelscanStatus.

    The following properties are returned in version 0001:

  • Status {scanning,stopped,busy,unknown}
  • Current Scan device
  • Current Scan Progress
  • Current Signal Strength as reported from device.
  • Currently Scanned Transponder
  • Number of Channels in VDR
  • Number of New Channels since Scan Start
  • NOTE: Most of the properties are meaningless, if no scan in progress.


    DoCmd

    Execute commands.

    Id = "wirbelscan_DoCmd#<VERSION>".
    Data is a pointer of type cWirbelscanCmd.

    Data->replycode will be true on success, false otherwise.
    The following commands are defined in version 0001:

  • Start Scan
  • Stop Scan
  • Store Current Setup

  • GetSetup

    Query actual setup parameters.

    Id = "wirbelscan_GetSetup#<VERSION>".
    Data is a pointer of type cWirbelscanScanSetup.


    SetSetup

    Change actual setup parameters.

    Id = "wirbelscan_SetSetup#<VERSION>".
    Data is a pointer of type cWirbelscanScanSetup.

    NOTE: The changes will be only permanent, if the command Store is called afterwards, see DoCmd.


    GetCountry

    Query list of country IDs and corresponding names.
    The ID is needed for wirbelscans Setup in case of DVB-C, DVB-T, ATSC or pvrinput scans. With wrong setup ID values scans are expected to fail, so the setup CountryId has to be set before starting a scan.

    Id = "wirbelscan_GetCountry#<VERSION>".
    Data is a pointer of type cPreAllocBuffer.

    Should be called twice.

  • first call with Data->size = 0. wirbelscan will initialize Data->size to minimum buffer size.
  • second call, this time Data->buffer should point to allocated memory of size * sizeof(SListItem). wirbelscan will fill in values.

    NOTE: It's the calling plugins responsibility to provide a buffer of sufficient size and to cleanup this buffer. If the provided buffer is too small, segmentation fault / memory corruption will occur.


    GetSat

    Query list of satellite IDs and corresponding names.
    The ID is needed for wirbelscans Setup in case of satellite scans. With wrong setup ID values scans are expected to fail, so the setup SatId has to be set before starting a scan.

    Id = "wirbelscan_GetSat#<VERSION>".
    Data is a pointer of type cPreAllocBuffer.

    Should be called twice.

  • first call with Data->size = 0. wirbelscan will initialize Data->size to minimum buffer size.
  • second call, this time Data->buffer should point to allocated memory of size * sizeof(SListItem). wirbelscan will fill in values.

    NOTE: It's the calling plugins responsibility to provide a buffer of sufficient size and to cleanup this buffer. If the provided buffer is too small, segmentation fault / memory corruption will occur.


    Further Information

    An example on usage is the servdemo plugin, available on the wirbelscan webpage. This demo plugin takes SVDRP commands and talks to wirbelscan using the service interface.

    For further details, please refer to VDRs PLUGIN.html and wirbelscan_services.h. wirbel-at-vdr-portal-wirbelscan-dev-eebef12/build000077500000000000000000000031021520154405700221720ustar00rootroot00000000000000#!/bin/bash HOSTNAME=$(env | grep HOSTNAME | cut -d= -f2 | cut -d. -f1) CC="g++ -std=c++11" #CCOPTS="-g -O3 -Wall -Wextra -Wno-unused-parameter -Werror=overloaded-virtual -Wno-parentheses -Wfatal-errors -fPIC -fstack-protector-all -D_FORTIFY_SOURCE=2 -DPLUGIN_NAME_I18N='"wirbelscan"' -D_GNU_SOURCE" CCOPTS="-g -O3 -Wall -Wextra -Wno-unused-parameter -Werror=overloaded-virtual -Wno-parentheses -Wfatal-errors -fPIC -DPLUGIN_NAME_I18N='"wirbelscan"' -D_GNU_SOURCE" INCLUDES="-I../../../include" CPPFILES=$(ls *.cpp) LIB=libvdr-wirbelscan.so PWD=$(pwd); VDRDIR=$PWD; for ((it=1; it <= 3 ; it++)) do VDRDIR=$(dirname $VDRDIR) done VDR=$(basename $VDRDIR); VDRVER=${VDR#*-}; LIBDIR="$VDRDIR/PLUGINS/lib"; LIB="${LIB%.so}.so.$VDRVER" echo -e "\033[1;34m/*********************************************************************" echo -e " * building for: vdr-$VDRVER" echo -e " * plugin dir : $LIBDIR" echo -e " *********************************************************************/\033[0m" for file in $CPPFILES do OBJ="${file%.cpp}.o" OBJS="$OBJS $OBJ" rm -f $OBJ echo -e "\033[1;34m/* $file */\033[0m" echo "$CC $CCOPTS $INCLUDES -c $file" $CC $CCOPTS $INCLUDES -c $file if [ ! -f $OBJ ] then echo -e "\033[0;31mERROR: did not compile..\033[0m" exit fi done rm -f $LIB echo -e "\033[1;34m/* $LIB */\033[0m" echo "$CC $CCOPTS -shared $OBJS -o $LIB" $CC $CCOPTS -shared $OBJS -o $LIB -lrepfunc if [ ! -f $OBJ ] then echo -e "\033[0;31mERROR: did not link..\033[0m" exit fi cp -f $LIB $LIBDIR echo -e "\033[1;34m hopefully everything done.. \033[0m" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/common.cpp000066400000000000000000000543611520154405700231560ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include // std::this_thread #include #include #include // std::min #include // std::stringstream #include // time_t, strftime #include // syslog() #include // fe_status_t, dvb_frontend_info #include // DVB_API_VERSION, DVB_API_VERSION_MINOR #include // cDevice #include // cDvbDevice #include // ioctl() #include "common.h" // #include "menusetup.h" // MenuScanning #include "satellites.h" // txt_to_satellite() #include "countries.h" // txt_to_country() /******************************************************************************* * Generic functions which will be used in the whole plugin. ******************************************************************************/ /******************************************************************************* * class cMySetup, plugin setup data ******************************************************************************/ cMySetup::cMySetup(void) { verbosity = 3; /* default to messages */ DVB_Type = SCAN_TERRESTRIAL; DVBT_Inversion = 0; /* auto/off */ DVBC_Inversion = 0; /* auto/off */ DVBC_Symbolrate = 0; /* default to AUTO */ DVBC_QAM = 0; /* default to AUTO */ DVBC_Network_PID = 0x10; /* as 300486 */ CountryIndex = COUNTRY::txt_to_country("DE"); SatIndex = txt_to_satellite("S19E2"); ATSC_type = 0; /* VSB */ logFile = STDOUT; /* log errors/messages to stdout */ scanflags = SCAN_TV | SCAN_RADIO | SCAN_FTA | SCAN_SCRAMBLED; update = false; initsystems = false; scan_remove_invalid = false; scan_update_existing = false; scan_append_new = true; ParseLCN = false; SignalWaitTime = 1; LockTimeout = 3; } void cMySetup::InitSystems(void) { memset(&systems[0], 0, sizeof(systems)); while(! cDevice::WaitForAllDevicesReady(20)) mSleep(100); for(int i=0; iProvidesSource(cSource::FromString("A"))) systems[SCAN_TERRCABLE_ATSC] = 1; if (device->ProvidesSource(cSource::FromString("C"))) systems[SCAN_CABLE] = 1; if (device->ProvidesSource(cSource::FromString("S"))) systems[SCAN_SATELLITE] = 1; if (device->ProvidesSource(cSource::FromString("T"))) systems[SCAN_TERRESTRIAL] = 1; } if (DVB_Type >= SCAN_NO_DEVICE || ! systems[DVB_Type]) { for(DVB_Type = SCAN_TERRESTRIAL; DVB_Type < SCAN_NO_DEVICE; DVB_Type++) { if (systems[DVB_Type]) break; } } initsystems = true; } cMySetup wSetup; std::map dmap = {{'A',0},{'T',1},{'S',2},{'C',3}}; /******************************************************************************* * plugins logging facility: dlog(), _log() and hexdump() ******************************************************************************/ void _log(const char* function, int line, const int level, std::string msg) { if (level > wSetup.verbosity) return; auto now = []()->std::string { char s[16]; time_t t = time(nullptr); strftime(s, sizeof(s), "%H:%M:%S ", localtime(&t)); return std::string(s); }; if (wSetup.logFile == SYSLOG) syslog(LOG_DEBUG, "%s", msg.c_str()); else if (wSetup.logFile == STDOUT) { std::cout << now(); if (wSetup.verbosity >= 5) std::cout << function << ':' << IntToStr(line) << ' '; std::cout << msg << std::endl; std::cout.flush(); } else if (wSetup.logFile == STDERR) { std::cerr << now(); if (wSetup.verbosity >= 5) std::cerr << function << ':' << IntToStr(line) << ' '; std::cerr << msg << std::endl; std::cerr.flush(); } if (MenuScanning) MenuScanning->AddLogMsg(msg); } void hexdump(std::string intro, const unsigned char* buf, size_t len) { if (wSetup.verbosity >= 3) { HexDump(intro, buf, len, true); } } /******************************************************************************* * encapsulation of the ioctl() syscall. ******************************************************************************/ int IOCTL(int fd, int cmd, void* data) { for(int retry=10; retry>=0;) { if (ioctl(fd, cmd, data) != 0) { /* :-( */ if (retry) { mSleep(10); /* 10msec */ retry--; continue; } return -1; /* :'-(( */ } else return 0; /* :-) */ } return 0; } int dvbc_modulation(int index) { switch(index) { case 0: return 256; case 1: return 64; case 2: return 128; default: return 999; } } int dvbc_symbolrate(int index) { switch(index) { case 0: return 6900000; case 1: return 6875000; case 2: return 6111000; case 3: return 6250000; case 4: return 6790000; case 5: return 6811000; case 6: return 5900000; case 7: return 5000000; case 8: return 3450000; case 9: return 4000000; case 10: return 6950000; case 11: return 7000000; case 12: return 6952000; case 13: return 5156000; case 14: return 5483000; default: return 0; } } /******************************************************************************* * TParams, read VDR param string and divide to separate items or vice versa. ******************************************************************************/ TParams::TParams() : Bandwidth(8), FEC(999), FEC_low(999), Guard(999), Polarization(0), Inversion(999), Modulation(2), Pilot(999), Rolloff(999), StreamId(0), SystemId(0), DelSys(0), Transmission(999), MISO(0), Hierarchy(999) {} TParams::TParams(std::string& s) : Bandwidth(8), FEC(999), FEC_low(999), Guard(999), Polarization(0), Inversion(999), Modulation(2), Pilot(999), Rolloff(999), StreamId(0), SystemId(0), DelSys(0), Transmission(999), MISO(0), Hierarchy(999) { Parse(s); } void TParams::Parse(std::string& s) { std::transform(s.begin(), s.end() ,s.begin(), ::toupper); const char* c = s.c_str(); while(*c) switch(*c) { case 'H': Polarization = *c++; break; case 'V': Polarization = *c++; break; case 'L': Polarization = *c++; break; case 'R': Polarization = *c++; break; case 'B': Bandwidth = Value(c); break; case 'C': FEC = Value(c); break; case 'D': FEC_low = Value(c); break; case 'G': Guard = Value(c); break; case 'I': Inversion = Value(c); break; case 'M': Modulation = Value(c); break; case 'N': Pilot = Value(c); break; case 'O': Rolloff = Value(c); break; case 'P': StreamId = Value(c); break; case 'Q': SystemId = Value(c); break; case 'S': DelSys = Value(c); break; case 'T': Transmission = Value(c); break; case 'X': MISO = Value(c); break; case 'Y': Hierarchy = Value(c); break; default : dlog(0, "error in '" + s + "': invalid char '" + *c + "'"); } } int TParams::Value(const char*& s) { int v = 0; s++; while(*s) { switch(*s) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': v = 10 * v + (*s++ - '0'); break; default: return v; } } return v; } void TParams::Print(std::string& dest, char Source) { dest.clear(); dest.reserve(18 * 4); switch(Source) { case 'A': if (Inversion != 999) dest += "I" + IntToStr(Inversion); if (Modulation != 999) dest += "M" + IntToStr(Modulation); break; case 'C': if (FEC != 999) dest += "C" + IntToStr(FEC); if (Inversion != 999) dest += "I" + IntToStr(Inversion); if (Modulation != 999) dest += "M" + IntToStr(Modulation); break; case 'S': if (Polarization) dest += Polarization; if (FEC != 999) dest += "C" + IntToStr(FEC); if (Inversion != 999) dest += "I" + IntToStr(Inversion); if (Modulation != 999) dest += "M" + IntToStr(Modulation); if (DelSys) { if (Pilot != 999) dest += "N" + IntToStr(Pilot); if (Rolloff != 999) dest += "O" + IntToStr(Rolloff); if (StreamId != 999) dest += "P" + IntToStr(StreamId); } if (DelSys != 999) dest += "S" + IntToStr(DelSys); break; case 'T': if (Bandwidth != 999) dest += "B" + IntToStr(Bandwidth); if (FEC != 999) dest += "C" + IntToStr(FEC); if (FEC_low != 999) dest += "D" + IntToStr(FEC_low); if (Guard != 999) dest += "G" + IntToStr(Guard); if (Inversion != 999) dest += "I" + IntToStr(Inversion); if (Modulation != 999) dest += "M" + IntToStr(Modulation); if (DelSys) { if (StreamId != 999) dest += "P" + IntToStr(StreamId); if (SystemId != 999) dest += "Q" + IntToStr(SystemId); } if (DelSys != 999) dest += "S" + IntToStr(DelSys); if (Transmission != 999) dest += "T" + IntToStr(Transmission); if (DelSys and MISO != 999) dest += "X" + IntToStr(MISO); if (Hierarchy != 999) dest += "Y" + IntToStr(Hierarchy); break; default: dlog(0, ": unknown Source " + IntToHex((size_t)Source, 2)); } } /******************************************************************************* * class TChannel, internal channel representation. ******************************************************************************/ TChannel::TChannel() : Name("???"), Shortname(""), Provider(""), Frequency(0), Bandwidth(8), FEC(999), FEC_low(999), Guard(999), Polarization(0), Inversion(999), Modulation(2), Pilot(999), Rolloff(999), StreamId(0), SystemId(0), DelSys(0), Transmission(999), MISO(0), Hierarchy(999), Symbolrate(0), PCR(0), TPID(0), SID(0), ONID(0), NID(0), TID(0), RID(0), LCN(-1), LCN_minor(-1), free_CA_mode(0), service_type(0xFFFF), OrbitalPos(0), reported(false), Tunable(false), Tested(false) {} TChannel& TChannel::operator= (const cChannel* rhs) { Name = rhs->Name(); Shortname = rhs->ShortName(); Provider = rhs->Provider(); Frequency = rhs->Frequency(); Source = *cSource::ToString(rhs->Source()); Symbolrate = rhs->Srate(); VPID.PID = rhs->Vpid(); VPID.Type = rhs->Vtype(); PCR = rhs->Ppid(); TPID = rhs->Tpid(); SID = rhs->Sid(); NID = ONID = rhs->Nid(); TID = rhs->Tid(); RID = rhs->Rid(); APIDs.Clear(); for(int i = 0; i < MAXAPIDS and rhs->Apid(i); ++i) { TPid a; a.PID = rhs->Apid(i); a.Type = rhs->Atype(i); a.Lang = rhs->Alang(i); APIDs.Add(a); } DPIDs.Clear(); for(int i = 0; i < MAXDPIDS and rhs->Dpid(i); ++i) { TPid d; d.PID = rhs->Dpid(i); d.Type = rhs->Dtype(i); d.Lang = rhs->Dlang(i); DPIDs.Add(d); } SPIDs.Clear(); for(int i = 0; i < MAXSPIDS and rhs->Spid(i); ++i) { TPid s; s.PID = rhs->Spid(i); s.Type = 0; s.Lang = rhs->Slang(i); SPIDs.Add(s); } CAIDs.Clear(); for(int i = 0; i < MAXCAIDS and rhs->Ca(i); ++i) { int ca = rhs->Ca(i); CAIDs.Add(ca); } std::string parameters = rhs->Parameters(); TParams p(parameters); Bandwidth = p.Bandwidth; FEC = p.FEC; FEC_low = p.FEC_low; Guard = p.Guard; Polarization = p.Polarization; Inversion = p.Inversion; Modulation = p.Modulation; Pilot = p.Pilot; Rolloff = p.Rolloff; StreamId = p.StreamId; SystemId = p.SystemId; DelSys = p.DelSys; Transmission = p.Transmission; MISO = p.MISO; Hierarchy = p.Hierarchy; return *this; } void TChannel::CopyTransponderData(const TChannel* Channel) { if (Channel) { Frequency = Channel->Frequency; Source = Channel->Source; Symbolrate = Channel->Symbolrate; Bandwidth = Channel->Bandwidth; FEC = Channel->FEC; FEC_low = Channel->FEC_low; Guard = Channel->Guard; Polarization = Channel->Polarization; Inversion = Channel->Inversion; Modulation = Channel->Modulation; Pilot = Channel->Pilot; Rolloff = Channel->Rolloff; StreamId = Channel->StreamId; SystemId = Channel->SystemId; DelSys = Channel->DelSys; Transmission = Channel->Transmission; MISO = Channel->MISO; Hierarchy = Channel->Hierarchy; } } void TChannel::Params(std::string& s) { s.clear(); s.reserve(18 * 4); if (Source.size() == 0) return; switch(Source[0]) { case 'A': if (Inversion != 999) s += "I" + IntToStr(Inversion); if (Modulation != 999) s += "M" + IntToStr(Modulation); break; case 'C': if (FEC != 999) s += "C" + IntToStr(FEC); if (Inversion != 999) s += "I" + IntToStr(Inversion); if (Modulation != 999) s += "M" + IntToStr(Modulation); break; case 'S': if (Polarization) s += Polarization; if (FEC != 999) s += "C" + IntToStr(FEC); if (Inversion != 999) s += "I" + IntToStr(Inversion); if (Modulation != 999) s += "M" + IntToStr(Modulation); if (DelSys) { if (Pilot != 999) s += "N" + IntToStr(Pilot); if (Rolloff != 999) s += "O" + IntToStr(Rolloff); if (StreamId != 999) s += "P" + IntToStr(StreamId); } if (DelSys != 999) s += "S" + IntToStr(DelSys); break; case 'T': if (Bandwidth != 999) s += "B" + IntToStr(Bandwidth); if (FEC != 999) s += "C" + IntToStr(FEC); if (FEC_low != 999) s += "D" + IntToStr(FEC_low); if (Guard != 999) s += "G" + IntToStr(Guard); if (Inversion != 999) s += "I" + IntToStr(Inversion); if (Modulation != 999) s += "M" + IntToStr(Modulation); if (DelSys) { if (StreamId != 999) s += "P" + IntToStr(StreamId); if (SystemId != 999) s += "Q" + IntToStr(SystemId); } if (DelSys != 999) s += "S" + IntToStr(DelSys); if (Transmission != 999) s += "T" + IntToStr(Transmission); if (DelSys and MISO != 999) s += "X" + IntToStr(MISO); if (Hierarchy != 999) s += "Y" + IntToStr(Hierarchy); break; default: dlog(0, ": unknown Source " + Source); } } void TChannel::PrintTransponder(std::string& dest) { std::stringstream ss; std::string params; Params(params); int i = Frequency; char source = Source[0]; if (i < 1000) i *= 1000; if (i > 999999) i /= 1000; ss << source; if (DelSys == 1) ss << "2 "; else ss << " "; ss << FloatToStr((source == 'S')?i:i/1000.0, 8, 2, false) << " MHz"; if ((source == 'C') or (source == 'S')) { i = Symbolrate; if (i < 1000) i *= 1000; if (i > 999999) i /= 1000; ss << " SR " << IntToStr(i) << ' ' << params; } dest = std::move(ss.str()); } void TChannel::Print(std::string& dest) { std::stringstream ss; std::string params; Params(params); if (Name.empty()) ss << "NULL"; else ss << Name; if (not Shortname.empty()) ss << ',' << Shortname; if (not Provider.empty()) ss << ';' << Provider; ss << ':' << IntToStr(Frequency) << ':' << params << ':' << Source << ':' << IntToStr(Symbolrate) << ':' << IntToStr(VPID.PID); if (PCR and (PCR != VPID.PID)) ss << '+' << IntToStr(PCR); if (VPID.Type) ss << '=' << IntToStr(VPID.Type); if (APIDs.Count()) { for(int i=0; i 999999) f /= 1000; if (Setup.DiSEqC) { cDiseqc* d; for(d = Diseqcs.First(); d; d = Diseqcs.Next(d)) if (SourceMatches(d->Source(), cSource::FromString(Source.c_str())) and d->Slof() > f and d->Polarization() == Polarization) { f -= d->Lof(); break; } if (!d) { dlog(0, "no diseqc settings for (" + Source + ", " + IntToStr(Frequency) + ", " + Polarization + ')'); return false; } } else f -= f < Setup.LnbSLOF ? Setup.LnbFrequLo : Setup.LnbFrequHi; if (f < 0) f *= -1; if (f < 950 or f > 2150) { dlog(0, "transponder (" + Source + ", " + IntToStr(Frequency) + ", " + Polarization + ") (freq " + IntToStr(f) + " -> out of tuning range)"); return false; } return true; } cDvbDevice* GetDvbDevice(cDevice* d) { #ifdef __DYNAMIC_DEVICE_PROBE /* vdr/device.h was patched for dynamite plugin */ if (d == nullptr) return nullptr; if (d->HasSubDevice()) return dynamic_cast(d->SubDevice()); #endif return dynamic_cast(d); } void PrintDvbApi(std::string& s) { s = "compiled for DVB API " + IntToStr(DVB_API_VERSION) + '.' + IntToStr(DVB_API_VERSION_MINOR); } unsigned int GetFrontendStatus(cDevice* dev) { fe_status_t status = FE_NONE; cDvbDevice* dvbdevice = GetDvbDevice(dev); if (dvbdevice == nullptr) return status; std::string s = "/dev/dvb/adapter" + std::to_string(dvbdevice->Adapter()) + "/frontend" + std::to_string(dvbdevice->Frontend()); int fe = open(s.c_str(), O_RDONLY | O_NONBLOCK); if (fe < 0) dlog(0, "could not open " + s); else { if (IOCTL(fe, FE_READ_STATUS, &status) < 0) dlog(0, "could not read status: " + s); close(fe); } return status; } unsigned int GetCapabilities(cDevice* dev) { struct dvb_frontend_info fe_info; fe_info.caps = FE_IS_STUPID; cDvbDevice* dvbdevice = GetDvbDevice(dev); if (dvbdevice == nullptr) return fe_info.caps; std::string s = "/dev/dvb/adapter" + std::to_string(dvbdevice->Adapter()) + "/frontend" + std::to_string(dvbdevice->Frontend()); int fe = open(s.c_str(), O_RDONLY | O_NONBLOCK); if (fe < 0) dlog(0, "could not open " + s); else { if (IOCTL(fe, FE_GET_INFO, &fe_info) < 0) dlog(0, "could not query: " + s); close(fe); } return fe_info.caps; } bool GetTerrCapabilities(cDevice* dev, bool* CodeRate, bool* Modulation, bool* Inversion, bool* Bandwidth, bool* Hierarchy, bool* TransmissionMode, bool* GuardInterval, bool* DvbT2) { unsigned int cap = GetCapabilities(dev); *CodeRate = cap & FE_CAN_FEC_AUTO; *Modulation = cap & FE_CAN_QAM_AUTO; *Inversion = cap & FE_CAN_INVERSION_AUTO; *Bandwidth = cap & FE_CAN_BANDWIDTH_AUTO; *Hierarchy = cap & FE_CAN_HIERARCHY_AUTO; *TransmissionMode = cap & FE_CAN_GUARD_INTERVAL_AUTO; *GuardInterval = cap & FE_CAN_TRANSMISSION_MODE_AUTO; *DvbT2 = cap & FE_CAN_2G_MODULATION; return cap != FE_IS_STUPID; } bool GetCableCapabilities(cDevice* dev, bool* Modulation, bool* Inversion) { unsigned int cap = GetCapabilities(dev); *Modulation = cap & FE_CAN_QAM_AUTO; *Inversion = cap & FE_CAN_INVERSION_AUTO; return cap != FE_IS_STUPID; } bool GetAtscCapabilities(cDevice* dev, bool* Modulation, bool* Inversion, bool* VSB, bool* QAM) { unsigned int cap = GetCapabilities(dev); *Modulation = cap & FE_CAN_QAM_AUTO; *Inversion = cap & FE_CAN_INVERSION_AUTO; *VSB = cap & FE_CAN_8VSB; *QAM = cap & FE_CAN_QAM_256; return cap != FE_IS_STUPID; } bool GetSatCapabilities(cDevice* dev, bool* CodeRate, bool* Modulation, bool* RollOff, bool* DvbS2) { unsigned int cap = GetCapabilities(dev); *CodeRate = cap & FE_CAN_FEC_AUTO; *Modulation = cap & FE_CAN_QAM_AUTO; *RollOff = 0; /* deprecated: bool* RollOff */ *DvbS2 = cap & FE_CAN_2G_MODULATION; return cap != FE_IS_STUPID; } std::string DeviceName(cDevice* dev) { auto name = dev->DeviceName(); // !! cString, keep it like this. return std::to_string(dev->DeviceNumber()) + ": " + *name; } wirbel-at-vdr-portal-wirbelscan-dev-eebef12/common.h000066400000000000000000000217761520154405700226270ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #pragma once #include #include #include #include // std::move #include #include #include #include #include "tlist.h" #define SCAN_TERRESTRIAL 0 /* DVB-T/T2 */ #define SCAN_CABLE 1 /* DVB-C */ #define SCAN_SATELLITE 2 /* DVB-S/S2 */ #define SCAN_TERRCABLE_ATSC 5 /* ATSC VSB and/or QAM */ #define SCAN_NO_DEVICE 6 #define SCAN_TRANSPONDER 999 #define SCAN_TV ( 1 << 0 ) #define SCAN_RADIO ( 1 << 1 ) #define SCAN_FTA ( 1 << 2 ) #define SCAN_SCRAMBLED ( 1 << 3 ) #define ADAPTER_AUTO 0 #define DVBC_INVERSION_AUTO 0 #define DVBC_QAM_AUTO 0 #define DVBC_QAM_64 1 #define DVBC_QAM_128 2 #define DVBC_QAM_256 3 #define EAST_FLAG 0 #define WEST_FLAG 1 #define MAXSIGNALSTRENGTH 65535 #define MINSIGNALSTRENGTH 16383 #define STDOUT 1 #define SYSLOG 2 #define STDERR 3 #define dlog(level, str) do { _log(__PRETTY_FUNCTION__,__LINE__, level, str); } while(0) void _log(const char* function, int line, const int level, std::string); #define fatal(x) dlog(0, x); return -1 #define warning(x) dlog(1, x) #define info(x) dlog(2, x) #define verbose(x) dlog(4, x) /******************************************************************************* * forward decls. ******************************************************************************/ class cChannel; class cDevice; class cDvbDevice; /******************************************************************************* * class TParams, provide VDR param string as separate items. ******************************************************************************/ class TParams { private: int Value(const char*& s); public: TParams(); TParams(std::string& s); void Parse(std::string& s); void Print(std::string& dest, char Source); // Source = {'A','C','S','T'} public: int Bandwidth; int FEC; int FEC_low; int Guard; char Polarization; int Inversion; int Modulation; int Pilot; int Rolloff; int StreamId; int SystemId; int DelSys; int Transmission; int MISO; int Hierarchy; }; /******************************************************************************* * class TChannel, internal channel representation. ******************************************************************************/ class TPid { public: TPid() : PID(0), Type(0), Lang("") {} int PID; int Type; std::string Lang; }; struct transposer { uint8_t cell_id_extension; uint32_t transposer_frequency; }; struct cell { uint16_t cell_id; // if TFS: up to 6 RF freqs. int num_center_frequencies; uint32_t center_frequencies[6]; int num_transposers; struct transposer transposers[16]; }; class TChannel { public: std::string Name; // ':' replaced by '|', may contain ',' std::string Shortname; // ',' replaced by '.' std::string Provider; int Frequency; // S:MHz, C,T: MHz,kHz,Hz int Bandwidth; // 'B' 1712, 5, 6, 7, 8, 10, DVB-T/DVB-T2 only int FEC; // 'C' 0, 12, 23, 34, 35, 45, 56, 67, 78, 89, 910 int FEC_low; // 'D', DVB-T/DVB-T2 only int Guard; // 'G' 4, 8, 16, 32, 128, 19128, 19256: DVB-T/DVB-T2 only char Polarization; // 'H', 'V', 'L', 'R' int Inversion; // 'I' 0, 1 : DVB-T and DVB-C only int Modulation; // 'M' 2, 5, 6, 7, 10, 11, 12, 16, 32, 64, 128, 256, 999 // 2 QPSK (DVB-S, DVB-S2, DVB-T, DVB-T2, ISDB-T) // 5 8PSK (DVB-S, DVB-S2) // 6 16APSK (DVB-S2) // 7 32APSK (DVB-S2) // 10 VSB8 (ATSC aerial) // 11 VSB16 (ATSC aerial) // 12 DQPSK (ISDB-T) // 16 QAM16 (DVB-T, DVB-T2, ISDB-T) // 32 QAM32 // 64 QAM64 (DVB-C, DVB-T, DVB-T2, ISDB-T) // 128 QAM128 (DVB-C) // 256 QAM256 (DVB-C, DVB-T2) int Pilot; // 'N' 0, 1, 999: DVB-S2 only int Rolloff; // 'O' 0, 20, 25, 35 int StreamId; // 'P' 0-255 int SystemId; // 'Q' 0-65535 int DelSys; // 'S' 0, 1 int Transmission; // 'T' 1, 2, 4, 8, 16, 32: DVB-T/DVB-T2 only int MISO; // 'X' 0 = siso, 1 = miso int Hierarchy; // 'Y' 0, 1, 2, 4 std::string Source; // as defined in the file sources.conf int Symbolrate; // DVB-S and DVB-C only //-- TPid VPID; // video PID, type may follow VPID, separated by '=' int PCR; // may follow VPID, separated by '+' TList APIDs; // separated by commas: 101=deu@4. Ends with ';' if Dpids follow. TList DPIDs; // separated by commas: 103=deu@4 int TPID; // The teletext PID. If this channel also carries DVB subtitles, TList SPIDs; // the DVB subtitling PIDs follow the teletext PID, sep by a ';' TList CAIDs; // hex int (!) list. int SID; // Service ID int ONID; // original Network ID int NID; // Network ID int TID; // Transport stream ID int RID; // just to mark invalid channels. int LCN; // 'Logical Channel Number', usually -1 (invalid) int LCN_minor; // if used and LCN valid, the LCN part after the dot. -1 otherwise. int PMT; bool free_CA_mode; uint16_t service_type; int OrbitalPos; bool West; bool reported; bool Tunable; bool Tested; TList cells; public: TChannel(void); TChannel& operator= (const cChannel* rhs); void CopyTransponderData(const TChannel* Channel); void Params(std::string& s); void PrintTransponder(std::string& dest); void Print(std::string& dest); void VdrChannel(cChannel& c); bool ValidSatIf(void); }; /******************************************************************************* * class TChannels ******************************************************************************/ bool is_different_transponder_deep_scan(const TChannel* a, const TChannel* b, bool auto_allowed); class TChannels : public TList { public: TChannel* GetByParams(const TChannel* NewTransponder) { for(auto t:v) if (!is_different_transponder_deep_scan(t, NewTransponder, true)) return t; return nullptr; } bool IsUniqueTransponder(const TChannel* NewTransponder) { return (GetByParams(NewTransponder) == nullptr); } }; /******************************************************************************* * class cMySetup ******************************************************************************/ class cMySetup { public: int verbosity; int logFile; int DVB_Type; int DVBT_Inversion; int DVBC_Inversion; int DVBC_Symbolrate; int DVBC_QAM; int DVBC_Network_PID; int CountryIndex; int SatIndex; int ATSC_type; uint32_t scanflags; bool update; uint32_t user[3]; int systems[8]; bool initsystems; int scan_remove_invalid; int scan_update_existing; int scan_append_new; bool ParseLCN; std::array preferred; int SignalWaitTime; int LockTimeout; public: cMySetup(void); void InitSystems(void); }; extern cMySetup wSetup; extern std::map dmap; /******************************************************************************* * generic functions ******************************************************************************/ void hexdump(std::string intro, const unsigned char* buf, size_t len); int IOCTL(int fd, int cmd, void* data); template inline void DeleteNullptr(T*& aClass) { T* temp = aClass; aClass = nullptr; delete temp; } cDvbDevice* GetDvbDevice(cDevice* d); int dvbc_modulation(int index); int dvbc_symbolrate(int index); void InitSystems(void); void PrintDvbApi(std::string& s); unsigned int GetFrontendStatus(cDevice* dev); bool GetTerrCapabilities (cDevice* dev, bool* CodeRate, bool* Modulation, bool* Inversion, bool* Bandwidth, bool* Hierarchy, bool* TransmissionMode, bool* GuardInterval, bool* DvbT2); bool GetCableCapabilities(cDevice* dev, bool* Modulation, bool* Inversion); bool GetAtscCapabilities (cDevice* dev, bool* Modulation, bool* Inversion, bool* VSB, bool* QAM); bool GetSatCapabilities (cDevice* dev, bool* CodeRate, bool* Modulation, bool* RollOff, bool* DvbS2); std::string DeviceName(cDevice* dev); wirbel-at-vdr-portal-wirbelscan-dev-eebef12/countries.cpp000066400000000000000000001327261520154405700237030ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include #include // std::array #include // setlocale() #include "countries.h" #include "common.h" namespace COUNTRY { /************************************************************************************************** * FREQUENCY CALCULATION SCHEME: * each frequency used by w_scan is calculated as follows: * * frequency(channellist, channel, frequency_offset_index) = * base_offset(channel, channellist) + * channel * freq_step(channel, channellist) + * freq_offset(channel, channellist, frequency_offset_index); * * * - channellist is choosen by user, if not choosen defaults are used. * - channel = 0..133 (might be extended if needed) * - frequency_offset_index = 0 (no offset) -> 1 (pos offset) -> 2 (neg offset) * * if base_offset(channel, channellist) returns -1 this channel will be skipped. * if freq_offset(channel, channellist, frequency_offset_index) returns -1 this offset will be skipped. * * example: * channellist = 4; channel = 12 * * base_offset(12, 4) = 142500000 * freq_step(12, 4) = 7000000 * freq_offset(12, 4, 0) = 0 * freq_offset(12, 4, 1) = -1 * freq_offset(12, 4, 2) = -1 * * frequency = 142500000 + 12 * 7000000 = 226500000 * since freq_offset returns -1 for frequency_offset_index = (1,2) no frequency offset is applied. * * 20090101 -wk **************************************************************************************************/ #define SKIP_CHANNEL -1 enum offset_type_t { NO_OFFSET = 0, POS_OFFSET = 1, NEG_OFFSET = 2, POS_OFFSET_1 = 3, POS_OFFSET_2 = 4, STOP_OFFSET_LOOP = -1 }; /******************************************************************************* * Every country has its own number here. Simply append new ones to enum. ******************************************************************************/ enum country_t { AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM, AW, AU, AT, AZ, BS, BH, BD, BB, BY, BE, BZ, BJ, BM, BT, BO, BQ, BA, BW, BV, BR, IO, BN, BG, BF, BI, KH, CM, CA, CV, KY, CF, TD, CL, CN, CX, CC, CO, KM, CG, CD, CK, CR, CI, HR, CU, CW, CY, CZ, DK, DJ, DM, DO, EC, EG, SV, GQ, ER, EE, ET, FK, FO, FJ, FI, FR, GF, PF, TF, GA, GM, GE, DE, GH, GI, GR, GL, GD, GP, GU, GT, GG, GN, GW, GY, HT, HM, VA, HN, HK, HU, IS, IN, ID, IR, IQ, IE, IM, IL, IT, JM, JP, JE, JO, KZ, KE, KI, KP, KR, KW, KG, LA, LV, LB, LS, LR, LY, LI, LT, LU, MO, MK, MG, MW, MY, MV, ML, MT, MH, MQ, MR, MU, YT, MX, FM, MD, MC, MN, ME, MS, MA, MZ, MM, NA, NR, NP, NL, NC, NZ, NI, NE, NG, NU, NF, MP, NO, OM, PK, PW, PS, PA, PG, PY, PE, PH, PN, PL, PT, PR, QA, RE, RO, RU, RW, BL, SH, KN, LC, MF, PM, VC, WS, SM, ST, SA, SN, RS, SC, SL, SX, SG, SK, SI, SB, SO, ZA, GS, ES, LK, SD, SR, SJ, SZ, SE, CH, SY, TW, TJ, TZ, TH, TL, TG, TK, TO, TT, TN, TR, TM, TC, TV, UG, UA, AE, GB, US, UM, UY, UZ, VU, VE, VN, VG, VI, WF, EH, YE, ZM, ZW }; std::string alpha3; /******************************************************************************* * User selects a country specific channellist. * therefore we know * - frontend type DVB or ATSC * - used frequency list (base_offsets, freq_step) * - other country-specific things (transmission mode, frequency offsets from center..) * use two letter uppercase for 'country', as defined by ISO 3166-1 ******************************************************************************/ int choose_country(std::string country, int& atsc, int& dvb, uint16_t& scan_type, int& channellist) { if (channellist == USERLIST) return 0; if (country_to_short_name(txt_to_country(country)) != country) { warning("\n\nCOUNTRY CODE IS NOT DEFINED. FALLING BACK TO 'DE'"); mSleep(10000); } info("using settings for '" + country_to_full_name(txt_to_country(country)) + "'"); alpha3 = country_to_alpha3(txt_to_country(country)); /* * choose DVB or ATSC frontend type */ switch(txt_to_country(country)) { case AD: // ANDORRA case AT: // AUSTRIA case AX: // Ã…LAND ISLANDS case BE: // BELGIUM case BG: // BULGARIA case CH: // SWITZERLAND case CO: // COLOMBIA case CZ: // CZECH REPUBLIC case DE: // GERMANY case DK: // DENMARK case EE: // ESTONIA case ES: // SPAIN case FR: // FRANCE case FI: // FINLAND case GB: // UNITED KINGDOM case GR: // GREECE case HK: // HONG KONG case HR: // CROATIA case HU: // HUNGARY case IE: // IRELAND case IL: // ISRAEL case IS: // ICELAND case IT: // ITALY case LT: // LITHUANIA case LU: // LUXEMBOURG case LV: // LATVIA case NL: // NETHERLANDS case NO: // NORWAY case NZ: // NEW ZEALAND case PL: // POLAND case PT: // PORTUGAL case RO: // ROMANIA case RU: // RUSSIAN FEDERATION case SE: // SWEDEN case SI: // SLOVENIA case SK: // SLOVAKIA case TW: // TAIWAN, DVB-T w. ATSC freq list (thanks for freqlist to mkrufky) case VN: // VIET NAM case AU: // AUSTRALIA, DVB-T w. 7MHz step switch(dvb) { case SCAN_CABLE: scan_type = SCAN_CABLE; info("DVB cable"); break; default: scan_type = SCAN_TERRESTRIAL; info("DVB aerial"); break; } break; case BR: // Brazil switch(dvb) { case SCAN_CABLE: scan_type = SCAN_CABLE; info("DVB cable"); break; default: scan_type = SCAN_TERRESTRIAL; info("ISDB-T (SBTVD)"); break; } break; case US: // UNITED STATES case CA: // CANADA scan_type = SCAN_TERRCABLE_ATSC; info("ATSC"); break; default: info("Country identifier '" + country + "' not defined. Using defaults."); return -1; break; } /* * choose channellist name */ switch(txt_to_country(country)) { //**********DVB freq lists*******************************************// case AD: // ANDORRA case AT: // AUSTRIA case AX: // Ã…LAND ISLANDS case BE: // BELGIUM case BG: // BULGARIA case CH: // SWITZERLAND case CO: // COLOMBIA case CZ: // CZECH REPUBLIC case DE: // GERMANY case DK: // DENMARK case EE: // ESTONIA case ES: // SPAIN case GR: // GREECE case HR: // CROATIA case HU: // HUNGARY case HK: // HONG KONG case IE: // IRELAND case IL: // ISRAEL case IS: // ICELAND case LT: // LITHUANIA case LU: // LUXEMBOURG case LV: // LATVIA case NL: // NETHERLANDS case NO: // NORWAY case NZ: // NEW ZEALAND case PT: // PORTUGAL case RO: // ROMANIA case SI: // SLOVENIA case SK: // SLOVAKIA case VN: // VIET NAM switch(dvb) { case SCAN_CABLE: channellist = DVBC_QAM; info("DVB-C"); break; default: channellist = DVBT_DE; info("DVB-T/T2 Europe"); break; } break; // see: THE USE OF BAND III IN EUROPE case IT: // ITALY case PL: // POLAND case SE: // SWEDEN case RU: // RUSSIAN FEDERATION switch(dvb) { case SCAN_CABLE: channellist = DVBC_QAM; info("DVB-C"); break; default: channellist = DVBT_EU_BAND3; info("DVB-T/T2 Europe w. Bd III"); break; } break; case FI: // FINLAND switch(dvb) { case SCAN_CABLE: channellist = DVBC_FI; info("DVB-C FI"); break; default: channellist = DVBT_DE; info("DVB-T/T2 Europe"); break; } break; case FR: // FRANCE switch(dvb) { case SCAN_CABLE: channellist = DVBC_FR; info("DVB-C FR"); break; default: channellist = DVBT_FR; info("DVB-T/T2 FR"); break; } break; case GB: // UNITED KINGDOM switch(dvb) { case SCAN_CABLE: channellist = DVBC_QAM; info("DVB-C"); break; default: channellist = DVBT_GB; info("DVB-T/T2 GB"); break; } break; case AU: // AUSTRALIA switch(dvb) { case SCAN_CABLE: info("cable australia not yet defined."); break; default: channellist = DVBT_AU; info("DVB-T/T2 AU"); break; } break; //**********ATSC freq lists******************************************// case US: // UNITED STATES case CA: // CANADA case TW: // TAIWAN, DVB-T w. ATSC freq list if (atsc_is_vsb(atsc)) { channellist = ATSC_VSB; info("VSB US/CA, DVB-T TW"); } if (atsc_is_qam(atsc)) { channellist = ATSC_QAM; info("QAM US/CA"); } break; case BR: // BRAZIL, DVB-C/ISDB-T w. ATSC freq list switch(dvb) { case SCAN_CABLE: channellist = DVBC_BR; info("DVB-C BR"); break; default: channellist = ISDBT_6MHZ; info("ISDB-T, BR"); break; } break; //******************************************************************// default: info("Country identifier '" + country + "' not defined. Using default freq lists."); return -1; break; } return 0; // success } /******************************************************************************* * return the base offsets for specified channellist and channel. ******************************************************************************/ int base_offset(int channel, int channellist) { switch(channellist) { case ATSC_QAM: //ATSC cable, US EIA/NCTA Std Cable center freqs + IRC list case DVBC_BR: //BRAZIL - same range as ATSC IRC switch(channel) { case 2 ... 4: return 45000000; case 5 ... 6: return 49000000; case 7 ... 13: return 135000000; case 14 ... 22: return 39000000; case 23 ... 94: return 81000000; case 95 ... 99: return -477000000; case 100 ... 133: return 51000000; default: return SKIP_CHANNEL; } case ATSC_VSB: //ATSC terrestrial, US NTSC center freqs switch(channel) { case 2 ... 4: return 45000000; case 5 ... 6: return 49000000; case 7 ... 13: return 135000000; case 14 ... 69: return 389000000; default: return SKIP_CHANNEL; } case ISDBT_6MHZ: // ISDB-T, 6 MHz central frequencies switch(channel) { // Channels 7-13 are reserved but aren't used yet //case 7 ... 13: return 135000000; case 14 ... 69: return 389000000; default: return SKIP_CHANNEL; } case DVBT_AU: //AUSTRALIA, 7MHz step list switch(channel) { case 5 ... 12: return 142500000; case 21 ... 69: return 333500000; default: return SKIP_CHANNEL; } case DVBT_DE: //GERMANY, 21..60, soon 21..48 switch(channel) { case 21 ... 59: return 306000000; default: return SKIP_CHANNEL; } case DVBT_EU_BAND3: switch(channel) { case 5 ... 12: return 142500000; // VHF band III case 21 ... 69: return 306000000; default: return SKIP_CHANNEL; } case DVBT_FR: //FRANCE, +/- offset 166kHz & +offset 332kHz & +offset 498kHz switch(channel) { case 21 ... 69: return 306000000; default: return SKIP_CHANNEL; } case DVBT_GB: //UNITED KINGDOM, +/- offset switch(channel) { case 21 ... 55: return 306000000; default: return SKIP_CHANNEL; } case DVBC_QAM: //EUROPE case DVBC_FI: //FINLAND, QAM128 switch(channel) { case 0: case 5 ... 98: return 74000000; default: return SKIP_CHANNEL; } case DVBC_FR: //FRANCE, needs user response. switch(channel) { case 1 ... 39: return 107000000; case 40 ... 89: return 138000000; default: return SKIP_CHANNEL; } default: fatal("undefined channellist " + IntToStr(channellist)); return SKIP_CHANNEL; } } /******************************************************************************* * return the freq step size for specified channellist ******************************************************************************/ int freq_step(int channel, int channellist) { switch(channellist) { case ATSC_QAM: case ATSC_VSB: case DVBC_BR: case ISDBT_6MHZ: return 6000000; // atsc, 6MHz step case DVBT_AU: return 7000000; // dvb-t australia, 7MHz step case DVBT_DE: case DVBT_FR: case DVBT_GB: case DVBT_EU_BAND3: switch(channel) { // dvb-t europe, 7MHz VHF ch5..12, all other 8MHz case 5 ... 12: return 7000000; case 21 ... 69: return 8000000; default: return 8000000; // should be never reached. } case DVBC_QAM: case DVBC_FI: case DVBC_FR: return 8000000; // dvb-c, 8MHz step default: fatal("undefined channellist " + IntToStr(channellist)); return SKIP_CHANNEL; } } /******************************************************************************* * estimate max possible DVB-C symbolrate for annex ac ******************************************************************************/ int max_dvbc_srate(int bandwidth) { /* EN300429 v1.2.1, chapter 9 Modulation p.16: * "I and Q signals shall be square-root raised cosine filtered. * The roll-off factor shall be 0,15" */ #define DVBC_ROLLOFF 0.15 #define DVBC_SYMBOL_LEN (1.0 + DVBC_ROLLOFF) switch(bandwidth) { case 8000000: case 7000000: case 6000000: case 5000000: return (int) (0.5 + ((double) bandwidth) / DVBC_SYMBOL_LEN); default: fatal("unknown channel bandwidth " + IntToStr(bandwidth)); return SKIP_CHANNEL; } } int bandwidth(int channel, int channellist) { return freq_step(channel, channellist); } /******************************************************************************* * some countries use constant offsets around center frequency. * define them here. ******************************************************************************/ int freq_offset(int channel, int channellist, int index) { switch(channellist) { case USERLIST: return 0; case ATSC_QAM: switch(channel) { case 14 ... 16: case 25 ... 53: case 98 ... 99: switch(index) { case NO_OFFSET: return 0; //Incrementally Related Carriers (IRC) case POS_OFFSET: return 12500; //US EIA/NCTA Standard Cable center frequencies default: return STOP_OFFSET_LOOP; } default: // IRC = standard cable center switch(index) { case NO_OFFSET: return 0; //center freq default: return STOP_OFFSET_LOOP; } } case DVBT_FR: switch(channel) { // see http://tvignaud.pagesperso-orange.fr/tv/canaux.htm case 5 ... 12: //VHF channels not used in FR return STOP_OFFSET_LOOP; default: //UHF channels. - 0,166 MHz /+ 0,166 MHz /+ 0,332 MHz /+ 0,498 MHz switch(index) { case NO_OFFSET: return 0; //center freq case POS_OFFSET: return +166000; //center+offset 166kHz case NEG_OFFSET: return -166000; //center-offset 166kHz case POS_OFFSET_1: return +332000; //center+offset 332kHz case POS_OFFSET_2: return +498000; //center+offset 498kHz default: return STOP_OFFSET_LOOP; } } case DVBT_GB: switch(channel) { case 5 ... 12: //VHF channels return STOP_OFFSET_LOOP; //VHF channels not used in GB default: //UHF channels switch(index) { case NO_OFFSET: return 0; //center freq case POS_OFFSET: return +167000; //center+offset case NEG_OFFSET: return -167000; //center-offset default: return STOP_OFFSET_LOOP; } } case DVBT_AU: switch(index) { case NO_OFFSET: return 0; //center freq case POS_OFFSET: return +125000; //center+offset default: return STOP_OFFSET_LOOP; } case DVBC_FR: switch(channel) { case 1 ... 39: switch(index) { case NO_OFFSET: return 0; //center freq case POS_OFFSET: return +125000; //center+offset default: return STOP_OFFSET_LOOP; } case 40 ... 89: default: switch(index) { case NO_OFFSET: return 0; default: return STOP_OFFSET_LOOP; } } case DVBC_QAM: case DVBC_FI: switch(channel) { case 0: switch(index) { case NO_OFFSET: return SKIP_CHANNEL; case POS_OFFSET: return SKIP_CHANNEL; case NEG_OFFSET: return -1000000; default: return STOP_OFFSET_LOOP; } case 5 ... 12: switch(index) { case NO_OFFSET: return 0; case POS_OFFSET: return SKIP_CHANNEL; case NEG_OFFSET: return -1000000; default: return STOP_OFFSET_LOOP; } default: switch(index) { case NO_OFFSET: return 0; default: return STOP_OFFSET_LOOP; } } case ISDBT_6MHZ: // ISDB-T, 6 MHz central frequencies switch(channel) { // Channels 7-13 are reserved but aren't used yet case 7 ... 13: case 14 ... 69: switch(index) { case NO_OFFSET: return SKIP_CHANNEL; //center freq case POS_OFFSET: return +142857; //center+offset default: return STOP_OFFSET_LOOP; } default: return STOP_OFFSET_LOOP; } default: switch(index) { case NO_OFFSET: return 0; default: return STOP_OFFSET_LOOP; } } } /******************************************************************************* * DVB-T: default value if transmission mode AUTO not supported ******************************************************************************/ int dvbt_transmission_mode(int channel, int channellist) { #define TRANSMISSION_MODE_8K 1 // fe_transmit_mode switch(channellist) { // GB seems to use 8k since 12/2009 default: return TRANSMISSION_MODE_8K; } } /******************************************************************************* * start/stop values for dvbc qam loop * 0 == QAM_64, 1 == QAM_256, 2 == QAM_128 ******************************************************************************/ int dvbc_qam_max(int channel, int channellist) { switch(channellist) { case DVBC_FI: return 2; //QAM128 case DVBC_BR: case DVBC_FR: case DVBC_QAM: return 1; //QAM256 default: return 0; //no qam loop } } int dvbc_qam_min(int channel, int channellist) { switch(channellist) { case DVBC_FI: case DVBC_BR: case DVBC_FR: case DVBC_QAM: return 0; //QAM64 default: return 0; //no qam loop } } int atsc_is_vsb(int atsc) { return (atsc & ATSC_VSB); } int atsc_is_qam(int atsc) { return (atsc & ATSC_QAM); } /******************************************************************************* * two letters constants from ISO 3166-1, alphabetically by long country name ******************************************************************************/ struct cCountry country_list[] = { /*- ISO 3166-1 - unique id - long country name alpha-3 numeric */ {"AF", AF, "AFGHANISTAN", "AFG"}, /*4 },*/ {"AX", AX, "Ã…LAND ISLANDS", "ALA"}, /*248},*/ {"AL", AL, "ALBANIA", "ALB"}, /*8 },*/ {"DZ", DZ, "ALGERIA", "DZA"}, /*12 },*/ {"AS", AS, "AMERICAN SAMOA", "ASM"}, /*16 },*/ {"AD", AD, "ANDORRA", "AND"}, /*20 },*/ {"AO", AO, "ANGOLA", "AGO"}, /*24 },*/ {"AI", AI, "ANGUILLA", "AIA"}, /*660},*/ {"AQ", AQ, "ANTARCTICA", "ATA"}, /*10 },*/ {"AG", AG, "ANTIGUA AND BARBUDA", "ATG"}, /*28 },*/ {"AR", AR, "ARGENTINA", "ARG"}, /*32 },*/ {"AM", AM, "ARMENIA", "ARM"}, /*51 },*/ {"AW", AW, "ARUBA", "ABW"}, /*533},*/ {"AU", AU, "AUSTRALIA", "AUS"}, /*36 },*/ {"AT", AT, "AUSTRIA", "AUT"}, /*40 },*/ {"AZ", AZ, "AZERBAIJAN", "AZE"}, /*31 },*/ {"BS", BS, "BAHAMAS", "BHS"}, /*44 },*/ {"BH", BH, "BAHRAIN", "BHR"}, /*48 },*/ {"BD", BD, "BANGLADESH", "BGD"}, /*50 },*/ {"BB", BB, "BARBADOS", "BRB"}, /*52 },*/ {"BY", BY, "BELARUS", "BLR"}, /*112},*/ {"BE", BE, "BELGIUM", "BEL"}, /*56 },*/ {"BZ", BZ, "BELIZE", "BLZ"}, /*84 },*/ {"BJ", BJ, "BENIN", "BEN"}, /*204},*/ {"BM", BM, "BERMUDA", "BMU"}, /*60 },*/ {"BT", BT, "BHUTAN", "BTN"}, /*64 },*/ {"BO", BO, "BOLIVIA", "BOL"}, /*68 },*/ {"BQ", BQ, "BONAIRE", "BES"}, /*535},*/ {"BA", BA, "BOSNIA AND HERZEGOVINA", "BIH"}, /*70 },*/ {"BW", BW, "BOTSWANA", "BWA"}, /*72 },*/ {"BV", BV, "BOUVET ISLAND", "BVT"}, /*74 },*/ {"BR", BR, "BRAZIL", "BRA"}, /*76 },*/ {"IO", IO, "BRITISH INDIAN OCEAN TERRITORY", "IOT"}, /*86 },*/ {"BN", BN, "BRUNEI DARUSSALAM", "BRN"}, /*96 },*/ {"BG", BG, "BULGARIA", "BGR"}, /*100},*/ {"BF", BF, "BURKINA FASO", "BFA"}, /*854},*/ {"BI", BI, "BURUNDI", "BDI"}, /*108},*/ {"KH", KH, "CAMBODIA", "KHM"}, /*116},*/ {"CM", CM, "CAMEROON", "CMR"}, /*120},*/ {"CA", CA, "CANADA", "CAN"}, /*124},*/ {"CV", CV, "CAPE VERDE", "CPV"}, /*132},*/ {"KY", KY, "CAYMAN ISLANDS", "CYM"}, /*136},*/ {"CF", CF, "CENTRAL AFRICAN REPUBLIC", "CAF"}, /*140},*/ {"TD", TD, "CHAD", "TCD"}, /*148},*/ {"CL", CL, "CHILE", "CHL"}, /*152},*/ {"CN", CN, "CHINA", "CHN"}, /*156},*/ {"CX", CX, "CHRISTMAS ISLAND", "CXR"}, /*162},*/ {"CC", CC, "COCOS (KEELING) ISLANDS", "CCK"}, /*166},*/ {"CO", CO, "COLOMBIA", "COL"}, /*170},*/ {"KM", KM, "COMOROS", "COM"}, /*174},*/ {"CG", CG, "CONGO", "COG"}, /*178},*/ {"CD", CD, "CONGO, THE DEMOCRATIC REPUBLIC OF THE", "COD"}, /*180},*/ {"CK", CK, "COOK ISLANDS", "COK"}, /*184},*/ {"CR", CR, "COSTA RICA", "CRI"}, /*188},*/ {"CI", CI, "CÔTE D'IVOIRE", "CIV"}, /*384},*/ {"HR", HR, "CROATIA", "HRV"}, /*191},*/ {"CU", CU, "CUBA", "CUB"}, /*192},*/ {"CW", CW, "CURAÇAO", "CUW"}, /*531},*/ {"CY", CY, "CYPRUS", "CYP"}, /*196},*/ {"CZ", CZ, "CZECH REPUBLIC", "CZE"}, /*203},*/ {"DK", DK, "DENMARK", "DNK"}, /*208},*/ {"DJ", DJ, "DJIBOUTI", "DJI"}, /*262},*/ {"DM", DM, "DOMINICA", "DMA"}, /*212},*/ {"DO", DO, "DOMINICAN REPUBLIC", "DOM"}, /*214},*/ {"EC", EC, "ECUADOR", "ECU"}, /*218},*/ {"EG", EG, "EGYPT", "EGY"}, /*818},*/ {"SV", SV, "EL SALVADOR", "SLV"}, /*222},*/ {"GQ", GQ, "EQUATORIAL GUINEA", "GNQ"}, /*226},*/ {"ER", ER, "ERITREA", "ERI"}, /*232},*/ {"EE", EE, "ESTONIA", "EST"}, /*233},*/ {"ET", ET, "ETHIOPIA", "ETH"}, /*231},*/ {"FK", FK, "FALKLAND ISLANDS (MALVINAS)", "FLK"}, /*238},*/ {"FO", FO, "FAROE ISLANDS", "FRO"}, /*234},*/ {"FJ", FJ, "FIJI", "FJI"}, /*242},*/ {"FI", FI, "FINLAND", "FIN"}, /*246},*/ {"FR", FR, "FRANCE", "FRA"}, /*250},*/ {"GF", GF, "FRENCH GUIANA", "GUF"}, /*254},*/ {"PF", PF, "FRENCH POLYNESIA", "PYF"}, /*258},*/ {"TF", TF, "FRENCH SOUTHERN TERRITORIES", "ATF"}, /*260},*/ {"GA", GA, "GABON", "GAB"}, /*266},*/ {"GM", GM, "GAMBIA", "GMB"}, /*270},*/ {"GE", GE, "GEORGIA", "GEO"}, /*268},*/ {"DE", DE, "GERMANY", "DEU"}, /*276},*/ {"GH", GH, "GHANA", "GHA"}, /*288},*/ {"GI", GI, "GIBRALTAR", "GIB"}, /*292},*/ {"GR", GR, "GREECE", "GRC"}, /*300},*/ {"GL", GL, "GREENLAND", "GRL"}, /*304},*/ {"GD", GD, "GRENADA", "GRD"}, /*308},*/ {"GP", GP, "GUADELOUPE", "GLP"}, /*312},*/ {"GU", GU, "GUAM", "GUM"}, /*316},*/ {"GT", GT, "GUATEMALA", "GTM"}, /*320},*/ {"GG", GG, "GUERNSEY", "GGY"}, /*831},*/ {"GN", GN, "GUINEA", "GIN"}, /*324},*/ {"GW", GW, "GUINEA-BISSAU", "GNB"}, /*624},*/ {"GY", GY, "GUYANA", "GUY"}, /*328},*/ {"HT", HT, "HAITI", "HTI"}, /*332},*/ {"HM", HM, "HEARD ISLAND AND MCDONALD ISLANDS", "HMD"}, /*334},*/ {"VA", VA, "HOLY SEE (VATICAN CITY STATE)", "VAT"}, /*336},*/ {"HN", HN, "HONDURAS", "HND"}, /*340},*/ {"HK", HK, "HONG KONG", "HKG"}, /*344},*/ {"HU", HU, "HUNGARY", "HUN"}, /*348},*/ {"IS", IS, "ICELAND", "ISL"}, /*352},*/ {"IN", IN, "INDIA", "IND"}, /*356},*/ {"ID", ID, "INDONESIA", "IDN"}, /*360},*/ {"IR", IR, "IRAN, ISLAMIC REPUBLIC OF", "IRN"}, /*364},*/ {"IQ", IQ, "IRAQ", "IRQ"}, /*368},*/ {"IE", IE, "IRELAND", "IRL"}, /*372},*/ {"IM", IM, "ISLE OF MAN", "IMN"}, /*833},*/ {"IL", IL, "ISRAEL", "ISR"}, /*376},*/ {"IT", IT, "ITALY", "ITA"}, /*380},*/ {"JM", JM, "JAMAICA", "JAM"}, /*388},*/ {"JP", JP, "JAPAN", "JPN"}, /*392},*/ {"JE", JE, "JERSEY", "JEY"}, /*832},*/ {"JO", JO, "JORDAN", "JOR"}, /*400},*/ {"KZ", KZ, "KAZAKHSTAN", "KAZ"}, /*398},*/ {"KE", KE, "KENYA", "KEN"}, /*404},*/ {"KI", KI, "KIRIBATI", "KIR"}, /*296},*/ {"KP", KP, "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", "PRK"}, /*408},*/ {"KR", KR, "KOREA, REPUBLIC OF", "KOR"}, /*410},*/ {"KW", KW, "KUWAIT", "KWT"}, /*414},*/ {"KG", KG, "KYRGYZSTAN", "KGZ"}, /*417},*/ {"LA", LA, "LAO PEOPLE'S DEMOCRATIC REPUBLIC", "LAO"}, /*418},*/ {"LV", LV, "LATVIA", "LVA"}, /*428},*/ {"LB", LB, "LEBANON", "LBN"}, /*422},*/ {"LS", LS, "LESOTHO", "LSO"}, /*426},*/ {"LR", LR, "LIBERIA", "LBR"}, /*430},*/ {"LY", LY, "LIBYAN ARAB JAMAHIRIYA", "LBY"}, /*434},*/ {"LI", LI, "LIECHTENSTEIN", "LIE"}, /*438},*/ {"LT", LT, "LITHUANIA", "LTU"}, /*440},*/ {"LU", LU, "LUXEMBOURG", "LUX"}, /*442},*/ {"MO", MO, "MACAO", "MAC"}, /*446},*/ {"MK", MK, "MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF", "MKD"}, /*807},*/ {"MG", MG, "MADAGASCAR", "MDG"}, /*450},*/ {"MW", MW, "MALAWI", "MWI"}, /*454},*/ {"MY", MY, "MALAYSIA", "MYS"}, /*458},*/ {"MV", MV, "MALDIVES", "MDV"}, /*462},*/ {"ML", ML, "MALI", "MLI"}, /*466},*/ {"MT", MT, "MALTA", "MLT"}, /*470},*/ {"MH", MH, "MARSHALL ISLANDS", "MHL"}, /*584},*/ {"MQ", MQ, "MARTINIQUE", "MTQ"}, /*474},*/ {"MR", MR, "MAURITANIA", "MRT"}, /*478},*/ {"MU", MU, "MAURITIUS", "MUS"}, /*480},*/ {"YT", YT, "MAYOTTE", "MYT"}, /*175},*/ {"MX", MX, "MEXICO", "MEX"}, /*484},*/ {"FM", FM, "MICRONESIA, FEDERATED STATES OF", "FSM"}, /*583},*/ {"MD", MD, "MOLDOVA", "MDA"}, /*498},*/ {"MC", MC, "MONACO", "MCO"}, /*492},*/ {"MN", MN, "MONGOLIA", "MNG"}, /*496},*/ {"ME", ME, "MONTENEGRO", "MNE"}, /*499},*/ {"MS", MS, "MONTSERRAT", "MSR"}, /*500},*/ {"MA", MA, "MOROCCO", "MAR"}, /*504},*/ {"MZ", MZ, "MOZAMBIQUE", "MOZ"}, /*508},*/ {"MM", MM, "MYANMAR", "MMR"}, /*104},*/ {"NA", NA, "NAMIBIA", "NAM"}, /*516},*/ {"NR", NR, "NAURU", "NRU"}, /*520},*/ {"NP", NP, "NEPAL", "NPL"}, /*524},*/ {"NL", NL, "NETHERLANDS", "NLD"}, /*528},*/ {"NC", NC, "NEW CALEDONIA", "NCL"}, /*540},*/ {"NZ", NZ, "NEW ZEALAND", "NZL"}, /*554},*/ {"NI", NI, "NICARAGUA", "NIC"}, /*558},*/ {"NE", NE, "NIGER", "NER"}, /*562},*/ {"NG", NG, "NIGERIA", "NGA"}, /*566},*/ {"NU", NU, "NIUE", "NIU"}, /*570},*/ {"NF", NF, "NORFOLK ISLAND", "NFK"}, /*574},*/ {"MP", MP, "NORTHERN MARIANA ISLANDS", "MNP"}, /*580},*/ {"NO", NO, "NORWAY", "NOR"}, /*578},*/ {"OM", OM, "OMAN", "OMN"}, /*512},*/ {"PK", PK, "PAKISTAN", "PAK"}, /*586},*/ {"PW", PW, "PALAU", "PLW"}, /*585},*/ {"PS", PS, "PALESTINIAN TERRITORY, OCCUPIED", "PSE"}, /*275},*/ {"PA", PA, "PANAMA", "PAN"}, /*591},*/ {"PG", PG, "PAPUA NEW GUINEA", "PNG"}, /*598},*/ {"PY", PY, "PARAGUAY", "PRY"}, /*600},*/ {"PE", PE, "PERU", "PER"}, /*604},*/ {"PH", PH, "PHILIPPINES", "PHL"}, /*608},*/ {"PN", PN, "PITCAIRN", "PCN"}, /*612},*/ {"PL", PL, "POLAND", "POL"}, /*616},*/ {"PT", PT, "PORTUGAL", "PRT"}, /*620},*/ {"PR", PR, "PUERTO RICO", "PRI"}, /*630},*/ {"QA", QA, "QATA", "QAT"}, /*634},*/ {"RE", RE, "RÉUNION", "REU"}, /*638},*/ {"RO", RO, "ROMANIA", "ROU"}, /*642},*/ {"RU", RU, "RUSSIAN FEDERATION", "RUS"}, /*643},*/ {"RW", RW, "RWANDA", "RWA"}, /*646},*/ {"BL", BL, "SAINT BARTHÉLEMY", "BLM"}, /*652},*/ {"SH", SH, "SAINT HELENA", "SHN"}, /*654},*/ {"KN", KN, "SAINT KITTS AND NEVIS", "KNA"}, /*659},*/ {"LC", LC, "SAINT LUCIA", "LCA"}, /*662},*/ {"MF", MF, "SAINT MARTIN", "MAF"}, /*663},*/ {"PM", PM, "SAINT PIERRE AND MIQUELON", "SPM"}, /*666},*/ {"VC", VC, "SAINT VINCENT AND THE GRENADINES", "VCT"}, /*670},*/ {"WS", WS, "SAMOA", "WSM"}, /*882},*/ {"SM", SM, "SAN MARINO", "SMR"}, /*674},*/ {"ST", ST, "SAO TOME AND PRINCIPE", "STP"}, /*678},*/ {"SA", SA, "SAUDI ARABIA", "SAU"}, /*682},*/ {"SN", SN, "SENEGAL", "SEN"}, /*686},*/ {"RS", RS, "SERBIA", "SRB"}, /*688},*/ {"SC", SC, "SEYCHELLES", "SYC"}, /*690},*/ {"SL", SL, "SIERRA LEONE", "SLE"}, /*694},*/ {"SX", SX, "SINT MAARTEN", "SXM"}, /*534},*/ {"SG", SG, "SINGAPORE", "SGP"}, /*702},*/ {"SK", SK, "SLOVAKIA", "SVK"}, /*703},*/ {"SI", SI, "SLOVENIA", "SVN"}, /*705},*/ {"SB", SB, "SOLOMON ISLANDS", "SLB"}, /*90 },*/ {"SO", SO, "SOMALIA", "SOM"}, /*706},*/ {"ZA", ZA, "SOUTH AFRICA", "ZAF"}, /*710},*/ {"GS", GS, "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", "SGS"}, /*239},*/ {"ES", ES, "SPAIN", "ESP"}, /*724},*/ {"LK", LK, "SRI LANKA", "LKA"}, /*144},*/ {"SD", SD, "SUDAN", "SDN"}, /*736},*/ {"SR", SR, "SURINAME", "SUR"}, /*740},*/ {"SJ", SJ, "SVALBARD AND JAN MAYEN", "SJM"}, /*744},*/ {"SZ", SZ, "SWAZILAND", "SWZ"}, /*748},*/ {"SE", SE, "SWEDEN", "SWE"}, /*752},*/ {"CH", CH, "SWITZERLAND", "CHE"}, /*756},*/ {"SY", SY, "SYRIAN ARAB REPUBLIC", "SYR"}, /*760},*/ {"TW", TW, "TAIWAN", "TWN"}, /*158},*/ {"TJ", TJ, "TAJIKISTAN", "TJK"}, /*762},*/ {"TZ", TZ, "TANZANIA, UNITED REPUBLIC OF", "TZA"}, /*834},*/ {"TH", TH, "THAILAND", "THA"}, /*764},*/ {"TL", TL, "TIMOR-LESTE", "TLS"}, /*626},*/ {"TG", TG, "TOGO", "TGO"}, /*768},*/ {"TK", TK, "TOKELAU", "TKL"}, /*772},*/ {"TO", TO, "TONGA", "TON"}, /*776},*/ {"TT", TT, "TRINIDAD AND TOBAGO", "TTO"}, /*780},*/ {"TN", TN, "TUNISIA", "TUN"}, /*788},*/ {"TR", TR, "TURKEY", "TUR"}, /*792},*/ {"TM", TM, "TURKMENISTAN", "TKM"}, /*795},*/ {"TC", TC, "TURKS AND CAICOS ISLANDS", "TCA"}, /*796},*/ {"TV", TV, "TUVALU", "TUV"}, /*798},*/ {"UG", UG, "UGANDA", "UGA"}, /*800},*/ {"UA", UA, "UKRAINE", "UKR"}, /*804},*/ {"AE", AE, "UNITED ARAB EMIRATES", "ARE"}, /*784},*/ {"GB", GB, "UNITED KINGDOM", "GBR"}, /*826},*/ {"US", US, "UNITED STATES", "USA"}, /*840},*/ {"UM", UM, "UNITED STATES MINOR OUTLYING ISLANDS", "UMI"}, /*581},*/ {"UY", UY, "URUGUAY", "URY"}, /*858},*/ {"UZ", UZ, "UZBEKISTAN", "UZB"}, /*860},*/ {"VU", VU, "VANUATU", "VUT"}, /*548},*/ {"VE", VE, "VENEZUELA", "VEN"}, /*862},*/ {"VN", VN, "VIET NAM", "VNM"}, /*704},*/ {"VG", VG, "VIRGIN ISLANDS, BRITISH", "VGB"}, /*92 },*/ {"VI", VI, "VIRGIN ISLANDS, U.S.", "VIR"}, /*850},*/ {"WF", WF, "WALLIS AND FUTUNA", "WLF"}, /*876},*/ {"EH", EH, "WESTERN SAHARA", "ESH"}, /*732},*/ {"YE", YE, "YEMEN", "YEM"}, /*887},*/ {"ZM", ZM, "ZAMBIA", "ZMB"}, /*894},*/ {"ZW", ZW, "ZIMBABWE", "ZWE"} /*716},*/ }; /******************************************************************************* * convert ISO 3166-1 two-letter constant to index ******************************************************************************/ int txt_to_country(std::string id) { for(size_t i=0; i categories = { LC_CTYPE, LC_COLLATE, LC_MESSAGES, LC_ALL }; for(auto category:categories) { /* Note: program's locale is not changed here, since locale isn't given. * the returned char * should be "C", "POSIX" or something valid. * If valid, we can only *guess* which format is returned. */ char* p = setlocale(category, ""); if ((p == nullptr) or (*p == 0)) continue; std::string Locale(p); if (Locale == "C" or Locale == "POSIX") continue; /* Assume here something like language[_territory][.codeset], ie. "de_DE.iso8859-1@euro" or "de_DE.utf-8" */ size_t p1 = Locale.find('_') + 1; size_t p2 = Locale.find_last_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", p1); std::string Country = Locale.substr(p1, 1+p2-p1); if (Locale.size() != 2) continue; for(size_t i=0; i #include namespace COUNTRY { enum channellist_t { ATSC_VSB = 1, ATSC_QAM = 2, DVBT_AU = 3, DVBT_DE = 4, DVBT_FR = 5, DVBT_GB = 6, DVBC_QAM = 7, DVBC_FI = 8, DVBC_FR = 9, DVBC_BR = 10, ISDBT_6MHZ = 11, DVBT_EU_BAND3 = 12, USERLIST = 999 }; typedef struct cCountry { const char* short_name; size_t id; const char* full_name; const char* alpha3; } _country; extern struct cCountry country_list[]; size_t country_count(void); void print_countries(void); int choose_country(std::string country, int& atsc, int& dvb_cable, uint16_t& scan_type, int& channellist); int txt_to_country(std::string id); std::string country_to_short_name(size_t idx); std::string country_to_full_name(size_t idx); std::string country_to_alpha3(size_t idx); std::string Alpha3(void); int base_offset(int channel, int channellist); int freq_step (int channel, int channellist); int bandwidth (int channel, int channellist); int freq_offset(int channel, int channellist, int index); int max_dvbc_srate(int bandwidth); int dvbt_transmission_mode(int channel, int channellist); int dvbc_qam_max(int channel, int channellist); int dvbc_qam_min(int channel, int channellist); int atsc_is_vsb(int atsc); int atsc_is_qam(int atsc); int get_user_country(void); } //end of namespace wirbel-at-vdr-portal-wirbelscan-dev-eebef12/menusetup.cpp000066400000000000000000000421701520154405700237060ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include #include #include #include // std::min() #include #include #include "menusetup.h" #include "common.h" #include "satellites.h" #include "countries.h" #include "wirbelscan.h" #include "scanner.h" #include "common.h" #include "wirbelscan_services.h" using namespace COUNTRY; extern cScanner* Scanner; #undef tr #define tr(str) (str) std::array DVB_Types = {"DVB-T/T2","DVB-C","DVB-S/S2","RESERVE1","RESERVE2","ATSC", "no device found"}; std::array logfiles = {"Off","stdout","syslog","stderr"}; std::array Symbolrates = {tr("AUTO"),"6900","6875","6111","6250", "6790","6811","5900","5000","3450","4000", "6950","7000","6952","5156","5483",tr("ALL (slow)")}; std::array Qams = {tr("AUTO"),"64","128","256",tr("ALL (slow)")}; std::array inversions = {tr("AUTO/OFF"),tr("AUTO/ON")}; std::array atsc_types = {"VSB (aerial)","QAM (cable)","VSB + QAM (aerial + cable)"}; std::array st = {"STOP","RUN","No device available - exiting!","No gen2 device available - trying gen1 device"," "}; std::vector SatNames; std::vector CountryNames; std::array flagslo = {"don\'t add channels", "TV", "Radio", "TV + Radio"}; std::array flagshi = {"don\'t add channels", "Free to Air", "Scrambled", "Free to Air + Scrambled"}; cMenuScanning* MenuScanning = nullptr; // pointer to actual menu int channelcount = 0; size_t lProgress = 0; size_t lStrength = 0; size_t lStatus = 0; std::string lTransponder; std::string lDeviceName; time_t timestamp; bool ScanAvailable(void) { return wSetup.systems[SCAN_TERRESTRIAL] || wSetup.systems[SCAN_CABLE] || wSetup.systems[SCAN_SATELLITE] || wSetup.systems[SCAN_TERRCABLE_ATSC]; } bool CableAvailable(void) { return wSetup.systems[SCAN_CABLE]; } bool TerrAvailable(void) { return wSetup.systems[SCAN_TERRESTRIAL]; } bool SatAvailable(void) { return wSetup.systems[SCAN_SATELLITE]; } bool AtscAvailable(void) { return wSetup.systems[SCAN_TERRCABLE_ATSC]; } bool TerrCableAvailable(void) { return wSetup.systems[SCAN_TERRESTRIAL] || wSetup.systems[SCAN_CABLE] || wSetup.systems[SCAN_TERRCABLE_ATSC]; } /******************************************************************************* * class cMenuSettings ******************************************************************************/ class cMenuSettings : public cMenuSetupPage { private: typedef struct { std::vector names; int index; } cMap; cMap map[4]; int scan_tv; int scan_radio; int scan_fta; int scan_scrambled; std::vector DeviceNames; void AddDevice(cDevice* dev, char s, const char* cstr, int index); protected: void AddCategory(std::string category); void Store(void); public: cMenuSettings(void); ~cMenuSettings(void) {}; virtual eOSState ProcessKey(eKeys Key); }; cMenuSettings::cMenuSettings(void) { // devices may have changed meanwhile wSetup.InitSystems(); if (not ScanAvailable()) { AddCategory("NO DEVICES FOUND."); return; } DeviceNames.reserve(1+cDevice::NumDevices()); DeviceNames.push_back("AUTO"); for(int i=0; i<4; i++) { map[i].index = 0; map[i].names.reserve(1+cDevice::NumDevices()); map[i].names.push_back(DeviceNames[0].c_str()); } for(int i=0; i 0; scan_radio = (wSetup.scanflags & SCAN_RADIO ) > 0; scan_scrambled = (wSetup.scanflags & SCAN_SCRAMBLED) > 0; scan_fta = (wSetup.scanflags & SCAN_FTA ) > 0; if (SatNames.empty()) { SatNames.reserve(sat_count()); for(size_t i=0; iProvidesSource(cSource(s,"?").Code())) { map[dmap[s]].names.push_back(cstr); if (wSetup.preferred[dmap[s]] == cstr) map[dmap[s]].index = 1 + index; } } eOSState cMenuSettings::ProcessKey(eKeys Key) { int direction = 0; eOSState state = cMenuSetupPage::ProcessKey(Key); switch(Key) { case kLeft: direction = -1; break; case kRight: direction = 1; break; case kOk: case kBack: thisPlugin->StoreSetup(); wSetup.update = true; state=osBack; break; default:; } if (state == osUnknown) { switch(Key) { case kGreen: case kRed: case kBlue: case kYellow: state=osContinue; break; default:; } } if (not ScanAvailable()) { // no devices found; recursive call until we reach SCAN_NO_DEVICE. if (wSetup.DVB_Type < SCAN_NO_DEVICE) ProcessKey(kRight); } else if (! wSetup.systems[wSetup.DVB_Type]) { if (direction) { if (wSetup.DVB_Type == SCAN_NO_DEVICE) { wSetup.DVB_Type = 1; ProcessKey(kLeft); // now, DVB_Type is 0. } else ProcessKey(kRight); } else { if (wSetup.DVB_Type == 0) wSetup.DVB_Type = SCAN_NO_DEVICE; ProcessKey(kLeft); } } return state; } /******************************************************************************* * class cMenuScanning ******************************************************************************/ cMenuScanning::cMenuScanning(void) : needs_update(false), log_busy(false), transponder(0), transponders(1) { SetHelp(tr("Stop"), tr("Start"), tr("Settings"), ""); wSetup.InitSystems(); if (not ScanAvailable()) { AddCategory("NO DEVICES FOUND."); return; } std::string status(DVB_Types[wSetup.DVB_Type]); status += " "; if (wSetup.DVB_Type == SCAN_SATELLITE) status += sat_list[wSetup.SatIndex].full_name; else status += country_list[wSetup.CountryIndex].full_name; AddCategory(tr("Status")); Add((ScanType = new cOsdItem(status.c_str() ))); Add((DevName = new cOsdItem("Device:" ))); Add((Progress = new cOsdItem("Scan:" ))); Add((CurrTransponder = new cOsdItem(" " ))); Add((Str = new cOsdItem("STR" ))); AddCategory(tr("Channels")); Add((ChanAdd = new cOsdItem(" " ))); Add((ChanNew = new cOsdItem("known Channels:"))); AddCategory(tr("Log Messages")); for(size_t i=0; i> 2; std::string s = flagslo[lo] + " (" + flagshi[hi] + ")"; ChanAdd->SetText(s.c_str(), true); ChanAdd->Set(); Display(); } void cMenuScanning::SetStatus(size_t status) { int type = Scanner?Scanner->DvbType() : wSetup.DVB_Type; static std::string s; s = DVB_Types[type]; s += " "; if (type == SCAN_SATELLITE) s += sat_list[wSetup.SatIndex].full_name; else s += country_list[wSetup.CountryIndex].full_name; s += " "; s += st[std::min(status, st.size()-1)]; ScanType->SetText(s.c_str(), true); ScanType->Set(); Display(); lStatus = status; } void cMenuScanning::SetCounters(int curr_tp, int all_tp) { transponder = curr_tp; transponders = all_tp; } std::string cMenuScanning::TimeStr(void) { time_t t = time(0) - timestamp; return IntToStr(t/60) + 'm' + IntToStr(t%60,2,false,'0') + 's'; } void cMenuScanning::SetProgress(size_t progress) { if (transponder <= 0) progress = lProgress; std::string s = "Scan: " + IntToStr(progress) + "% running " + TimeStr(); if ((transponder > 0) and (transponders > 0)) { s += " (" + IntToStr(transponder) + '/' + IntToStr(transponders) + ')'; lProgress = (size_t) (0.5 + (100.0 * transponder) / transponders); } Progress->SetText(s.c_str(), true); Progress->Set(); if (needs_update) { SetStatus(lStatus); SetDeviceName(lDeviceName, false); needs_update = false; } Display(); } void cMenuScanning::SetTransponder(const TChannel* transponder) { std::string s; ((TChannel*) transponder)->PrintTransponder(s); CurrTransponder->SetText(s.c_str(), true); CurrTransponder->Set(); Display(); } void cMenuScanning::SetStr(size_t strength, bool locked) { std::string s; if (locked and (strength == 0)) strength = 100; else strength = std::min(strength, (size_t)100); std::string t = IntToStr(strength); s = "STR " + t + '%' + std::string(4-t.size(), ' '); std::string u((size_t)(0.5 + strength/12.5), '_'); s+= '[' + u + ']' + std::string(9-u.size(), ' '); if (locked) s += "LOCK"; Str->SetText(s.c_str(), true); Str->Set(); Display(); } void cMenuScanning::SetChan(size_t count) { static std::string s; s = "known Channels: " + IntToStr(channelcount = count); ChanNew->SetText(s.c_str(), true); ChanNew->Set(); Display(); } void cMenuScanning::SetDeviceName(std::string Name, bool update) { std::string s("Device "); if (update) lDeviceName = Name; s += lDeviceName; DevName->SetText(s.c_str(), true); DevName->Set(); Display(); } void cMenuScanning::AddLogMsg(std::string Msg) { if (log_busy) return; log_busy = true; for(size_t i=0; iSetText(LogMsg[i+1]->Text(), true); LogMsg[i]->Set(); } LogMsg[LOGLEN - 1]->SetText(Msg.c_str(), true); LogMsg[LOGLEN - 1]->Set(); Display(); log_busy = false; } void cMenuScanning::AddCategory(std::string category) { Add(new cOsdItem(("--------------- " + category).c_str())); } eOSState cMenuScanning::ProcessKey(eKeys Key) { if (wSetup.update) { SetStatus(4); SetChanAdd(wSetup.scanflags); wSetup.update = false; } eOSState state = cMenuSetupPage::ProcessKey(Key); switch (Key) { case kUp: case kDown: return osContinue; default:; } if (state == osUnknown) { switch(Key) { case kBack: case kOk: state=osBack; return state; case kGreen: if (ScanAvailable()) { state=osContinue; needs_update = true; StartScan(); } break; case kRed: if (ScanAvailable()) { state=osContinue; needs_update = true; StopScan(); } break; case kYellow: if (ScanAvailable()) return AddSubMenu(new cMenuSettings()); default: break; } } if (Scanner && Scanner->Active() && (state != osBack)) return osContinue; return state; } bool cMenuScanning::StopScan(void) { DoStop(); return true; } bool cMenuScanning::StartScan(void) { int type = wSetup.DVB_Type; dlog(0, "StartScan(" + std::string(DVB_Types[type]) + ')'); if (!wSetup.systems[type]) { dlog(0, "Skipping scan: CANNOT SCAN - No device!"); Skins.Message(mtInfo, tr("CANNOT SCAN - No device!")); mSleep(6000); return false; } return DoScan(type); } void cMenuScanning::Store(void) { thisPlugin->StoreSetup(); } /******************************************************************************* * Stop Scanner now, we're destroying the plugin.. ******************************************************************************/ void stopScanners(void) { if (Scanner) { dlog(0, "Stopping scanner."); Scanner->SetShouldstop(true); } } /******************************************************************************* * create new scanner. ******************************************************************************/ bool DoScan(int DVB_Type) { if (Scanner && Scanner->Active()) { dlog(0, "ERROR: already scanning"); return false; } wSetup.InitSystems(); if (DVB_Type == SCAN_TRANSPONDER) { WIRBELSCAN_SERVICE::cUserTransponder t(&wSetup.user[0]); if (! wSetup.systems[t.Type()]) { dlog(0, "ERROR: no device found"); return false; } } else if (DVB_Type == SCAN_NO_DEVICE || ! wSetup.systems[DVB_Type]) { dlog(0, "ERROR: no device found"); return false; } timestamp = time(0); channelcount = 0; Scanner = new cScanner("wirbelscan Scanner", DVB_Type); return true; } /******************************************************************************* * Stop Scanner. ******************************************************************************/ void DoStop(void) { if (Scanner && Scanner->Active()) Scanner->SetShouldstop(true); } wirbel-at-vdr-portal-wirbelscan-dev-eebef12/menusetup.h000066400000000000000000000036531520154405700233560ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #pragma once #include #include /******************************************************************************* * forward decls. ******************************************************************************/ class TChannel; /******************************************************************************* * class cMenuScanning ******************************************************************************/ class cMenuScanning : public cMenuSetupPage { private: static constexpr size_t LOGLEN = 8; cOsdItem* DevName; cOsdItem* Progress; cOsdItem* CurrTransponder; cOsdItem* Str; cOsdItem* ChanAdd; cOsdItem* ChanNew; cOsdItem* ScanType; cOsdItem* LogMsg[LOGLEN]; bool needs_update; bool log_busy; int transponder; int transponders; std::string TimeStr(void); protected: virtual bool StartScan(void); virtual bool StopScan(void); virtual void AddCategory(std::string category); public: cMenuScanning(void); ~cMenuScanning(void); virtual void Store(void); virtual eOSState ProcessKey(eKeys Key); void SetStatus(size_t status); void SetProgress(size_t progress); void SetCounters(int curr_tp, int all_tp); void SetTransponder(const TChannel* transponder); void SetStr(size_t strength, bool locked); void SetChan(size_t count); void SetDeviceName(std::string Name, bool update = true); void SetChanAdd(size_t flags); void AddLogMsg(std::string Msg); }; extern cMenuScanning* MenuScanning; extern std::string lDeviceName; extern std::string lTransponder; extern size_t lProgress; extern size_t lStrength; void stopScanners(void); bool DoScan(int DVB_Type); void DoStop(void); wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/000077500000000000000000000000001520154405700215675ustar00rootroot00000000000000wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/ca_ES.po000066400000000000000000000047621520154405700231120ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Marc Rovira Vall , 2003 # Ramon Roca , 2003 # Jordi Vilà , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-03 18:38+0200\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: ca_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/cs_CZ.po000066400000000000000000000046471520154405700231430ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Vladimír Bárta , 2006 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-03 18:38+0200\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: cs_CZ\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/da_DK.po000066400000000000000000000046721520154405700231020ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Mogens Elneff , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-03 18:38+0200\n" "Last-Translator: Mogens Elneff \n" "Language-Team: \n" "Language: da_DK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/de_DE.po000066400000000000000000000043001520154405700230640ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Klaus Schmidinger , 2000 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-03 18:38+0200\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "Alle (langsam)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/EIN" msgid "Setup" msgstr "Einstellungen" msgid "General" msgstr "Allgemein" msgid "Source Type" msgstr "Signal Art" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "Logmeldungen" msgid "logfile" msgstr "Log Ausgabe" msgid "Channels" msgstr "Kanäle" msgid "TV channels" msgstr "TV Kanäle" msgid "Radio channels" msgstr "Radio Kanäle" msgid "FTA channels" msgstr "unverschlüsselte Kanäle" msgid "Scrambled channels" msgstr "verschlüsselte Kanäle" msgid "Cable and Terrestrial" msgstr "Kabel und Terrestrisch" msgid "Country" msgstr "Land" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Inversion DVB-C" msgid "Cable Symbolrate" msgstr "Symbolrate DVB-C" msgid "Cable modulation" msgstr "Modulation DVB-C" msgid "Cable Network PID" msgstr "Kabel Netzwerk PID" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Inversion T/T2" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "" msgid "Satellite" msgstr "Satellit" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" msgid "remove invalid channels" msgstr "ungültige Kanäle löschen" msgid "update existing channels" msgstr "Kanäle aktualisieren" msgid "append new channels" msgstr "neue Kanäle anfügen" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Einstellungen" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "" msgid "CANNOT SCAN - No device!" msgstr "KANN NICHT SCANNEN - kein Device!" #~ msgid "Off" #~ msgstr "Aus" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/el_GR.po000066400000000000000000000047111520154405700231220ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Dimitrios Dimitrakos , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-03 18:38+0200\n" "Last-Translator: Dimitrios Dimitrakos \n" "Language-Team: \n" "Language: el_GR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-7\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/es_ES.po000066400000000000000000000046541520154405700231360ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Ruben Nunez Francisco , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:43+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: es_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/et_EE.po000066400000000000000000000046351520154405700231200ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Arthur Konovalov , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:43+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: et_EE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-13\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/fi_FI.po000066400000000000000000000050531520154405700231060ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Hannu Savolainen , 2002 # Jaakko Hyvätti , 2002 # Niko Tarnanen , 2003 # Rolf Ahrenberg , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:43+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: fi_FI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/fr_FR.po000066400000000000000000000047771520154405700231440ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Jean-Claude Repetto , 2001 # Olivier Jacques , 2003 # Gregoire Favre , 2003 # Nicolas Huillard , 2005 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:43+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: fr_FR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" msgid "remove invalid channels" msgstr "" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/hr_HR.po000066400000000000000000000046741520154405700231440ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Drazen Dupor , 2004 # Dino Ravnic , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:43+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: hr_HR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "" msgid "Setup" msgstr "Setup" msgid "General" msgstr "" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/hu_HU.po000066400000000000000000000047261520154405700231500ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Istvan Koenigsberger , 2002 # Guido Josten , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:44+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: hu_HU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/it_IT.po000066400000000000000000000052531520154405700231440ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Alberto Carraro , 2001 # Antonio Ospite , 2003 # Sean Carlos , 2005 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2010-03-02 23:56+0100\n" "Last-Translator: Diego Pierotto \n" "Language-Team: \n" "Language: it_IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Italian\n" "X-Poedit-Country: ITALY\n" "X-Poedit-SourceCharset: utf-8\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "TUTTI (lento)" msgid "AUTO/OFF" msgstr "AUTO/DISATTIVO" msgid "AUTO/ON" msgstr "AUTO/ATTIVO (non raccomandato)" msgid "Setup" msgstr "Opzioni" msgid "General" msgstr "Generale" msgid "Source Type" msgstr "Tipo sorgente" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "Messaggi di log" msgid "logfile" msgstr "File di log" msgid "Channels" msgstr "Canali" msgid "TV channels" msgstr "Canali TV" msgid "Radio channels" msgstr "Canali Radio" msgid "FTA channels" msgstr "Canali FTA" msgid "Scrambled channels" msgstr "Canali codificati" msgid "Cable and Terrestrial" msgstr "Cavo e terrestre" msgid "Country" msgstr "Paese" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Inversione cavo" msgid "Cable Symbolrate" msgstr "SymbolRate cavo" msgid "Cable modulation" msgstr "Modulazione cavo" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Inversione terrestre" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Canali codificati" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Canali Radio" msgid "Stop" msgstr "Ferma" msgid "Start" msgstr "Avvia" msgid "Settings" msgstr "Impostazioni" msgid "Status" msgstr "Stato" msgid "Log Messages" msgstr "Registro messaggi" msgid "CANNOT SCAN - No device!" msgstr "SCANSIONE FALLITA - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Disattivo" #~ msgid "HD channels" #~ msgstr "Canali HD" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "SCANSIONE FALLITA - Timer active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "SCANSIONE FALLITA - Timer in programmazione!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/nl_NL.po000066400000000000000000000050351520154405700231340ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Arnold Niessen , 2001 # Hans Dingemans , 2003 # Maarten Wisse , 2005 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:44+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: nn_NL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/nn_NO.po000066400000000000000000000047071520154405700231460ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Jørgen Tvedt , 2001 # Truls Slevigen , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:44+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: nn_NO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/pl_PL.po000066400000000000000000000041401520154405700231340ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Michael Rakowski , 2002 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:44+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "" msgid "AUTO/ON" msgstr "" msgid "Setup" msgstr "Setup" msgid "General" msgstr "" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "" msgid "TV channels" msgstr "" msgid "Radio channels" msgstr "" msgid "FTA channels" msgstr "" msgid "Scrambled channels" msgstr "" msgid "Cable and Terrestrial" msgstr "" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "" msgid "Cable Symbolrate" msgstr "" msgid "Cable modulation" msgstr "" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" msgid "remove invalid channels" msgstr "" msgid "update existing channels" msgstr "" msgid "append new channels" msgstr "" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "Off" #~ msgstr "Off" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/pt_PT.po000066400000000000000000000037731520154405700231670ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Paulo Lopes , 2001 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:45+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: pt_PT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "" msgid "AUTO/ON" msgstr "" msgid "Setup" msgstr "Setup" msgid "General" msgstr "" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "" msgid "TV channels" msgstr "" msgid "Radio channels" msgstr "" msgid "FTA channels" msgstr "" msgid "Scrambled channels" msgstr "" msgid "Cable and Terrestrial" msgstr "" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "" msgid "Cable Symbolrate" msgstr "" msgid "Cable modulation" msgstr "" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" msgid "remove invalid channels" msgstr "" msgid "update existing channels" msgstr "" msgid "append new channels" msgstr "" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "" msgid "Log Messages" msgstr "" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "Off" #~ msgstr "Off" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/ro_RO.po000066400000000000000000000047271520154405700231610ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Paul Lacatus , 2002 # Lucian Muresan , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:45+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: ro_RO\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/ru_RU.po000066400000000000000000000041331520154405700231640ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Vyacheslav Dikonov , 2004 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:45+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: ru_RU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-5\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "" msgid "AUTO/ON" msgstr "" msgid "Setup" msgstr "Setup" msgid "General" msgstr "" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "" msgid "TV channels" msgstr "" msgid "Radio channels" msgstr "" msgid "FTA channels" msgstr "" msgid "Scrambled channels" msgstr "" msgid "Cable and Terrestrial" msgstr "" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "" msgid "Cable Symbolrate" msgstr "" msgid "Cable modulation" msgstr "" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" msgid "remove invalid channels" msgstr "" msgid "update existing channels" msgstr "" msgid "append new channels" msgstr "" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "Off" #~ msgstr "Off" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/sl_SI.po000066400000000000000000000047261520154405700231510ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Miha Setina , 2000 # Matjaz Thaler , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:45+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: sl_SI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/sv_SE.po000066400000000000000000000047021520154405700231510ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Tomas Prybil , 2002 # Jan Ekholm , 2003 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:45+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: sv_SE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/po/tr_TR.po000066400000000000000000000046361520154405700231720ustar00rootroot00000000000000# VDR plugin language source file. # Copyright (C) 2007 Klaus Schmidinger # This file is distributed under the same license as the VDR package. # Oktay Yolgeçen , 2007 # msgid "" msgstr "" "Project-Id-Version: VDR 1.5.7\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-11 10:46+0200\n" "PO-Revision-Date: 2007-09-10 19:45+0100\n" "Last-Translator: wk\n" "Language-Team: \n" "Language: tr_TR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-9\n" "Content-Transfer-Encoding: 8bit\n" msgid "AUTO" msgstr "AUTO" msgid "ALL (slow)" msgstr "ALL (slow)" msgid "AUTO/OFF" msgstr "AUTO/OFF" msgid "AUTO/ON" msgstr "AUTO/ON" msgid "Setup" msgstr "Setup" msgid "General" msgstr "General" msgid "Source Type" msgstr "Source Type" msgid "Signal Wait Time" msgstr "" msgid "Lock Timeout" msgstr "" msgid "verbosity" msgstr "verbosity" msgid "logfile" msgstr "logfile" msgid "Channels" msgstr "Channels" msgid "TV channels" msgstr "TV channels" msgid "Radio channels" msgstr "Radio channels" msgid "FTA channels" msgstr "FTA channels" msgid "Scrambled channels" msgstr "Scrambled channels" msgid "Cable and Terrestrial" msgstr "Cable and Terrestrial" msgid "Country" msgstr "Country" msgid "Cable Device" msgstr "" msgid "Cable Inversion" msgstr "Cable Inversion" msgid "Cable Symbolrate" msgstr "Cable Symbolrate" msgid "Cable modulation" msgstr "Cable modulation" msgid "Cable Network PID" msgstr "" msgid "Terr Device" msgstr "" msgid "Terr Inversion" msgstr "Terr Inversion" msgid "ATSC Device" msgstr "" msgid "ATSC Type" msgstr "ATSC Type" msgid "Satellite" msgstr "Satellite" msgid "Sat Device" msgstr "" msgid "Scan Mode" msgstr "" #, fuzzy msgid "remove invalid channels" msgstr "Scrambled channels" msgid "update existing channels" msgstr "" #, fuzzy msgid "append new channels" msgstr "Radio channels" msgid "Stop" msgstr "Stop" msgid "Start" msgstr "Start" msgid "Settings" msgstr "Settings" msgid "Status" msgstr "Status" msgid "Log Messages" msgstr "Log Messages" msgid "CANNOT SCAN - No device!" msgstr "CANNOT SCAN - No device!" #~ msgid "DVB-S2" #~ msgstr "DVB-S2" #~ msgid "Off" #~ msgstr "Off" #~ msgid "HD channels" #~ msgstr "HD channels" #~ msgid "CANNOT SCAN - Timers active!" #~ msgstr "CANNOT SCAN - Timers active!" #~ msgid "CANNOT SCAN - Timers on Schedule!" #~ msgstr "CANNOT SCAN - Timers on Schedule!" wirbel-at-vdr-portal-wirbelscan-dev-eebef12/satellites.cpp000066400000000000000000000066441520154405700240400ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #define SAT_COUNT(x) (sizeof(x)/sizeof(struct cSat)) #define SAT_TRANSPONDER_COUNT(x) (sizeof(x)/sizeof(struct __sat_transponder)) #define B(ID) static const struct __sat_transponder ID[] = { #define E(ID) }; #include #include "common.h" #include "satellites.h" #include "satellites.dat" /****************************************************************************** * convert position constant to index number *****************************************************************************/ int txt_to_satellite(std::string id) { for(size_t i=0; i #include // uint{8,16,32}_t int choose_satellite(std::string satellite, int& channellist); int txt_to_satellite(std::string id); size_t sat_count(void); std::string satellite_to_short_name(size_t idx); std::string satellite_to_full_name(size_t idx); int rotor_position_to_sat_list_index(int rotor_position); void print_satellites(void); /****************************************************************************** * only used for storage of data *****************************************************************************/ struct __sat_transponder { uint8_t modulation_system; uint32_t intermediate_frequency; uint8_t polarization; uint32_t symbol_rate; uint8_t fec_inner; uint8_t rolloff; uint8_t modulation_type; uint8_t stream_id; }; struct cSat { const char* short_name; const size_t id; const char* full_name; const struct __sat_transponder* items; const size_t item_count; const uint8_t west_east_flag; const uint16_t orbital_position; int rotor_position; // Note: *not* const const char* source_id; // VDR sources.conf }; extern struct cSat sat_list[]; wirbel-at-vdr-portal-wirbelscan-dev-eebef12/scanfilter.cpp000066400000000000000000002066231520154405700240200ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include #include // std::vector<> #include // std::sort, std::unique #include #include // round() #include // cDevice #include #include #include "scanfilter.h" #include "si_ext.h" #include "countries.h" // COUNTRY::Alpha3() /******************************************************************************* * IMPORTANT!! cNitScanner, cPatScanner, cSdtScanner, cEitScanner are modified * versions of (ancient) core VDR's own classes cEIT, cNitFilter, cSdtFilter. * * License GPLv2, original Copyright (C) Klaus Schmidinger, see www.tvdr.de/vdr ******************************************************************************/ extern TSdtData SdtData; extern TNitData NitData; TChannels NewChannels; TChannels NewTransponders; TChannels ScannedTransponders; std::vector ChannelListItems; int nextTransponders; void resetLists(void) { NewChannels.Clear(); NewTransponders.Clear(); ScannedTransponders.Clear(); SdtData.services.Clear(); NitData.frequency_list.Clear(); NitData.cell_frequency_links.Clear(); NitData.service_types.Clear(); for(int i = 0; i < NitData.transport_streams.Count(); i++) delete NitData.transport_streams[i]; NitData.transport_streams.Clear(); nextTransponders = 0; NewChannels.Capacity(2500); NewTransponders.Capacity(500); ScannedTransponders.Capacity(500); } bool known_transponder(TChannel* newChannel, bool auto_allowed, TChannels* list) { if (list == NULL) { return (known_transponder(newChannel, auto_allowed, &NewTransponders) || known_transponder(newChannel, auto_allowed, &ScannedTransponders)); } for(int idx = 0; idx < list->Count(); ++idx) { TChannel* channel = list->Items(idx); if (newChannel->Source[0] != channel->Source[0]) continue; char c = newChannel->Source[0]; if (c == 'T') { if (newChannel->DelSys and (channel->StreamId != newChannel->StreamId)) continue; // may be multiple plps. if (newChannel->DelSys != channel->DelSys and !channel->Tunable) continue; // skip freqs with T!=T1, but not those which had success. if (is_nearly_same_frequency(channel, newChannel)) return true; } else if (c == 'C') { if (is_nearly_same_frequency(channel, newChannel)) return true; } else if (c == 'A') { if (is_nearly_same_frequency(channel, newChannel) && channel->Modulation == newChannel->Modulation) return true; } else if (c == 'S') { if (!is_different_transponder_deep_scan(newChannel, channel, auto_allowed)) return true; } else dlog(0, std::string(__FUNCTION__) + ": source[0] = " + IntToHex((unsigned) c, 2)); } return (false); } int FormatFreq(int f) { if (f < 1000) f *= 1000; if (f > 999999) f /= 1000; return (f); } bool is_nearly_same_frequency(const TChannel* chan_a, const TChannel* chan_b, unsigned delta) { uint32_t diff; // s: 4000..13000 (MHz) // c,t,a: 95000 .. 870000 (kHz) int f1 = FormatFreq(chan_a->Frequency); int f2 = FormatFreq(chan_b->Frequency); if (f1 == f2) return true; diff = (f1 > f2) ? (f1 - f2) : (f2 - f1); //FIXME: use symbolrate etc. to estimate bandwidth if (diff <= delta) { return true; } return (false); } bool is_different_transponder_deep_scan(const TChannel* a, const TChannel* b, bool auto_allowed) { auto different = [](int a, int b, bool relaxed, int defValue) -> bool { if ((a == defValue) or (b == defValue)) if (relaxed) return false; return a != b; }; if (a->Source != b->Source) return true; char asource = a->Source[0]; int maxdelta = 500; //kHz if (asource == 'S') maxdelta = 2; //MHz else if (asource == 'T') maxdelta = 250; //kHz -> France if (!is_nearly_same_frequency(a, b, maxdelta)) return true; switch(asource) { case 'T': { if (different(a->Modulation, b->Modulation, auto_allowed, 999)) return true; if (different(a->Bandwidth, b->Bandwidth, auto_allowed, 8)) return true; if (different(a->FEC, b->FEC, auto_allowed, 999)) return true; if (different(a->Hierarchy, b->Hierarchy, auto_allowed, 999)) return true; if (different(a->FEC_low, b->FEC_low, auto_allowed, 999)) return true; if (different(a->Transmission, b->Transmission, auto_allowed, 999)) return true; if (different(a->Guard, b->Guard, auto_allowed, 999)) return true; if (different(a->DelSys, b->DelSys, false, 0)) return true; return false; } case 'A': { if (different(a->Modulation, b->Modulation, auto_allowed, 999)) return true; return false; } case 'C': { if (different(a->Modulation, b->Modulation, auto_allowed, 999)) return true; if (different(a->Symbolrate, b->Symbolrate, false, 6900)) return true; if (different(a->FEC, b->FEC, auto_allowed, 999)) return true; if (different(a->DelSys, b->DelSys, false, 0)) return true; return false; } case 'S': { if (different(a->Symbolrate, b->Symbolrate, false, -1)) return true; if (different(a->Polarization, b->Polarization, false, 0)) return true; if (different(a->FEC, b->FEC, auto_allowed, 999)) return true; if (different(a->DelSys, b->DelSys, false, 0)) return true; if (a->DelSys == 1) { //if (different(a->Rolloff, b->Rolloff, auto_allowed, 999)) { // std::cout << "a->Rolloff = " << std::to_string(a->Rolloff) << ", b->Rolloff = " << std::to_string(b->Rolloff) << std::endl; // return true; // } if (different(a->Modulation, b->Modulation, auto_allowed, 999)) return true; if (a->StreamId != b->StreamId) return true; } return false; } default: dlog(0, std::string(__FUNCTION__) + ": unknown source type '" + a->Source + "'"); } return true; } /******************************************************************************* * cPatScanner ******************************************************************************/ cPatScanner::cPatScanner(cDevice* Parent, struct TPatData& Dest) : device(Parent), PatData(Dest), isActive(true), hasPAT(false), anyBytes(false) { PatData.services.Clear(); PatData.network_PID = 0; Sync.Reset(); Start(); } cPatScanner::~cPatScanner() { isActive = false; wait.Signal(); } void cPatScanner::Action(void) { int count = 0; int nbytes = 0; int fd = device->OpenFilter(SI_EXT::PID_PAT, SI_EXT::TABLE_ID_PAT, 0xFF); unsigned char buffer[4096]; while(Running() && isActive) { if (wait.Wait(10)) { dlog(5, "cPatScanner: received signal"); break; } if (count++ > 1000) { // > 10sec dlog(5, "cPatScanner: PAT timeout."); break; } else if ((count > 300) and not(anyBytes)) { dlog(5, "cPatScanner: PAT timeout."); break; } nbytes = device->ReadFilter(fd, buffer, sizeof(buffer)); if (nbytes > 0) { anyBytes = true; Process(buffer, nbytes); } if (hasPAT) break; } device->CloseFilter(fd); fd = -1; isActive = false; } void cPatScanner::Process(const unsigned char* Data, int Length) { SI::PAT tsPAT(Data, false); if (!tsPAT.CheckCRCAndParse()) { hexdump("PAT CRC error", Data, Length); return; } if (!Sync.Sync(tsPAT.getVersionNumber(), tsPAT.getSectionNumber(), tsPAT.getLastSectionNumber())) { dlog(4, "cPatScanner: wait for PAT Sync"); return; } if (wSetup.verbosity > 5) hexdump("PAT", Data, Length); SI::PAT::Association assoc; for (SI::Loop::Iterator it; tsPAT.associationLoop.getNext(assoc, it);) { if (assoc.getServiceId() == 0) { PatData.network_PID = assoc.getPid(); continue; } struct service s; hasPAT = true; s.transport_stream_id = tsPAT.getTransportStreamId(); s.program_map_PID = assoc.getPid(); s.program_number = assoc.getServiceId(); PatData.services.Add(s); } // all parts of PAT seen. if (tsPAT.getSectionNumber() == tsPAT.getLastSectionNumber()) hasPAT = true; } /******************************************************************************* * cPmtScanner ******************************************************************************/ cPmtScanner::cPmtScanner(cDevice* Parent, TPmtData* Data) : device(Parent), data(Data), isActive(false), jobDone(false) { data->program_number = 0; data->PCR_PID = 0; data->Vpid.PID = 0; data->Tpid = 0; data->Apids.Clear(); data->Dpids.Clear(); data->Spids.Clear(); data->Caids.Clear(); } cPmtScanner::~cPmtScanner() { isActive = false; wait.Signal(); } void cPmtScanner::Action(void) { isActive = true; int count = 0; int nbytes = 0; int fd = device->OpenFilter(data->program_map_PID, SI_EXT::TABLE_ID_PMT, 0xFF); unsigned char buffer[4096]; while (Running() && isActive) { if (wait.Wait(10)) { break; } if (count++ > 500) { //>5sec isActive = false; break; } nbytes = device->ReadFilter(fd, buffer, sizeof(buffer)); if (nbytes > 0) Process(buffer, nbytes); } device->CloseFilter(fd); fd = -1; jobDone = true; isActive = false; } void cPmtScanner::Process(const unsigned char* Data, int Length) { SI::PMT pmt(Data, false); if (!pmt.CheckCRCAndParse()/* || (pmt.getServiceId() != pmtSid)*/) return; data->program_number = pmt.getServiceId(); SI::CaDescriptor* d; // Scan the common loop: for(SI::Loop::Iterator it; (d = (SI::CaDescriptor *) pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag));) { int ca = d->getCaType(); if (data->Caids.IndexOf(ca) < 0) data->Caids.Add(ca); DeleteNullptr(d); } SI::PMT::Stream stream; // Scan the stream-specific loop: for(SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it);) { int StreamType = stream.getStreamType(); switch(StreamType) { case SI_EXT::STREAMTYPE_11172_VIDEO: case SI_EXT::STREAMTYPE_13818_VIDEO: case SI_EXT::STREAMTYPE_14496_VISUAL: case SI_EXT::STREAMTYPE_14496_H264_VIDEO: case SI_EXT::STREAMTYPE_23008_H265_VIDEO: data->Vpid.PID = stream.getPid(); data->Vpid.Type = StreamType; data->PCR_PID = pmt.getPCRPid(); break; case SI_EXT::STREAMTYPE_11172_AUDIO: case SI_EXT::STREAMTYPE_13818_AUDIO: case SI_EXT::STREAMTYPE_13818_AUDIO_ADTS: case SI_EXT::STREAMTYPE_14496_AUDIO_LATM: case SI_EXT::STREAMTYPE_14496_H264_AUDIO: { TPid apid; apid.PID = stream.getPid(); apid.Type = StreamType; SI::Descriptor * d; for(SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it));) { switch(d->getDescriptorTag()) { case SI::ISO639LanguageDescriptorTag: { SI::ISO639LanguageDescriptor* ld = (SI::ISO639LanguageDescriptor*) d; SI::ISO639LanguageDescriptor::Language l; char b[16] = {0}, *s = b; int n = 0; for(SI::Loop::Iterator it; ld->languageLoop.getNext(l, it);) { if (*ld->languageCode != '-') { // some use "---" to indicate "none" if (n > 0) *s++ = '+'; strn0cpy(s, I18nNormalizeLanguageCode(l.languageCode), MAXLANGCODE1); s += strlen(s); if (n++ > 1) break; } } apid.Lang = b; } break; default:; } DeleteNullptr(d); } data->Apids.Add(apid); } break; case SI_EXT::STREAMTYPE_13818_PRIVATE: case SI_EXT::STREAMTYPE_13818_PES_PRIVATE: { TPid dpid; dpid.PID = 0; dpid.Type = 0; char lang[MAXLANGCODE1] = {0}; SI::Descriptor * d; for(SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it));) { switch (d->getDescriptorTag()) { case SI::AC3DescriptorTag: case SI_EXT::EnhancedAC3DescriptorTag: case SI_EXT::DTSDescriptorTag: case SI_EXT::AACDescriptorTag: dpid.PID = stream.getPid(); dpid.Type = d->getDescriptorTag(); break; case SI::SubtitlingDescriptorTag: { char b[16] = {0}, *s = b; TPid spid; spid.PID = stream.getPid(); SI::SubtitlingDescriptor* sd = (SI::SubtitlingDescriptor*) d; SI::SubtitlingDescriptor::Subtitling sub; int n = 0; for(SI::Loop::Iterator it; sd->subtitlingLoop.getNext(sub, it);) { if (sub.languageCode[0]) { if (n > 0) *s++ = '+'; strn0cpy(s, I18nNormalizeLanguageCode(sub.languageCode), MAXLANGCODE1); s += strlen(s); if (n++ > 1) break; } } spid.Lang = b; data->Spids.Add(spid); } break; case SI::TeletextDescriptorTag: data->Tpid = stream.getPid(); break; case SI::ISO639LanguageDescriptorTag: { SI::ISO639LanguageDescriptor* ld = (SI::ISO639LanguageDescriptor*) d; strn0cpy(lang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1); } break; default:; } DeleteNullptr(d); } if (dpid.PID) { dpid.Lang = lang; data->Dpids.Add(dpid); } } break; case SI_EXT::STREAMTYPE_13818_USR_PRIVATE_81: { //if (Channel->Source[0] == 'A') { char dlang[MAXLANGCODE1] = { 0 }; SI::Descriptor *d; for(SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { switch(d->getDescriptorTag()) { case SI::ISO639LanguageDescriptorTag: { SI::ISO639LanguageDescriptor* ld = (SI::ISO639LanguageDescriptor*) d; strn0cpy(dlang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1); } break; default:; } DeleteNullptr(d); } TPid dpid; dpid.PID = stream.getPid(); dpid.Type = SI::AC3DescriptorTag; dpid.Lang = dlang; data->Dpids.Add(dpid); // } } break; default:; } for(SI::Loop::Iterator it; (d = (SI::CaDescriptor*) stream.streamDescriptors.getNext(it, SI::CaDescriptorTag));) { int ca = d->getCaType(); if (data->Caids.IndexOf(ca) < 0) data->Caids.Add(ca); DeleteNullptr(d); } } isActive = false; } /******************************************************************************* * cNitScanner * basically this is cNitFilter from older vdr/nit.{h,c} with some changes ******************************************************************************/ cNitScanner::cNitScanner(cDevice* Parent, uint16_t network_PID, TNitData& Data, int Type) : active(true), device(Parent), nit(network_PID), data(Data), type(Type), hasNIT(false), anyBytes(false) { first_crc32 = 0; west = Data.West; orbital = Data.OrbitalPos; Start(); } cNitScanner::~cNitScanner() { active = false; wait.Signal(); } void cNitScanner::Action(void) { int count = 0; int nbytes = 0; int fd = device->OpenFilter(nit, SI_EXT::TABLE_ID_NIT_ACTUAL, 0xFF); unsigned char buffer[4096]; size_t items = ChannelListItems.size(); while(Running() && active) { if (wait.Wait(10)) { break; } if (count++ > 4000) { // 4000 x 10msec = 40sec dlog(2, "NIT timeout"); break; } else if ((count > 1800) and not(anyBytes)) break; nbytes = device->ReadFilter(fd, buffer, sizeof(buffer)); if (nbytes > 0) { anyBytes = true; Process(buffer, nbytes); } if (hasNIT) { if (ChannelListItems.size() > items) { // new ChannelListItems, remove duplicates. std::sort(ChannelListItems.begin(), ChannelListItems.end()); auto first_duplicate = std::unique(ChannelListItems.begin(), ChannelListItems.end()); ChannelListItems.erase(first_duplicate, ChannelListItems.end()); } break; } } device->CloseFilter(fd); Cancel(); active = false; } /* std::sort */ bool operator<(TCell const& lhs, TCell const& rhs) { return lhs.cell_id < rhs.cell_id; } /* std::sort */ void swap(TCell& a, TCell& b) { TCell c; memcpy(&c, &a, sizeof(TCell)); memcpy(&a, &b, sizeof(TCell)); memcpy(&b, &c, sizeof(TCell)); } /* std::sort */ bool operator<(TFrequencyListItem const& lhs, TFrequencyListItem const& rhs) { return ((lhs.network_id < rhs.network_id) or (lhs.frequency < rhs.frequency)); } /* std::sort */ void swap(TFrequencyListItem& a, TFrequencyListItem& b) { TFrequencyListItem c; memcpy(&c, &a, sizeof(TFrequencyListItem)); memcpy(&a, &b, sizeof(TFrequencyListItem)); memcpy(&b, &c, sizeof(TFrequencyListItem)); } /* std::sort */ bool TChannelListItem::operator < (const TChannelListItem& rhs) const { if (channel_list_id != rhs.channel_list_id) return channel_list_id < rhs.channel_list_id; if (original_network_id != rhs.original_network_id) return original_network_id < rhs.original_network_id; if (transport_stream_id != rhs.transport_stream_id) return transport_stream_id < rhs.transport_stream_id; if (service_id != rhs.service_id) return service_id < rhs.service_id; if (HD_simulcast != rhs.HD_simulcast) return HD_simulcast; return false; } /* std::unique */ bool TChannelListItem::operator == (const TChannelListItem& rhs) const { return ( channel_list_id == rhs.channel_list_id ) and ( original_network_id == rhs.original_network_id ) and ( transport_stream_id == rhs.transport_stream_id ) and ( service_id == rhs.service_id ) and ( HD_simulcast == rhs.HD_simulcast ); } bool GetLCN(TChannel* c) { if (c == nullptr) return false; for(auto& it:ChannelListItems) { if (((it.original_network_id == c->ONID) or (it.network_id == c->NID)) and (it.transport_stream_id == c->TID ) and (it.service_id == c->SID )) { c->LCN = it.LCN; c->LCN_minor = it.LCN_minor; return true; } } dlog(5, "no LCN for " + IntToStr(c->SID) + ":" + IntToStr(c->ONID) + ":" + IntToStr(c->TID)); return false; } void cNitScanner::ParseCellFrequencyLinks(uint16_t network_id, const unsigned char* Data, TList& list) { int len = 2 + *(Data + 1); int offset = 2; TCell c; c.network_id = network_id; if (wSetup.verbosity > 5) hexdump("cNitScanner", Data, len); while(len >= 7) { c.cell_id = Data[offset + 0] << 8 | Data[offset + 1]; c.frequency = (Data[offset + 2] << 24 | Data[offset + 3] << 16 | Data[offset + 4] << 8 | Data[offset + 5]) * 10; c.subcellcount = Data[offset + 6] / 5; offset += 7; len -= 7; for(int i = 0; i < c.subcellcount; i++) { c.subcells[i].cell_id_extension = Data[offset]; c.subcells[i].transposer_frequency = (Data[offset + 1] << 24 | Data[offset + 2] << 16 | Data[offset + 3] << 8 | Data[offset + 4]) * 10; offset += 5; len -= 5; } bool found = false; for(int i = 0; i < list.Count(); i++) { if ((list[i].cell_id == c.cell_id) and (list[i].network_id == c.network_id)) { found = true; break; } } if (!found) { list.Add(c); list.Sort(); } } } void cNitScanner::Process(const unsigned char* Data, int Length) { SI::NIT nit(Data, false); if (!nit.CheckCRCAndParse()) return; if (Data[0] != SI_EXT::TABLE_ID_NIT_ACTUAL and Data[0] != SI_EXT::TABLE_ID_NIT_OTHER) return; int len = nit.getLength(); uint32_t crc32 = Data[len-4] << 24 | Data[len-3] << 16 | Data[len-2] << 8 | Data[len-1]; if (first_crc32 == crc32) { hasNIT = true; return; } if (!first_crc32) first_crc32 = crc32; if (wSetup.verbosity > 5) hexdump(__PRETTY_FUNCTION__, Data, Length); uint32_t PrivateDataSpecifier = SI_EXT::private_data_specifier_Reserved; SI::NIT::TransportStream ts; for(SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it);) { SI::Descriptor* d; SI::Loop::Iterator it2; SI::FrequencyListDescriptor* fld = (SI::FrequencyListDescriptor*) ts.transportStreamDescriptors.getNext(it2, SI::FrequencyListDescriptorTag); if (fld) { int ct = fld->getCodingType(); if (ct > 0) { for(SI::Loop::Iterator it3; fld->frequencies.hasNext(it3);) { uint32_t f = fld->frequencies.getNext(it3); switch(ct) { case 1: f = round(BCDtoDecimal(f) / 100.0); break; //satellite case 2: f = round(BCDtoDecimal(f) / 10.0); break; //cable case 3: f *= 10; break; //terrestrial default:; } bool found = false; for(int i = 0; i < data.frequency_list.Count(); i++) { if (data.frequency_list[i].frequency == f) { found = true; break; } } if (!found) { TFrequencyListItem item; item.network_id = nit.getNetworkId(); item.frequency = f; data.frequency_list.Add(item); data.frequency_list.Sort(); } } } } DeleteNullptr(fld); // dirty hack because libsi is missing needed cell_frequency_link_descriptor // and support is only possible with patching libsi :-(( // -> has to be removed as soon libsi supports cell_frequency_link_descriptor int offset = 16 + (((*(Data + 8) << 8) & 0x0F00) | *(Data + 9)); int stop = ((*(Data + offset) << 8) & 0x0F00) | *(Data + offset + 1); offset += 2; // Transport_descriptor_length stop += offset; while (offset < stop) { int len = *(Data + offset + 1); switch(*(Data + offset)) { case SI::CellFrequencyLinkDescriptorTag: { // cell_frequency_link_descriptor, DVB-T/T2 only. ParseCellFrequencyLinks(nit.getNetworkId(), Data + offset, data.cell_frequency_links); offset += 2 + *(Data + offset + 1); break; } case SI::CellListDescriptorTag: dlog(0, "SI::CellListDescriptorTag in first loop."); /* Falls through. */ default: offset += len + 2; // all other descriptors handled regularly } if (!len) break; } // end dirty hack for(SI::Loop::Iterator it2; (d = ts.transportStreamDescriptors.getNext(it2));) { switch((unsigned) d->getDescriptorTag()) { case SI::SatelliteDeliverySystemDescriptorTag: { if (type != SCAN_SATELLITE) continue; SI::SatelliteDeliverySystemDescriptor * sd = (SI::SatelliteDeliverySystemDescriptor *) d; int Source = cSource::FromData(cSource::stSat, BCDtoDecimal(sd->getOrbitalPosition()), sd->getWestEastFlag()); int RollOff = 35; int Modulation = 2; int System = 0; bool west_flag = sd->getWestEastFlag() == 0; if ((west_flag != west) or ( abs(BCDtoDecimal(sd->getOrbitalPosition()) - orbital) > 2 )) { char c = west_flag?'W':'E'; dlog(4, "Skipping transportStreamDescriptor for S" + FloatToStr(BCDtoDecimal(sd->getOrbitalPosition())/10.0, 1, 1, false) + c); continue; } if ((System = sd->getModulationSystem())) { // {DVB-S2} if (sd->getModulationType() == 2) Modulation = 5; else if (sd->getModulationType() == 3) Modulation = 16; if (sd->getRollOff() == 1) RollOff = 25; else if (sd->getRollOff() == 2) RollOff = 20; } uint32_t Frequency = round(BCDtoDecimal(sd->getFrequency()) / 100.0); char Polarization = 'H'; if (sd->getPolarization() == 1) Polarization = 'V'; else if (sd->getPolarization() == 2) Polarization = 'L'; else if (sd->getPolarization() == 3) Polarization = 'R'; int CodeRate; switch(sd->getFecInner()) { case 1 : CodeRate = 12; break; case 2 : CodeRate = 23; break; case 3 : CodeRate = 34; break; case 4 : CodeRate = 56; break; case 5 : CodeRate = 78; break; case 6 : CodeRate = 89; break; case 7 : CodeRate = 35; break; case 8 : CodeRate = 45; break; case 9 : CodeRate = 910; break; case 15: CodeRate = 0; break; default: CodeRate = 999; } uint32_t SymbolRate = round(BCDtoDecimal(sd->getSymbolRate()) / 10.0); TChannel* transponder = new TChannel; transponder->NID = nit.getNetworkId(); transponder->ONID = ts.getOriginalNetworkId(); transponder->TID = ts.getTransportStreamId(); transponder->Source = *cSource::ToString(Source); transponder->Frequency = Frequency; transponder->Symbolrate = SymbolRate; transponder->Polarization = Polarization; transponder->Inversion = 999; transponder->FEC = CodeRate; transponder->Modulation = Modulation; transponder->DelSys = System; transponder->Rolloff = RollOff; transponder->OrbitalPos = BCDtoDecimal(sd->getOrbitalPosition()); if (!sd->getWestEastFlag()) transponder->OrbitalPos *= -1; bool found = false; for(int i = 0; !found and i < data.transport_streams.Count(); i++) { std::string t; transponder->PrintTransponder(t); TChannel* ts = data.transport_streams[i]; ts->PrintTransponder(s); if (s == t and ts->TID == transponder->TID and (ts->NID == transponder->NID or ts->ONID == transponder->ONID)) found = true; } if (!found) data.transport_streams.Add(transponder); } // end SI::SatelliteDeliverySystemDescriptorTag break; case SI::S2SatelliteDeliverySystemDescriptorTag: { // only interesting if NBC-BS if (type != SCAN_SATELLITE) continue; SI::S2SatelliteDeliverySystemDescriptor * sd = (SI::S2SatelliteDeliverySystemDescriptor *) d; #if 0 //i have no idea whether i need the scrambling index and if so for what.., 0 is default anyway. int scrambling_sequence_index = (sd->getScramblingSequenceSelector()) ? sd->getScramblingSequenceIndex() : 0; #endif int DVBS_backward_compatibility = sd->getBackwardsCompatibilityIndicator(); if (DVBS_backward_compatibility) { // okay: we should add a dvb-s transponder // with same source, same polarization and QPSK to list of transponders // if this transponder isn't already marked as known. // } // now we should re-check whether this s2 transponder is really known// } // end SI::S2SatelliteDeliverySystemDescriptorTag break; case SI::CableDeliverySystemDescriptorTag: { if (type != SCAN_CABLE) continue; SI::CableDeliverySystemDescriptor* sd = (SI::CableDeliverySystemDescriptor*) d; uint32_t Frequency = round(BCDtoDecimal(sd->getFrequency()) / 10.0); int CodeRate; switch(sd->getFecInner()) { case 1 : CodeRate = 12; break; case 2 : CodeRate = 23; break; case 3 : CodeRate = 34; break; case 4 : CodeRate = 56; break; case 5 : CodeRate = 78; break; case 6 : CodeRate = 89; break; case 7 : CodeRate = 35; break; case 8 : CodeRate = 45; break; case 9 : CodeRate = 910; break; case 15: CodeRate = 0; break; default: CodeRate = 999; } int Modulation; switch(sd->getModulation()) { case 1 : Modulation = 16; break; case 2 : Modulation = 32; break; case 3 : Modulation = 64; break; case 4 : Modulation = 128; break; case 5 : Modulation = 256; break; default: Modulation = 999; } TChannel* transponder = new TChannel; uint32_t SymbolRate = round(BCDtoDecimal(sd->getSymbolRate()) / 10.0); transponder->NID = nit.getNetworkId(); transponder->ONID = ts.getOriginalNetworkId(); transponder->TID = ts.getTransportStreamId(); transponder->Source = "C"; transponder->Frequency = Frequency; transponder->Symbolrate = SymbolRate; transponder->Inversion = 999; transponder->FEC = CodeRate; transponder->Modulation = Modulation; bool found = false; for(int i = 0; !found and i < data.transport_streams.Count(); i++) { std::string t; transponder->PrintTransponder(t); TChannel* ts = data.transport_streams[i]; ts->PrintTransponder(s); if (s == t and ts->TID == transponder->TID and (ts->NID == transponder->NID or ts->ONID == transponder->ONID)) found = true; } if (!found) data.transport_streams.Add(transponder); } // end SI::CableDeliverySystemDescriptorTag break; case SI::TerrestrialDeliverySystemDescriptorTag: { if (type != SCAN_TERRESTRIAL) continue; SI::TerrestrialDeliverySystemDescriptor* sd = (SI::TerrestrialDeliverySystemDescriptor*) d; int Source = cSource::FromData(cSource::stTerr); uint32_t Frequency = sd->getFrequency() * 10; int Bandwidth = 8; if (sd->getBandwidth() == 1) Bandwidth = 7; else if (sd->getBandwidth() == 2) Bandwidth = 6; else if (sd->getBandwidth() == 3) Bandwidth = 5; int Modulation = 999; if (sd->getConstellation() == 0) Modulation = 2; else if (sd->getConstellation() == 1) Modulation = 16; else if (sd->getConstellation() == 2) Modulation = 64; int Hierarchy = 0; if (sd->getHierarchy() == 1) Hierarchy = 1; else if (sd->getHierarchy() == 2) Hierarchy = 2; else if (sd->getHierarchy() == 3) Hierarchy = 4; int CodeRateHP = 999; switch(sd->getCodeRateHP()) { case 0 : CodeRateHP = 12; break; case 1 : CodeRateHP = 23; break; case 2 : CodeRateHP = 34; break; case 3 : CodeRateHP = 56; break; case 4 : CodeRateHP = 78; break; default: CodeRateHP = 999; } int CodeRateLP = 0; switch(sd->getCodeRateLP()) { case 0 : CodeRateLP = 12; break; case 1 : CodeRateLP = 23; break; case 2 : CodeRateLP = 34; break; case 3 : CodeRateLP = 56; break; case 4 : CodeRateLP = 78; break; default: CodeRateLP = 999; } int GuardInterval = 999; switch(sd->getGuardInterval()) { case 0 : GuardInterval = 32; break; case 1 : GuardInterval = 16; break; case 2 : GuardInterval = 8; break; case 3 : GuardInterval = 4; break; default:; } int TransmissionMode = 999; switch(sd->getTransmissionMode()) { case 0 : TransmissionMode = 2; break; case 1 : TransmissionMode = 8; break; case 2 : TransmissionMode = 4; break; default:; } TChannel* transponder = new TChannel; transponder->NID = nit.getNetworkId(); transponder->ONID = ts.getOriginalNetworkId(); transponder->TID = ts.getTransportStreamId(); transponder->Source = *cSource::ToString(Source); transponder->Frequency = Frequency; transponder->Symbolrate = 27500; transponder->Inversion = 999; transponder->Bandwidth = Bandwidth; transponder->FEC = CodeRateHP; transponder->FEC_low = CodeRateLP; transponder->Modulation = Modulation; transponder->DelSys = 0; transponder->Transmission = TransmissionMode; transponder->Guard = GuardInterval; transponder->Hierarchy = Hierarchy; bool found = false; for(int i = 0; !found and i < data.transport_streams.Count(); i++) { std::string t; transponder->PrintTransponder(t); TChannel* ts = data.transport_streams[i]; ts->PrintTransponder(s); if (s == t and ts->TID == transponder->TID and (ts->NID == transponder->NID or ts->ONID == transponder->ONID)) found = true; } if (!found) data.transport_streams.Add(transponder); } // end SI::TerrestrialDeliverySystemDescriptorTag break; case SI::ExtensionDescriptorTag: { SI::ExtensionDescriptor* sd = (SI::ExtensionDescriptor*) d; switch(sd->getExtensionDescriptorTag()) { case SI::T2DeliverySystemDescriptorTag: { if (type != SCAN_TERRESTRIAL) continue; SI::T2DeliverySystemDescriptor* td = (SI::T2DeliverySystemDescriptor*) d; TChannel* transponder = new TChannel; transponder->NID = nit.getNetworkId(); transponder->ONID = ts.getOriginalNetworkId(); transponder->TID = ts.getTransportStreamId(); transponder->Source = "T"; transponder->DelSys = 1; transponder->Frequency = 0; transponder->Symbolrate = 27500; transponder->Inversion = 999; transponder->Modulation = 999; // not transmitted in SI transponder->Hierarchy = 0; // not in use. transponder->FEC = 999; // not transmitted in SI transponder->FEC_low = 0; // not transmitted in SI transponder->SystemId = td->getT2SystemId(); transponder->StreamId = td->getPlpId(); transponder->reported = false; int Bandwidth = 8; if (td->getBandwidth() == 1) Bandwidth = 7; else if (td->getBandwidth() == 2) Bandwidth = 6; else if (td->getBandwidth() == 3) Bandwidth = 5; else if (td->getBandwidth() == 4) Bandwidth = 10; else if (td->getBandwidth() == 5) Bandwidth = 1712; transponder->Bandwidth = Bandwidth; int GuardInterval = 999; switch(td->getGuardInterval()) { case 0: GuardInterval = 32; break; case 1: GuardInterval = 16; break; case 2: GuardInterval = 8; break; case 3: GuardInterval = 4; break; case 4: GuardInterval = 128; break; case 5: GuardInterval = 19128; break; case 6: GuardInterval = 19256; break; default:; } transponder->Guard = GuardInterval; int TransmissionMode = 999; switch(td->getTransmissionMode()) { case 0: TransmissionMode = 2; break; case 1: TransmissionMode = 8; break; case 2: TransmissionMode = 4; break; case 3: TransmissionMode = 1; break; case 4: TransmissionMode = 16; break; case 5: TransmissionMode = 32; break; default:; } transponder->Transmission = TransmissionMode; int N = td->getLength() - 8; transponder->cells.Clear(); if (N > 0) { const unsigned char* bytes = d->getData().getData() + 8; //hexdump("T2 freq loop", bytes, N); while(N > 0) { struct cell cell; cell.num_center_frequencies = 0; cell.num_transposers = 0; cell.cell_id = *bytes++ << 8; cell.cell_id |= *bytes++; N-=2; if (td->getTfsFlag() > 0) { int frequency_loop_length = *bytes++; while(frequency_loop_length > 0) { uint32_t cf; cf = *bytes++ << 24; cf |= *bytes++ << 16; cf |= *bytes++ << 8; cf |= *bytes++; frequency_loop_length -= 4; N-=4; cell.center_frequencies[cell.num_center_frequencies++] = cf * 10; } } else { uint32_t cf; cf = *bytes++ << 24; cf |= *bytes++ << 16; cf |= *bytes++ << 8; cf |= *bytes++; N-=4; cell.center_frequencies[cell.num_center_frequencies++] = cf * 10; } uint8_t subcell_info_loop_length = *bytes++; N-=1; while(subcell_info_loop_length > 0) { if (cell.num_transposers > 15) continue; cell.transposers[cell.num_transposers].cell_id_extension = *bytes++; uint32_t tf; tf = *bytes++ << 24; tf |= *bytes++ << 16; tf |= *bytes++ << 8; tf |= *bytes++; cell.transposers[cell.num_transposers].transposer_frequency = tf * 10; cell.num_transposers++; N -= 5; } transponder->cells.Add(cell); } } if (transponder->cells.Count() > 0) transponder->Frequency = transponder->cells[0].center_frequencies[0]; bool found = false; for(int i = 0; !found and i < data.transport_streams.Count(); i++) { std::string t; transponder->PrintTransponder(t); TChannel* ts = data.transport_streams[i]; ts->PrintTransponder(s); if (s == t and ts->TID == transponder->TID and (ts->NID == transponder->NID or ts->ONID == transponder->ONID) and ts->cells.Count() == transponder->cells.Count()) found = true; } if (!found) data.transport_streams.Add(transponder); } // SI::T2DeliverySystemDescriptorTag break; // end T2 delsys default:; } } // SI::ExtensionDescriptorTag break; case SI::ServiceListDescriptorTag: { SI::ServiceListDescriptor* sd = (SI::ServiceListDescriptor*) d; SI::ServiceListDescriptor::Service Service; for(SI::Loop::Iterator it; sd->serviceLoop.getNext(Service, it);) { TServiceListItem item; item.network_id = nit.getNetworkId(); item.original_network_id = ts.getOriginalNetworkId(); item.transport_stream_id = ts.getTransportStreamId(); item.service_id = Service.getServiceId(); item.service_type = Service.getServiceType(); bool found = false; for(int i = 0; i < data.service_types.Count(); i++) { if ((data.service_types[i].service_id == item.service_id) and (data.service_types[i].network_id == item.network_id)) { found = true; break; } } if (!found) data.service_types.Add(item); } } // end SI::ServiceListDescriptorTag break; case SI::CellFrequencyLinkDescriptorTag: if (type != SCAN_TERRESTRIAL) continue; ParseCellFrequencyLinks(nit.getNetworkId(), d->getData().getData(), data.cell_frequency_links); break; // not implemented in libsi case SI::CellListDescriptorTag: if (type != SCAN_TERRESTRIAL) continue; dlog(0, "SI::CellListDescriptorTag in second loop."); break; case SI::FrequencyListDescriptorTag: break; // already handled case SI::PrivateDataSpecifierDescriptorTag: { SI::PrivateDataSpecifierDescriptor* pds = (SI::PrivateDataSpecifierDescriptor*) d; uint32_t pdsv = (uint32_t) pds->getPrivateDataSpecifier(); if (pdsv != PrivateDataSpecifier) dlog(5, "Second NIT loop: New private data specifier " + IntToHex(pdsv,2)); PrivateDataSpecifier = pdsv; } // PrivateDataSpecifierDescriptorTag break; case 0x80 ... 0xFE: /* Private Descriptors 0x80 ... 0xFE. * Descriptors 0x80 ... 0xFE are not part of the DVB SI specs (for any SI table, not only NIT). * Each of them is defined *only* in the context of it's preceeding private data specifier. * * Including one of those without checking the current value of the private data specifier * is a serious bug. */ if (not wSetup.ParseLCN) break; switch(PrivateDataSpecifier) { case SI_EXT::private_data_specifier_Singapore: { /* 0x19: Draft IDA-MDA TS DVB-T2 IRD i1r2 Mar14 (Singapore) */ switch((unsigned) d->getDescriptorTag()) { case SI_SINGAPORE::LogicalChannelDescriptorTag: { hexdump("SI_SINGAPORE::LogicalChannelDescriptor", d->getData().getData(), d->getLength()); SI_SINGAPORE::LogicalChannelDescriptor* lcd = (SI_SINGAPORE::LogicalChannelDescriptor*) d; SI_SINGAPORE::LogicalChannel LogicalChannel; for(SI::Loop::Iterator it; lcd->LogicalChannels.getNext(LogicalChannel, it);) { if (LogicalChannel.Visible()) { struct TChannelListItem item; item.network_id = nit.getNetworkId(); item.original_network_id = ts.getOriginalNetworkId(); item.transport_stream_id = ts.getTransportStreamId(); item.service_id = LogicalChannel.ServiceId(); item.channel_list_id = 100000; /* v2 list IDs: 0..255 */ item.HD_simulcast = false; item.LCN = LogicalChannel.LCN(); item.LCN_minor = -1; /* invalid */ ChannelListItems.push_back(item); dlog(6, "logical channel" ", ONID:" + IntToStr(item.original_network_id) + ", TSID:" + IntToStr(item.transport_stream_id) + ", SID:" + IntToStr(item.service_id) + ", LID:" + IntToStr(item.channel_list_id) + ", LCN:" + IntToStr(item.LCN)); } } } break; case SI_SINGAPORE::LogicalChannelDescriptorV2Tag: { /* When both Logical Channel Descriptor version 1 and version 2 are broadcasted * within one Original Network ID, the DVB-T2 IRD supporting both descriptors * *shall* only sort according to the version 2 (higher priority). */ hexdump("SI_SINGAPORE::LogicalChannelDescriptorV2", d->getData().getData(), d->getLength()); const unsigned char* C = (d->getData().getData()) + 2; for(int len=d->getLength()-2; len>0; ) { int channel_list_id = *C++; int channel_list_name_length = *C++; if (wSetup.verbosity > 4) { std::string channel_list_name; channel_list_name.reserve(1 + channel_list_name_length); for(int i=0; i 0; item.LCN = ((u8 & 0x3) << 8) | *C++; item.LCN_minor = -1; /* invalid */ if (visible) { dlog(5, "logical channel" ", ONID:" + IntToStr(item.original_network_id) + ", TSID:" + IntToStr(item.transport_stream_id) + ", SID:" + IntToStr(item.service_id) + ", LID:" + IntToStr(item.channel_list_id) + ", LCN:" + IntToStr(item.LCN)); ChannelListItems.push_back(item); } } // LCN loop } // byte loop } // SI_SINGAPORE::LogicalChannelDescriptorV2Tag break; default: hexdump("SI_SINGAPORE unknown descriptor " + IntToHex(d->getDescriptorTag(),2), d->getData().getData(), d->getLength()); } } break; case SI_EXT::private_data_specifier_EACEM: { /* 0x28: CSA-Signalling-Profile3.4 (France) */ switch((unsigned) d->getDescriptorTag()) { case SI_EACEM::LogicalChannelDescriptorTag: /* fall-through */ case SI_EACEM::HdSimulcastLogicalChannelDescriptorTag: { bool HD_simulcast = (int) d->getDescriptorTag() == (int) SI_EACEM::HdSimulcastLogicalChannelDescriptorTag; if (wSetup.verbosity >= 3) { std::string name("LogicalChannelDescriptor"); if (HD_simulcast) name.insert(0, "HdSimulcast"); hexdump("SI_EACEM::" + name, d->getData().getData(), d->getLength()); } SI_EACEM::LogicalChannelDescriptor* lcd = (SI_EACEM::LogicalChannelDescriptor*) d; SI_EACEM::LogicalChannel LogicalChannel; for(SI::Loop::Iterator it; lcd->LogicalChannels.getNext(LogicalChannel, it);) { if (LogicalChannel.Visible()) { struct TChannelListItem item; item.network_id = nit.getNetworkId(); item.original_network_id = ts.getOriginalNetworkId(); item.transport_stream_id = ts.getTransportStreamId(); item.service_id = LogicalChannel.ServiceId(); item.channel_list_id = 100000; /* v2 list IDs: 0..255. (No v2 yet in EACEM, but anyhow) */ item.HD_simulcast = HD_simulcast; item.LCN = LogicalChannel.LCN(); item.LCN_minor = -1; /* invalid */ ChannelListItems.push_back(item); dlog(6, "logical channel" ", ONID:" + IntToStr(item.original_network_id) + ", TSID:" + IntToStr(item.transport_stream_id) + ", SID:" + IntToStr(item.service_id) + ", LID:" + IntToStr(item.channel_list_id) + ", LCN:" + IntToStr(item.LCN)); } } } break; default: hexdump("SI_EACEM unknown descriptor " + IntToHex(d->getDescriptorTag(),2), d->getData().getData(), d->getLength()); } } break; case SI_EXT::private_data_specifier_NorDig: { /* 0x29: NorDig Unified Requirements ver. 3.2 (Denmark, Finland, Iceland, Norway, Sweden, Irland) */ switch((unsigned) d->getDescriptorTag()) { case SI_NORDIG::LogicalChannelDescriptorTag: { hexdump("SI_NORDIG::LogicalChannelDescriptor", d->getData().getData(), d->getLength()); SI_NORDIG::LogicalChannelDescriptor* lcd = (SI_NORDIG::LogicalChannelDescriptor*) d; SI_NORDIG::LogicalChannel LogicalChannel; for(SI::Loop::Iterator it; lcd->LogicalChannels.getNext(LogicalChannel, it);) { if (LogicalChannel.Visible()) { struct TChannelListItem item; item.network_id = nit.getNetworkId(); item.original_network_id = ts.getOriginalNetworkId(); item.transport_stream_id = ts.getTransportStreamId(); item.service_id = LogicalChannel.ServiceId(); item.channel_list_id = 100000; /* v2 list IDs: 0..255 */ item.HD_simulcast = false; item.LCN = LogicalChannel.LCN(); item.LCN_minor = -1; /* invalid */ ChannelListItems.push_back(item); dlog(6, "logical channel" ", ONID:" + IntToStr(item.original_network_id) + ", TSID:" + IntToStr(item.transport_stream_id) + ", SID:" + IntToStr(item.service_id) + ", LID:" + IntToStr(item.channel_list_id) + ", LCN:" + IntToStr(item.LCN) + ","); } } } break; case SI_NORDIG::LogicalChannelDescriptorV2Tag: { /* When both Logical Channel Descriptor version 1 and version 2 are broadcasted * within one Original Network ID, the IRD supporting both descriptors * *shall* only sort according to the version 2 (higher priority). */ hexdump("SI_NORDIG::LogicalChannelDescriptorV2", d->getData().getData(), d->getLength()); const unsigned char* C = (d->getData().getData()) + 2; for(int len=d->getLength()-2; len>0; ) { int channel_list_id = *C++; int channel_list_name_length = *C++; if (wSetup.verbosity > 4) { std::string channel_list_name; channel_list_name.reserve(1 + channel_list_name_length); for(int i=0; i 0; item.LCN = ((u8 & 0x3) << 8) | *C++; item.LCN_minor = -1; /* invalid */ if (visible) { dlog(5, "logical channel" ", ONID:" + IntToStr(item.original_network_id) + ", TSID:" + IntToStr(item.transport_stream_id) + ", SID:" + IntToStr(item.service_id) + ", LID:" + IntToStr(item.channel_list_id) + ", LCN:" + IntToStr(item.LCN)); ChannelListItems.push_back(item); } } // LCN loop } // byte loop } // SI_NORDIG::LogicalChannelDescriptorV2Tag break; default: hexdump("SI_NORDIG unknown descriptor " + IntToHex(d->getDescriptorTag(),2), d->getData().getData(), d->getLength()); } } break; default:; } // switch(PrivateDataSpecifier) break; // 0x80 ... 0xFE, user defined default: dlog(5, " NIT: unknown descriptor tag " + IntToHex(d->getDescriptorTag(),2)); } DeleteNullptr(d); } // end TS descriptor loop } // end TS stream loop // we have all parts of nit seen. if (nit.getSectionNumber() == nit.getLastSectionNumber()) active = false; } TChannel* GetByTransponder(const TChannel* Transponder) { int maxdelta = 500; // kHz. DVB-C 113MHz vs. 114MHz etc. char source = Transponder->Source[0]; if (source == 'S') maxdelta = 2; // MHz. LNB drift else if (source == 'T') maxdelta = 250; // kHz -> France (UK: no longer) if (NewChannels.Count()) { for(int idx = 0; idx < NewChannels.Count(); ++idx) { TChannel* ch = NewChannels[idx]; if (is_nearly_same_frequency(ch, Transponder, maxdelta) && ch->Source == Transponder->Source && ch->TID == Transponder->TID && ch->SID == Transponder->SID) { return (ch); } } } return (NULL); } /******************************************************************************* * cSdtScanner ******************************************************************************/ cSdtScanner::cSdtScanner(cDevice * Parent, TSdtData& Data) : active(true), device(Parent), data(Data), hasSDT(false), anyBytes(false) { data.original_network_id = 0; first_crc32 = 0; Start(); } cSdtScanner::~cSdtScanner() { active = false; wait.Signal(); } void cSdtScanner::Action(void) { int count = 0; int nbytes = 0; unsigned char buffer[4096]; int fd = device->OpenFilter(SI_EXT::PID_SDT, SI_EXT::TABLE_ID_SDT_ACTUAL, 0xFF); while(Running() && active) { if (wait.Wait(10)) { dlog(5, "cSdtScanner: received signal"); break; } if (count++ > 4000) { //40sec dlog(2, "SDT timeout"); break; } else if ((count > 1800) and not(anyBytes)) break; nbytes = device->ReadFilter(fd, buffer, sizeof(buffer)); if (nbytes > 0) { anyBytes = true; Process(buffer, nbytes); } if (hasSDT) break; } device->CloseFilter(fd); fd = -1; active = false; } void cSdtScanner::Process(const unsigned char* Data, int Length) { SI::SDT sdt(Data, false); if (!sdt.CheckCRCAndParse()) return; int len = sdt.getLength(); uint32_t crc32 = Data[len-4] << 24 | Data[len-3] << 16 | Data[len-2] << 8 | Data[len-1]; if (first_crc32 == crc32) { hasSDT = true; return; } if (!first_crc32) first_crc32 = crc32; if (data.original_network_id == 0) data.original_network_id = sdt.getOriginalNetworkId(); if (wSetup.verbosity > 5) hexdump("cSdtScanner", Data, Length); SI::SDT::Service SiSdtService; for(SI::Loop::Iterator it; sdt.serviceLoop.getNext(SiSdtService, it);) { struct sdtservice service; service.transport_stream_id = sdt.getTransportStreamId(); service.original_network_id = sdt.getOriginalNetworkId(); service.service_id = SiSdtService.getServiceId(); service.free_CA_mode = SiSdtService.getFreeCaMode(); service.service_type = 0xFFFF; service.reported = false; SI::Descriptor* d; for(SI::Loop::Iterator it2; (d = SiSdtService.serviceDescriptors.getNext(it2));) { switch((unsigned) d->getDescriptorTag()) { case SI::ServiceDescriptorTag: { SI::ServiceDescriptor* sd = (SI::ServiceDescriptor*) d; char NameBuf[4096]; char ShortNameBuf[4096]; char ProviderNameBuf[4096]; sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf)); char* pn = compactspace(NameBuf); char* ps = compactspace(ShortNameBuf); if (!*ps && (strchr(pn, '>') || strchr(pn, ','))) { char* p = strchr(pn, '>'); // fix for UPC Wien: "name>short name" if (!p) p = strchr(pn, ','); // fix for "Kabel Deutschland": "name, short name" if (p && p > pn) { *p++ = 0; strcpy(ShortNameBuf, skipspace(p)); } } sd->providerName.getText(ProviderNameBuf, sizeof(ProviderNameBuf)); char* pp = compactspace(ProviderNameBuf); service.Name = pn; service.Shortname = ps; service.Provider = pp; service.service_type = sd->getServiceType(); } break; case SI::ComponentDescriptorTag: { /* SI::ComponentDescriptor* cd = (SI::ComponentDescriptor*) d; const unsigned char* p = d->getData().getData(); if (wSetup.verbosity > 4) hexdump("ComponentDescriptor", p, 2 + *(p + 1)); uint8_t stream_content = cd->getStreamContent(); uint8_t stream_content_ext = *(p + 2) >> 4; uint8_t component_type = cd->getComponentType(); uint8_t component_tag = cd->getComponentTag(); std::string ISO_639_language_code = cd->languageCode; std::string text_char; char buf[256]; cd->description.getText(buf, sizeof(buf)); text_char = buf; */ break; } case SI::NVODReferenceDescriptorTag: case SI::BouquetNameDescriptorTag: case SI::MultilingualServiceNameDescriptorTag: case SI::ServiceIdentifierDescriptorTag: case SI::ServiceAvailabilityDescriptorTag: case SI::DefaultAuthorityDescriptorTag: case SI::AnnouncementSupportDescriptorTag: case SI::DataBroadcastDescriptorTag: case SI::TelephoneDescriptorTag: case SI::CaIdentifierDescriptorTag: case SI::PrivateDataSpecifierDescriptorTag: case SI::ContentDescriptorTag: case SI::LinkageDescriptorTag: case 0x80 ... 0xFE: // user defined // break; default: dlog(5, "SDT: unknown descriptor " + IntToHex(d->getDescriptorTag(),2)); } DeleteNullptr(d); } if (service.Name != "") { bool found = false; for(int i = 0; i < data.services.Count(); i++) { if (data.services[i].transport_stream_id == service.transport_stream_id and data.services[i].original_network_id == service.original_network_id and data.services[i].service_id == service.service_id) { found = true; break; } } if (!found) data.services.Add(service); } } } wirbel-at-vdr-portal-wirbelscan-dev-eebef12/scanfilter.h000066400000000000000000000162071520154405700234620ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #pragma once #include #include // uint{8.16,32}_t #include // std::atomic #include // cCondWait #include // cSectionSyncer #include "tlist.h" // TList #include "common.h" // TPid /******************************************************************************* * forward decls ******************************************************************************/ class cDevice; class TChannel; extern int nextTransponders; bool known_transponder(TChannel* newChannel, bool auto_allowed, TChannels* list = nullptr); bool is_nearly_same_frequency(const TChannel* chan_a, const TChannel* chan_b, unsigned delta = 2001); bool is_different_transponder_deep_scan(const TChannel* a, const TChannel* b, bool auto_allowed); TChannel* GetByTransponder(const TChannel* Transponder); void resetLists(void); /******************************************************************************* * class cTransponders ******************************************************************************/ class cTransponders : public TChannels { private: protected: public: bool IsUniqueTransponder(const TChannel* NewTransponder); TChannel* GetByParams(const TChannel* NewTransponder); TChannel* NextTransponder(void); }; struct service { uint16_t transport_stream_id; uint16_t program_map_PID; uint16_t program_number; }; struct TPatData { uint16_t network_PID; TList services; }; struct TPmtData { uint16_t program_map_PID; uint16_t program_number; uint16_t PCR_PID; TPid Vpid; int Tpid; TList Apids; TList Dpids; TList Spids; TList Caids; }; struct TCell { uint16_t network_id; uint16_t cell_id; uint32_t frequency; uint8_t subcellcount; struct { uint8_t cell_id_extension; uint32_t transposer_frequency; } subcells[51]; }; struct TServiceListItem { uint16_t network_id; uint16_t original_network_id; uint16_t transport_stream_id; uint16_t service_id; uint16_t service_type; }; struct TFrequencyListItem { uint16_t network_id; uint32_t frequency; }; struct TChannelListItem { uint16_t network_id; uint16_t original_network_id; uint16_t transport_stream_id; uint16_t service_id; int channel_list_id; bool HD_simulcast; int LCN; int LCN_minor; bool operator <(const TChannelListItem& rhs) const; bool operator==(const TChannelListItem& rhs) const; }; // returns true, if GetLCN() assigned a new LCN to 'c'. bool GetLCN(TChannel* c); struct TNitData { int OrbitalPos; bool West; TList frequency_list; TList cell_frequency_links; TList service_types; TList transport_streams; }; struct sdtservice { uint16_t transport_stream_id; uint16_t original_network_id; uint16_t service_id; uint16_t service_type; bool free_CA_mode; std::string Name; std::string Shortname; std::string Provider; bool reported; }; struct TSdtData { uint16_t original_network_id; TList services; }; /******************************************************************************* * class cPatScanner ******************************************************************************/ class cPatScanner : public ThreadBase { private: class PatSync { private: /* PatSync is the old & down stripped version of cSectionSyncer */ int currentVersion; bool synced; uint8_t sections[32]; void SetSectionFlag(uint8_t Section, bool On) { if (On) sections[Section / 8] |= (1 << (Section % 8)); else sections[Section / 8] &= ~(1 << (Section % 8)); } bool GetSectionFlag(uint8_t Section) { return sections[Section / 8] & (1 << (Section % 8)); } public: PatSync(void) { Reset(); } void Reset(void) { currentVersion = -1; synced = false; memset(sections, 0, sizeof(sections)); } bool Sync(uint8_t Version, int Number, int LastNumber) { if (Version != currentVersion) { Reset(); currentVersion = Version; } if (!synced) { if (Number != 0) return false; else synced = true; } bool Result = !GetSectionFlag(Number); SetSectionFlag(Number, true); return Result; } }; cDevice* device; struct TPatData& PatData; std::atomic isActive; PatSync Sync; std::string s; cCondWait wait; TChannel channel; std::atomic hasPAT; bool anyBytes; protected: virtual void Process(const unsigned char* Data, int Length); virtual void Action(void); public: cPatScanner(cDevice* Parent, struct TPatData& Dest); ~cPatScanner(); bool HasPAT(void) { return hasPAT; }; bool Active(void) { return isActive; }; }; /******************************************************************************* * class cPmtScanner ******************************************************************************/ class cPmtScanner : public ThreadBase { private: cDevice* device; TPmtData* data; std::atomic isActive; std::atomic jobDone; std::string s; cCondWait wait; protected: virtual void Process(const unsigned char* Data, int Length); virtual void Action(void); public: cPmtScanner(cDevice* Parent, TPmtData* Data); ~cPmtScanner(); bool Active(void) { return isActive; }; bool Finished(void) { return jobDone; }; }; /******************************************************************************* * class cNitScanner ******************************************************************************/ class cNitScanner : public ThreadBase { private: std::atomic active; cDevice* device; uint16_t nit; std::string s; cCondWait wait; TNitData& data; uint32_t first_crc32; int type; std::atomic hasNIT; bool west; uint16_t orbital; bool anyBytes; void ParseCellFrequencyLinks(uint16_t network_id, const unsigned char* Data, TList& list); protected: virtual void Process(const unsigned char* Data, int Length); virtual void Action(void); public: cNitScanner(cDevice* Parent, uint16_t network_PID, TNitData& Data, int Type); ~cNitScanner(); bool Active(void) { return (active); }; bool HasNIT(void) { return hasNIT; }; }; /******************************************************************************* * class cSdtScanner ******************************************************************************/ class cSdtScanner : public ThreadBase { private: std::atomic active; cDevice* device; TSdtData& data; std::string s; cCondWait wait; uint32_t first_crc32; std::atomic hasSDT; bool anyBytes; protected: virtual void Process(const unsigned char* Data, int Length); virtual void Action(void); public: cSdtScanner(cDevice* Parent, TSdtData& Data); ~cSdtScanner(); bool Active(void) { return active; }; bool SdtNIT(void) { return hasSDT; }; }; wirbel-at-vdr-portal-wirbelscan-dev-eebef12/scanner.cpp000066400000000000000000001136041520154405700233130ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include #include #include // std::min() #include #include #include "scanner.h" #include "menusetup.h" #include "common.h" #include "satellites.h" #include "scanfilter.h" #include "statemachine.h" #include "countries.h" #include "wirbelscan_services.h" #if VDRVERSNUM < 20301 #error "Your VDR version is too old - STOP." #endif using namespace COUNTRY; extern const char* WIRBELSCAN_VERSION; int initialTransponders; cScanner* Scanner = nullptr; static unsigned int chan_to_freq(int channel, int channellist) { if (channellist == 999) dlog(6, "channellist=" + IntToStr(channellist) + ", base_offset=" + IntToStr(base_offset(channel, channellist)) + ", channel=" + IntToStr(channel) + ", step=" + IntToStr(freq_step(channel, channellist))); if (base_offset(channel, channellist) != -1) // -1 == invalid return (base_offset(channel, channellist) + channel * freq_step(channel, channellist)); return 0; } static int device_is_preferred(TChannel* Channel, std::string name, bool secondGen) { int preferred = 1; // no preferrence /* add other good/bad cards here. */ if (name == "VLSI VES1820") { /* bad working FF dvb-c card, known to have qam256 probs */ preferred = 0; // not preferred } else if (name == "Sony CXD2820R") { /* PCTV 290e known to have qam256 probs. */ /* PCTV 290e doesnt support newer DVB-T2 */ preferred = 0; // not preferred } else if (secondGen) { /* wirbelscan preferres devices which are DVB-{S,C,T}2 */ preferred = 2; // preferred } return preferred; } cDevice* DefaultDevice(TChannel* Channel) { std::string preferred = wSetup.preferred[dmap[*(Channel->Source.c_str())]]; for(int i=0; iPrintTransponder(s); dlog(6, "'" + Channel->Source + "' " + s); // skip ChannelID check in cChannel::Parse() // we just want to find a device here, nothing else. int nid = Channel->NID; int sid = Channel->SID; Channel->NID = 0x2000; Channel->SID = 0x2000; cChannel c; Channel->VdrChannel(c); Channel->NID = nid; Channel->SID = sid; dlog(4, "testing '" + std::string(*c.ToText()) + "'"); for(int i=0; iDeviceName(); if (!dev->ProvidesTransponder(&c)) { dlog(4, "device " + IntToStr(dev->CardIndex()) + " = " + name + " (not usable)"); continue; } if (Channel->Source[0] == 'S' or Channel->Source[0] == 'T') { ch2nd = &c; ch2nd.DelSys = 1; ch2nd.NID = 0x2000; ch2nd.SID = 0x2000; ch2nd.VdrChannel(c); gen2 = dev->ProvidesTransponder(&c); } else gen2 = false; dlog(4, "device " + IntToStr(dev->CardIndex()) + " = " + name); if (device_is_preferred(Channel, name, gen2) >= preferred) { preferred = device_is_preferred(Channel, name, gen2); pref_device = i; } switch(preferred) { case 0: dlog(4, "device known to have probs. usable anyway.."); break; case 1: dlog(4, "device has no gen2 delsys support."); break; case 2: dlog(4, "device has gen2 delsys support."); return dev; default:; } } if (pref_device >= 0) { dev = cDevice::GetDevice(pref_device); return dev; } return nullptr; } /******************************************************************************* * class cScanner ******************************************************************************/ cScanner::cScanner(const char* Description, int Type) : shouldstop(false), single(false), status(0), initialTransponders(0), newTransponders(0), thisChannel(-1), type(Type), dev(nullptr), aChannel(nullptr), StateMachine(nullptr) { user[0] = user[1] = user[2] = 0; Start(); } cScanner::~cScanner(void) { dlog(5, "destroying scanner"); Scanner = nullptr; } void cScanner::SetShouldstop(bool On) { shouldstop = On; if (StateMachine) StateMachine->DoStop(); } bool cScanner::ActionAllowed(void) { return Running() and not shouldstop; } bool cScanner::Active(void) { return Running(); } void cScanner::Progress(void) { extern TChannels ScannedTransponders; extern TChannels NewTransponders; lProgress = 0.5 + (100.0 * (ThisChannel() + ScannedTransponders.Count()) / (NewTransponders.Count() + InitialTransponders())); if (!initialTransponders) lProgress = 0; if (lProgress > 100) lProgress = 100; if (MenuScanning) { MenuScanning->SetCounters(thisChannel + ScannedTransponders.Count(), NewTransponders.Count() + initialTransponders); MenuScanning->SetProgress(lProgress); } } cDvbDevice* cScanner::DvbDevice(void) { return GetDvbDevice(dev); } void cScanner::Action(void) { bool crAuto, modAuto, invAuto, bwAuto, hAuto, tmAuto, gAuto, t2Support, roAuto, s2Support, vsbSupport, qamSupport; bool useNit = true; bool isSatip = false; int f = 0; int mod_parm, modulation_min = 0, modulation_max = 1; int sr_parm, dvbc_symbolrate_min = 0, dvbc_symbolrate_max = 1; int sys_parm = 0, thisSystem = -1; int streamid_parm = 0; int channel, channel_min = 0, channel_max = 133; int offs, freq_offset_min = 0, freq_offset_max = 2; int this_channellist = DVBT_DE, this_bandwidth = 8, this_qam = 999, atsc = ATSC_VSB, dvb; int qam_no_auto = 0, this_atsc = 0; uint16_t frontend_type = SCAN_SATELLITE; std::string country = country_to_short_name(wSetup.CountryIndex); std::string satellite = satellite_to_short_name(wSetup.SatIndex); std::string channelname, shortname; int caps_inversion = 0, caps_qam = 999, caps_hierarchy = 0; int caps_fec = 999, caps_guard_interval = 999, caps_transmission_mode = 999; int caps_s2 = 1; std::string s; resetLists(); thisChannel = 0; initialTransponders = 0; dev = nullptr; status = 1; if (MenuScanning) MenuScanning->SetStatus(status); dlog(3, "wirbelscan version " + std::string(WIRBELSCAN_VERSION) + " @ VDR " + std::string(VDRVERSION)); switch(type) { case SCAN_TRANSPONDER: { using namespace WIRBELSCAN_SERVICE; cUserTransponder* t = new cUserTransponder(&wSetup.user[0]); this_channellist = USERLIST; useNit = t->UseNit(); // disable all loops modulation_min = modulation_max = 0; dvbc_symbolrate_min = dvbc_symbolrate_max = 0; channel_min = channel_max = 1; freq_offset_min = freq_offset_max = 0; single = true; thisChannel = -1; aChannel = new TChannel; switch(t->Type()) { case SCAN_TERRESTRIAL: dvb = frontend_type = SCAN_TERRESTRIAL; aChannel->Source = "T"; aChannel->Frequency = t->Frequency(); aChannel->Inversion = t->Inversion(); aChannel->Bandwidth = t->Bandwidth(); aChannel->FEC = t->FecHP(); aChannel->FEC_low = t->FecLP(); aChannel->Modulation = t->Modulation(); aChannel->DelSys = t->System(); aChannel->Transmission = t->Transmission(); aChannel->Guard = t->Guard(); aChannel->Hierarchy = t->Hierarchy(); break; case SCAN_CABLE: dvb = frontend_type = SCAN_CABLE; aChannel->Source = "C"; aChannel->Frequency = t->Frequency(); aChannel->Modulation = t->Modulation(); aChannel->Symbolrate = t->Symbolrate(); aChannel->Inversion = t->Inversion(); aChannel->FEC = FEC_NONE; aChannel->DelSys = t->System(); break; case SCAN_SATELLITE: dvb = frontend_type = SCAN_SATELLITE; aChannel->Source = sat_list[t->Id()].source_id; aChannel->West = sat_list[t->Id()].west_east_flag == WEST_FLAG; aChannel->OrbitalPos = aChannel->West ? BCDtoDecimal(0x3600) - BCDtoDecimal(sat_list[t->Id()].orbital_position) : BCDtoDecimal(sat_list[t->Id()].orbital_position); aChannel->Frequency = t->Frequency(); aChannel->Symbolrate = t->Symbolrate(); aChannel->Polarization = t->Polarisation() == 0 ? 'H': t->Polarisation() == 1 ? 'V': t->Polarisation() == 2 ? 'L': 'R'; aChannel->FEC = t->FecHP(); aChannel->Modulation = t->Modulation(); aChannel->DelSys = t->System(); aChannel->Rolloff = t->Rolloff(); break; case SCAN_TERRCABLE_ATSC: dvb = frontend_type = SCAN_TERRCABLE_ATSC; //fixme: vsb vs qam here aChannel->Source = "A"; aChannel->Frequency = t->Frequency(); aChannel->Symbolrate = t->Symbolrate(); aChannel->Inversion = t->Inversion(); aChannel->FEC = FEC_NONE; aChannel->Bandwidth = 6; break; default: dlog(0, "unsupported user transponder type."); } if ((dev = GetPreferredDevice(aChannel)) == nullptr) { dlog(0, "No device available - exiting!"); if (MenuScanning) MenuScanning->SetStatus((status = 2)); DeleteNullptr(aChannel); return; } if (std::string(dev->DeviceName()).find("SAT>IP") == std::string::npos) { PrintDvbApi(s); dlog(5, s); switch(t->Type()) { case SCAN_TERRESTRIAL: if (! GetTerrCapabilities(dev, &crAuto, &modAuto, &invAuto, &bwAuto, &hAuto, &tmAuto, &gAuto, &t2Support)) dlog(0, "ERROR: Could not query capabilites."); break; case SCAN_CABLE: if (! GetCableCapabilities(dev, &modAuto, &invAuto)) dlog(0, "ERROR: Could not query capabilites."); break; case SCAN_SATELLITE: if (! GetSatCapabilities(dev, &crAuto, &modAuto, &roAuto, &s2Support)) dlog(0, "ERROR: Could not query capabilites."); break; case SCAN_TERRCABLE_ATSC: if (! GetAtscCapabilities(dev, &modAuto, &invAuto, &vsbSupport, &qamSupport)) dlog(0, "ERROR: Could not query capabilites."); break; default:; } } else { crAuto = 0; modAuto = 0; invAuto = 0; bwAuto = 0; hAuto = 0; tmAuto = 0; gAuto = 0; t2Support = 1; crAuto = 0; modAuto = 0; roAuto = 0; s2Support = 1; } lDeviceName = dev->DeviceName(); dlog(3, "frontend " + lDeviceName); if (MenuScanning) MenuScanning->SetDeviceName(lDeviceName); break; } case SCAN_TERRESTRIAL: { dvb = type; frontend_type = type; choose_country(country, atsc, dvb, frontend_type, this_channellist); /* find a dvb-t2 capable device using *some* channel */ aChannel = new TChannel; aChannel->Name = "???"; aChannel->Source = "T"; aChannel->Frequency = 474; aChannel->Inversion = 999; aChannel->Bandwidth = 8; aChannel->FEC = 23; aChannel->Modulation = 256; aChannel->DelSys = 1; aChannel->Transmission = 8; aChannel->Guard = 999; aChannel->Hierarchy = 0; if ((dev = GetPreferredDevice(aChannel)) == nullptr) { dlog(0, "No DVB-T2 device available - trying fallback to DVB-T"); if (MenuScanning) MenuScanning->SetStatus((status = 3)); aChannel->Modulation = 64; aChannel->DelSys = 0; if ((dev = GetPreferredDevice(aChannel)) == nullptr) { dlog(0, "No device available - exiting!"); if (MenuScanning) MenuScanning->SetStatus((status = 2)); DeleteNullptr(aChannel); return; } } if (std::string(dev->DeviceName()).find("SAT>IP") == std::string::npos) { PrintDvbApi(s); dlog(5, s); if (! GetTerrCapabilities(dev, &crAuto, &modAuto, &invAuto, &bwAuto, &hAuto, &tmAuto, &gAuto, &t2Support)) dlog(0, "ERROR: Could not query capabilites."); } else { crAuto = 0; modAuto = 0; invAuto = 0; bwAuto = 0; hAuto = 0; tmAuto = 0; gAuto = 0; t2Support = 1; } lDeviceName = dev->DeviceName(); dlog(3, "frontend " + lDeviceName); if (MenuScanning) MenuScanning->SetDeviceName(lDeviceName); if (invAuto) caps_inversion = 999; else { dlog(5, "I999 not supported, trying I" + IntToStr(wSetup.DVBT_Inversion) + "."); caps_inversion = wSetup.DVBT_Inversion; } if (modAuto) caps_qam = 999; else { caps_qam = 64; dlog(5, "M999 not supported, trying M" + IntToStr(caps_qam) + "."); } if (tmAuto) caps_transmission_mode = 999; else { const int t[] = {2,8,999,4,1,16,32}; caps_transmission_mode = t[dvbt_transmission_mode(5, this_channellist)]; dlog(5, "T999 not supported, trying T" + IntToStr(caps_transmission_mode) + "."); } if (gAuto) caps_guard_interval = 999; else { caps_guard_interval = 8; dlog(5, "G999 not supported, trying G" + IntToStr(caps_guard_interval) + "."); } if (hAuto) caps_hierarchy = 999; else { caps_hierarchy = 0; dlog(5, "Y999 not supported, trying Y" + IntToStr(caps_hierarchy) + "."); } if (crAuto) caps_fec = 999; else { caps_fec = 0; dlog(5, "C999 not supported, trying C" + IntToStr(caps_fec) + "."); } if (t2Support) dlog(5, "DVB-T2 supported"); else dlog(0, "WARN: you are using an outdated DVB device: no DVB-T2 support."); // use mod as system T/T2 to avoid a further loop. // min = T2, max = T modulation_min = t2Support ? 0 : 1; modulation_max = 1; sys_parm = 0; // use srate as plp 0/1 to avoid a further loop. dvbc_symbolrate_min = 0; dvbc_symbolrate_max = t2Support ? 3 : 0; break; } case SCAN_CABLE: { dvb = type; frontend_type = type; choose_country(country, atsc, dvb, frontend_type, this_channellist); /* find a dvb-c capable device using *some* channel */ aChannel = new TChannel; aChannel->Name = "???"; aChannel->Source = "C"; aChannel->Frequency = 410; aChannel->Modulation = 64; aChannel->Symbolrate = 6900; aChannel->Inversion = 999; aChannel->FEC = 0; aChannel->DelSys = 0; if ((dev = GetPreferredDevice(aChannel)) == nullptr) { dlog(0, "No device available - exiting!"); if (MenuScanning) MenuScanning->SetStatus((status = 2)); DeleteNullptr(aChannel); return; } if (std::string(dev->DeviceName()).find("SAT>IP") == std::string::npos) { PrintDvbApi(s); dlog(5, s); if (! GetCableCapabilities(dev, &modAuto, &invAuto)) dlog(0, "ERROR: Could not query capabilites."); } else { invAuto = 0; modAuto = 0; } lDeviceName = dev->DeviceName(); dlog(3, "frontend " + lDeviceName); if (MenuScanning) MenuScanning->SetDeviceName(lDeviceName); if (invAuto) caps_inversion = 999; else { caps_inversion = wSetup.DVBC_Inversion; dlog(5, "I999 not supported, trying I" + IntToStr(caps_inversion) + "."); } if (modAuto) caps_qam = 999; else { std::string s; for(int i = modulation_min; i <= modulation_max; i++) { if (s.size()) s += ", "; s += "M" + IntToStr(dvbc_modulation(i)); } dlog(5, "M999 not supported, trying " + s + "."); caps_qam = 64; qam_no_auto = 1; } caps_fec = 0; switch(wSetup.DVBC_Symbolrate) { case 0: // auto dvbc_symbolrate_min = 0; dvbc_symbolrate_max = 1; break; case 1 ... 15: dvbc_symbolrate_min = dvbc_symbolrate_max = wSetup.DVBC_Symbolrate - 1; break; default:// all dvbc_symbolrate_min = 0; dvbc_symbolrate_max = 14; break; } break; } case SCAN_SATELLITE: { dvb = type; frontend_type = type; choose_satellite(satellite, this_channellist); /* find a dvb-s2 capable device using *some* channel */ char p[] = {'H','V','L','R'}; aChannel = new TChannel; size_t ch = 0; for(size_t i=0; iSource = sat_list[this_channellist].source_id; aChannel->Frequency = sat_list[this_channellist].items[i].intermediate_frequency; aChannel->Polarization = p[sat_list[this_channellist].items[i].polarization]; if (aChannel->ValidSatIf()) { ch = i; break; } } aChannel->Name = "???"; aChannel->Source = sat_list[this_channellist].source_id; aChannel->West = sat_list[this_channellist].west_east_flag == WEST_FLAG; aChannel->OrbitalPos = aChannel->West ? BCDtoDecimal(0x3600) - BCDtoDecimal(sat_list[this_channellist].orbital_position) : BCDtoDecimal(sat_list[this_channellist].orbital_position); aChannel->Frequency = sat_list[this_channellist].items[ch].intermediate_frequency; aChannel->Polarization = p[sat_list[this_channellist].items[ch].polarization]; aChannel->Symbolrate = 27500; aChannel->FEC = 23; aChannel->Modulation = 5; aChannel->DelSys = 1; aChannel->Rolloff = 35; if ((dev = GetPreferredDevice(aChannel)) == nullptr) { dlog(0, "No DVB-S2 device available - trying fallback to DVB-S"); if (MenuScanning) MenuScanning->SetStatus((status = 3)); aChannel->Modulation = 2; aChannel->DelSys = 0; caps_s2 = 0; if ((dev = GetPreferredDevice(aChannel)) == nullptr) { dlog(0, "No device available - exiting!"); if (MenuScanning) MenuScanning->SetStatus((status = 2)); DeleteNullptr(aChannel); return; } } if (std::string(dev->DeviceName()).find("SAT>IP") == std::string::npos) { PrintDvbApi(s); dlog(5, s); if (! GetSatCapabilities(dev, &crAuto, &modAuto, &roAuto, &s2Support)) dlog(0, "ERROR: Could not query capabilites."); } else { crAuto = 0; modAuto = 0; roAuto = 0; s2Support = 1; } if (caps_s2) s2Support = 1; lDeviceName = dev->DeviceName(); dlog(3, "frontend " + lDeviceName); if (MenuScanning) MenuScanning->SetDeviceName(lDeviceName); caps_inversion = 999; if (crAuto) caps_fec = 999; dlog(5, "DVB-S"); if (s2Support) { dlog(5, "DVB-S2"); caps_s2 = 1; } else caps_s2 = 0; // channel means here: transponder, // last channel == (item_count - 1) since we're counting from 0 channel_max = sat_list[this_channellist].item_count - 1; // disable qam loop modulation_min = modulation_max = 0; // disable symbolrate loop dvbc_symbolrate_min = dvbc_symbolrate_max = 0; // disable freq offset loop freq_offset_min = freq_offset_max = 0; break; } case SCAN_TERRCABLE_ATSC: { int atsc = 1 + wSetup.ATSC_type; frontend_type = type; choose_country(country, atsc, dvb, frontend_type, this_channellist); /* TODO: distinguish between atsc vsb && atsc qam */ aChannel = new TChannel; aChannel->Source = "A"; aChannel->Frequency = 474; aChannel->Modulation = 256; aChannel->Symbolrate = 6900; aChannel->Inversion = 0; aChannel->FEC = 0; aChannel->DelSys = 0; if ((dev = GetPreferredDevice(aChannel)) == nullptr) { dlog(0, "No device available - exiting!"); if (MenuScanning) MenuScanning->SetStatus((status = 2)); DeleteNullptr(aChannel); return; } if (std::string(dev->DeviceName()).find("SAT>IP") == std::string::npos) { PrintDvbApi(s); dlog(5, s); if (! GetAtscCapabilities(dev, &modAuto, &invAuto, &vsbSupport, &qamSupport)) dlog(0, "ERROR: Could not query capabilites."); } else { modAuto = 0; invAuto = 0; vsbSupport = 1; qamSupport = 1; } lDeviceName = dev->DeviceName(); dlog(3, "frontend " + lDeviceName); if (MenuScanning) MenuScanning->SetDeviceName(lDeviceName); if (invAuto) caps_inversion = 999; else { caps_inversion = 0; dlog(5, "I999 not supported, trying I" + IntToStr(caps_inversion) + "."); } if (vsbSupport) dlog(5, "VSB"); if (qamSupport) { dlog(5, "QAM"); caps_qam = 1; } switch (1 + wSetup.ATSC_type) { case ATSC_VSB: modulation_min = modulation_max = ATSC_VSB; break; case ATSC_QAM: modulation_min = modulation_max = ATSC_QAM; break; default: modulation_min = ATSC_VSB; modulation_max = ATSC_QAM; break; } // disable symbolrate loop dvbc_symbolrate_min = dvbc_symbolrate_max = 0; break; } default: dlog(0, "ERROR: Unknown scan type " + IntToStr(type)); return; } // end switch type if (lDeviceName.compare(0, 6, "SAT>IP") == 0) isSatip = true; if (MenuScanning) MenuScanning->SetStatus((status = 1)); //count channels. switch(type) { case SCAN_SATELLITE: case SCAN_TRANSPONDER: initialTransponders = channel_max; break; default: // number depends on offset and symbolrates; counting in nested loops is easiest way. for(mod_parm = modulation_min; mod_parm <= modulation_max; mod_parm++) for(channel = channel_min; channel <= channel_max; channel++) for(offs = freq_offset_min; offs <= freq_offset_max; offs++) for(sr_parm = dvbc_symbolrate_min; sr_parm <= dvbc_symbolrate_max; sr_parm++) { if ((! chan_to_freq(channel, this_channellist)) || (freq_offset(channel, this_channellist, offs) == -1)) continue; ++initialTransponders; } } // switch(type) cChannel c; for(mod_parm = modulation_min; mod_parm <= modulation_max; mod_parm++) { for(channel = channel_min; channel <= channel_max; channel++) { for(offs = freq_offset_min; offs <= freq_offset_max; offs++) for(sr_parm = dvbc_symbolrate_min; sr_parm <= dvbc_symbolrate_max; sr_parm++) { if (!ActionAllowed()) goto stop; switch (type) { case SCAN_TERRESTRIAL: { std::array DelSys = {1,0}; // {T2,T} sys_parm = DelSys[mod_parm]; // NOTE: mod_parm is abused as 'system' if (thisSystem != sys_parm) { thisSystem = sys_parm; std::string Gen2(sys_parm, '2'); dlog(4, "Scanning DVB-T" + Gen2 + "..."); } if (sys_parm == 0) { // DVB-T: no plp, skip plp loop. streamid_parm = 0; sr_parm = dvbc_symbolrate_max; } else { streamid_parm = sr_parm; // NOTE: sr_parm is abused as 'plp' } f = chan_to_freq(channel, this_channellist); if (!f) continue; //skip unused channels if (freq_offset(channel, this_channellist, offs) == -1) continue; //skip this one f += freq_offset(channel, this_channellist, offs); { int bHz = bandwidth(channel, this_channellist), bvdr = bHz / 1000000; if (bHz == 1712000) bvdr = 1712; if (this_bandwidth != bvdr) { if (bvdr < 11) dlog(4, "Scanning " + IntToStr(bvdr) + "MHz frequencies..."); else dlog(4, "Scanning " + FloatToStr(bvdr/1000.0,1,2,false) + "MHz frequencies..."); } this_bandwidth = bvdr; } aChannel->Source = "T"; aChannel->Frequency = f; aChannel->Symbolrate = 0; aChannel->Inversion = caps_inversion; aChannel->Bandwidth = this_bandwidth; aChannel->FEC = caps_fec; aChannel->FEC_low = caps_fec; aChannel->Modulation = caps_qam; aChannel->DelSys = sys_parm; aChannel->Transmission = caps_transmission_mode; aChannel->Guard = caps_guard_interval; aChannel->Hierarchy = caps_hierarchy; aChannel->NID = 0; aChannel->TID = 0; aChannel->SID = 0; aChannel->RID = 0; aChannel->StreamId = streamid_parm; aChannel->SystemId = 0; aChannel->PrintTransponder(s); dlog(4, s); if (known_transponder(aChannel, false)) { dlog(4, FloatToStr(aChannel->Frequency/1e6, 1, 3, false) + "MHz: skipped (already known transponder)"); thisChannel++; Progress(); continue; } } break; case SCAN_CABLE: f = chan_to_freq(channel, this_channellist); if (!f) continue; //skip unused channels if (freq_offset(channel, this_channellist, offs) == -1) continue; //skip this one f += freq_offset(channel, this_channellist, offs); this_qam = caps_qam; if (qam_no_auto > 0) { this_qam = dvbc_modulation(mod_parm); if ((int) aChannel->Modulation != this_qam) dlog(4, "searching M" + IntToStr(this_qam) + "..."); } else if (mod_parm > 0) { continue; // demod supports qam_auto, and we had one loop with QAM_AUTO. } aChannel->Source = "C"; aChannel->Frequency = f / 1000; aChannel->Symbolrate = dvbc_symbolrate(sr_parm) / 1000; aChannel->Inversion = caps_inversion; aChannel->Bandwidth = 999; aChannel->FEC = caps_fec; aChannel->Modulation = this_qam; aChannel->DelSys = 0; aChannel->NID = 0; aChannel->TID = 0; aChannel->SID = 0; aChannel->RID = 0; aChannel->PrintTransponder(s); dlog(4, s); if (known_transponder(aChannel, false)) { dlog(4, FloatToStr(aChannel->Frequency/1e3, 1, 3, false) + "MHz: skipped (already known transponder)"); thisChannel++; Progress(); continue; } break; case SCAN_SATELLITE: { auto& sat = sat_list[this_channellist]; auto& tp = sat.items[channel]; aChannel->Source = sat.source_id; aChannel->Frequency = tp.intermediate_frequency; aChannel->Symbolrate = tp.symbol_rate; aChannel->DelSys = tp.modulation_system == 6 ? 1:0; aChannel->StreamId = tp.stream_id; char p[] = {'H','V','L','R'}; aChannel->Polarization = p[tp.polarization]; int f[] = {0,12,23,34,45,56,67,78,89,999,35,910}; aChannel->FEC = f[tp.fec_inner]; int m[] = {2,16,32,64,128,256,999,10,11,5,6,7,12,0}; aChannel->Modulation = m[tp.modulation_type]; int r[] = {35,20,25,999}; aChannel->Rolloff = r[tp.rolloff]; aChannel->Pilot = 999; aChannel->NID = 0; aChannel->TID = 0; aChannel->SID = 0; aChannel->RID = 0; } if (! aChannel->ValidSatIf()) continue; aChannel->Print(s); dlog(4, s); ///orbital_position = sat_list[this_channellist].orbital_position; ///west_east_flag = sat_list[this_channellist].west_east_flag; if (sat_list[this_channellist].items[channel].modulation_system == 6) { if (not(caps_s2)) { dlog(4, IntToStr(sat_list[this_channellist].items[channel].intermediate_frequency) + ": skipped (no S2 support)"); thisChannel++; Progress(); continue; } } if (known_transponder(aChannel, false)) { dlog(4, FloatToStr(aChannel->Frequency/1e0, 1, 3, false) + ": skipped (already known transponder)"); thisChannel++; continue; } break; case SCAN_TERRCABLE_ATSC: switch(mod_parm) { case ATSC_VSB: this_atsc = 10; f = chan_to_freq(channel, ATSC_VSB); if (!f) continue; //skip unused channels if (freq_offset(channel, ATSC_VSB, offs) == -1) continue; //skip this one f += freq_offset(channel, ATSC_VSB, offs); break; case ATSC_QAM: this_atsc = 256; f = chan_to_freq(channel, ATSC_QAM); if (!f) continue; //skip unused channels if (freq_offset(channel, ATSC_QAM, offs) == -1) continue; //skip this one f += freq_offset(channel, ATSC_QAM, offs); break; default: dlog(0, "unknown atsc modulation id " + IntToStr(mod_parm)); return; } // end switch mod_parm //fixme: vsb vs qam here aChannel->Source = "A"; aChannel->Frequency = f / 1000; aChannel->Symbolrate = dvbc_symbolrate(sr_parm) / 1000; aChannel->Modulation = this_atsc; aChannel->Inversion = caps_inversion; aChannel->FEC = caps_fec; aChannel->DelSys = 0; aChannel->NID = 0; aChannel->TID = 0; aChannel->SID = 0; aChannel->RID = 0; aChannel->PrintTransponder(s); dlog(4, s); if (known_transponder(aChannel, false)) { dlog(4, FloatToStr(aChannel->Frequency/1e6, 1, 3, false) + "MHz M" + IntToStr(this_atsc) + ": skipped (already known transponder)"); thisChannel++; Progress(); continue; } break; case SCAN_TRANSPONDER: aChannel->PrintTransponder(s); dlog(4, s); break; default:; } // end switch type ++thisChannel; lStrength = 0; Progress(); lTransponder = s.c_str(); if (MenuScanning) { MenuScanning->SetTransponder(aChannel); } aChannel->Tested = false; int nid = aChannel->NID; int sid = aChannel->SID; aChannel->NID = 0x2000; aChannel->SID = 0x2000; aChannel->VdrChannel(c); aChannel->NID = nid; aChannel->SID = sid; dev->SwitchChannel(&c, false); { bool lock; if (MenuScanning) MenuScanning->SetStr(0, false); mSleep(wSetup.SignalWaitTime * 1000); if (isSatip or GetFrontendStatus(dev) & FE_HAS_SIGNAL) lock = dev->HasLock(wSetup.LockTimeout * 1000); else lock = false; if (lock) { lStrength = std::min((size_t)dev->SignalStrength(), (size_t)100); if (MenuScanning) MenuScanning->SetStr(lStrength, lock); StateMachine = new cStateMachine(dev, aChannel, useNit, this); while(StateMachine && StateMachine->Active()) mSleep(100); DeleteNullptr(StateMachine); } } if (dev) dev->DetachAllReceivers(); } // end loop sr_parm } // end loop channel } // end loop mod_parm stop: AddChannels(); if (MenuScanning) MenuScanning->SetStatus((status = 0)); if (dev) dev->DetachAllReceivers(); //Channels.ReNumber(); SetShouldstop(true); dlog(3, "leaving scanner"); Cancel(); Scanner = nullptr; } /* Here i cannot avoid anymore dealing with vdrs lists and * channel classes. So the real complicated stuff is here.. */ #include void cScanner::AddChannels(void) { cStateKey WriteState; cChannels* WChannels = (cChannels*) cChannels::GetChannelsWrite(WriteState, 30000); extern TChannels NewChannels; if (!WChannels) return; for(int i = 0; i < WChannels->Count(); i++) { const cChannel* ch = WChannels->Get(i); TChannel* newCh = nullptr; int source = 0; // is 'ch' known in NewChannels? for(int idx = 0; idx < NewChannels.Count(); idx++) { if (!source) source = cSource::FromString(NewChannels[idx]->Source.c_str()); if (ch->Nid() != NewChannels[idx]->ONID or ch->Tid() != NewChannels[idx]->TID or ch->Sid() != NewChannels[idx]->SID or ch->Source() != cSource::FromString(NewChannels[idx]->Source.c_str())) continue; // this channel is already known. newCh = NewChannels[idx]; break; } // existing channel not found by IDs if (wSetup.scan_remove_invalid and !newCh and ch->Source() == source) { dlog(4, "remove invalid channel '" + std::string(*ch->ToText()) + "'"); WChannels->Del((cChannel*) ch); i--; continue; } // update existing if (wSetup.scan_update_existing and newCh) { std::string s; newCh->Print(s); if (s != *ch->ToText()) { ((cChannel*) ch)->Parse(s.c_str()); dlog(4, "updated channel '" + std::string(*ch->ToText()) + "'"); } } } if (wSetup.scan_append_new) for(int i=0; iFirst(); old; old = WChannels->Next(old)) { if (old->Nid() == n->ONID and old->Tid() == n->TID and old->Sid() == n->SID and *cSource::ToString(old->Source()) == n->Source) { break; } } if (!old) { std::string s; cChannel* c = new cChannel; n->Print(s); c->Parse(s.c_str()); dlog(4, "Add channel '" + s + "'"); WChannels->Add(c); } } WChannels->ReNumber(); WriteState.Remove(); } wirbel-at-vdr-portal-wirbelscan-dev-eebef12/scanner.h000066400000000000000000000022711520154405700227550ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #pragma once #include class cDevice; class cDvbDevice; class TChannel; class cStateMachine; class cScanner : public ThreadBase { private: bool shouldstop; bool single; size_t user[3]; int status; int initialTransponders; int newTransponders; int thisChannel; int type; cDevice* dev; TChannel* aChannel; cStateMachine* StateMachine; protected: virtual void Action(void); void AddChannels(void); public: cScanner(const char* Description, int Type); virtual ~cScanner(void); virtual void SetShouldstop(bool On); virtual bool ActionAllowed(void); bool Active(void); int Status(void) { return status; }; int DvbType(void) { return type; }; int InitialTransponders(void) { return initialTransponders; }; int ThisChannel(void) { return thisChannel; }; void Progress(void); cDvbDevice* DvbDevice(void); }; wirbel-at-vdr-portal-wirbelscan-dev-eebef12/si_ext.cpp000066400000000000000000000132541520154405700231550ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include // std::uint32_t #include #include "scanfilter.h" #include "si_ext.h" struct descr_generic { u_char descriptor_tag :8; u_char descriptor_length :8; }; struct item_logical_channel { u_char service_id_hi :8; u_char service_id_lo :8; #if BYTE_ORDER == BIG_ENDIAN u_char visible_service_flag :1; u_char logical_channel_number_hi :7; #else u_char logical_channel_number_hi :7; u_char visible_service_flag :1; #endif u_char logical_channel_number_lo :8; }; /******************************************************************************/ namespace SI_EACEM { /******************************************************************************* * SI_EACEM::LogicalChannelDescriptor, IEC/CENELEC 62216 ******************************************************************************/ /* SYNTAX: * logical_channel_descriptor () { * descriptor_tag 8 uimsbf, 0x83 (HdSimulcast: 0x88) * descriptor_length 8 uimsbf * for(i=0;i(); LogicalChannels.setData(data+sizeof(descr_generic), getLength()-sizeof(descr_generic)); LogicalChannel lc; for(SI::Loop::Iterator it; LogicalChannels.getNext(lc, it);) { lc.HdSimulcast = (head->descriptor_tag == HdSimulcastLogicalChannelDescriptorTag); } } int LogicalChannel::ServiceId() const { return HILO(s->service_id); } int LogicalChannel::LCN() const { return ((uint16_t) HILO(s->logical_channel_number) ) & 0x3FF; } bool LogicalChannel::Visible() const { return s->visible_service_flag > 0; } int LogicalChannel::getLength() { return sizeof(item_logical_channel); } void LogicalChannel::Parse() { s = data.getData(); } } // end of namespace SI_EACEM /******************************************************************************/ namespace SI_NORDIG { /******************************************************************************* * SI_NORDIG::LogicalChannelDescriptor, NorDig Unified Requirements v3.2 ******************************************************************************/ /* SYNTAX: * logical_channel_descriptor () { * descriptor_tag 8 uimsbf, 0x83 * descriptor_length 8 uimsbf * for(i=0;ilogical_channel_number) ) & 0x3FFF; } /******************************************************************************* * SI_NORDIG::LogicalChannelDescriptor (Version 2) ******************************************************************************/ /* The older version of the NorDig Logical Channel Descriptor is in some NorDig Networks * replaced by the newer version 2 below. * The NorDig IRD shall at least store the sorting from one of the available Channel lists * as default, but it is recommended that the NorDig IRD store all the transmitted * Channel Lists sorting that matches the IRD’s country code settings (especially for * IRDs that are not letting the user choose list during installation). * When several Channel Lists are available from same network (original network id) for * the IRD during first time installation (or complete re-installation), the NorDig IRD * shall choose the channel list as the default one with following priority: * * 1. The list with same country code as the IRD’s user preference setting’s * country code. If several lists available with same matching country code, the * IRD shall choose the one with lowest list_id value OR let the viewer choose * from a list, (typically using the channel_list_name). * * 2. If no Channel list has a country code that matches the user preference * setting’s country code, the NorDig IRD shall let the viewer choose from a * list (recommended) OR choose the one with lowest list_id value. * * When broadcasting both LCD version 1 and version 2 within one Original Network ID, * the NorDig IRD supporting both descriptors *shall* only sort according to the * version 2 (i.e. NorDig LCD version 2 has higher priority). */ /* SYNTAX: * logical_channel_descriptor () { * descriptor_tag 8 uimsbf, 0x87 * descriptor_length 8 uimsbf * for(i=0;i #include #include /******************************************************************************* * class LogicalChannel ******************************************************************************/ class LogicalChannel : public SI::LoopElement { public: virtual int ServiceId() const { return -1; } virtual int LCN() const { return -1; } virtual bool Visible() const { return false; } virtual int getLength() { return 0; } protected: virtual void Parse() {} }; /******************************************************************************* * forward decls ******************************************************************************/ namespace SI_EACEM { class LogicalChannel; } namespace SI_EACEM { class LogicalChannelDescriptor; } namespace SI_NORDIG { class LogicalChannel; } struct item_logical_channel; /******************************************************************************/ namespace SI_SINGAPORE { /* 0x19 */ enum DescriptorTag { LogicalChannelDescriptorTag = 0x83, LogicalChannelDescriptorV2Tag = 0x87, }; typedef SI_EACEM::LogicalChannel LogicalChannel; typedef SI_EACEM::LogicalChannelDescriptor LogicalChannelDescriptor; } // end of namespace SI_SINGAPORE /******************************************************************************/ namespace SI_EACEM { /* 0x28 */ enum DescriptorTag { LogicalChannelDescriptorTag = 0x83, HdSimulcastLogicalChannelDescriptorTag = 0x88, }; class LogicalChannel : public ::LogicalChannel { public: LogicalChannel(){} bool HdSimulcast; int ServiceId() const; virtual int LCN() const; bool Visible() const; int getLength(); protected: void Parse(); const item_logical_channel* s; }; class LogicalChannelDescriptor : public SI::Descriptor { public: SI::StructureLoop LogicalChannels; protected: void Parse(); }; typedef LogicalChannelDescriptor HdSimulcastLogicalChannelDescriptor; } // end of namespace SI_EACEM /******************************************************************************/ namespace SI_NORDIG { /* 0x29 */ enum DescriptorTag { LogicalChannelDescriptorTag = 0x83, LogicalChannelDescriptorV2Tag = 0x87, }; class LogicalChannel : public SI_EACEM::LogicalChannel { public: int LCN() const; }; class LogicalChannelDescriptor : public SI::Descriptor { public: SI::StructureLoop LogicalChannels; protected: void Parse(); }; } // end of namespace SI_NORDIG wirbel-at-vdr-portal-wirbelscan-dev-eebef12/statemachine.cpp000066400000000000000000000722061520154405700243310ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include #include // std::min() #include #include "tlist.h" #include "scanner.h" #include "statemachine.h" #include "scanfilter.h" #include "common.h" #include "menusetup.h" #include "si_ext.h" extern TChannels NewChannels; extern TChannels NewTransponders; extern TChannels ScannedTransponders; /******************************************************************************* * class cScanReceiver * a dummy receiver. Might be used real later. ******************************************************************************/ class cScanReceiver : public cReceiver, public ThreadBase { private: protected: virtual void Activate(bool On); virtual void Receive(const uchar* Data, int Length); virtual void Action(void); public: cScanReceiver(); virtual ~cScanReceiver(); }; cScanReceiver::cScanReceiver() : cReceiver(nullptr, 99) {} cScanReceiver::~cScanReceiver() { cReceiver::Detach(); } void cScanReceiver::Receive(const uchar* Data, int Length) {} void cScanReceiver::Action(void) { while(Running()) std::this_thread::sleep_for(std::chrono::milliseconds(5)); }; void cScanReceiver::Activate(bool On) { if (On) Start(); else Cancel(); }; /******************************************************************************* * class cStateMachine ******************************************************************************/ cStateMachine::cStateMachine(cDevice* Dev, TChannel* InitialTransponder, bool UseNit, void* Parent) : state(eStart), lastState(eStop), initial(InitialTransponder), dev(Dev), dvbdevice(nullptr), stop(false), useNit(UseNit), parent(Parent) { Start(); } cStateMachine::~cStateMachine(void) { stop = true; } void cStateMachine::DoStop(void) { stop = true; } bool cStateMachine::Active(void) { return Running(); } // store state in lastState if modified and report new state void cStateMachine::Report(eState State) { const char* stateMsg[] = { // be careful here: same order as eState "------- Start -------", "------- Stop -------", "------- Tune -------", "------- NextTransponder -------", "------- DetachReceiver -------", "------- ScanPat -------", "------- ScanPmt -------", "------- ScanNit -------", "------- ScanSdt -------", "------- ScanEit -------", "------- ERROR IN STATEMACHINE, UNKNOWN STATE. -------", "------- AddChannels -------", "------- GetTables -------", "------- NULL -------" }; if ((State != lastState) and (wSetup.verbosity > 4)) dlog(5, stateMsg[lastState = State]); }; TSdtData SdtData; TNitData NitData; // v 0.0.5, StateMachine itself void cStateMachine::Action(void) { TChannel* Transponder = nullptr; cScanReceiver* aReceiver = nullptr; cPatScanner* PatScanner = nullptr; cNitScanner* NitScanner = nullptr; cSdtScanner* SdtScanner = nullptr; eState newState = state; cScanner* scanner = (cScanner*)parent; int dvbtype = scanner->DvbType(); dvbdevice = scanner->DvbDevice(); std::string s; TList PmtScanners; struct TPatData PatData; TList PmtData; bool pmtstart = false; bool tblstart = false; while (Running() && !stop) { mSleep(10); Report(state); switch(state) { case eStart: Transponder = initial; if (known_transponder(Transponder, false, &ScannedTransponders)) newState = eStop; else newState = eTune; break; case eStop: stop = true; goto DIRECT_EXIT; break; case eTune: { Transponder->PrintTransponder(s); dlog(4, "tuning to " + s); lTransponder = s; if (MenuScanning) MenuScanning->SetTransponder(Transponder); //scanner->SetCounter(ScannedTransponders.Count(), NewTransponders.Count()); if (MenuScanning) MenuScanning->SetStr(0, false); cChannel c; // skip ChannelID check in cChannel::Parse() // we just want to tune here, nothing else. int nid = Transponder->NID; int sid = Transponder->SID; Transponder->NID = 0x2000; Transponder->SID = 0x2000; Transponder->VdrChannel(c); dev->SwitchChannel(&c, false); Transponder->NID = nid; Transponder->SID = sid; aReceiver = new cScanReceiver(); dev->AttachReceiver(aReceiver); TChannel* tp = new TChannel; tp->CopyTransponderData(Transponder); tp->Tested = true; tp->PrintTransponder(s); mSleep(wSetup.SignalWaitTime * 1000); if (dev->HasLock(wSetup.LockTimeout * 1000)) { dev->SetOccupied(90); dlog(4, "lock."); tp->Tunable = true; newState = eScanPat; } else { dev->Detach(aReceiver); DeleteNullptr(aReceiver); tp->Tunable = false; newState = eNextTransponder; } dlog(4, "ScannedTransponders.Add: '" + s + "'"); ScannedTransponders.Add(tp); lStrength = std::min((size_t)dev->SignalStrength(), (size_t)100); if (MenuScanning) MenuScanning->SetStr(lStrength, dev->HasLock(1)); break; } case eNextTransponder: { nextTransponders = NewTransponders.Count(); //scanner->SetCounter(ScannedTransponders.Count(), NewTransponders.Count()); if (! useNit) goto DIRECT_EXIT; newState = eStop; if (NewTransponders.Count()) { Transponder = nullptr; for(int i = 0; i < NewTransponders.Count(); i++) { if (NewTransponders[i]->Tested) continue; NewTransponders[i]->Tested = true; Transponder = NewTransponders[i]; newState = eTune; break; } } lProgress = 0.5 + (100.0 * (scanner->ThisChannel() + ScannedTransponders.Count()) / (NewTransponders.Count() + scanner->InitialTransponders())); if (MenuScanning) { MenuScanning->SetCounters(scanner->ThisChannel() + ScannedTransponders.Count(), NewTransponders.Count() + scanner->InitialTransponders()); MenuScanning->SetProgress(lProgress); } break; } case eDetachReceiver: if (dev) { dev->DetachAllReceivers(); dev->SetOccupied(0); } DeleteNullptr(aReceiver); if (stop) newState = eStop; else newState = eNextTransponder; break; case eScanPat: if (PatScanner == nullptr) { PatScanner = new cPatScanner(dev, PatData); mSleep(100); } else if (!PatScanner->Active()) { pmtstart = true; bool hasPAT = PatScanner->HasPAT(); DeleteNullptr(PatScanner); if (stop or !hasPAT or !PatData.services.Count()) newState = eDetachReceiver; else { dlog(4, "searching " + IntToStr(PatData.services.Count()) + " services"); newState = eScanPmt; } break; } break; case eScanPmt: if (pmtstart) { pmtstart = false; PmtScanners.Clear(); PmtData.Clear(); for(int i = 0; i < PatData.services.Count(); i++) { TPmtData* d = new TPmtData; d->program_map_PID = PatData.services[i].program_map_PID; PmtData.Add(d); cPmtScanner* p = new cPmtScanner(dev, PmtData[i]); PmtScanners.Add(p); } } else { // run up to 16 filters in parallel; up to 32 should be safe. int activePmts = 0; int finished = 0; for(int i = 0; i < PmtScanners.Count() and !stop; i++) { cPmtScanner* p = (cPmtScanner*) PmtScanners[i]; if (p->Finished()) { finished++; continue; } if (p->Active()) { if (++activePmts > 16) break; } else { p->Start(); if (++activePmts > 16) break; } } if (finished < PmtScanners.Count()) break; for(int i=0; iOrbitalPos; NitData.West = initial->West; NitScanner = new cNitScanner(dev, PatData.network_PID, NitData, dvbtype); SdtScanner = new cSdtScanner(dev, SdtData); } else { if (!NitScanner->Active() and !SdtScanner->Active()) { DeleteNullptr(NitScanner); DeleteNullptr(SdtScanner); if (stop) newState = eDetachReceiver; else newState = eAddChannels; } if (time(0) != tm) { if (MenuScanning) MenuScanning->SetProgress(lProgress); tm = time(0); } } } break; case eAddChannels: { if (wSetup.verbosity > 4) { for(int i = 0; i < PmtData.Count(); i++) dlog(0, "PMT " + IntToStr(PmtData[i]->program_map_PID) + ": program_number = " + IntToStr(PmtData[i]->program_number) + "; Vpid = " + IntToStr(PmtData[i]->Vpid.PID) + " (" + IntToStr(PmtData[i]->PCR_PID) + "); Tpid = " + IntToStr(PmtData[i]->Tpid) + "; Apid = " + IntToStr(PmtData[i]->Apids.Count()?PmtData[i]->Apids[0].PID:0) + "; Dpid = " + IntToStr(PmtData[i]->Dpids.Count()?PmtData[i]->Dpids[0].PID:0)); for(int i = 0; i < SdtData.services.Count(); i++) { if (SdtData.services[i].reported) continue; SdtData.services[i].reported = true; dlog(0, "SDT: ONID = " + IntToStr(SdtData.services[i].original_network_id) + ", TID = " + IntToStr(SdtData.services[i].transport_stream_id) + ", SID = " + IntToStr(SdtData.services[i].service_id) + ", FreeCA = " + IntToStr(SdtData.services[i].free_CA_mode) + ", Name = '" + SdtData.services[i].Name + "'"); } for(int i = 0; i < NitData.transport_streams.Count(); i++) { if (NitData.transport_streams[i]->reported) continue; NitData.transport_streams[i]->reported = true; NitData.transport_streams[i]->PrintTransponder(s); std::string is_wrong; if (abs(NitData.transport_streams[i]->OrbitalPos - initial->OrbitalPos) > 5) is_wrong = "WRONG SATELLITE: "; dlog(0, "NIT: " + is_wrong + "'" + s + "'" + ", NID = " + IntToStr(NitData.transport_streams[i]->NID) + ", ONID = " + IntToStr(NitData.transport_streams[i]->ONID) + ", TID = " + IntToStr(NitData.transport_streams[i]->TID)); if (NitData.transport_streams[i]->Source == "T" and NitData.transport_streams[i]->DelSys == 1) { for(int c=0; ccells.Count(); c++) { for(int cf=0; cfcells[c].num_center_frequencies; cf++) dlog(0, " center" + IntToStr(c+1) + " = " + IntToStr(NitData.transport_streams[i]->cells[c].center_frequencies[cf]) + " (cell_id " + IntToStr(NitData.transport_streams[i]->cells[c].cell_id) + ")"); for(int tf=0; tfcells[c].num_transposers; tf++) dlog(0, " transposer" + IntToStr(tf+1) + " = " + IntToStr(NitData.transport_streams[i]->cells[c].transposers[tf].transposer_frequency) + " (cell_id_extension " + IntToStr(NitData.transport_streams[i]->cells[c].transposers[tf].cell_id_extension) + ")"); } } } } // PAT: transport_stream_id, network_pid (0x10), program_map_PIDs // PMT: program_number(service_id), PCR_PID, [stream_type, elementary_PID] // NIT: network_id, [transport_stream_id, original_network_id] // SDT: transport_stream_id, original_network_id, [service_id, free_CA_mode] Transponder->TID = PatData.services[0].transport_stream_id; if (SdtData.original_network_id) // update onid, if sdt found. Transponder->ONID = SdtData.original_network_id; for(int i = 0; i < NitData.transport_streams.Count(); i++) { if ((NitData.transport_streams[i]->NID == Transponder->NID or NitData.transport_streams[i]->ONID == Transponder->ONID) and NitData.transport_streams[i]->TID == Transponder->TID) { uint32_t f = Transponder->Frequency; uint32_t center_freq = NitData.transport_streams[i]->Frequency; Transponder->CopyTransponderData(NitData.transport_streams[i]); if ((center_freq < 100000000) or (center_freq > 858000000) or (abs((int)center_freq - (int)f) > 2000000)) Transponder->Frequency = f; break; } } for(int i = 0; i < PmtData.Count(); i++) { TChannel* n = new TChannel; n->CopyTransponderData(Transponder); n->NID = Transponder->NID; n->ONID = Transponder->ONID; n->TID = Transponder->TID; n->SID = PmtData[i]->program_number; n->VPID.PID = PmtData[i]->Vpid.PID; n->VPID.Type = PmtData[i]->Vpid.Type; n->VPID.Lang = PmtData[i]->Vpid.Lang; n->PCR = PmtData[i]->PCR_PID; n->TPID = PmtData[i]->Tpid; n->APIDs = PmtData[i]->Apids; n->DPIDs = PmtData[i]->Dpids; n->SPIDs = PmtData[i]->Spids; n->CAIDs = PmtData[i]->Caids; n->PMT = PmtData[i]->program_map_PID; if (!n->VPID.PID and !n->APIDs.Count() and !n->DPIDs.Count()) { delete n; continue; } for(int j = 0; j < SdtData.services.Count(); j++) { if (n->TID == SdtData.services[j].transport_stream_id and n->SID == SdtData.services[j].service_id) { n->Name = SdtData.services[j].Name; n->Shortname = SdtData.services[j].Shortname; n->Provider = SdtData.services[j].Provider; n->free_CA_mode = SdtData.services[j].free_CA_mode; n->service_type = SdtData.services[j].service_type; n->ONID = SdtData.services[j].original_network_id; break; } } if (n->service_type == SI_EXT::Teletext_service or n->service_type == SI_EXT::DVB_SRM_service or n->service_type == SI_EXT::mosaic_service or n->service_type == SI_EXT::data_broadcast_service or n->service_type == SI_EXT::reserved_Common_Interface_Usage_EN50221 or n->service_type == SI_EXT::RCS_Map_EN301790 or n->service_type == SI_EXT::RCS_FLS_EN301790 or n->service_type == SI_EXT::DVB_MHP_service or n->service_type == SI_EXT::H264_AVC_codec_mosaic_service) { dlog(5, "skip service " + IntToStr(n->SID) + " '" + n->Name + "' (no Audio/Video)"); continue; } #define PMT_ALL (SCAN_TV | SCAN_RADIO | SCAN_SCRAMBLED | SCAN_FTA) if ((wSetup.scanflags & PMT_ALL) != PMT_ALL and n->service_type < 0xFFFF) { if ((wSetup.scanflags & SCAN_SCRAMBLED) != SCAN_SCRAMBLED and n->free_CA_mode) { dlog(5, "skip service " + IntToStr(n->SID) + " '" + n->Name + "' (encrypted)"); continue; } if ((wSetup.scanflags & SCAN_FTA) != SCAN_FTA and !n->free_CA_mode) { dlog(5, "skip service " + IntToStr(n->SID) + " '" + n->Name + "' (FTA)"); continue; } if ((wSetup.scanflags & SCAN_TV) != SCAN_TV) { if (n->service_type == SI_EXT::digital_television_service or n->service_type == SI_EXT::digital_television_NVOD_reference_service or n->service_type == SI_EXT::digital_television_NVOD_timeshifted_service or n->service_type == SI_EXT::MPEG2_HD_digital_television_service or n->service_type == SI_EXT::H264_AVC_SD_digital_television_service or n->service_type == SI_EXT::H264_AVC_SD_NVOD_timeshifted_service or n->service_type == SI_EXT::H264_AVC_SD_NVOD_reference_service or n->service_type == SI_EXT::H264_AVC_HD_digital_television_service or n->service_type == SI_EXT::H264_AVC_HD_NVOD_timeshifted_service or n->service_type == SI_EXT::H264_AVC_HD_NVOD_reference_service or n->service_type == SI_EXT::H264_AVC_frame_compat_plano_stereoscopic_HD_digital_television_service or n->service_type == SI_EXT::H264_AVC_frame_compat_plano_stereoscopic_HD_NVOD_timeshifted_service or n->service_type == SI_EXT::H264_AVC_frame_compat_plano_stereoscopic_HD_NVOD_reference_service or n->service_type == SI_EXT::HEVC_digital_television_service) { dlog(5, "skip service " + IntToStr(n->SID) + " '" + n->Name + "' (tv)"); continue; } } if ((wSetup.scanflags & SCAN_RADIO) != SCAN_RADIO) { if (n->service_type == SI_EXT::digital_radio_sound_service or n->service_type == SI_EXT::FM_radio_service or n->service_type == SI_EXT::advanced_codec_digital_radio_sound_service) { dlog(5, "skip service " + IntToStr(n->SID) + " '" + n->Name + "' (radio)"); continue; } } } if (wSetup.verbosity > 4) { n->Print(s); dlog(4, "NewChannels.Add: '" + s + "'"); } else { if (n->Name != "???") dlog(0, n->Name); } NewChannels.Add(n); if (MenuScanning) MenuScanning->SetChan(NewChannels.Count()); } for(int i = 0; i < NewChannels.Count(); i++) { if (NewChannels[i]->Name != "???") continue; for(int j = 0; j < SdtData.services.Count(); j++) { if (NewChannels[i]->TID == SdtData.services[j].transport_stream_id and /*NewChannels[i]->NID == SdtData.services[j].original_network_id and*/ NewChannels[i]->SID == SdtData.services[j].service_id) { NewChannels[i]->Name = SdtData.services[j].Name; NewChannels[i]->Shortname = SdtData.services[j].Shortname; NewChannels[i]->Provider = SdtData.services[j].Provider; NewChannels[i]->free_CA_mode = SdtData.services[j].free_CA_mode; NewChannels[i]->Print(s); dlog(5, "Update: '" + s + "'"); break; } } } for(int i = 0; i < NitData.transport_streams.Count(); i++) { if (abs(NitData.transport_streams[i]->OrbitalPos - initial->OrbitalPos) > 5) continue; if (!known_transponder(NitData.transport_streams[i], true)) { TChannel* tp = new TChannel; tp->CopyTransponderData(NitData.transport_streams[i]); tp->NID = NitData.transport_streams[i]->NID; tp->ONID = NitData.transport_streams[i]->ONID; tp->TID = NitData.transport_streams[i]->TID; tp->PrintTransponder(s); dlog(4, "NewTransponders.Add: '" + s + "'" + ", NID = " + IntToStr(tp->NID) + ", TID = " + IntToStr(tp->TID)); NewTransponders.Add(tp); } if (NitData.transport_streams[i]->Source == "T" and NitData.transport_streams[i]->DelSys == 1) { for(int c = 0; c < NitData.transport_streams[i]->cells.Count(); c++) { for(int cf = 0; cf < NitData.transport_streams[i]->cells[c].num_center_frequencies; cf++) { TChannel* tp = new TChannel; tp->CopyTransponderData(NitData.transport_streams[i]); tp->NID = NitData.transport_streams[i]->NID; tp->TID = NitData.transport_streams[i]->TID; tp->Frequency = NitData.transport_streams[i]->cells[c].center_frequencies[cf]; if (!known_transponder(tp, true)) { tp->PrintTransponder(s); dlog(4, "NewTransponders.Add: '" + s + "'" + ", NID = " + IntToStr(tp->NID) + ", TID = " + IntToStr(tp->TID)); NewTransponders.Add(tp); } else delete tp; } for(int tf = 0; tf < NitData.transport_streams[i]->cells[c].num_transposers; tf++) { TChannel* tp = new TChannel; tp->CopyTransponderData(NitData.transport_streams[i]); tp->NID = NitData.transport_streams[i]->NID; tp->TID = NitData.transport_streams[i]->TID; tp->Frequency = NitData.transport_streams[i]->cells[c].transposers[tf].transposer_frequency; if (!known_transponder(tp, true)) { tp->PrintTransponder(s); dlog(4, "NewTransponders.Add: '" + s + "'" + ", NID = " + IntToStr(tp->NID) + ", TID = " + IntToStr(tp->TID)); NewTransponders.Add(tp); } else delete tp; } } } } for(int i = 0; i < NitData.cell_frequency_links.Count(); i++) { TChannel t; if (wSetup.verbosity > 5) dlog(0, "NIT: cell_id " + IntToStr (NitData.cell_frequency_links[i].cell_id) + ", frequency " + FloatToStr(NitData.cell_frequency_links[i].frequency/1e6, 7, 3, false) + "MHz network_id " + IntToStr (NitData.cell_frequency_links[i].network_id)); t.Source = 'T'; t.Frequency = NitData.cell_frequency_links[i].frequency; t.Bandwidth = t.Frequency <= 226500000 ? 7 : 8; t.Inversion = 999; t.FEC = 999; t.FEC_low = 999; t.Modulation = 999; t.Transmission = 999; t.Guard = 999; t.Hierarchy = 999; t.DelSys = 0; if (!known_transponder(&t, true)) { TChannel* n = new TChannel; n->CopyTransponderData(&t); n->PrintTransponder(s); dlog(4, "NewTransponders.Add: '" + s + "'" + ", NID = " + IntToStr(n->NID) + ", TID = " + IntToStr(n->TID)); NewTransponders.Add(n); } t.DelSys = 1; if (!known_transponder(&t, true)) { TChannel* n = new TChannel; n->CopyTransponderData(&t); n->PrintTransponder(s); dlog(4, "NewTransponders.Add: '" + s + "'" + ", NID = " + IntToStr(n->NID) + ", TID = " + IntToStr(n->TID)); NewTransponders.Add(n); } for(int j = 0; j < NitData.cell_frequency_links[i].subcellcount; j++) { dlog(5, "NIT: cell_id_extension " + IntToStr(NitData.cell_frequency_links[i].subcells[j].cell_id_extension) + ", frequency " + FloatToStr(NitData.cell_frequency_links[i].subcells[j].transposer_frequency/1e6, 7, 3, false) + "MHz"); t.Frequency = NitData.cell_frequency_links[i].subcells[j].transposer_frequency; t.Bandwidth = t.Frequency <= 226500000 ? 7 : 8; t.DelSys = 0; if (!known_transponder(&t, true)) { TChannel* tp = new TChannel; tp->CopyTransponderData(&t); tp->PrintTransponder(s); dlog(4, "NewTransponders.Add: '" + s + "'" + ", NID = " + IntToStr(tp->NID) + ", TID = " + IntToStr(tp->TID)); NewTransponders.Add(tp); } t.DelSys = 1; if (!known_transponder(&t, true)) { TChannel* tp = new TChannel; tp->CopyTransponderData(&t); tp->PrintTransponder(s); dlog(4, "NewTransponders.Add: '" + s + "'" + ", NID = " + IntToStr(tp->NID) + ", TID = " + IntToStr(tp->TID)); NewTransponders.Add(tp); } } } for(int i = 0; i < NewChannels.Count(); i++) { if (NewChannels[i]->LCN == -1 and GetLCN(NewChannels[i]) and wSetup.verbosity > 4) { std::string s; s = "assigned LCN: " + FrontFill(IntToStr(NewChannels[i]->LCN),4); if (NewChannels[i]->LCN_minor > -1) s += "." + IntToStr(NewChannels[i]->LCN_minor); s += " = (SID:ONID:TID) " + IntToStr(NewChannels[i]->SID ) + ":" + IntToStr(NewChannels[i]->ONID) + ":" + IntToStr(NewChannels[i]->TID ); dlog(5, s); } } // delete data from current tp PatData.network_PID = 0x10; PatData.services.Clear(); for(int i=0; i /******************************************************************************* * forward decls ******************************************************************************/ class cDevice; class cDvbDevice; class TChannel; /******************************************************************************* * class cStateMachine ******************************************************************************/ class cStateMachine : public ThreadBase { private: enum eState { eStart = 0, // init, add next_from_list to NewTransponders (NextTransponder) eStop, // cleanup and leave loop () eTune, // tune, check for lock (AttachReceiver, NextTransponder) eNextTransponder, // next unsearched transponder from NewTransponders (Tune, Stop) eDetachReceiver, // detach all receivers (NextTransponder) eScanPat, // pat/pmt scan (ScanNit) eScanPmt, eScanNit, // nit scan (ScanNitOther) eScanSdt, // sdt scan (ScanSdtOther) eScanEit, // eit scan (DetachReceiver) eUnknown, // oops (Stop) eAddChannels, // adding results eGetTables, ePatNG, }; eState state, lastState; TChannel* initial; cDevice* dev; cDvbDevice* dvbdevice; bool stop; bool useNit; void* parent; protected: virtual void Action(void); virtual void Report(eState State); public: cStateMachine(cDevice* Dev, TChannel* InitialTransponder, bool UseNit, void* Parent); virtual ~cStateMachine(void); void DoStop(void); bool Active(void); }; wirbel-at-vdr-portal-wirbelscan-dev-eebef12/tlist.h000066400000000000000000000134331520154405700224650ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #pragma once #include #include #include /******************************************************************************* * returns true if Item1 should be sorted before Item2 in a TList. ******************************************************************************/ typedef bool (*TListSortCompare)(void* Item1, void* Item2); /******************************************************************************* * class TList ******************************************************************************/ template class TList { private: std::mutex m; protected: std::vector v; public: TList(void) {} // constructor TList(const TList& other) : v(other.v) {} // non-swap copy constructor ~TList() { v.clear(); } void Add(T p) { // Add a new item to the list. const std::lock_guard lock(m); v.push_back(p); if (v.size() == v.capacity()) v.reserve(v.capacity() << 1); } int Capacity(void) { // returns max number of items const std::lock_guard lock(m); return v.capacity(); } void Capacity(size_t newCap) { // sets max number of items const std::lock_guard lock(m); v.reserve(newCap); } void Clear(void) { // Clears the list. const std::lock_guard lock(m); v.clear(); } int Count(void) { // Current number of items. const std::lock_guard lock(m); return v.size(); } void Delete(size_t Index) { // Removes items from list. const std::lock_guard lock(m); v.erase(v.begin()+Index); } void Exchange(size_t Index1, size_t Index2) { // Exchanges two items const std::lock_guard lock(m); T p1 = v[Index1]; T p2 = v[Index2]; v[Index1] = p2; v[Index2] = p1; } TList Expand(void) { // Increases the capacity of the list if needed. const std::lock_guard lock(m); if (v.size() == v.capacity()) v.resize(v.capacity() << 1); return *this; } T First(void) { // Returns the first non-nil pointer in the list. const std::lock_guard lock(m); return v.front(); } T Last(void) { // Returns the last non-nil pointer in the list. const std::lock_guard lock(m); return v.back(); } int IndexOf(T Item) { // Returns the index of a given item. const std::lock_guard lock(m); for(size_t i=0; i lock(m); v.insert(v.begin() + Index , Item); } void Move(size_t CurIndex, size_t NewIndex) { // Moves a pointer from one position in the list to another. if (CurIndex == NewIndex) return; const std::lock_guard lock(m); T& item = v[CurIndex]; Delete(CurIndex); if (CurIndex < NewIndex) Insert(NewIndex-1, item); else Insert(NewIndex , item); } T& operator[](int const& Index) { // Provides access to Items (pointers) in the list. const std::lock_guard lock(m); return v[Index]; } TList& operator=(const TList& other) { // copy assignment operator. if (this != &other) { const std::lock_guard lock(m); v = other.v; } return *this; } T& Items(size_t const& Index) { const std::lock_guard lock(m); return v[Index]; } int Remove(T Item) { // Removes a value from the list & returns it's index before removal const std::lock_guard lock(m); for(size_t i=0; i lock(m); std::sort(v.begin(), v.end(), Compare); } void Sort(void) { // Sorts the items in the list using operator '<'. const std::lock_guard lock(m); std::sort(v.begin(), v.end()); } void Assign(TList& from) { // Copy the contents of other lists. const std::lock_guard lock(m); v.assign(from.v.begin(), from.v.end()); } void AddList(TList& aList) { // Add all items from another list const std::lock_guard lock(m); v.insert(v.end(),aList.v.begin(),aList.v.end()); } T* List(void) { // Returns the items in an array. const std::lock_guard lock(m); return v.data(); } void Pack(void) { // Removes nullptr's from the list and frees unused memory. const std::lock_guard lock(m); v.shrink_to_fit(); } }; wirbel-at-vdr-portal-wirbelscan-dev-eebef12/wirbelscan.cpp000066400000000000000000000465411520154405700240200ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #include #include #include #include // std::toupper() #include #include #include "common.h" // wSetup #include "wirbelscan.h" #include "wirbelscan_services.h" #include "menusetup.h" #include "countries.h" #include "satellites.h" class cScanner; extern int channelcount; // menusetup.c extern int nextTransponders; // scanfilter.c extern cScanner* Scanner; const char* WIRBELSCAN_VERSION = "2026.05.15"; /* YYYY.MM.DD */ const char* WIRBELSCAN_DESCRIPTION = "DVB channel scan for VDR"; const char* WIRBELSCAN_MAINMENUENTRY = nullptr; /* main menu -> use wirbelscancontrol plugin */ cPluginWirbelscan* thisPlugin; const char* cPluginWirbelscan::Version(void) { return WIRBELSCAN_VERSION; } const char* cPluginWirbelscan::Description(void) { return WIRBELSCAN_DESCRIPTION; //return I18nTranslate(WIRBELSCAN_DESCRIPTION, "vdr-wirbelscan"); } const char* cPluginWirbelscan::MainMenuEntry(void) { return WIRBELSCAN_MAINMENUENTRY; } // constructor cPluginWirbelscan::cPluginWirbelscan(void) { thisPlugin = this; servicetype("", true); } // destructor cPluginWirbelscan::~cPluginWirbelscan() { } // Return a string that describes all known command line options. const char* cPluginWirbelscan::CommandLineHelp(void) { return nullptr; } // Implement command line argument processing here if applicable. bool cPluginWirbelscan::ProcessArgs(int argc, char* argv[]) { return true; } // Initialize any background activities the plugin shall perform. bool cPluginWirbelscan::Initialize(void) { return true; } // Start any background activities the plugin shall perform. bool cPluginWirbelscan::Start(void) { return true; } // Stop any background activities the plugin shall perform. void cPluginWirbelscan::Stop(void) { stopScanners(); } // Perform any cleanup or other regular tasks. void cPluginWirbelscan::Housekeeping(void) { } // Perform actions in the context of the main program thread. void cPluginWirbelscan::MainThreadHook(void) { } // Return a message string if shutdown should be postponed cString cPluginWirbelscan::Active(void) { return nullptr; } // Perform the action when selected from the main VDR menu. cOsdObject* cPluginWirbelscan::MainMenuAction(void) { return nullptr; } // Return a setup menu in case the plugin supports one. cMenuSetupPage* cPluginWirbelscan::SetupMenu(void) { return new cMenuScanning(); } // read back plugins settings. bool cPluginWirbelscan::SetupParse(const char* Name, const char* Value) { std::string name(Name); if (name == "verbosity") wSetup.verbosity = constrain(std::stoi(Value), 0, 6); else if (name == "logFile") wSetup.logFile = constrain(std::stoi(Value), 0, STDERR); else if (name == "DVB_Type") wSetup.DVB_Type = constrain(std::stoi(Value), SCAN_TERRESTRIAL, SCAN_TRANSPONDER); else if (name == "DVBT_Inversion") wSetup.DVBT_Inversion = constrain(std::stoi(Value), 0, 1); else if (name == "DVBC_Inversion") wSetup.DVBC_Inversion = constrain(std::stoi(Value), 0, 1); else if (name == "DVBC_Symbolrate") wSetup.DVBC_Symbolrate = constrain(std::stoi(Value), 0, 16); else if (name == "DVBC_Network_PID") wSetup.DVBC_Network_PID = constrain(std::stoi(Value), 0x10, 0xFFFF); else if (name == "DVBC_QAM") wSetup.DVBC_QAM = constrain(std::stoi(Value), 0, 4); else if (name == "CountryIndex") wSetup.CountryIndex = constrain(std::stoi(Value), 0, (int)COUNTRY::country_count()-1); else if (name == "SatIndex") wSetup.SatIndex = constrain(std::stoi(Value), 0, (int)sat_count()-1); else if (name == "enable_s2") ; else if (name == "ATSC_type") wSetup.ATSC_type = constrain(std::stoi(Value), 0, 2); else if (name == "scanflags") wSetup.scanflags = constrain(std::stoi(Value), 0, 255); else if (name == "user0") wSetup.user[0] = std::stol(Value); else if (name == "user1") wSetup.user[1] = std::stol(Value); else if (name == "user2") wSetup.user[2] = std::stol(Value); else if (name == "ri") wSetup.scan_remove_invalid = constrain(std::stoi(Value), 0, 1); else if (name == "ue") wSetup.scan_update_existing = constrain(std::stoi(Value), 0, 1); else if (name == "an") wSetup.scan_append_new = constrain(std::stoi(Value), 0, 1); else if (name == "ParseLCN") wSetup.ParseLCN = std::stol(Value) != 0; else if (name == "SignalWaitTime") wSetup.SignalWaitTime = constrain(std::stoi(Value), 1, 5); else if (name == "LockTimeout") wSetup.LockTimeout = constrain(std::stoi(Value), 1, 10); else if (name == "preferred") { auto items = SplitStr(Value,';'); for(size_t i=0; i 5) wSetup.DVB_Type = (int) G(wSetup.user[1],3,29); SetupStore("verbosity", wSetup.verbosity); SetupStore("logFile", wSetup.logFile); SetupStore("DVB_Type", wSetup.DVB_Type); SetupStore("DVBT_Inversion", wSetup.DVBT_Inversion); SetupStore("DVBC_Inversion", wSetup.DVBC_Inversion); SetupStore("DVBC_Symbolrate", wSetup.DVBC_Symbolrate); SetupStore("DVBC_QAM", wSetup.DVBC_QAM); SetupStore("DVBC_Network_PID",wSetup.DVBC_Network_PID); SetupStore("CountryIndex", wSetup.CountryIndex); SetupStore("SatIndex", wSetup.SatIndex); SetupStore("ATSC_type", wSetup.ATSC_type); SetupStore("scanflags", wSetup.scanflags); SetupStore("user0", wSetup.user[0]); SetupStore("user1", wSetup.user[1]); SetupStore("user2", wSetup.user[2]); SetupStore("ri", wSetup.scan_remove_invalid); SetupStore("ue", wSetup.scan_update_existing); SetupStore("an", wSetup.scan_append_new); SetupStore("SignalWaitTime", wSetup.SignalWaitTime); SetupStore("LockTimeout", wSetup.LockTimeout); SetupStore("preferred", preferred.c_str()); Setup.Save(); } /* convert service strings to zero based int, -1 on error */ int cPluginWirbelscan::servicetype(const char* id, bool init) { static std::vector services; if (init) { std::string s(SPlugin); services.clear(); services.push_back(s + SInfo); services.push_back(s + "Get" + SStatus); services.push_back(s + SCommand); services.push_back(s + "Get" + SSetup); services.push_back(s + "Set" + SSetup); services.push_back(s + "Get" + SSat); services.push_back(s + "Get" + SCountry); services.push_back(s + "Get" + SUser); services.push_back(s + "Set" + SUser); services.push_back(s + + SExport); } for(size_t i=0; iPluginVersion = WIRBELSCAN_VERSION; info->CommandVersion = SCommand; info->StatusVersion = SStatus; info->SetupVersion = SSetup; info->CountryVersion = SCountry; info->SatVersion = SSat; info->UserVersion = SUser; // 0.0.5-pre12b info->reserved2 = WIRBELSCAN_VERSION; // may change later. info->reserved3 = WIRBELSCAN_VERSION; // may change later. return true; } case 1: { // status if (! Data) return true; // check for support. cWirbelscanStatus* s = (cWirbelscanStatus*) Data; if (Scanner) s->status = StatusScanning; else s->status = StatusStopped; memset(s->curr_device, 0, 256); strcpy(s->curr_device, lDeviceName.size()? lDeviceName.c_str():"none"); memset(s->transponder, 0, 256); strcpy(s->transponder, lTransponder.length()? lTransponder.c_str():"none"); s->progress = s->status == StatusScanning?lProgress:0; s->strength = s->status == StatusScanning?lStrength:0; s->numChannels = 0; // Channels.Count(); // not possible any longer. s->newChannels = channelcount; // ((Channels.Count() - channelcount) > 0) && channelcount?Channels.Count() - channelcount:0; s->nextTransponders = nextTransponders; return true; } case 2: { // command if (! Data) return true; // check for support. cWirbelscanCmd* request = (cWirbelscanCmd*) Data; switch (request->cmd) { case CmdStartScan: request->replycode = DoScan(wSetup.DVB_Type); break; case CmdStopScan: DoStop(); request->replycode = true; break; case CmdStore: StoreSetup(); request->replycode = true; break; default: request->replycode = false; return false; } return true; } case 3: { // get setup if (! Data) return true; // check for support. cWirbelscanScanSetup* d = (cWirbelscanScanSetup*) Data; d->verbosity = wSetup.verbosity; d->logFile = wSetup.logFile; d->DVB_Type = wSetup.DVB_Type; d->DVBT_Inversion = wSetup.DVBT_Inversion; d->DVBC_Inversion = wSetup.DVBC_Inversion; d->DVBC_Symbolrate = wSetup.DVBC_Symbolrate; d->DVBC_QAM = wSetup.DVBC_QAM; d->CountryId = wSetup.CountryIndex; d->SatId = wSetup.SatIndex; d->scanflags = wSetup.scanflags; d->ATSC_type = wSetup.ATSC_type; d->SignalWaitTime = wSetup.SignalWaitTime; d->LockTimeout = wSetup.LockTimeout; return true; } case 4: { // set setup if (! Data) return true; // check for support. cWirbelscanScanSetup* d = (cWirbelscanScanSetup*) Data; if (d->SignalWaitTime < 1 or d->SignalWaitTime > 5) d->SignalWaitTime = 1; if (d->LockTimeout < 1 or d->LockTimeout > 10) d->LockTimeout = 3; wSetup.verbosity = d->verbosity; wSetup.logFile = d->logFile; wSetup.DVB_Type = (int) d->DVB_Type; wSetup.DVBT_Inversion = d->DVBT_Inversion; wSetup.DVBC_Inversion = d->DVBC_Inversion; wSetup.DVBC_Symbolrate = d->DVBC_Symbolrate; wSetup.DVBC_QAM = d->DVBC_QAM; wSetup.CountryIndex = d->CountryId; wSetup.SatIndex = d->SatId; wSetup.scanflags = d->scanflags; wSetup.ATSC_type = d->ATSC_type; wSetup.SignalWaitTime = d->SignalWaitTime; wSetup.LockTimeout = d->LockTimeout; return true; } case 5: { // get sat if (! Data) return true; // check for support. cPreAllocBuffer* b = (cPreAllocBuffer*) Data; SListItem* l = b->buffer; b->count = 0; if (b->size < sat_count()) { b->size = sat_count(); return true; } for(size_t i=0; icount++; } return true; } case 6: { // get country if (! Data) return true; // check for support. cPreAllocBuffer* b = (cPreAllocBuffer*) Data; SListItem* l = b->buffer; b->count = 0; if (b->size < COUNTRY::country_count()) { b->size = COUNTRY::country_count(); return true; } for(size_t i=0; icount++; } return true; } case 7: { // get user if (! Data) return true; // check for support *((uint32_t*) Data + 0) = wSetup.user[0]; *((uint32_t*) Data + 1) = wSetup.user[1]; *((uint32_t*) Data + 2) = wSetup.user[2]; return true; } case 8: { // set user if (! Data) return true; // check for support wSetup.user[0] = *((uint32_t*) Data + 0); wSetup.user[1] = *((uint32_t*) Data + 1); wSetup.user[2] = *((uint32_t*) Data + 2); return true; } case 9: { // Export if (! Data) return true; // check for support extern TChannels NewChannels; std::vector* list = (std::vector*) Data; for(int idx = 0; idx < NewChannels.Count(); ++idx) { TChannel t = *NewChannels[idx]; list->push_back(t); } return true; } default: return false; } } const char** cPluginWirbelscan::SVDRPHelpPages(void) { static const char* SVDRHelp[] = { "S_START\n" " Start scan", "S_STOP\n" " Stop scan(s) (if any)", "S_TERR\n" " Start DVB-T scan", "S_CABL\n" " Start DVB-C scan", "S_SAT\n" " Start DVB-S/S2 scan", "SETUP \n" " verb verbostity (0..5)\n" " log logfile (0=OFF, 1=stdout, 2=syslog)\n" " type scan type\n" " (0=DVB-T, 1=DVB-C, 2=DVB-S/S2, 5=ATSC)\n" " inv_t DVB-T inversion\n" " (0=AUTO/OFF, 1=AUTO/ON)\n" " inv_c DVB-C inversion\n" " (0=AUTO/OFF, 1=AUTO/ON)\n" " srate DVB-C Symbolrate (0..15)\n" " qam DVB-C modulation\n" " (0=AUTO, 1=QAM64, 2=QAM128, 3=QAM256, 4=ALL)\n" " cidx country list index\n" " sidx satellite list index\n" " s2 enable DVB-S2 (0=OFF, 1=ON)\n" " atsc ATSC scan type\n" " (0=VSB, 1=QAM, 2=VSB+QAM)\n" " flags bitwise flag of\n" " TV=1, RADIO=2, FTA=4, SCRAMBLED=8, HDTV=16", "STORE\n" " Store current setup", "LSTC\n" " list countries", "LSTS\n" " list satellites", "QUERY\n" " return plugin version, current setup and service versions", nullptr }; return SVDRHelp; } // process svdrp commands. cString cPluginWirbelscan::SVDRPCommand(const char* Command, const char* Option, int& ReplyCode) { std::string cmd(UpperCase(Command)); if (cmd == "S_TERR" ) { return DoScan(wSetup.DVB_Type = SCAN_TERRESTRIAL) ? "DVB-T scan started" : "Could not start DVB-T scan."; } else if (cmd == "S_CABL" ) { return DoScan(wSetup.DVB_Type = SCAN_CABLE) ? "DVB-C scan started" : "Could not start DVB-C scan."; } else if (cmd == "S_SAT" ) { return DoScan(wSetup.DVB_Type = SCAN_SATELLITE) ? "DVB-S scan started" : "Could not start DVB-S scan."; } else if (cmd == "S_START") { return DoScan(wSetup.DVB_Type) ? "starting scan" : "Could not start scan."; } else if (cmd == "S_STOP" ) { DoStop(); return "stopping scan(s)"; } else if (cmd == "STORE" ) { StoreSetup(); return "setup stored."; } else if (cmd == "SETUP") { std::vector items; if (Option and *Option) items = SplitStr(Option, ':'); bool valid = items.size() == 12; for(auto i:items) if (i.empty() or i.find_first_not_of("0123456789") != std::string::npos) valid = false; if (not valid) { ReplyCode = 501; return "couldnt parse setup string."; } wSetup.verbosity = std::stol(items[0]); wSetup.logFile = std::stol(items[1]); wSetup.DVB_Type = std::stol(items[2]); wSetup.DVBT_Inversion = std::stol(items[3]); wSetup.DVBC_Inversion = std::stol(items[4]); wSetup.DVBC_Symbolrate = std::stol(items[5]); wSetup.DVBC_QAM = std::stol(items[6]); wSetup.CountryIndex = std::stol(items[7]); wSetup.SatIndex = std::stol(items[8]); //removed:enable_s2 items[9] wSetup.ATSC_type = std::stol(items[10]); wSetup.scanflags = std::stol(items[11]); std::string s = "changed setup to " + IntToStr(wSetup.verbosity) + ':' + IntToStr(wSetup.logFile) + ':' + IntToStr(wSetup.DVB_Type) + ':' + IntToStr(wSetup.DVBT_Inversion) + ':' + IntToStr(wSetup.DVBC_Inversion) + ':' + IntToStr(wSetup.DVBC_Symbolrate) + ':' + IntToStr(wSetup.DVBC_QAM) + ':' + IntToStr(wSetup.CountryIndex) + ':' + IntToStr(wSetup.SatIndex) + ':' + "1" + ':' + IntToStr(wSetup.ATSC_type) + ':' + IntToStr(wSetup.scanflags); return s.c_str(); } else if (cmd == "QUERY") { std::string s; s = "plugin version: " + std::string(WIRBELSCAN_VERSION) + '\n' + IntToStr(wSetup.verbosity) + ':' + "current setup: " + IntToStr(wSetup.verbosity) + ':' + IntToStr(wSetup.logFile) + ':' + IntToStr(wSetup.DVB_Type) + ':' + IntToStr(wSetup.DVBT_Inversion) + ':' + IntToStr(wSetup.DVBC_Inversion) + ':' + IntToStr(wSetup.DVBC_Symbolrate) + ':' + IntToStr(wSetup.DVBC_QAM) + ':' + IntToStr(wSetup.CountryIndex) + ':' + IntToStr(wSetup.SatIndex) + ':' + "1" + ':' + IntToStr(wSetup.ATSC_type) + ':' + IntToStr(wSetup.scanflags) + '\n' + "commands api: " + std::string(SCommand) + "\n" "status api: " + std::string(SStatus) + "\n" "setup api: " + std::string(SSetup) + "\n" "country api: " + std::string(SCountry) + "\n" "sat api: " + std::string(SSat) + "\n" "user api: " + std::string(SUser); return s.c_str(); } else if (cmd == "LSTC") { std::stringstream ss; for(size_t i=0; i class cPluginWirbelscan : public cPlugin { private: int servicetype(const char* id, bool init = false); public: cPluginWirbelscan(void); virtual ~cPluginWirbelscan(); virtual const char* Version(void); virtual const char* Description(void); virtual const char* CommandLineHelp(void); virtual bool ProcessArgs(int argc, char* argv[]); virtual bool Initialize(void); virtual bool Start(void); virtual void Stop(void); virtual void Housekeeping(void); virtual void MainThreadHook(void); virtual cString Active(void); virtual const char* MainMenuEntry(void); virtual cOsdObject* MainMenuAction(void); virtual cMenuSetupPage* SetupMenu(void); virtual bool SetupParse(const char* Name, const char* Value); virtual void StoreSetup(void); virtual bool Service(const char* Id, void* Data = nullptr); virtual const char** SVDRPHelpPages(void); virtual cString SVDRPCommand(const char* Command, const char* Option, int& ReplyCode); }; extern cPluginWirbelscan* thisPlugin; wirbel-at-vdr-portal-wirbelscan-dev-eebef12/wirbelscan_services.h000066400000000000000000000301411520154405700253550ustar00rootroot00000000000000/******************************************************************************* * wirbelscan: A plugin for the Video Disk Recorder * See the README file for copyright information and how to reach the author. ******************************************************************************/ #pragma once #include // uint{8,16,32}_t /******************************************************************************* * wirbelscans plugin service interface * see https://www.gen2vdr.de/wirbel/wirbelscan/vdr-servdemo-0.0.1.tgz * for example on usage. ******************************************************************************/ namespace WIRBELSCAN_SERVICE { /* begin of namespace. to use this header file: * #include "../wirbelscan/wirbelscan_services.h" * using namespace WIRBELSCAN_SERVICE; */ /* --- service(s) version ---------------------------------------------------- */ #define SPlugin "wirbelscan_" // prefix #define SInfo "GetVersion" // plugin version and service api #define SCommand "DoCmd#0001" // command api 0001 #define SStatus "Status#0003" // query status #define SSetup "Setup#0003" // get/set setup, GetSetup#XXXX/SetSetup#XXXX #define SCountry "Country#0001" // get list of country IDs and Names #define SSat "Sat#0001" // get list of satellite IDs and Names #define SUser "User#0002" // get/set single user transponder, GetUser#XXXX/SetUser#XXXX #define SExport "Export#0001" // raw data export /* --- wirbelscan_GetVersion ------------------------------------------------- * Query wirbelscans versions, will fail only if plugin version doesnt support service at all. */ typedef struct { const char* PluginVersion; // plugin version const char* CommandVersion; // commands service version const char* StatusVersion; // status service version const char* SetupVersion; // get/put setup service version const char* CountryVersion; // country ID list version const char* SatVersion; // satellite ID list version const char* UserVersion; // user transponder api version, 0.0.5-pre12b or higher. const char* reserved2; // reserved, do not use. const char* reserved3; // reserved, do not use. } cWirbelscanInfo; /* --- wirbelscan_DoCmd ------------------------------------------------------ * Execute commands. */ typedef enum { CmdStartScan = 0, // start scanning CmdStopScan = 1, // stop scanning CmdStore = 2, // store current setup } s_cmd; typedef struct { s_cmd cmd; // see above. bool replycode; // false, if unsuccessful. } cWirbelscanCmd; /* --- wirbelscan_Status ----------------------------------------------------- * Query Status. Use this to build up your osd information displayed to user. */ typedef enum { StatusUnknown = 0, // no status information available, try again later. StatusScanning = 1, // scan in progress. StatusStopped = 2, // no scan in progress (not started, finished or stopped). StatusBusy = 3, // plugin is busy, try again later. } cStatus; typedef struct { cStatus status; // see above. char curr_device[256]; // name of current device. meaningless, if (status != StatusScanning) uint16_t progress; // estimated(!) progress (0..100) NOTE: may jump or step forward/backward. meaningless, if (status != StatusScanning) uint16_t strength; // current signal strength as reported from device. NOTE: updated only after switching to new transponder. meaningless, if (status != StatusScanning) char transponder[256]; // current transponder. meaningless, if (status != StatusScanning) uint16_t numChannels; // current number of (all) channels, including those which are new. meaningless, if (status != StatusScanning) uint16_t newChannels; // number of channels found during this scan. meaningless, if (status != StatusScanning) uint16_t nextTransponders; // number of transponders still to be scanned from NIT on this transponder. meaningless, if (status != StatusScanning) uint16_t reserved2; // reserved, do not use. uint16_t reserved3; // reserved, do not use. } cWirbelscanStatus; /* --- wirbelscan_GetSetup, wirbelscan_SetSetup ------------------------------ * Get/Set Setup. Use this to build up your setup osd displayed to user. */ typedef struct { uint16_t verbosity; // 0 (errors only) .. 5 (extended debug); default = 3 (messages) uint16_t logFile; // 0 = off, 1 = stdout, 2 = syslog uint16_t DVB_Type; // DVB-T = 0, DVB-C = 1, DVB-S/S2 = 2, ATSC = 5, TRANSPONDER = 999 uint16_t DVBT_Inversion; // AUTO/OFF = 0, AUTO/ON = 1 uint16_t DVBC_Inversion; // AUTO/OFF = 0, AUTO/ON = 1 uint16_t DVBC_Symbolrate; // careful here - may change. AUTO = 0, 6900 = 1, 6875 = 2 (...) 14 = 5483, 15 = ALL uint16_t DVBC_QAM; // AUTO = 0,QAM64 = 1, QAM128 = 2, QAM256 = 3, ALL = 4 uint16_t CountryId; // the id according to country, found in country list, see wirbelscan_GetCountry uint16_t SatId; // the id according to satellite, found in list, see wirbelscan_GetSat uint32_t scanflags; // bitwise flag of wanted channels: TV = (1 << 0), RADIO = (1 << 1), FTA = (1 << 2), SCRAMBLED = (1 << 4), HDTV = (1 << 5) uint16_t ATSC_type; // VSB = 0, QAM = 1, both VSB+QAM = 2 uint16_t SignalWaitTime; // 0 = default, 1..5 time to expect some signal after tune in seconds, > 5 invalid. uint16_t LockTimeout; // 0 = default, 1..10 time to expect full lock after signal was reported in seconds, > 10 invalid. uint16_t stuffing[4]; // do not use. } cWirbelscanScanSetup; /* --- wirbelscan_GetCountry, wirbelscan_GetSat ------------------------------ * Use this to build up your setup OSD - user needs to choose satellite and * country by name and assign correct IDs to setup, see * * cWirbelscanScanSetup::CountryId * * cWirbelscanScanSetup::SatId. * * 1) Query needed buffer size with cPreAllocBuffer::size == 0 * 2) allocate memory in your plugin, to be at least: cPreAllocBuffer::size * sizeof(SListItem) * 3) second call fills buffer with count * sizeof(SListItem) bytes. * 4) access to items as SListItem* */ typedef struct { int id; char short_name[8]; char full_name[64]; } SListItem; typedef struct { uint32_t size; uint32_t count; SListItem* buffer; } cPreAllocBuffer; /* --- wirbelscan_GetUser, wirbelscan_SetUser -------------------------------- * Scan a user defined Transponder. Service() expects a pointer to uint32_t Data[3]; * Data should be initialized and read using class cUserTransponder. * * --------------------------------------------- * id : 9 country-id/sat-id * frequency : 21 DVB-T: 177500..858000; ATSC/DVB-C: 73000..858000, DVB-S/S2: 2000..15000 * polarisation : 2 0=h, 1=v, 2=l, 3=r * type : 3 DVB_Type * symbolrate : 17 i.e. 27500, 6900 * fec_hi : 4 DVB-S/S2: 1=1/2, 2=2/3, 3=3/4, 4=4/5, 5=5/6, 6=6/7, 7=7/8, 8=8/9, 9=forbidden, 10=3/5, 11=9/10 * DVB-T 1=1/2, 2=2/3, 3=3/4, 4=forbidden, 5=5/6, 6=forbidden, 7=7/8, 8..15=forbidden * fec_lo : 4 DVB-T 1=1/2, 2=2/3, 3=3/4, 4=forbidden, 5=5/6, 6=forbidden, 7=7/8, 8..15=forbidden * modulation : 4 DVB-C: 0=forbidden, 1=QAM16, 2=QAM32, 3=QAM64, 4=QAM128, 5=QAM256, 6..15: forbidden * DVB-T: 0=QPSK, 1=QAM16, 2=forbidden, 3=QAM64, 4..15: forbidden * DVB-S: 0=QPSK, 1=QAM16, 2..8: forbidden, 9=PSK8, 10..15:forbidden * ATSC: 0..2: forbidden, 3=QAM64, 4=forbidden, 5=QAM256, 6=QAM_AUTO, 7=VSB8, 8=VSB16, 9..15=forbidden * orbit : 12 i.e. 192 for S19E2 * we_flag : 1 0=west, 1=east * rolloff : 2 0=0,35, 1=0,25, 2=0,20 * 2nd_gen_sys : 1 0=DVB-S/T, 1=DVB-S2/T2 * bw : 2 0=8MHz, 1=7MHz, 2=6MHz, 3=5MHz * priority : 1 0=LP, 1=HP * hierarchy : 4 0=OFF, 1=alpha1, 2=alpha2, 3=alpha4 * guardinterval : 2 0=1/32, 1=1/16, 2=1/8, 3=1/4 * transmission : 2 0=2k, 1=8k, 2=4k * inversion : 1 0=OFF, 1=ON * use_nit : 1 0=OFF, 1=ON * reserved : 3 always 0 * --------------------------------------------- */ #define P(v,b,p) ((v & ((1 << b) -1)) << p) #define G(v,b,p) ((v >> p) & ((1 << b) -1)) class cUserTransponder { private: uint32_t data[3]; public: ~cUserTransponder() { }; cUserTransponder(uint32_t * Data) { data[0] = *(Data + 0); data[1] = *(Data + 1); data[2] = *(Data + 2); }; // DVB-T cUserTransponder(uint8_t id, uint32_t frequency, uint8_t modulation, uint8_t fec_hp, uint8_t fec_lp, uint8_t bw, uint8_t priority, uint8_t hierarchy, uint8_t guard, uint8_t tm, uint8_t inversion, uint8_t use_nit) { data[0] = P(id,9,23) | P(frequency,21,2); data[1] = P(fec_hp,4,8) | P(fec_lp,4,4) | P(modulation,4,0); data[2] = P(bw,2,14) | P(priority,1,13) | P(hierarchy,4,9) | P(guard,2,7) | P(tm,2,5) | P(inversion,1,4) | P(use_nit,1,3); }; // DVB-C cUserTransponder(uint8_t id, uint32_t frequency, uint32_t symbolrate, uint8_t modulation, uint8_t inversion, uint8_t use_nit) { data[0] = P(id,9,23) | P(frequency,21,2); data[1] = P(1,3,29) | P(symbolrate,17,12) | P(modulation,4,0); data[2] = P(inversion,1,4) | P(use_nit,1,3); }; // DVB-S cUserTransponder(uint8_t id, uint8_t system, uint32_t frequency, uint8_t polarisation, uint32_t symbolrate, uint8_t modulation, uint8_t fec, uint16_t orbit, uint8_t we_flag, uint8_t rolloff, uint8_t use_nit) { data[0] = P(id,9,23) | P(frequency,21,2) | P(polarisation,2,0); data[1] = P(2,3,29) | P(symbolrate,17,12) | P(fec,4,8) | P(modulation,4,0); data[2] = P(orbit,12,20) | P(we_flag,1,19) | P(rolloff,2,17) | P(system,1,16) | P(use_nit,1,3); }; // ATSC cUserTransponder(uint8_t id, uint32_t frequency, uint8_t modulation, uint8_t use_nit) { data[0] = P(id,9,23) | P(frequency,21,2); data[1] = P(5,3,29) | P(modulation,4,0); data[2] = P(use_nit,1,3); }; const uint32_t * Data(void) { return data; }; int Id(void) { return G(data[0],9,23); }; int Frequency(void) { return G(data[0],21,2); }; int Polarisation(void){ return G(data[0],2,0); }; int Type(void) { return G(data[1],3,29); }; int Symbolrate(void) { return G(data[1],17,12); }; int FecHP(void) { return G(data[1],4,8); }; int FecLP(void) { return G(data[1],4,4); }; int Modulation(void) { return G(data[1],4,0); }; int Orbit(void) { return G(data[2],12,20); }; int EastFlag(void) { return G(data[2],1,19); }; int Rolloff(void) { return G(data[2],2,17); }; int System(void) { return G(data[2],1,16) + 5; }; int Bandwidth(void) { return (8 - G(data[2],2,14)) * (int) 1E6; }; int Priority(void) { return G(data[2],1,13); }; int Hierarchy(void) { return G(data[2],4,9); }; int Guard(void) { return G(data[2],2,7); }; int Transmission(void){ return G(data[2],2,5); }; int Inversion(void) { return G(data[2],1,4); }; int UseNit(void) { return G(data[2],1,3); }; bool IsTerr(void) { return IsType(0); }; bool IsCable(void) { return IsType(1); }; bool IsSat(void) { return IsType(2); }; bool IsAtsc(void) { return IsType(5); }; bool IsType(int type) { return type == Type(); }; }; } /* end of namespace, do not touch */