mirror of
				https://github.com/rofafor/vdr-plugin-satip.git
				synced 2023-10-10 11:37:42 +00:00 
			
		
		
		
	Compare commits
	
		
			77 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6c4c8a10b7 | ||
|  | 8b43cdc634 | ||
|  | fe010ab72c | ||
|  | 7bdc152f76 | ||
|  | bd6774ba28 | ||
|  | fbf7977853 | ||
|  | 19a6a4a5ee | ||
|  | 7b683dba8d | ||
|  | 942d3a936e | ||
|  | 748ea15d1d | ||
|  | 1d75da403a | ||
|  | 4d8263e8fd | ||
|  | 7019b719a5 | ||
|  | 39249ca2d5 | ||
|  | 68e0d1474e | ||
|  | ad5c221e44 | ||
|  | 826e53e8ea | ||
|  | f4dd02a9aa | ||
|  | 8184a785b7 | ||
|  | 1b4094696a | ||
|  | 4139e87f4a | ||
|  | 7196c9403b | ||
|  | e1c896c1a6 | ||
|  | 6b63ad145f | ||
|  | 84dfc6701e | ||
|  | 653d9d659b | ||
|  | 26cd34f965 | ||
|  | df258d127f | ||
|  | 3e4b1c0383 | ||
|  | 73ed299ed9 | ||
|  | 37e151b3e3 | ||
|  | b1aad3fb80 | ||
|  | a87dfc43f7 | ||
|  | 26be862d89 | ||
|  | ab2a47e3e7 | ||
|  | 3d1efe7a80 | ||
|  | c9898bfbfd | ||
|  | 46bfc805e6 | ||
|  | 30925337cb | ||
|  | 63e47ad24a | ||
|  | 14123e160f | ||
|  | 278d0478cf | ||
|  | 9989c36eee | ||
|  | d2064f0c04 | ||
|  | 714d3ed902 | ||
|  | b466d6836e | ||
|  | 184ddf2a53 | ||
|  | 65a2158051 | ||
|  | e833ca6fdd | ||
|  | c9abfddf11 | ||
|  | fb7a7fe3a2 | ||
|  | 3b9269e9de | ||
|  | 09e6c272cd | ||
|  | 266aadb999 | ||
|  | aed5a7820a | ||
|  | bcb11b6257 | ||
|  | 21261f8042 | ||
|  | 2f11ad7a98 | ||
|  | 83a0233780 | ||
|  | 6f3715eb8b | ||
|  | 92991cd144 | ||
|  | 304addbc00 | ||
|  | 26ff10ce1e | ||
|  | e654b3bbd2 | ||
|  | acea8748a4 | ||
|  | 755f1049bb | ||
|  | 2f6315280f | ||
|  | 695dd53bfc | ||
|  | 5fef77518e | ||
|  | 791767f02b | ||
|  | 0d52649dbd | ||
|  | 0c03c1b8d4 | ||
|  | db59aa9c29 | ||
|  | 0fd559ce79 | ||
|  | e10ce57210 | ||
|  | c7f4b265d5 | ||
|  | 35c0f25c38 | 
							
								
								
									
										49
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -88,3 +88,52 @@ VDR Plugin 'satip' Revision History | |||||||
| - Added plenty of performance tweaks (Thanks to | - Added plenty of performance tweaks (Thanks to | ||||||
|   Stefan Schallenberg). |   Stefan Schallenberg). | ||||||
| - Fixed EIT scan (Thanks to Stefan Schallenberg). | - Fixed EIT scan (Thanks to Stefan Schallenberg). | ||||||
|  |  | ||||||
|  | 2015-01-10: Version 1.0.1 | ||||||
|  |  | ||||||
|  | - Updated the command-line help and README. | ||||||
|  | - Fixed the server teardown. | ||||||
|  | - Removed the unnecessary config directory definition. | ||||||
|  | - Added a fallback for older glibc libraries. | ||||||
|  | - Improved pid selection performance. | ||||||
|  | - Added support for Digital Devices CI extension. | ||||||
|  |  | ||||||
|  | 2015-01-18: Version 1.0.2 | ||||||
|  |  | ||||||
|  | - Added configurable CI slots. | ||||||
|  | - Fixed parsing of the setup values. | ||||||
|  | - Added an option to disable sources via sources.conf. | ||||||
|  | - Added a command-line option to disable all the | ||||||
|  |   SAT>IP server quirks. | ||||||
|  | - Updated Spanish and Catalan translations (Thanks to | ||||||
|  |   Gabriel Bonich). | ||||||
|  | - Updated German translations (Thanks to Frank Neumann). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | =================================== | ||||||
|  | VDR Plugin 'satip' Revision History | ||||||
|  | =================================== | ||||||
|  |  | ||||||
|  | 2015-02-19: Version 2.2.0 | ||||||
|  |  | ||||||
|  | - Updated for vdr-2.2.0. | ||||||
|  | - Fixed memory deallocation errors. | ||||||
|  | - Cleaned up all scan-build warnings. | ||||||
|  | - Refactored the frontend handling. | ||||||
|  |  | ||||||
|  | 2015-04-04: Version 2.2.1 | ||||||
|  |  | ||||||
|  | - Improved RTSP error checking. | ||||||
|  | - Got rid of SATIP_DEBUG. | ||||||
|  | - Robustify the server discovery. | ||||||
|  | - Fixed a memory leak in TinyXML implementation | ||||||
|  |   (Thanks to Oliver Endriss). | ||||||
|  | - Updated against SAT>IP protocol specification | ||||||
|  |   version 1.2.2. | ||||||
|  |  | ||||||
|  | 2015-04-26: Version 2.2.2 | ||||||
|  |  | ||||||
|  | - Added a more flexible OPER command in the SVDRP | ||||||
|  |   interface. | ||||||
|  | - Added new ATTA and DETA SVDRP commands. | ||||||
|  | - Set the default device count to two. | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Makefile
									
									
									
									
									
								
							| @@ -2,18 +2,10 @@ | |||||||
| # Makefile for SAT>IP plugin | # Makefile for SAT>IP plugin | ||||||
| # | # | ||||||
|  |  | ||||||
| # Debugging on/off |  | ||||||
|  |  | ||||||
| #SATIP_DEBUG = 1 |  | ||||||
|  |  | ||||||
| # Use TinyXML instead of PugiXML | # Use TinyXML instead of PugiXML | ||||||
|  |  | ||||||
| #SATIP_USE_TINYXML = 1 | #SATIP_USE_TINYXML = 1 | ||||||
|  |  | ||||||
| # Strip debug symbols?  Set eg. to /bin/true if not |  | ||||||
|  |  | ||||||
| STRIP = strip |  | ||||||
|  |  | ||||||
| # The official name of this plugin. | # The official name of this plugin. | ||||||
| # This name will be used in the '-P...' option of VDR to load the plugin. | # This name will be used in the '-P...' option of VDR to load the plugin. | ||||||
| # By default the main source file also carries this name. | # By default the main source file also carries this name. | ||||||
| @@ -40,6 +32,7 @@ TMPDIR ?= /tmp | |||||||
|  |  | ||||||
| export CFLAGS   = $(call PKGCFG,cflags) | export CFLAGS   = $(call PKGCFG,cflags) | ||||||
| export CXXFLAGS = $(call PKGCFG,cxxflags) | export CXXFLAGS = $(call PKGCFG,cxxflags) | ||||||
|  | STRIP           ?= /bin/true | ||||||
|  |  | ||||||
| ### The version number of VDR's plugin API: | ### The version number of VDR's plugin API: | ||||||
|  |  | ||||||
| @@ -75,10 +68,6 @@ else | |||||||
| LIBS += -lpugixml | LIBS += -lpugixml | ||||||
| endif | endif | ||||||
|  |  | ||||||
| ifdef SATIP_DEBUG |  | ||||||
| DEFINES += -DDEBUG |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| ifneq ($(strip $(GITTAG)),) | ifneq ($(strip $(GITTAG)),) | ||||||
| DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"' | DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"' | ||||||
| endif | endif | ||||||
| @@ -140,9 +129,7 @@ install-i18n: $(I18Nmsgs) | |||||||
|  |  | ||||||
| $(SOFILE): $(OBJS) | $(SOFILE): $(OBJS) | ||||||
| 	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ | 	$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ | ||||||
| ifndef SATIP_DEBUG |  | ||||||
| 	@$(STRIP) $@ | 	@$(STRIP) $@ | ||||||
| endif |  | ||||||
|  |  | ||||||
| install-lib: $(SOFILE) | install-lib: $(SOFILE) | ||||||
| 	install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) | 	install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								README
									
									
									
									
									
								
							| @@ -23,7 +23,8 @@ Requirements: | |||||||
|   TinyXML - a simple, small, C++ XML parser |   TinyXML - a simple, small, C++ XML parser | ||||||
|   http://www.grinninglizard.com/tinyxml/ |   http://www.grinninglizard.com/tinyxml/ | ||||||
|  |  | ||||||
| - VDR >= 2.1.4 for scrambled channels | - Glibc >= 2.12 - the GNU C library (recvmmsg) | ||||||
|  |   http://www.gnu.org/software/libc/ | ||||||
|  |  | ||||||
| Description: | Description: | ||||||
|  |  | ||||||
| @@ -41,17 +42,24 @@ make -C satip-X.Y.Z install | |||||||
| Configuration: | Configuration: | ||||||
|  |  | ||||||
| The plugin accepts a "--devices" (-d) command-line parameter defaulting | The plugin accepts a "--devices" (-d) command-line parameter defaulting | ||||||
| to one. This parameter defines how many simultaneous transponders can | to two. This parameter defines how many simultaneous transponders can | ||||||
| be received, if there are available SAT>IP tuners. | be received, if there are available SAT>IP tuners. | ||||||
|  |  | ||||||
| The plugin accepts also a "--server" (-s) command-line parameter, that | The plugin accepts also a "--server" (-s) command-line parameter, that | ||||||
| can be used to manually configure static SAT>IP servers if autodetection | can be used to manually configure static SAT>IP servers if autodetection | ||||||
| via UPnP somehow can't be used. | via UPnP somehow can't be used. The parameter string is a semicolon | ||||||
|  | separated list of "<ipaddress>|<model>|<description>" entries. The model | ||||||
|  | consists of a DVB system (DVBS2,DVBT2,DVBT,DVBC) and number of available | ||||||
|  | frontends separated by a hyphen: | ||||||
|  |  | ||||||
|  | vdr -P 'satip -s <ipaddress>|<model>|<description>;...' | ||||||
|  | vdr -P 'satip -s 192.168.0.1|DVBS2-2,DVBT2-2|Octo1' | ||||||
|  | vdr -P 'satip -s 192.168.0.1|DVBS2-4|Octo1;192.168.0.2|DVBT2-4|Octo2' | ||||||
|  |  | ||||||
| SAT>IP satellite positions (aka. signal sources) shall be defined via | SAT>IP satellite positions (aka. signal sources) shall be defined via | ||||||
| sources.conf. If the source description begins with a number, it's used | sources.conf. If the source description begins with a number, it's used | ||||||
| as SAT>IP signal source selection parameter. Otherwise, the default | as SAT>IP signal source selection parameter. A special number zero can | ||||||
| parameter is one: | be used to disable the source. Otherwise, the default parameter is one: | ||||||
|  |  | ||||||
| S19.2E  Astra 1KR/1L/1M/2C | S19.2E  Astra 1KR/1L/1M/2C | ||||||
| => Signal source = 1 | => Signal source = 1 | ||||||
| @@ -62,9 +70,13 @@ S19.2E  2 | |||||||
| S19.2E  3 Astra 1KR/1L/1M/2C | S19.2E  3 Astra 1KR/1L/1M/2C | ||||||
| => Signal source = 3 | => Signal source = 3 | ||||||
|  |  | ||||||
|  | S19.2E 0 Astra 1KR/1L/1M/2C | ||||||
|  | => Source is disabled | ||||||
|  |  | ||||||
| A channel can be assigned into a specific SAT>IP frontend by giving the | A channel can be assigned into a specific SAT>IP frontend by giving the | ||||||
| identifier number in RID field of a channels.conf entry. | identifier number in RID field of a channels.conf entry: | ||||||
| Valid range: 1 ... 8 | FE = RID % 100 | ||||||
|  | Valid range: 1 ... 99 | ||||||
|  |  | ||||||
| Setup menu: | Setup menu: | ||||||
|  |  | ||||||
| @@ -76,6 +88,13 @@ Setup menu: | |||||||
|                              option to "low". Similarly, the "high" |                              option to "low". Similarly, the "high" | ||||||
|                              value prefers the SAT>IP over the local |                              value prefers the SAT>IP over the local | ||||||
|                              DVB cards when selecting available devices. |                              DVB cards when selecting available devices. | ||||||
|  | - Use CI extension = no      If you want to use the CI extension found | ||||||
|  |                              in some SAT>IP hardware (e.g. Digital | ||||||
|  |                              Devices OctopusNet), set this option to | ||||||
|  |                              "yes". | ||||||
|  | - CICAM #<slot> = <system>   If you want to assign a CA system into | ||||||
|  |                              a specific CI slot, set this option to | ||||||
|  |                              a named one. Use "---" for autoselection. | ||||||
| - Enable EPG scanning = yes  If you want exclude all SAT>IP devices | - Enable EPG scanning = yes  If you want exclude all SAT>IP devices | ||||||
|                              from VDR's EIT background scanning, set |                              from VDR's EIT background scanning, set | ||||||
|                              this option to "no". |                              this option to "no". | ||||||
| @@ -113,12 +132,19 @@ Notes: | |||||||
|   your setup doesn't have firewalled the UDP port 1900. |   your setup doesn't have firewalled the UDP port 1900. | ||||||
|  |  | ||||||
| - Stream decryption requires a separate CAM plugin that works without | - Stream decryption requires a separate CAM plugin that works without | ||||||
|   direct access to any DVB card devices. The integrated CAM slot in |   direct access to any DVB card devices. Also the integrated CAM slots | ||||||
|   Octopus Net devices isn't supported. |   in Octopus Net devices are supported. | ||||||
|  |  | ||||||
| - Tracing can be set on/off dynamically via command-line switch or | - Tracing can be set on/off dynamically via command-line switch or | ||||||
|   SVDRP command. |   SVDRP command. | ||||||
|  |  | ||||||
|  | - OctopusNet firmware 1.0.40 or greater recommended. | ||||||
|  |  | ||||||
|  | - Inverto OEM firmware 1.17.0.120 or greater recommended. | ||||||
|  |   The firmware 1.16.0.120 can be downloaded and installed | ||||||
|  |   from their webpage: http://www.inverto.tv/support/ | ||||||
|  |   An update to a newer firmware should be offered afterwards. | ||||||
|  |  | ||||||
| Acknowledgements: | Acknowledgements: | ||||||
|  |  | ||||||
| - Big thanks to Digital Devices GmbH for providing the Octopus Net | - Big thanks to Digital Devices GmbH for providing the Octopus Net | ||||||
|   | |||||||
							
								
								
									
										64
									
								
								common.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								common.c
									
									
									
									
									
								
							| @@ -79,10 +79,72 @@ cString ChangeCase(const cString &strP, bool upperP) | |||||||
|  |  | ||||||
| const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] = | const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE] = | ||||||
| { | { | ||||||
|   /* description                        tag    pid   tid   mask */ |   // description                        tag    pid   tid   mask | ||||||
|   {trNOOP("PAT (0x00)"),                "PAT", 0x00, 0x00, 0xFF}, |   {trNOOP("PAT (0x00)"),                "PAT", 0x00, 0x00, 0xFF}, | ||||||
|   {trNOOP("NIT (0x40)"),                "NIT", 0x10, 0x40, 0xFF}, |   {trNOOP("NIT (0x40)"),                "NIT", 0x10, 0x40, 0xFF}, | ||||||
|   {trNOOP("SDT (0x42)"),                "SDT", 0x11, 0x42, 0xFF}, |   {trNOOP("SDT (0x42)"),                "SDT", 0x11, 0x42, 0xFF}, | ||||||
|   {trNOOP("EIT (0x4E/0x4F/0x5X/0x6X)"), "EIT", 0x12, 0x40, 0xC0}, |   {trNOOP("EIT (0x4E/0x4F/0x5X/0x6X)"), "EIT", 0x12, 0x40, 0xC0}, | ||||||
|   {trNOOP("TDT (0x70)"),                "TDT", 0x14, 0x70, 0xFF}, |   {trNOOP("TDT (0x70)"),                "TDT", 0x14, 0x70, 0xFF}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const ca_systems_table_type ca_systems_table[CA_SYSTEMS_TABLE_SIZE] = | ||||||
|  | { | ||||||
|  |   // http://www.dvb.org/index.php?id=174 | ||||||
|  |   // http://en.wikipedia.org/wiki/Conditional_access_system | ||||||
|  |   // start end     description | ||||||
|  |   {0x0000, 0x0000, "---"                       }, // 0 | ||||||
|  |   {0x0100, 0x01FF, "SECA Mediaguard (100..1FF)"}, // 1 | ||||||
|  |   {0x0464, 0x0464, "EuroDec (464)"             }, // 2 | ||||||
|  |   {0x0500, 0x05FF, "Viaccess (500..5FF)"       }, // 3 | ||||||
|  |   {0x0600, 0x06FF, "Irdeto (600..6FF)"         }, // 4 | ||||||
|  |   {0x0700, 0x07FF, "DigiCipher 2 (700..7FF)"   }, // 5 | ||||||
|  |   {0x0900, 0x09FF, "NDS Videoguard (900..9FF)" }, // 6 | ||||||
|  |   {0x0B00, 0x0BFF, "Conax (B00..BFF)"          }, // 7 | ||||||
|  |   {0x0D00, 0x0DFF, "CryptoWorks (D00..DFF)"    }, // 8 | ||||||
|  |   {0x0E00, 0x0EFF, "PowerVu (E00..EFF)"        }, // 9 | ||||||
|  |   {0x1000, 0x10FF, "RAS (1000..10FF)"          }, // 10 | ||||||
|  |   {0x1200, 0x12FF, "NagraVision (1200..12FF)"  }, // 11 | ||||||
|  |   {0x1700, 0x17FF, "VCAS (1700..17FF)"         }, // 12 | ||||||
|  |   {0x1800, 0x18FF, "NagraVision (1800..18FF)"  }, // 13 | ||||||
|  |   {0x22F0, 0x22F0, "Codicrypt (22F0)"          }, // 14 | ||||||
|  |   {0x2600, 0x2600, "BISS (2600)"               }, // 15 | ||||||
|  |   {0x2719, 0x2719, "VanyaCas (2719)"           }, // 16 | ||||||
|  |   {0x4347, 0x4347, "CryptOn (4347)"            }, // 17 | ||||||
|  |   {0x4800, 0x4800, "Accessgate (4800)"         }, // 18 | ||||||
|  |   {0x4900, 0x4900, "China Crypt (4900)"        }, // 19 | ||||||
|  |   {0x4A02, 0x4A02, "Tongfang (4A02)"           }, // 20 | ||||||
|  |   {0x4A10, 0x4A10, "EasyCas (4A10)"            }, // 21 | ||||||
|  |   {0x4A20, 0x4A20, "AlphaCrypt (4A20)"         }, // 22 | ||||||
|  |   {0x4A60, 0x4A60, "SkyCrypt (4A60)"           }, // 23 | ||||||
|  |   {0x4A61, 0x4A61, "Neotioncrypt (4A61)"       }, // 24 | ||||||
|  |   {0x4A62, 0x4A62, "SkyCrypt (4A62)"           }, // 25 | ||||||
|  |   {0x4A63, 0x4A63, "Neotion SHL (4A63)"        }, // 26 | ||||||
|  |   {0x4A64, 0x4A6F, "SkyCrypt (4A64)"           }, // 27 | ||||||
|  |   {0x4A70, 0x4A70, "DreamCrypt (4A70)"         }, // 28 | ||||||
|  |   {0x4A80, 0x4A80, "ThalesCrypt (4A80)"        }, // 29 | ||||||
|  |   {0x4AA1, 0x4AA1, "KeyFly (4AA1)"             }, // 30 | ||||||
|  |   {0x4ABF, 0x4ABF, "CTI-CAS (4ABF)"            }, // 31 | ||||||
|  |   {0x4AC1, 0x4AC1, "Latens (4AC1)"             }, // 32 | ||||||
|  |   {0x4AD0, 0x4AD1, "X-Crypt (4AD0)"            }, // 33 | ||||||
|  |   {0x4AD4, 0x4AD4, "OmniCrypt (4AD4)"          }, // 34 | ||||||
|  |   {0x4AE0, 0x4AE1, "Z-Crypt (4AE0)"            }, // 35 | ||||||
|  |   {0x4AE4, 0x4AE4, "CoreCrypt (4AE4)"          }, // 36 | ||||||
|  |   {0x4AE5, 0x4AE5, "PRO-Crypt (4AE5)"          }, // 37 | ||||||
|  |   {0x4AEA, 0x4AEA, "Cryptoguard (4AEA)"        }, // 38 | ||||||
|  |   {0x4AEB, 0x4AEB, "Abel Quintic (4AEB)"       }, // 39 | ||||||
|  |   {0x4AF0, 0x4AF0, "ABV (4AF0)"                }, // 40 | ||||||
|  |   {0x5500, 0x5500, "Z-Crypt (5500)"            }, // 41 | ||||||
|  |   {0x5501, 0x5501, "Griffin (5501)"            }, // 42 | ||||||
|  |   {0x5581, 0x5581, "Bulcrypt (5581)"           }, // 43 | ||||||
|  |   {0x7BE1, 0x7BE1, "DRE-Crypt (7BE1)"          }, // 44 | ||||||
|  |   {0xA101, 0xA101, "RosCrypt-M (A101)"         }, // 45 | ||||||
|  |   {0xEAD0, 0xEAD0, "VanyaCas (EAD0)"           }, // 46 | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | bool checkCASystem(unsigned int cicamP, int caidP) | ||||||
|  | { | ||||||
|  |   // always skip the first row | ||||||
|  |   if ((cicamP > 0) && (cicamP < ELEMENTS(ca_systems_table))) | ||||||
|  |      return ((caidP >= ca_systems_table[cicamP].start) && (caidP <= ca_systems_table[cicamP].end)); | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										66
									
								
								common.h
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								common.h
									
									
									
									
									
								
							| @@ -13,8 +13,6 @@ | |||||||
| #include <vdr/config.h> | #include <vdr/config.h> | ||||||
| #include <vdr/i18n.h> | #include <vdr/i18n.h> | ||||||
|  |  | ||||||
| #define ELEMENTS(x)                      (sizeof(x) / sizeof(x[0])) |  | ||||||
|  |  | ||||||
| #define SATIP_MAX_DEVICES                MAXDEVICES | #define SATIP_MAX_DEVICES                MAXDEVICES | ||||||
|  |  | ||||||
| #define SATIP_BUFFER_SIZE                KILOBYTE(1024) | #define SATIP_BUFFER_SIZE                KILOBYTE(1024) | ||||||
| @@ -29,12 +27,15 @@ | |||||||
| #define SATIP_STATS_ACTIVE_PIDS_COUNT    10 | #define SATIP_STATS_ACTIVE_PIDS_COUNT    10 | ||||||
| #define SATIP_STATS_ACTIVE_FILTERS_COUNT 10 | #define SATIP_STATS_ACTIVE_FILTERS_COUNT 10 | ||||||
|  |  | ||||||
| #define MAX_DISABLED_SOURCES_COUNT       5 | #define MAX_DISABLED_SOURCES_COUNT       25 | ||||||
| #define SECTION_FILTER_TABLE_SIZE        5 | #define SECTION_FILTER_TABLE_SIZE        5 | ||||||
|  |  | ||||||
|  | #define MAX_CICAM_COUNT                  2 | ||||||
|  | #define CA_SYSTEMS_TABLE_SIZE            47 | ||||||
|  |  | ||||||
| #define SATIP_CURL_EASY_GETINFO(X, Y, Z) \ | #define SATIP_CURL_EASY_GETINFO(X, Y, Z) \ | ||||||
|   if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \ |   if ((res = curl_easy_getinfo((X), (Y), (Z))) != CURLE_OK) { \ | ||||||
|      error("curl_easy_getinfo(%s) [%s,%d] failed: %s (%d)", #Y,  __FILE__, __LINE__, curl_easy_strerror(res), res); \ |      esyslog("curl_easy_getinfo(%s) [%s,%d] failed: %s (%d)", #Y,  __FILE__, __LINE__, curl_easy_strerror(res), res); \ | ||||||
|      } |      } | ||||||
|  |  | ||||||
| #define SATIP_CURL_EASY_SETOPT(X, Y, Z) \ | #define SATIP_CURL_EASY_SETOPT(X, Y, Z) \ | ||||||
| @@ -81,7 +82,53 @@ | |||||||
|         }                        \ |         }                        \ | ||||||
|   } while (0) |   } while (0) | ||||||
|  |  | ||||||
| #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | #define ELEMENTS(x) (sizeof(x) / sizeof(x[0])) | ||||||
|  |  | ||||||
|  | class cSatipMemoryBuffer { | ||||||
|  | private: | ||||||
|  |   enum { | ||||||
|  |     eMaxDataSize = MEGABYTE(2) | ||||||
|  |   }; | ||||||
|  |   char *dataM; | ||||||
|  |   size_t sizeM; | ||||||
|  |   void *AllocBuffer(void *ptrP, size_t sizeP) | ||||||
|  |   { | ||||||
|  |     // There might be a realloc() out there that doesn't like reallocing NULL pointers, so we take care of it here | ||||||
|  |     if (ptrP) | ||||||
|  |        return realloc(ptrP, sizeP); | ||||||
|  |     else | ||||||
|  |        return malloc(sizeP); | ||||||
|  |   } | ||||||
|  |   // to prevent copy constructor and assignment | ||||||
|  |   cSatipMemoryBuffer(const cSatipMemoryBuffer&); | ||||||
|  |   cSatipMemoryBuffer& operator=(const cSatipMemoryBuffer&); | ||||||
|  | public: | ||||||
|  |   cSatipMemoryBuffer() : dataM(NULL), sizeM(0) {} | ||||||
|  |   ~cSatipMemoryBuffer() { Reset(); } | ||||||
|  |   size_t Add(char *dataP, size_t sizeP) | ||||||
|  |   { | ||||||
|  |      if (sizeP > 0) { | ||||||
|  |         size_t len = sizeM + sizeP + 1; | ||||||
|  |         if (len < eMaxDataSize) { | ||||||
|  |            dataM = (char *)AllocBuffer(dataM, len); | ||||||
|  |            if (dataM) { | ||||||
|  |               memcpy(&(dataM[sizeM]), dataP, sizeP); | ||||||
|  |               sizeM += sizeP; | ||||||
|  |               dataM[sizeM] = 0; | ||||||
|  |               return sizeP; | ||||||
|  |               } | ||||||
|  |            else | ||||||
|  |               esyslog("[%s,%d]: Failed to allocate memory", __FILE__, __LINE__); | ||||||
|  |           } | ||||||
|  |        else | ||||||
|  |           esyslog("[%s,%d]: Buffer overflow", __FILE__, __LINE__); | ||||||
|  |        } | ||||||
|  |      return 0; | ||||||
|  |   }; | ||||||
|  |   char *Data(void) { return dataM; } | ||||||
|  |   size_t Size(void) { return sizeM; } | ||||||
|  |   void Reset(void) { FREE_POINTER(dataM); sizeM = 0; }; | ||||||
|  | }; | ||||||
|  |  | ||||||
| uint16_t ts_pid(const uint8_t *bufP); | uint16_t ts_pid(const uint8_t *bufP); | ||||||
| uint8_t payload(const uint8_t *bufP); | uint8_t payload(const uint8_t *bufP); | ||||||
| @@ -100,6 +147,15 @@ struct section_filter_table_type { | |||||||
|  |  | ||||||
| extern const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE]; | extern const section_filter_table_type section_filter_table[SECTION_FILTER_TABLE_SIZE]; | ||||||
|  |  | ||||||
|  | struct ca_systems_table_type { | ||||||
|  |   int start; | ||||||
|  |   int end; | ||||||
|  |   const char *description; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | extern const ca_systems_table_type ca_systems_table[CA_SYSTEMS_TABLE_SIZE]; | ||||||
|  | extern bool checkCASystem(unsigned int cicamP, int caidP); | ||||||
|  |  | ||||||
| extern const char VERSION[]; | extern const char VERSION[]; | ||||||
|  |  | ||||||
| #endif // __SATIP_COMMON_H | #endif // __SATIP_COMMON_H | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								config.c
									
									
									
									
									
								
							| @@ -14,56 +14,66 @@ cSatipConfig SatipConfig; | |||||||
| cSatipConfig::cSatipConfig(void) | cSatipConfig::cSatipConfig(void) | ||||||
| : operatingModeM(eOperatingModeLow), | : operatingModeM(eOperatingModeLow), | ||||||
|   traceModeM(eTraceModeNormal), |   traceModeM(eTraceModeNormal), | ||||||
|  |   ciExtensionM(0), | ||||||
|   eitScanM(1), |   eitScanM(1), | ||||||
|   useBytesM(1) |   useBytesM(1), | ||||||
|  |   detachedModeM(false), | ||||||
|  |   disableServerQuirksM(false), | ||||||
|  |   useSingleModelServersM(false) | ||||||
| { | { | ||||||
|   for (unsigned int i = 0; i < ARRAY_SIZE(disabledSourcesM); ++i) |   for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i) | ||||||
|  |       cicamsM[i] = 0; | ||||||
|  |   for (unsigned int i = 0; i < ELEMENTS(disabledSourcesM); ++i) | ||||||
|       disabledSourcesM[i] = cSource::stNone; |       disabledSourcesM[i] = cSource::stNone; | ||||||
|   for (unsigned int i = 0; i < ARRAY_SIZE(disabledFiltersM); ++i) |   for (unsigned int i = 0; i < ELEMENTS(disabledFiltersM); ++i) | ||||||
|       disabledFiltersM[i] = -1; |       disabledFiltersM[i] = -1; | ||||||
|   memset(configDirectoryM, 0, sizeof(configDirectoryM)); | } | ||||||
|  |  | ||||||
|  | int cSatipConfig::GetCICAM(unsigned int indexP) const | ||||||
|  | { | ||||||
|  |   return (indexP < ELEMENTS(cicamsM)) ? cicamsM[indexP] : -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void cSatipConfig::SetCICAM(unsigned int indexP, int cicamP) | ||||||
|  | { | ||||||
|  |   if (indexP < ELEMENTS(cicamsM)) | ||||||
|  |      cicamsM[indexP] = cicamP; | ||||||
| } | } | ||||||
|  |  | ||||||
| unsigned int cSatipConfig::GetDisabledSourcesCount(void) const | unsigned int cSatipConfig::GetDisabledSourcesCount(void) const | ||||||
| { | { | ||||||
|   unsigned int n = 0; |   unsigned int n = 0; | ||||||
|   while ((n < ARRAY_SIZE(disabledSourcesM) && (disabledSourcesM[n] != cSource::stNone))) |   while ((n < ELEMENTS(disabledSourcesM) && (disabledSourcesM[n] != cSource::stNone))) | ||||||
|         n++; |         n++; | ||||||
|   return n; |   return n; | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipConfig::GetDisabledSources(unsigned int indexP) const | int cSatipConfig::GetDisabledSources(unsigned int indexP) const | ||||||
| { | { | ||||||
|   return (indexP < ARRAY_SIZE(disabledSourcesM)) ? disabledSourcesM[indexP] : cSource::stNone; |   return (indexP < ELEMENTS(disabledSourcesM)) ? disabledSourcesM[indexP] : cSource::stNone; | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipConfig::SetDisabledSources(unsigned int indexP, int sourceP) | void cSatipConfig::SetDisabledSources(unsigned int indexP, int sourceP) | ||||||
| { | { | ||||||
|   if (indexP < ARRAY_SIZE(disabledSourcesM)) |   if (indexP < ELEMENTS(disabledSourcesM)) | ||||||
|      disabledSourcesM[indexP] = sourceP; |      disabledSourcesM[indexP] = sourceP; | ||||||
| } | } | ||||||
|  |  | ||||||
| unsigned int cSatipConfig::GetDisabledFiltersCount(void) const | unsigned int cSatipConfig::GetDisabledFiltersCount(void) const | ||||||
| { | { | ||||||
|   unsigned int n = 0; |   unsigned int n = 0; | ||||||
|   while ((n < ARRAY_SIZE(disabledFiltersM) && (disabledFiltersM[n] != -1))) |   while ((n < ELEMENTS(disabledFiltersM) && (disabledFiltersM[n] != -1))) | ||||||
|         n++; |         n++; | ||||||
|   return n; |   return n; | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipConfig::GetDisabledFilters(unsigned int indexP) const | int cSatipConfig::GetDisabledFilters(unsigned int indexP) const | ||||||
| { | { | ||||||
|   return (indexP < ARRAY_SIZE(disabledFiltersM)) ? disabledFiltersM[indexP] : -1; |   return (indexP < ELEMENTS(disabledFiltersM)) ? disabledFiltersM[indexP] : -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipConfig::SetDisabledFilters(unsigned int indexP, int numberP) | void cSatipConfig::SetDisabledFilters(unsigned int indexP, int numberP) | ||||||
| { | { | ||||||
|   if (indexP < ARRAY_SIZE(disabledFiltersM)) |   if (indexP < ELEMENTS(disabledFiltersM)) | ||||||
|      disabledFiltersM[indexP] = numberP; |      disabledFiltersM[indexP] = numberP; | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipConfig::SetConfigDirectory(const char *directoryP) |  | ||||||
| { |  | ||||||
|   debug1("%s (%s)", __PRETTY_FUNCTION__, directoryP); |  | ||||||
|   ERROR_IF(!realpath(directoryP, configDirectoryM), "Cannot canonicalize configuration directory"); |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								config.h
									
									
									
									
									
								
							| @@ -16,11 +16,15 @@ class cSatipConfig | |||||||
| private: | private: | ||||||
|   unsigned int operatingModeM; |   unsigned int operatingModeM; | ||||||
|   unsigned int traceModeM; |   unsigned int traceModeM; | ||||||
|  |   unsigned int ciExtensionM; | ||||||
|   unsigned int eitScanM; |   unsigned int eitScanM; | ||||||
|   unsigned int useBytesM; |   unsigned int useBytesM; | ||||||
|  |   bool detachedModeM; | ||||||
|  |   bool disableServerQuirksM; | ||||||
|  |   bool useSingleModelServersM; | ||||||
|  |   int cicamsM[MAX_CICAM_COUNT]; | ||||||
|   int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT]; |   int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT]; | ||||||
|   int disabledFiltersM[SECTION_FILTER_TABLE_SIZE]; |   int disabledFiltersM[SECTION_FILTER_TABLE_SIZE]; | ||||||
|   char configDirectoryM[PATH_MAX]; |  | ||||||
|  |  | ||||||
| public: | public: | ||||||
|   enum eOperatingMode { |   enum eOperatingMode { | ||||||
| @@ -59,9 +63,13 @@ public: | |||||||
|   void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % eOperatingModeCount; } |   void ToggleOperatingMode(void) { operatingModeM = (operatingModeM + 1) % eOperatingModeCount; } | ||||||
|   unsigned int GetTraceMode(void) const { return traceModeM; } |   unsigned int GetTraceMode(void) const { return traceModeM; } | ||||||
|   bool IsTraceMode(eTraceMode modeP) const { return (traceModeM & modeP); } |   bool IsTraceMode(eTraceMode modeP) const { return (traceModeM & modeP); } | ||||||
|  |   unsigned int GetCIExtension(void) const { return ciExtensionM; } | ||||||
|  |   int GetCICAM(unsigned int indexP) const; | ||||||
|   unsigned int GetEITScan(void) const { return eitScanM; } |   unsigned int GetEITScan(void) const { return eitScanM; } | ||||||
|   unsigned int GetUseBytes(void) const { return useBytesM; } |   unsigned int GetUseBytes(void) const { return useBytesM; } | ||||||
|   const char *GetConfigDirectory(void) const { return configDirectoryM; } |   bool GetDetachedMode(void) const { return detachedModeM; } | ||||||
|  |   bool GetDisableServerQuirks(void) const { return disableServerQuirksM; } | ||||||
|  |   bool GetUseSingleModelServers(void) const { return useSingleModelServersM; } | ||||||
|   unsigned int GetDisabledSourcesCount(void) const; |   unsigned int GetDisabledSourcesCount(void) const; | ||||||
|   int GetDisabledSources(unsigned int indexP) const; |   int GetDisabledSources(unsigned int indexP) const; | ||||||
|   unsigned int GetDisabledFiltersCount(void) const; |   unsigned int GetDisabledFiltersCount(void) const; | ||||||
| @@ -69,9 +77,13 @@ public: | |||||||
|  |  | ||||||
|   void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; } |   void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; } | ||||||
|   void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); } |   void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); } | ||||||
|  |   void SetCIExtension(unsigned int onOffP) { ciExtensionM = onOffP; } | ||||||
|  |   void SetCICAM(unsigned int indexP, int cicamP); | ||||||
|   void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; } |   void SetEITScan(unsigned int onOffP) { eitScanM = onOffP; } | ||||||
|   void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; } |   void SetUseBytes(unsigned int onOffP) { useBytesM = onOffP; } | ||||||
|   void SetConfigDirectory(const char *directoryP); |   void SetDetachedMode(bool onOffP) { detachedModeM = onOffP; } | ||||||
|  |   void SetDisableServerQuirks(bool onOffP) { disableServerQuirksM = onOffP; } | ||||||
|  |   void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; } | ||||||
|   void SetDisabledSources(unsigned int indexP, int sourceP); |   void SetDisabledSources(unsigned int indexP, int sourceP); | ||||||
|   void SetDisabledFilters(unsigned int indexP, int numberP); |   void SetDisabledFilters(unsigned int indexP, int numberP); | ||||||
| }; | }; | ||||||
|   | |||||||
							
								
								
									
										58
									
								
								device.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								device.c
									
									
									
									
									
								
							| @@ -217,7 +217,13 @@ int cSatipDevice::SignalQuality(void) const | |||||||
|  |  | ||||||
| bool cSatipDevice::ProvidesSource(int sourceP) const | bool cSatipDevice::ProvidesSource(int sourceP) const | ||||||
| { | { | ||||||
|   debug9("%s (%c) [device %u]", __PRETTY_FUNCTION__, cSource::ToChar(sourceP), deviceIndexM); |   cSource *s = Sources.Get(sourceP); | ||||||
|  |   debug9("%s (%c) desc='%s' [device %u]", __PRETTY_FUNCTION__, cSource::ToChar(sourceP), s ? s->Description() : "", deviceIndexM); | ||||||
|  |   if (SatipConfig.GetDetachedMode()) | ||||||
|  |      return false; | ||||||
|  |   // source descriptions starting with '0' are disabled | ||||||
|  |   if (s && s->Description() && (*(s->Description()) == '0')) | ||||||
|  |      return false; | ||||||
|   if (!SatipConfig.IsOperatingModeOff() && !!cSatipDiscover::GetInstance()->GetServer(sourceP)) { |   if (!SatipConfig.IsOperatingModeOff() && !!cSatipDiscover::GetInstance()->GetServer(sourceP)) { | ||||||
|      int numDisabledSourcesM = SatipConfig.GetDisabledSourcesCount(); |      int numDisabledSourcesM = SatipConfig.GetDisabledSourcesCount(); | ||||||
|      for (int i = 0; i < numDisabledSourcesM; ++i) { |      for (int i = 0; i < numDisabledSourcesM; ++i) { | ||||||
| @@ -324,20 +330,19 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP) | |||||||
|         return false; |         return false; | ||||||
|         } |         } | ||||||
|      cString address; |      cString address; | ||||||
|      cSatipServer *server = cSatipDiscover::GetInstance()->GetServer(channelP->Source(), channelP->Transponder(), dtp.System()); |      cSatipServer *server = cSatipDiscover::GetInstance()->AssignServer(deviceIndexM, channelP->Source(), channelP->Transponder(), dtp.System()); | ||||||
|      if (!server) { |      if (!server) { | ||||||
|         debug1("%s No suitable server found [device %u]", __PRETTY_FUNCTION__, deviceIndexM); |         debug9("%s No suitable server found [device %u]", __PRETTY_FUNCTION__, deviceIndexM); | ||||||
|         return false; |         return false; | ||||||
|         } |         } | ||||||
|      cSatipDiscover::GetInstance()->SetTransponder(server, channelP->Transponder()); |      if (pTunerM && pTunerM->SetSource(server, channelP->Transponder(), *params, deviceIndexM)) { | ||||||
|      if (pTunerM && pTunerM->SetSource(server, *params, deviceIndexM)) { |  | ||||||
|         deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server)); |  | ||||||
|         channelM = *channelP; |         channelM = *channelP; | ||||||
|  |         deviceNameM = cString::sprintf("%s %d %s", *DeviceType(), deviceIndexM, *cSatipDiscover::GetInstance()->GetServerString(server)); | ||||||
|         return true; |         return true; | ||||||
|         } |         } | ||||||
|      } |      } | ||||||
|   else if (pTunerM) { |   else if (pTunerM) { | ||||||
|      pTunerM->SetSource(NULL, NULL, deviceIndexM); |      pTunerM->SetSource(NULL, 0, NULL, deviceIndexM); | ||||||
|      return true; |      return true; | ||||||
|      } |      } | ||||||
|   return false; |   return false; | ||||||
| @@ -345,7 +350,7 @@ bool cSatipDevice::SetChannelDevice(const cChannel *channelP, bool liveViewP) | |||||||
|  |  | ||||||
| bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP) | bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP) | ||||||
| { | { | ||||||
|   debug9("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP->pid, typeP, onP, deviceIndexM); |   debug12("%s (%d, %d, %d) [device %u]", __PRETTY_FUNCTION__, handleP->pid, typeP, onP, deviceIndexM); | ||||||
|   if (pTunerM && handleP && handleP->pid >= 0) { |   if (pTunerM && handleP && handleP->pid >= 0) { | ||||||
|      if (onP) |      if (onP) | ||||||
|         return pTunerM->SetPid(handleP->pid, typeP, true); |         return pTunerM->SetPid(handleP->pid, typeP, true); | ||||||
| @@ -357,7 +362,7 @@ bool cSatipDevice::SetPid(cPidHandle *handleP, int typeP, bool onP) | |||||||
|  |  | ||||||
| int cSatipDevice::OpenFilter(u_short pidP, u_char tidP, u_char maskP) | int cSatipDevice::OpenFilter(u_short pidP, u_char tidP, u_char maskP) | ||||||
| { | { | ||||||
|   debug9("%s (%d, %02X, %02X) [device %d]", __PRETTY_FUNCTION__, pidP, tidP, maskP, deviceIndexM); |   debug12("%s (%d, %02X, %02X) [device %d]", __PRETTY_FUNCTION__, pidP, tidP, maskP, deviceIndexM); | ||||||
|   if (pSectionFilterHandlerM) { |   if (pSectionFilterHandlerM) { | ||||||
|      int handle = pSectionFilterHandlerM->Open(pidP, tidP, maskP); |      int handle = pSectionFilterHandlerM->Open(pidP, tidP, maskP); | ||||||
|      if (pTunerM && (handle >= 0)) |      if (pTunerM && (handle >= 0)) | ||||||
| @@ -371,7 +376,7 @@ void cSatipDevice::CloseFilter(int handleP) | |||||||
| { | { | ||||||
|   if (pSectionFilterHandlerM) { |   if (pSectionFilterHandlerM) { | ||||||
|      int pid = pSectionFilterHandlerM->GetPid(handleP); |      int pid = pSectionFilterHandlerM->GetPid(handleP); | ||||||
|      debug9("%s (%d) [device %u]", __PRETTY_FUNCTION__, pid, deviceIndexM); |      debug12("%s (%d) [device %u]", __PRETTY_FUNCTION__, pid, deviceIndexM); | ||||||
|      if (pTunerM) |      if (pTunerM) | ||||||
|         pTunerM->SetPid(pid, ptOther, false); |         pTunerM->SetPid(pid, ptOther, false); | ||||||
|      pSectionFilterHandlerM->Close(handleP); |      pSectionFilterHandlerM->Close(handleP); | ||||||
| @@ -406,7 +411,7 @@ bool cSatipDevice::HasLock(int timeoutMsP) const | |||||||
| bool cSatipDevice::HasInternalCam(void) | bool cSatipDevice::HasInternalCam(void) | ||||||
| { | { | ||||||
|   debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); |   debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); | ||||||
|   return false; |   return SatipConfig.GetCIExtension(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipDevice::WriteData(uchar *bufferP, int lengthP) | void cSatipDevice::WriteData(uchar *bufferP, int lengthP) | ||||||
| @@ -428,6 +433,33 @@ int cSatipDevice::GetId(void) | |||||||
|   return deviceIndexM; |   return deviceIndexM; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int cSatipDevice::GetPmtPid(void) | ||||||
|  | { | ||||||
|  |   int pid = channelM.Ca() ? ::GetPmtPid(channelM.Source(), channelM.Transponder(), channelM.Sid()) : 0; | ||||||
|  |   debug11("%s pmtpid=%d source=%c transponder=%d sid=%d name=%s [device %u]", __PRETTY_FUNCTION__, pid, cSource::ToChar(channelM.Source()), channelM.Transponder(), channelM.Sid(), channelM.Name(), deviceIndexM); | ||||||
|  |   return pid; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cSatipDevice::GetCISlot(void) | ||||||
|  | { | ||||||
|  |   int slot = 0; | ||||||
|  |   int ca = 0; | ||||||
|  |   for (const int *id = channelM.Caids(); *id; ++id) { | ||||||
|  |       if (checkCASystem(SatipConfig.GetCICAM(0), *id)) { | ||||||
|  |          ca = *id; | ||||||
|  |          slot = 1; | ||||||
|  |          break; | ||||||
|  |          } | ||||||
|  |       else if (checkCASystem(SatipConfig.GetCICAM(1), *id)) { | ||||||
|  |          ca = *id; | ||||||
|  |          slot = 2; | ||||||
|  |          break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |   debug11("%s slot=%d ca=%X name=%s [device %u]", __PRETTY_FUNCTION__, slot, ca, channelM.Name(), deviceIndexM); | ||||||
|  |   return slot; | ||||||
|  | } | ||||||
|  |  | ||||||
| uchar *cSatipDevice::GetData(int *availableP) | uchar *cSatipDevice::GetData(int *availableP) | ||||||
| { | { | ||||||
|   debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); |   debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); | ||||||
| @@ -471,8 +503,9 @@ void cSatipDevice::SkipData(int countP) | |||||||
| bool cSatipDevice::GetTSPacket(uchar *&dataP) | bool cSatipDevice::GetTSPacket(uchar *&dataP) | ||||||
| { | { | ||||||
|   debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); |   debug16("%s [device %u]", __PRETTY_FUNCTION__, deviceIndexM); | ||||||
|  |   if (SatipConfig.GetDetachedMode()) | ||||||
|  |      return false; | ||||||
|   if (tsBufferM) { |   if (tsBufferM) { | ||||||
| #if defined(APIVERSNUM) && APIVERSNUM >= 20104 |  | ||||||
|      if (cCamSlot *cs = CamSlot()) { |      if (cCamSlot *cs = CamSlot()) { | ||||||
|         if (cs->WantsTsData()) { |         if (cs->WantsTsData()) { | ||||||
|            int available; |            int available; | ||||||
| @@ -484,7 +517,6 @@ bool cSatipDevice::GetTSPacket(uchar *&dataP) | |||||||
|            return true; |            return true; | ||||||
|            } |            } | ||||||
|         } |         } | ||||||
| #endif |  | ||||||
|      dataP = GetData(); |      dataP = GetData(); | ||||||
|      return true; |      return true; | ||||||
|      } |      } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								device.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								device.h
									
									
									
									
									
								
							| @@ -108,6 +108,8 @@ public: | |||||||
| public: | public: | ||||||
|   virtual void WriteData(u_char *bufferP, int lengthP); |   virtual void WriteData(u_char *bufferP, int lengthP); | ||||||
|   virtual int GetId(void); |   virtual int GetId(void); | ||||||
|  |   virtual int GetPmtPid(void); | ||||||
|  |   virtual int GetCISlot(void); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // __SATIP_DEVICE_H | #endif // __SATIP_DEVICE_H | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ public: | |||||||
|   virtual ~cSatipDeviceIf() {} |   virtual ~cSatipDeviceIf() {} | ||||||
|   virtual void WriteData(u_char *bufferP, int lengthP) = 0; |   virtual void WriteData(u_char *bufferP, int lengthP) = 0; | ||||||
|   virtual int GetId(void) = 0; |   virtual int GetId(void) = 0; | ||||||
|  |   virtual int GetPmtPid(void) = 0; | ||||||
|  |   virtual int GetCISlot(void) = 0; | ||||||
|  |  | ||||||
| private: | private: | ||||||
|   cSatipDeviceIf(const cSatipDeviceIf&); |   cSatipDeviceIf(const cSatipDeviceIf&); | ||||||
|   | |||||||
							
								
								
									
										147
									
								
								discover.c
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								discover.c
									
									
									
									
									
								
							| @@ -47,43 +47,14 @@ void cSatipDiscover::Destroy(void) | |||||||
|      instanceS->Deactivate(); |      instanceS->Deactivate(); | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t cSatipDiscover::WriteCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP) | size_t cSatipDiscover::DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP) | ||||||
| { | { | ||||||
|   cSatipDiscover *obj = reinterpret_cast<cSatipDiscover *>(dataP); |   cSatipDiscover *obj = reinterpret_cast<cSatipDiscover *>(dataP); | ||||||
|   size_t len = sizeP * nmembP; |   size_t len = sizeP * nmembP; | ||||||
|   debug16("%s len=%zu", __PRETTY_FUNCTION__, len); |   debug16("%s len=%zu", __PRETTY_FUNCTION__, len); | ||||||
|  |  | ||||||
|   if (obj) { |   if (obj && (len > 0)) | ||||||
|      CURLcode res = CURLE_OK; |      obj->dataBufferM.Add(ptrP, len); | ||||||
|      const char *desc = NULL, *model = NULL, *addr = NULL; |  | ||||||
| #ifdef USE_TINYXML |  | ||||||
|      TiXmlDocument doc; |  | ||||||
|      char *xml = MALLOC(char, len + 1); |  | ||||||
|      memcpy(xml, ptrP, len); |  | ||||||
|      *(xml + len + 1) = 0; |  | ||||||
|      doc.Parse((const char *)xml); |  | ||||||
|      TiXmlHandle docHandle(&doc); |  | ||||||
|      TiXmlElement *descElement = docHandle.FirstChild("root").FirstChild("device").FirstChild("friendlyName").ToElement(); |  | ||||||
|      if (descElement) |  | ||||||
|         desc = descElement->GetText() ? descElement->GetText() : "MyBrokenHardware"; |  | ||||||
|      TiXmlElement *modelElement = docHandle.FirstChild("root").FirstChild("device").FirstChild("satip:X_SATIPCAP").ToElement(); |  | ||||||
|      if (modelElement) |  | ||||||
|         model = modelElement->GetText() ? modelElement->GetText() : "DVBS2-1"; |  | ||||||
| #else |  | ||||||
|      pugi::xml_document doc; |  | ||||||
|      pugi::xml_parse_result result = doc.load_buffer(ptrP, len); |  | ||||||
|      if (result) { |  | ||||||
|         pugi::xml_node descNode = doc.first_element_by_path("root/device/friendlyName"); |  | ||||||
|         if (descNode) |  | ||||||
|            desc = descNode.text().as_string("MyBrokenHardware"); |  | ||||||
|         pugi::xml_node modelNode = doc.first_element_by_path("root/device/satip:X_SATIPCAP"); |  | ||||||
|         if (modelNode) |  | ||||||
|            model = modelNode.text().as_string("DVBS2-1"); |  | ||||||
|         } |  | ||||||
| #endif |  | ||||||
|      SATIP_CURL_EASY_GETINFO(obj->handleM, CURLINFO_PRIMARY_IP, &addr); |  | ||||||
|      obj->AddServer(addr, model, desc); |  | ||||||
|      } |  | ||||||
|  |  | ||||||
|   return len; |   return len; | ||||||
| } | } | ||||||
| @@ -120,6 +91,7 @@ int cSatipDiscover::DebugCallback(CURL *handleP, curl_infotype typeP, char *data | |||||||
| cSatipDiscover::cSatipDiscover() | cSatipDiscover::cSatipDiscover() | ||||||
| : cThread("SATIP discover"), | : cThread("SATIP discover"), | ||||||
|   mutexM(), |   mutexM(), | ||||||
|  |   dataBufferM(), | ||||||
|   msearchM(*this), |   msearchM(*this), | ||||||
|   probeUrlListM(), |   probeUrlListM(), | ||||||
|   handleM(curl_easy_init()), |   handleM(curl_easy_init()), | ||||||
| @@ -170,7 +142,7 @@ void cSatipDiscover::Action(void) | |||||||
|            probeIntervalM.Set(eProbeIntervalMs); |            probeIntervalM.Set(eProbeIntervalMs); | ||||||
|            msearchM.Probe(); |            msearchM.Probe(); | ||||||
|            mutexM.Lock(); |            mutexM.Lock(); | ||||||
|            serversM.Cleanup(eProbeIntervalMs * 2); |            serversM.Cleanup(eCleanupTimeoutMs); | ||||||
|            mutexM.Unlock(); |            mutexM.Unlock(); | ||||||
|            } |            } | ||||||
|         mutexM.Lock(); |         mutexM.Lock(); | ||||||
| @@ -195,6 +167,7 @@ void cSatipDiscover::Fetch(const char *urlP) | |||||||
| { | { | ||||||
|   debug1("%s (%s)", __PRETTY_FUNCTION__, urlP); |   debug1("%s (%s)", __PRETTY_FUNCTION__, urlP); | ||||||
|   if (handleM && !isempty(urlP)) { |   if (handleM && !isempty(urlP)) { | ||||||
|  |      const char *addr = NULL; | ||||||
|      long rc = 0; |      long rc = 0; | ||||||
|      CURLcode res = CURLE_OK; |      CURLcode res = CURLE_OK; | ||||||
|  |  | ||||||
| @@ -204,7 +177,7 @@ void cSatipDiscover::Fetch(const char *urlP) | |||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_DEBUGDATA, this); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_DEBUGDATA, this); | ||||||
|  |  | ||||||
|      // Set callback |      // Set callback | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipDiscover::WriteCallback); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipDiscover::DataCallback); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this); | ||||||
|  |  | ||||||
|      // No progress meter and no signaling |      // No progress meter and no signaling | ||||||
| @@ -224,23 +197,75 @@ void cSatipDiscover::Fetch(const char *urlP) | |||||||
|      // Fetch the data |      // Fetch the data | ||||||
|      SATIP_CURL_EASY_PERFORM(handleM); |      SATIP_CURL_EASY_PERFORM(handleM); | ||||||
|      SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc); |      SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc); | ||||||
|      if (rc != 200) |      SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_PRIMARY_IP, &addr); | ||||||
|  |      if (rc == 200) { | ||||||
|  |         ParseDeviceInfo(addr); | ||||||
|  |         dataBufferM.Reset(); | ||||||
|  |         } | ||||||
|  |      else | ||||||
|         error("Discovery detected invalid status code: %ld", rc); |         error("Discovery detected invalid status code: %ld", rc); | ||||||
|      } |      } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void cSatipDiscover::ParseDeviceInfo(const char *addrP) | ||||||
|  | { | ||||||
|  |   debug1("%s (%s)", __PRETTY_FUNCTION__, addrP); | ||||||
|  |   const char *desc = NULL, *model = NULL; | ||||||
|  | #ifdef USE_TINYXML | ||||||
|  |   TiXmlDocument doc; | ||||||
|  |   doc.Parse(dataBufferM.Data()); | ||||||
|  |   TiXmlHandle docHandle(&doc); | ||||||
|  |   TiXmlElement *descElement = docHandle.FirstChild("root").FirstChild("device").FirstChild("friendlyName").ToElement(); | ||||||
|  |   if (descElement) | ||||||
|  |      desc = descElement->GetText() ? descElement->GetText() : "MyBrokenHardware"; | ||||||
|  |   TiXmlElement *modelElement = docHandle.FirstChild("root").FirstChild("device").FirstChild("satip:X_SATIPCAP").ToElement(); | ||||||
|  |   if (modelElement) | ||||||
|  |      model = modelElement->GetText() ? modelElement->GetText() : "DVBS2-1"; | ||||||
|  | #else | ||||||
|  |   pugi::xml_document doc; | ||||||
|  |   if (doc.load_buffer(dataBufferM.Data(), dataBufferM.Size())) { | ||||||
|  |      pugi::xml_node descNode = doc.first_element_by_path("root/device/friendlyName"); | ||||||
|  |      if (descNode) | ||||||
|  |         desc = descNode.text().as_string("MyBrokenHardware"); | ||||||
|  |      pugi::xml_node modelNode = doc.first_element_by_path("root/device/satip:X_SATIPCAP"); | ||||||
|  |      if (modelNode) | ||||||
|  |         model = modelNode.text().as_string("DVBS2-1"); | ||||||
|  |      } | ||||||
|  | #endif | ||||||
|  |   AddServer(addrP, model, desc); | ||||||
|  | } | ||||||
|  |  | ||||||
| void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char * descP) | void cSatipDiscover::AddServer(const char *addrP, const char *modelP, const char * descP) | ||||||
| { | { | ||||||
|   debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP); |   debug1("%s (%s, %s, %s)", __PRETTY_FUNCTION__, addrP, modelP, descP); | ||||||
|   cMutexLock MutexLock(&mutexM); |   cMutexLock MutexLock(&mutexM); | ||||||
|   cSatipServer *tmp = new cSatipServer(addrP, modelP, descP); |   if (SatipConfig.GetUseSingleModelServers() && modelP && !isempty(modelP)) { | ||||||
|   // Validate against existing servers |      int n = 0; | ||||||
|  |      char *s, *p = strdup(modelP); | ||||||
|  |      char *r = strtok_r(p, ",", &s); | ||||||
|  |      while (r) { | ||||||
|  |            r = skipspace(r); | ||||||
|  |            cString desc = cString::sprintf("%s #%d", !isempty(descP) ? descP : "MyBrokenHardware", n++); | ||||||
|  |            cSatipServer *tmp = new cSatipServer(addrP, r, desc); | ||||||
|            if (!serversM.Update(tmp)) { |            if (!serversM.Update(tmp)) { | ||||||
|      info("Adding server '%s|%s|%s'",  tmp->Address(), tmp->Model(), tmp->Description()); |               info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none"); | ||||||
|               serversM.Add(tmp); |               serversM.Add(tmp); | ||||||
|               } |               } | ||||||
|            else |            else | ||||||
|               DELETENULL(tmp); |               DELETENULL(tmp); | ||||||
|  |            r = strtok_r(NULL, ",", &s); | ||||||
|  |            } | ||||||
|  |      FREE_POINTER(p); | ||||||
|  |      } | ||||||
|  |   else { | ||||||
|  |      cSatipServer *tmp = new cSatipServer(addrP, modelP, descP); | ||||||
|  |      if (!serversM.Update(tmp)) { | ||||||
|  |         info("Adding server '%s|%s|%s' CI: %s Quirks: %s", tmp->Address(), tmp->Model(), tmp->Description(), tmp->HasCI() ? "yes" : "no", tmp->HasQuirk() ? tmp->Quirks() : "none"); | ||||||
|  |         serversM.Add(tmp); | ||||||
|  |         } | ||||||
|  |      else | ||||||
|  |         DELETENULL(tmp); | ||||||
|  |      } | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipDiscover::GetServerCount(void) | int cSatipDiscover::GetServerCount(void) | ||||||
| @@ -250,11 +275,18 @@ int cSatipDiscover::GetServerCount(void) | |||||||
|   return serversM.Count(); |   return serversM.Count(); | ||||||
| } | } | ||||||
|  |  | ||||||
| cSatipServer *cSatipDiscover::GetServer(int sourceP, int transponderP, int systemP) | cSatipServer *cSatipDiscover::AssignServer(int deviceIdP, int sourceP, int transponderP, int systemP) | ||||||
| { | { | ||||||
|   debug16("%s (%d, %d, %d)", __PRETTY_FUNCTION__, sourceP, transponderP, systemP); |   debug16("%s (%d, %d, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, sourceP, transponderP, systemP); | ||||||
|   cMutexLock MutexLock(&mutexM); |   cMutexLock MutexLock(&mutexM); | ||||||
|   return serversM.Find(sourceP, transponderP, systemP); |   return serversM.Assign(deviceIdP, sourceP, transponderP, systemP); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | cSatipServer *cSatipDiscover::GetServer(int sourceP) | ||||||
|  | { | ||||||
|  |   debug16("%s (%d)", __PRETTY_FUNCTION__, sourceP); | ||||||
|  |   cMutexLock MutexLock(&mutexM); | ||||||
|  |   return serversM.Find(sourceP); | ||||||
| } | } | ||||||
|  |  | ||||||
| cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP) | cSatipServer *cSatipDiscover::GetServer(cSatipServer *serverP) | ||||||
| @@ -285,18 +317,39 @@ cString cSatipDiscover::GetServerList(void) | |||||||
|   return serversM.List(); |   return serversM.List(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipDiscover::SetTransponder(cSatipServer *serverP, int transponderP) | void cSatipDiscover::AttachServer(cSatipServer *serverP, int deviceIdP, int transponderP) | ||||||
| { | { | ||||||
|   debug16("%s (, %d)", __PRETTY_FUNCTION__, transponderP); |   debug16("%s (, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, transponderP); | ||||||
|   cMutexLock MutexLock(&mutexM); |   cMutexLock MutexLock(&mutexM); | ||||||
|   serversM.SetTransponder(serverP, transponderP); |   serversM.Attach(serverP, deviceIdP, transponderP); | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipDiscover::UseServer(cSatipServer *serverP, bool onOffP) | void cSatipDiscover::DetachServer(cSatipServer *serverP, int deviceIdP, int transponderP) | ||||||
| { | { | ||||||
|   debug16("%s (, %d)", __PRETTY_FUNCTION__, onOffP); |   debug16("%s (, %d, %d)", __PRETTY_FUNCTION__, deviceIdP, transponderP); | ||||||
|   cMutexLock MutexLock(&mutexM); |   cMutexLock MutexLock(&mutexM); | ||||||
|   serversM.Use(serverP, onOffP); |   serversM.Detach(serverP, deviceIdP, transponderP); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipDiscover::IsServerQuirk(cSatipServer *serverP, int quirkP) | ||||||
|  | { | ||||||
|  |   debug16("%s (, %d)", __PRETTY_FUNCTION__, quirkP); | ||||||
|  |   cMutexLock MutexLock(&mutexM); | ||||||
|  |   return serversM.IsQuirk(serverP, quirkP); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipDiscover::HasServerCI(cSatipServer *serverP) | ||||||
|  | { | ||||||
|  |   debug16("%s", __PRETTY_FUNCTION__); | ||||||
|  |   cMutexLock MutexLock(&mutexM); | ||||||
|  |   return serversM.HasCI(serverP); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | cString cSatipDiscover::GetServerAddress(cSatipServer *serverP) | ||||||
|  | { | ||||||
|  |   debug16("%s", __PRETTY_FUNCTION__); | ||||||
|  |   cMutexLock MutexLock(&mutexM); | ||||||
|  |   return serversM.GetAddress(serverP); | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipDiscover::NumProvidedSystems(void) | int cSatipDiscover::NumProvidedSystems(void) | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								discover.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								discover.h
									
									
									
									
									
								
							| @@ -13,6 +13,7 @@ | |||||||
| #include <vdr/thread.h> | #include <vdr/thread.h> | ||||||
| #include <vdr/tools.h> | #include <vdr/tools.h> | ||||||
|  |  | ||||||
|  | #include "common.h" | ||||||
| #include "discoverif.h" | #include "discoverif.h" | ||||||
| #include "msearch.h" | #include "msearch.h" | ||||||
| #include "server.h" | #include "server.h" | ||||||
| @@ -42,12 +43,14 @@ private: | |||||||
|     eSleepTimeoutMs   = 500,   // in milliseconds |     eSleepTimeoutMs   = 500,   // in milliseconds | ||||||
|     eConnectTimeoutMs = 1500,  // in milliseconds |     eConnectTimeoutMs = 1500,  // in milliseconds | ||||||
|     eProbeTimeoutMs   = 2000,  // in milliseconds |     eProbeTimeoutMs   = 2000,  // in milliseconds | ||||||
|     eProbeIntervalMs  = 60000 // in milliseconds |     eProbeIntervalMs  = 60000, // in milliseconds | ||||||
|  |     eCleanupTimeoutMs = 124000 // in milliseoonds | ||||||
|   }; |   }; | ||||||
|   static cSatipDiscover *instanceS; |   static cSatipDiscover *instanceS; | ||||||
|   static size_t WriteCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP); |   static size_t DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP); | ||||||
|   static int    DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP); |   static int    DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP); | ||||||
|   cMutex mutexM; |   cMutex mutexM; | ||||||
|  |   cSatipMemoryBuffer dataBufferM; | ||||||
|   cSatipMsearch msearchM; |   cSatipMsearch msearchM; | ||||||
|   cStringList probeUrlListM; |   cStringList probeUrlListM; | ||||||
|   CURL *handleM; |   CURL *handleM; | ||||||
| @@ -56,6 +59,7 @@ private: | |||||||
|   cSatipServers serversM; |   cSatipServers serversM; | ||||||
|   void Activate(void); |   void Activate(void); | ||||||
|   void Deactivate(void); |   void Deactivate(void); | ||||||
|  |   void ParseDeviceInfo(const char *addrP); | ||||||
|   void AddServer(const char *addrP, const char *modelP, const char *descP); |   void AddServer(const char *addrP, const char *modelP, const char *descP); | ||||||
|   void Fetch(const char *urlP); |   void Fetch(const char *urlP); | ||||||
|   // constructor |   // constructor | ||||||
| @@ -74,12 +78,16 @@ public: | |||||||
|   virtual ~cSatipDiscover(); |   virtual ~cSatipDiscover(); | ||||||
|   void TriggerScan(void) { probeIntervalM.Set(0); } |   void TriggerScan(void) { probeIntervalM.Set(0); } | ||||||
|   int GetServerCount(void); |   int GetServerCount(void); | ||||||
|   cSatipServer *GetServer(int sourceP, int transponderP = 0, int systemP = -1); |   cSatipServer *AssignServer(int deviceIdP, int sourceP, int transponderP, int systemP); | ||||||
|  |   cSatipServer *GetServer(int sourceP); | ||||||
|   cSatipServer *GetServer(cSatipServer *serverP); |   cSatipServer *GetServer(cSatipServer *serverP); | ||||||
|   cSatipServers *GetServers(void); |   cSatipServers *GetServers(void); | ||||||
|   cString GetServerString(cSatipServer *serverP); |   cString GetServerString(cSatipServer *serverP); | ||||||
|   void SetTransponder(cSatipServer *serverP, int transponderP); |   void AttachServer(cSatipServer *serverP, int deviceIdP, int transponderP); | ||||||
|   void UseServer(cSatipServer *serverP, bool onOffP); |   void DetachServer(cSatipServer *serverP, int deviceIdP, int transponderP); | ||||||
|  |   bool IsServerQuirk(cSatipServer *serverP, int quirkP); | ||||||
|  |   bool HasServerCI(cSatipServer *serverP); | ||||||
|  |   cString GetServerAddress(cSatipServer *serverP); | ||||||
|   cString GetServerList(void); |   cString GetServerList(void); | ||||||
|   int NumProvidedSystems(void); |   int NumProvidedSystems(void); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								log.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								log.h
									
									
									
									
									
								
							| @@ -32,11 +32,11 @@ | |||||||
| #define debug9(x...)  void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug9)  ? dsyslog("SATIP9: " x)  : void() ) | #define debug9(x...)  void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug9)  ? dsyslog("SATIP9: " x)  : void() ) | ||||||
| // 0x0200: RTCP packets | // 0x0200: RTCP packets | ||||||
| #define debug10(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug10) ? dsyslog("SATIP10: " x) : void() ) | #define debug10(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug10) ? dsyslog("SATIP10: " x) : void() ) | ||||||
| // 0x0400: TBD | // 0x0400: CI | ||||||
| #define debug11(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug11) ? dsyslog("SATIP11: " x) : void() ) | #define debug11(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug11) ? dsyslog("SATIP11: " x) : void() ) | ||||||
| // 0x0800: TBD | // 0x0800: Pids | ||||||
| #define debug12(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug12) ? dsyslog("SATIP12: " x) : void() ) | #define debug12(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug12) ? dsyslog("SATIP12: " x) : void() ) | ||||||
| // 0x1000: TBD | // 0x1000: Discovery | ||||||
| #define debug13(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug13) ? dsyslog("SATIP13: " x) : void() ) | #define debug13(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug13) ? dsyslog("SATIP13: " x) : void() ) | ||||||
| // 0x2000: TBD | // 0x2000: TBD | ||||||
| #define debug14(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug14) ? dsyslog("SATIP14: " x) : void() ) | #define debug14(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug14) ? dsyslog("SATIP14: " x) : void() ) | ||||||
| @@ -46,4 +46,3 @@ | |||||||
| #define debug16(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug16) ? dsyslog("SATIP16: " x) : void() ) | #define debug16(x...) void( SatipConfig.IsTraceMode(cSatipConfig::eTraceModeDebug16) ? dsyslog("SATIP16: " x) : void() ) | ||||||
|  |  | ||||||
| #endif // __SATIP_LOG_H | #endif // __SATIP_LOG_H | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								msearch.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								msearch.c
									
									
									
									
									
								
							| @@ -35,6 +35,7 @@ cSatipMsearch::cSatipMsearch(cSatipDiscoverIf &discoverP) | |||||||
|  |  | ||||||
| cSatipMsearch::~cSatipMsearch() | cSatipMsearch::~cSatipMsearch() | ||||||
| { | { | ||||||
|  |   FREE_POINTER(bufferM); | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipMsearch::Probe(void) | void cSatipMsearch::Probe(void) | ||||||
| @@ -44,6 +45,9 @@ void cSatipMsearch::Probe(void) | |||||||
|      cSatipPoller::GetInstance()->Register(*this); |      cSatipPoller::GetInstance()->Register(*this); | ||||||
|      registeredM = true; |      registeredM = true; | ||||||
|      } |      } | ||||||
|  |   // Send two queries with one second interval | ||||||
|  |   Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), strlen(bcastMessageS)); | ||||||
|  |   cCondWait::SleepMs(1000); | ||||||
|   Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), strlen(bcastMessageS)); |   Write(bcastAddressS, reinterpret_cast<const unsigned char *>(bcastMessageS), strlen(bcastMessageS)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -59,12 +63,12 @@ void cSatipMsearch::Process(void) | |||||||
|      int length; |      int length; | ||||||
|      while ((length = Read(bufferM, bufferLenM)) > 0) { |      while ((length = Read(bufferM, bufferLenM)) > 0) { | ||||||
|            bufferM[min(length, int(bufferLenM - 1))] = 0; |            bufferM[min(length, int(bufferLenM - 1))] = 0; | ||||||
|            debug3("%s len=%d buf=%s", __PRETTY_FUNCTION__, length, bufferM); |            debug13("%s len=%d buf=%s", __PRETTY_FUNCTION__, length, bufferM); | ||||||
|            bool status = false, valid = false; |            bool status = false, valid = false; | ||||||
|            char *s, *p = reinterpret_cast<char *>(bufferM), *location = NULL; |            char *s, *p = reinterpret_cast<char *>(bufferM), *location = NULL; | ||||||
|            char *r = strtok_r(p, "\r\n", &s); |            char *r = strtok_r(p, "\r\n", &s); | ||||||
|            while (r) { |            while (r) { | ||||||
|                  debug3("%s r=%s", __PRETTY_FUNCTION__, r); |                  debug13("%s r=%s", __PRETTY_FUNCTION__, r); | ||||||
|                  // Check the status code |                  // Check the status code | ||||||
|                  // HTTP/1.1 200 OK |                  // HTTP/1.1 200 OK | ||||||
|                  if (!status && startswith(r, "HTTP/1.1 200 OK")) |                  if (!status && startswith(r, "HTTP/1.1 200 OK")) | ||||||
| @@ -93,8 +97,6 @@ void cSatipMsearch::Process(void) | |||||||
|                  r = strtok_r(NULL, "\r\n", &s); |                  r = strtok_r(NULL, "\r\n", &s); | ||||||
|                  } |                  } | ||||||
|            } |            } | ||||||
|      if (errno != EAGAIN && errno != EWOULDBLOCK) |  | ||||||
|         error("Error %d reading in %s", errno, *ToString()); |  | ||||||
|      } |      } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								param.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								param.c
									
									
									
									
									
								
							| @@ -147,15 +147,6 @@ cString GetTransponderUrlParameters(const cChannel *channelP) | |||||||
|      cDvbTransponderParameters dtp(channelP->Parameters()); |      cDvbTransponderParameters dtp(channelP->Parameters()); | ||||||
|      int DataSlice = 0; |      int DataSlice = 0; | ||||||
|      int C2TuningFrequencyType = 0; |      int C2TuningFrequencyType = 0; | ||||||
| #if defined(APIVERSNUM) && APIVERSNUM < 20106 |  | ||||||
|      int Pilot = PILOT_AUTO; |  | ||||||
|      int T2SystemId = 0; |  | ||||||
|      int SisoMiso = 0; |  | ||||||
| #else |  | ||||||
|      int Pilot = dtp.Pilot(); |  | ||||||
|      int T2SystemId = dtp.T2SystemId(); |  | ||||||
|      int SisoMiso = dtp.SisoMiso(); |  | ||||||
| #endif |  | ||||||
|      float freq = channelP->Frequency(); |      float freq = channelP->Frequency(); | ||||||
|      char type = cSource::ToChar(channelP->Source()); |      char type = cSource::ToChar(channelP->Source()); | ||||||
|      cSource *source = Sources.Get(channelP->Source()); |      cSource *source = Sources.Get(channelP->Source()); | ||||||
| @@ -167,32 +158,37 @@ cString GetTransponderUrlParameters(const cChannel *channelP) | |||||||
|            freq /= 1000L; |            freq /= 1000L; | ||||||
| #define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*'))) | #define ST(s) if (strchr(s, type) && (strchr(s, '0' + dtp.System() + 1) || strchr(s, '*'))) | ||||||
| #define STBUFLEFT (sizeof(buffer) - (q - buffer)) | #define STBUFLEFT (sizeof(buffer) - (q - buffer)) | ||||||
|  |      ST(" S 1") { // to comply with SAT>IP protocol specification 1.2.2 | ||||||
|  |        dtp.SetPilot(PILOT_OFF); | ||||||
|  |        dtp.SetModulation(QPSK); | ||||||
|  |        dtp.SetRollOff(ROLLOFF_35); | ||||||
|  |        } | ||||||
|                 q += snprintf(q,       STBUFLEFT, "freq=%s",          *dtoa(freq, "%lg")); |                 q += snprintf(q,       STBUFLEFT, "freq=%s",          *dtoa(freq, "%lg")); | ||||||
|      ST(" S *") q += snprintf(q,       STBUFLEFT, "&src=%d",          ((src > 0) && (src <= 255)) ? src : 1); |      ST(" S *") q += snprintf(q,       STBUFLEFT, "&src=%d",          ((src > 0) && (src <= 255)) ? src : 1); | ||||||
|      ST(" S *") q += snprintf(q,       STBUFLEFT, "&sr=%d",           channelP->Srate()); |      ST(" S *") q += snprintf(q,       STBUFLEFT, "&sr=%d",           channelP->Srate()); | ||||||
|      ST("C  1") q += snprintf(q,       STBUFLEFT, "&sr=%d",           channelP->Srate()); |      ST("C  1") q += snprintf(q,       STBUFLEFT, "&sr=%d",           channelP->Srate()); | ||||||
|      ST(" S *") q += snprintf(q,       STBUFLEFT, "&pol=%c",          tolower(dtp.Polarization())); |      ST(" S *") q += snprintf(q,       STBUFLEFT, "&pol=%c",          tolower(dtp.Polarization())); | ||||||
|      ST("C T2") q += snprintf(q,       STBUFLEFT, "&plp=%d",          dtp.StreamId()); |      ST("C T2") q += snprintf(q,       STBUFLEFT, "&plp=%d",          dtp.StreamId()); | ||||||
|      ST("  T2") q += snprintf(q,       STBUFLEFT, "&t2id=%d",         T2SystemId); |      ST("  T2") q += snprintf(q,       STBUFLEFT, "&t2id=%d",         dtp.T2SystemId()); | ||||||
|      ST("C  2") q += snprintf(q,       STBUFLEFT, "&c2tft=%d",        C2TuningFrequencyType); |      ST("C  2") q += snprintf(q,       STBUFLEFT, "&c2tft=%d",        C2TuningFrequencyType); | ||||||
|      ST("C  2") q += snprintf(q,       STBUFLEFT, "&ds=%d",           DataSlice); |      ST("C  2") q += snprintf(q,       STBUFLEFT, "&ds=%d",           DataSlice); | ||||||
|      ST("C  1") q += PrintUrlString(q, STBUFLEFT, dtp.Inversion(),    SatipInversionValues); |      ST("C  1") q += PrintUrlString(q, STBUFLEFT, dtp.Inversion(),    SatipInversionValues); | ||||||
|      ST("  T2") q += PrintUrlString(q, STBUFLEFT, SisoMiso,           SatipSisoMisoValues); |      ST("  T2") q += PrintUrlString(q, STBUFLEFT, dtp.SisoMiso(),     SatipSisoMisoValues); | ||||||
|      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(),    SatipBandwidthValues); |      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(),    SatipBandwidthValues); | ||||||
|      ST("C  2") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(),    SatipBandwidthValues); |      ST("C  2") q += PrintUrlString(q, STBUFLEFT, dtp.Bandwidth(),    SatipBandwidthValues); | ||||||
|      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(),        SatipGuardValues); |      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Guard(),        SatipGuardValues); | ||||||
|      ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(),    SatipCodeRateValues); |      ST("CST*") q += PrintUrlString(q, STBUFLEFT, dtp.CoderateH(),    SatipCodeRateValues); | ||||||
|      ST(" S 2") q += PrintUrlString(q, STBUFLEFT, Pilot,              SatipPilotValues); |      ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Pilot(),        SatipPilotValues); | ||||||
|      ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   SatipModulationValues); |      ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   SatipModulationValues); | ||||||
|      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   SatipModulationValues); |      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   SatipModulationValues); | ||||||
|      ST("C  1") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   SatipModulationValues); |      ST("C  1") q += PrintUrlString(q, STBUFLEFT, dtp.Modulation(),   SatipModulationValues); | ||||||
|      ST(" S 2") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(),      SatipRollOffValues); |      ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.RollOff(),      SatipRollOffValues); | ||||||
|      ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.System(),       SatipSystemValuesSat); |      ST(" S *") q += PrintUrlString(q, STBUFLEFT, dtp.System(),       SatipSystemValuesSat); | ||||||
|      ST("C  *") q += PrintUrlString(q, STBUFLEFT, dtp.System(),       SatipSystemValuesCable); |      ST("C  *") q += PrintUrlString(q, STBUFLEFT, dtp.System(),       SatipSystemValuesCable); | ||||||
|      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.System(),       SatipSystemValuesTerrestrial); |      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.System(),       SatipSystemValuesTerrestrial); | ||||||
|      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues); |      ST("  T*") q += PrintUrlString(q, STBUFLEFT, dtp.Transmission(), SatipTransmissionValues); | ||||||
|      if (channelP->Rid() > 0) |      if ((channelP->Rid() % 100) > 0) | ||||||
|                 q += snprintf(q,       STBUFLEFT, "&fe=%d",           channelP->Rid()); |                 snprintf(q,            STBUFLEFT, "&fe=%d",           channelP->Rid() % 100); | ||||||
| #undef ST | #undef ST | ||||||
|      return buffer; |      return buffer; | ||||||
|      } |      } | ||||||
|   | |||||||
							
								
								
									
										54
									
								
								po/ca_ES.po
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								po/ca_ES.po
									
									
									
									
									
								
							| @@ -1,14 +1,14 @@ | |||||||
| # VDR plugin language source file. | # VDR plugin language source file. | ||||||
| # Copyright (C) 2007-2014 Rolf Ahrenberg | # Copyright (C) 2007-2015 Rolf Ahrenberg | ||||||
| # This file is distributed under the same license as the satip package. | # This file is distributed under the same license as the satip package. | ||||||
| # Gabriel Bonich, 2014 | # Gabriel Bonich, 2014-2015 | ||||||
| # | # | ||||||
| msgid "" | msgid "" | ||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: vdr-satip 1.0.0\n" | "Project-Id-Version: vdr-satip 2.2.2\n" | ||||||
| "Report-Msgid-Bugs-To: <see README>\n" | "Report-Msgid-Bugs-To: <see README>\n" | ||||||
| "POT-Creation-Date: 2014-12-24 12:24+0200\n" | "POT-Creation-Date: 2015-04-26 04:26+0300\n" | ||||||
| "PO-Revision-Date: 2014-12-24 12:24+0200\n" | "PO-Revision-Date: 2015-04-26 04:26+0300\n" | ||||||
| "Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n" | "Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n" | ||||||
| "Language-Team: Catalan <vdr@linuxtv.org>\n" | "Language-Team: Catalan <vdr@linuxtv.org>\n" | ||||||
| "Language: ca\n" | "Language: ca\n" | ||||||
| @@ -38,7 +38,7 @@ msgid "SAT>IP Devices" | |||||||
| msgstr "SAT>IP Dispositius" | msgstr "SAT>IP Dispositius" | ||||||
|  |  | ||||||
| msgid "SAT>IP Server" | msgid "SAT>IP Server" | ||||||
| msgstr "" | msgstr "SAT>IP Server" | ||||||
|  |  | ||||||
| msgid "Address" | msgid "Address" | ||||||
| msgstr "Adressa" | msgstr "Adressa" | ||||||
| @@ -49,11 +49,14 @@ msgstr "Model" | |||||||
| msgid "Description" | msgid "Description" | ||||||
| msgstr "Descripció" | msgstr "Descripció" | ||||||
|  |  | ||||||
|  | msgid "CI extension" | ||||||
|  | msgstr "Extensió CI" | ||||||
|  |  | ||||||
| msgid "Creation date" | msgid "Creation date" | ||||||
| msgstr "Creació de data" | msgstr "Creació de data" | ||||||
|  |  | ||||||
| msgid "SAT>IP Device Status" | msgid "SAT>IP Device Status" | ||||||
| msgstr "" | msgstr "SAT>IP Estat Dispositiu" | ||||||
|  |  | ||||||
| msgid "SAT>IP Information" | msgid "SAT>IP Information" | ||||||
| msgstr "SAT>IP Informació" | msgstr "SAT>IP Informació" | ||||||
| @@ -83,7 +86,7 @@ msgid "high" | |||||||
| msgstr "Alt" | msgstr "Alt" | ||||||
|  |  | ||||||
| msgid "Button$Devices" | msgid "Button$Devices" | ||||||
| msgstr "" | msgstr "Dispositius" | ||||||
|  |  | ||||||
| msgid "Operating mode" | msgid "Operating mode" | ||||||
| msgstr "Mode de operació" | msgstr "Mode de operació" | ||||||
| @@ -96,13 +99,37 @@ msgid "" | |||||||
| "normal - devices are working within normal parameters\n" | "normal - devices are working within normal parameters\n" | ||||||
| "high - devices are working at the highest priority" | "high - devices are working at the highest priority" | ||||||
| msgstr "" | msgstr "" | ||||||
| "Defineig la manera de operar els Disposituis SAT>IP:\n" | "Defineig la manera de operar els Dispositius SAT>IP:\n" | ||||||
| "\n" | "\n" | ||||||
| "Apagat - Dispositius desactivats\n" | "Apagat - Dispositius desactivats\n" | ||||||
| "Baix - Dispositius treballan a baixa prioritat\n" | "Baix - Dispositius treballan a baixa prioritat\n" | ||||||
| "Normal - Dispositius treballan en parametres normals\n" | "Normal - Dispositius treballan en parametres normals\n" | ||||||
| "Alta - Dispositius treballan a prioritat Alta" | "Alta - Dispositius treballan a prioritat Alta" | ||||||
|  |  | ||||||
|  | msgid "Enable CI extension" | ||||||
|  | msgstr "Habilita la extenció CI" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define whether a CI extension shall be used.\n" | ||||||
|  | "\n" | ||||||
|  | "This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)." | ||||||
|  | msgstr "" | ||||||
|  | "Definir si s'utilitzarà una extensió de CI.\n" | ||||||
|  | "\n" | ||||||
|  | "Aquesta configuració permet utilitzar CI/CAM integrat que es troba en alguns equips SAT>IP (ex. Digital Devices OctopusNet)." | ||||||
|  |  | ||||||
|  | msgid "CI/CAM" | ||||||
|  | msgstr "CI/CAM" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define a desired CAM type for the CI slot.\n" | ||||||
|  | "\n" | ||||||
|  | "The '---' option lets SAT>IP hardware do the auto-selection." | ||||||
|  | msgstr "" | ||||||
|  | "Definir quin tipus de CAM vols per a la ranura CI.\n" | ||||||
|  | "\n" | ||||||
|  | "L'opció '---' permet l'equip SAT>IP fer la selecció automàtica." | ||||||
|  |  | ||||||
| msgid "Enable EPG scanning" | msgid "Enable EPG scanning" | ||||||
| msgstr "Activa Escanneig EPG" | msgstr "Activa Escanneig EPG" | ||||||
|  |  | ||||||
| @@ -116,7 +143,7 @@ msgstr "" | |||||||
| "Aquesta configuració desactiva la funcionalitat d'escaneig EIT automàtica per a tots els dispositius SAT>IP." | "Aquesta configuració desactiva la funcionalitat d'escaneig EIT automàtica per a tots els dispositius SAT>IP." | ||||||
|  |  | ||||||
| msgid "Disabled sources" | msgid "Disabled sources" | ||||||
| msgstr "" | msgstr "Desactiva entrades" | ||||||
|  |  | ||||||
| msgid "none" | msgid "none" | ||||||
| msgstr "no" | msgstr "no" | ||||||
| @@ -126,9 +153,12 @@ msgid "" | |||||||
| "\n" | "\n" | ||||||
| "SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here." | "SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here." | ||||||
| msgstr "" | msgstr "" | ||||||
|  | "Definir nombre de entrades que es desactiven.\n" | ||||||
|  | "\n" | ||||||
|  | "SAT>IP els servidors podrien no tenir totes les posicions dels satèl·lits disponibles i aquestes entrades poden ser la llista negra." | ||||||
|  |  | ||||||
| msgid "Define a source to be blacklisted." | msgid "Define a source to be blacklisted." | ||||||
| msgstr "" | msgstr "Definir una entrada a la llista negra" | ||||||
|  |  | ||||||
| msgid "Disabled filters" | msgid "Disabled filters" | ||||||
| msgstr "Desactiva filtres" | msgstr "Desactiva filtres" | ||||||
| @@ -149,7 +179,7 @@ msgid "Define an ill-behaving filter to be blacklisted." | |||||||
| msgstr "Definir un filtre mal comportar a la llista negra." | msgstr "Definir un filtre mal comportar a la llista negra." | ||||||
|  |  | ||||||
| msgid "Active SAT>IP servers:" | msgid "Active SAT>IP servers:" | ||||||
| msgstr "" | msgstr "Activa SAT>IP servers:" | ||||||
|  |  | ||||||
| msgid "Help" | msgid "Help" | ||||||
| msgstr "Ajuda" | msgstr "Ajuda" | ||||||
|   | |||||||
							
								
								
									
										45
									
								
								po/de_DE.po
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								po/de_DE.po
									
									
									
									
									
								
							| @@ -1,14 +1,14 @@ | |||||||
| # VDR plugin language source file. | # VDR plugin language source file. | ||||||
| # Copyright (C) 2007-2014 Rolf Ahrenberg | # Copyright (C) 2007-2015 Rolf Ahrenberg | ||||||
| # This file is distributed under the same license as the satip package. | # This file is distributed under the same license as the satip package. | ||||||
| # Frank Neumann, 2014 | # Frank Neumann, 2014-2015 | ||||||
| # | # | ||||||
| msgid "" | msgid "" | ||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: vdr-satip 1.0.0\n" | "Project-Id-Version: vdr-satip 2.2.2\n" | ||||||
| "Report-Msgid-Bugs-To: <see README>\n" | "Report-Msgid-Bugs-To: <see README>\n" | ||||||
| "POT-Creation-Date: 2014-12-24 12:24+0200\n" | "POT-Creation-Date: 2015-04-26 04:26+0300\n" | ||||||
| "PO-Revision-Date: 2014-12-24 12:24+0200\n" | "PO-Revision-Date: 2015-04-26 04:26+0300\n" | ||||||
| "Last-Translator: Frank Neumann <fnu@yavdr.org>\n" | "Last-Translator: Frank Neumann <fnu@yavdr.org>\n" | ||||||
| "Language-Team: German <vdr@linuxtv.org>\n" | "Language-Team: German <vdr@linuxtv.org>\n" | ||||||
| "Language: de\n" | "Language: de\n" | ||||||
| @@ -49,6 +49,9 @@ msgstr "Modell" | |||||||
| msgid "Description" | msgid "Description" | ||||||
| msgstr "Beschreibung" | msgstr "Beschreibung" | ||||||
|  |  | ||||||
|  | msgid "CI extension" | ||||||
|  | msgstr "CI Erweiterung" | ||||||
|  |  | ||||||
| msgid "Creation date" | msgid "Creation date" | ||||||
| msgstr "Zeitpunkt der Erstellung" | msgstr "Zeitpunkt der Erstellung" | ||||||
|  |  | ||||||
| @@ -83,7 +86,7 @@ msgid "high" | |||||||
| msgstr "hoch" | msgstr "hoch" | ||||||
|  |  | ||||||
| msgid "Button$Devices" | msgid "Button$Devices" | ||||||
| msgstr "" | msgstr "Geräte" | ||||||
|  |  | ||||||
| msgid "Operating mode" | msgid "Operating mode" | ||||||
| msgstr "Betriebsmodus" | msgstr "Betriebsmodus" | ||||||
| @@ -103,6 +106,30 @@ msgstr "" | |||||||
| "normal - Geräte arbeiten innerhalb der gewöhnlichen Parameter\n" | "normal - Geräte arbeiten innerhalb der gewöhnlichen Parameter\n" | ||||||
| "hoch - Geräte arbeiten mit höchste Priorität" | "hoch - Geräte arbeiten mit höchste Priorität" | ||||||
|  |  | ||||||
|  | msgid "Enable CI extension" | ||||||
|  | msgstr "Aktiviere CI Erweiterung" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define whether a CI extension shall be used.\n" | ||||||
|  | "\n" | ||||||
|  | "This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)." | ||||||
|  | msgstr "" | ||||||
|  | "Legt fest ob eine CI Erweiterung genutzt werden soll.\n" | ||||||
|  | "\n" | ||||||
|  | "Diese Einstellung aktiviert die Nutzung des integrierten CI/CAM einiger SAT>IP Geräte (z.B. Digital Devices OctopusNet)." | ||||||
|  |  | ||||||
|  | msgid "CI/CAM" | ||||||
|  | msgstr "CI/CAM" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define a desired CAM type for the CI slot.\n" | ||||||
|  | "\n" | ||||||
|  | "The '---' option lets SAT>IP hardware do the auto-selection." | ||||||
|  | msgstr "" | ||||||
|  | "Bestimmt welcher CI Einschub für ein CAM genutzt werden soll.\n" | ||||||
|  | "\n" | ||||||
|  | "Die Option '---' überlässt der SAT>IP Hardware die automatische Auswahl." | ||||||
|  |  | ||||||
| msgid "Enable EPG scanning" | msgid "Enable EPG scanning" | ||||||
| msgstr "Aktiviere EPG Aktualisierung" | msgstr "Aktiviere EPG Aktualisierung" | ||||||
|  |  | ||||||
| @@ -111,7 +138,7 @@ msgid "" | |||||||
| "\n" | "\n" | ||||||
| "This setting disables the automatic EIT scanning functionality for all SAT>IP devices." | "This setting disables the automatic EIT scanning functionality for all SAT>IP devices." | ||||||
| msgstr "" | msgstr "" | ||||||
| "Definiert ob EPG im Hintergrund aktualisiert werden soll oder nicht.\n" | "Legt fest ob EPG im Hintergrund aktualisiert werden soll oder nicht.\n" | ||||||
| "\n" | "\n" | ||||||
| "Diese Einstellung schaltet die automatische EIT Aktualisierung für alle SAT>IP Geräte." | "Diese Einstellung schaltet die automatische EIT Aktualisierung für alle SAT>IP Geräte." | ||||||
|  |  | ||||||
| @@ -126,7 +153,7 @@ msgid "" | |||||||
| "\n" | "\n" | ||||||
| "SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here." | "SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here." | ||||||
| msgstr "" | msgstr "" | ||||||
| "Definiert die Anzahl der deaktivierten Quellen.\n" | "Legt die Anzahl der deaktivierten Quellen fest.\n" | ||||||
| "\n" | "\n" | ||||||
| "Für einige SAT>IP server sind nicht alle Satellitenpositionen verfügbar, nicht verfügbare Quellen können hier ausgeblendet werden" | "Für einige SAT>IP server sind nicht alle Satellitenpositionen verfügbar, nicht verfügbare Quellen können hier ausgeblendet werden" | ||||||
|  |  | ||||||
| @@ -152,7 +179,7 @@ msgid "Define an ill-behaving filter to be blacklisted." | |||||||
| msgstr "Bestimme einen fehlerhaften Filter der ausgeblendet werden soll." | msgstr "Bestimme einen fehlerhaften Filter der ausgeblendet werden soll." | ||||||
|  |  | ||||||
| msgid "Active SAT>IP servers:" | msgid "Active SAT>IP servers:" | ||||||
| msgstr "Aktive SAT>IP Server" | msgstr "Aktive SAT>IP Server:" | ||||||
|  |  | ||||||
| msgid "Help" | msgid "Help" | ||||||
| msgstr "Hilfe" | msgstr "Hilfe" | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								po/es_ES.po
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								po/es_ES.po
									
									
									
									
									
								
							| @@ -1,14 +1,14 @@ | |||||||
| # VDR plugin language source file. | # VDR plugin language source file. | ||||||
| # Copyright (C) 2007-2014 Rolf Ahrenberg | # Copyright (C) 2007-2015 Rolf Ahrenberg | ||||||
| # This file is distributed under the same license as the satip package. | # This file is distributed under the same license as the satip package. | ||||||
| # Gabriel Bonich, 2014 | # Gabriel Bonich, 2014-2015 | ||||||
| # | # | ||||||
| msgid "" | msgid "" | ||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: vdr-satip 1.0.0\n" | "Project-Id-Version: vdr-satip 2.2.2\n" | ||||||
| "Report-Msgid-Bugs-To: <see README>\n" | "Report-Msgid-Bugs-To: <see README>\n" | ||||||
| "POT-Creation-Date: 2014-12-24 12:24+0200\n" | "POT-Creation-Date: 2015-04-26 04:26+0300\n" | ||||||
| "PO-Revision-Date: 2014-12-24 12:24+0200\n" | "PO-Revision-Date: 2015-04-26 04:26+0300\n" | ||||||
| "Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n" | "Last-Translator: Gabriel Bonich <gbonich@gmail.com>\n" | ||||||
| "Language-Team: Spanish <vdr@linuxtv.org>\n" | "Language-Team: Spanish <vdr@linuxtv.org>\n" | ||||||
| "Language: es\n" | "Language: es\n" | ||||||
| @@ -38,7 +38,7 @@ msgid "SAT>IP Devices" | |||||||
| msgstr "SAT>IP Dispositivos" | msgstr "SAT>IP Dispositivos" | ||||||
|  |  | ||||||
| msgid "SAT>IP Server" | msgid "SAT>IP Server" | ||||||
| msgstr "" | msgstr "SAT>IP Server" | ||||||
|  |  | ||||||
| msgid "Address" | msgid "Address" | ||||||
| msgstr "Dirección" | msgstr "Dirección" | ||||||
| @@ -49,11 +49,14 @@ msgstr "Modelo" | |||||||
| msgid "Description" | msgid "Description" | ||||||
| msgstr "Descripción" | msgstr "Descripción" | ||||||
|  |  | ||||||
|  | msgid "CI extension" | ||||||
|  | msgstr "Extensión CI" | ||||||
|  |  | ||||||
| msgid "Creation date" | msgid "Creation date" | ||||||
| msgstr "Fecha creación" | msgstr "Fecha creación" | ||||||
|  |  | ||||||
| msgid "SAT>IP Device Status" | msgid "SAT>IP Device Status" | ||||||
| msgstr "" | msgstr "SAT>IP Estado del Dispositivo" | ||||||
|  |  | ||||||
| msgid "SAT>IP Information" | msgid "SAT>IP Information" | ||||||
| msgstr "SAT>IP Información" | msgstr "SAT>IP Información" | ||||||
| @@ -83,7 +86,7 @@ msgid "high" | |||||||
| msgstr "Alto" | msgstr "Alto" | ||||||
|  |  | ||||||
| msgid "Button$Devices" | msgid "Button$Devices" | ||||||
| msgstr "" | msgstr "Dispositivos" | ||||||
|  |  | ||||||
| msgid "Operating mode" | msgid "Operating mode" | ||||||
| msgstr "Modo de operación" | msgstr "Modo de operación" | ||||||
| @@ -103,6 +106,30 @@ msgstr "" | |||||||
| "Normal - Dispositivos trabajando con prioridad Normal\n" | "Normal - Dispositivos trabajando con prioridad Normal\n" | ||||||
| "Alta - Dispositivos trabajando con prioridad Alta" | "Alta - Dispositivos trabajando con prioridad Alta" | ||||||
|  |  | ||||||
|  | msgid "Enable CI extension" | ||||||
|  | msgstr "Habilitar extensión CI" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define whether a CI extension shall be used.\n" | ||||||
|  | "\n" | ||||||
|  | "This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)." | ||||||
|  | msgstr "" | ||||||
|  | "Definir si se utilizará una extensión de CI.\n" | ||||||
|  | "\n" | ||||||
|  | "Esto permite la configuración CI/CAM integrado que se encuentra en algunos equipos SAT>IP (ej. Digital Devices OctopusNet)." | ||||||
|  |  | ||||||
|  | msgid "CI/CAM" | ||||||
|  | msgstr "CI/CAM" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define a desired CAM type for the CI slot.\n" | ||||||
|  | "\n" | ||||||
|  | "The '---' option lets SAT>IP hardware do the auto-selection." | ||||||
|  | msgstr "" | ||||||
|  | "Definir el tipo de CAM para la ranura CI.\n" | ||||||
|  | "\n" | ||||||
|  | "La opción '---' permite al equipo SAT>IP hacer la selección automática." | ||||||
|  |  | ||||||
| msgid "Enable EPG scanning" | msgid "Enable EPG scanning" | ||||||
| msgstr "Activa Escaneo EPG" | msgstr "Activa Escaneo EPG" | ||||||
|  |  | ||||||
| @@ -116,7 +143,7 @@ msgstr "" | |||||||
| "Esta configuración desactiva la funcionalidad del escaneo EIT automática para todos los Dispositivos SAT>IP." | "Esta configuración desactiva la funcionalidad del escaneo EIT automática para todos los Dispositivos SAT>IP." | ||||||
|  |  | ||||||
| msgid "Disabled sources" | msgid "Disabled sources" | ||||||
| msgstr "" | msgstr "Desactiva fuentes" | ||||||
|  |  | ||||||
| msgid "none" | msgid "none" | ||||||
| msgstr "no" | msgstr "no" | ||||||
| @@ -126,9 +153,12 @@ msgid "" | |||||||
| "\n" | "\n" | ||||||
| "SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here." | "SAT>IP servers might not have all satellite positions available and such sources can be blacklisted here." | ||||||
| msgstr "" | msgstr "" | ||||||
|  | "Definir número de fuentes desactivadas.\n" | ||||||
|  | "\n" | ||||||
|  | "SAT>IP servidores que no tenga todas las posiciones de los satélites disponibles y estas se ponen en la lista negra." | ||||||
|  |  | ||||||
| msgid "Define a source to be blacklisted." | msgid "Define a source to be blacklisted." | ||||||
| msgstr "" | msgstr "Define fuentes de la lista negra" | ||||||
|  |  | ||||||
| msgid "Disabled filters" | msgid "Disabled filters" | ||||||
| msgstr "Desactiva filtros" | msgstr "Desactiva filtros" | ||||||
| @@ -149,7 +179,7 @@ msgid "Define an ill-behaving filter to be blacklisted." | |||||||
| msgstr "Define un filtro para poner en la lista negra." | msgstr "Define un filtro para poner en la lista negra." | ||||||
|  |  | ||||||
| msgid "Active SAT>IP servers:" | msgid "Active SAT>IP servers:" | ||||||
| msgstr "" | msgstr "Activa SAT>IP servers:" | ||||||
|  |  | ||||||
| msgid "Help" | msgid "Help" | ||||||
| msgstr "Ayuda" | msgstr "Ayuda" | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								po/fi_FI.po
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								po/fi_FI.po
									
									
									
									
									
								
							| @@ -1,14 +1,14 @@ | |||||||
| # VDR plugin language source file. | # VDR plugin language source file. | ||||||
| # Copyright (C) 2007-2014 Rolf Ahrenberg | # Copyright (C) 2007-2015 Rolf Ahrenberg | ||||||
| # This file is distributed under the same license as the satip package. | # This file is distributed under the same license as the satip package. | ||||||
| # Rolf Ahrenberg, 2014 | # Rolf Ahrenberg, 2015 | ||||||
| # | # | ||||||
| msgid "" | msgid "" | ||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: vdr-satip 1.0.0\n" | "Project-Id-Version: vdr-satip 2.2.2\n" | ||||||
| "Report-Msgid-Bugs-To: <see README>\n" | "Report-Msgid-Bugs-To: <see README>\n" | ||||||
| "POT-Creation-Date: 2014-12-24 12:24+0200\n" | "POT-Creation-Date: 2015-04-26 04:26+0300\n" | ||||||
| "PO-Revision-Date: 2014-12-24 12:24+0200\n" | "PO-Revision-Date: 2015-04-26 04:26+0300\n" | ||||||
| "Last-Translator: Rolf Ahrenberg\n" | "Last-Translator: Rolf Ahrenberg\n" | ||||||
| "Language-Team: Finnish <vdr@linuxtv.org>\n" | "Language-Team: Finnish <vdr@linuxtv.org>\n" | ||||||
| "Language: fi\n" | "Language: fi\n" | ||||||
| @@ -49,6 +49,9 @@ msgstr "Malli" | |||||||
| msgid "Description" | msgid "Description" | ||||||
| msgstr "Kuvaus" | msgstr "Kuvaus" | ||||||
|  |  | ||||||
|  | msgid "CI extension" | ||||||
|  | msgstr "CI-laajennos" | ||||||
|  |  | ||||||
| msgid "Creation date" | msgid "Creation date" | ||||||
| msgstr "Luontiajankohta" | msgstr "Luontiajankohta" | ||||||
|  |  | ||||||
| @@ -102,6 +105,30 @@ msgstr "" | |||||||
| "normaali - laitteet toimivat normaalilla prioriteetilla\n" | "normaali - laitteet toimivat normaalilla prioriteetilla\n" | ||||||
| "korkea - laitteet toimivat korkealla prioriteetilla" | "korkea - laitteet toimivat korkealla prioriteetilla" | ||||||
|  |  | ||||||
|  | msgid "Enable CI extension" | ||||||
|  | msgstr "Käytä CI-laajennosta" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define whether a CI extension shall be used.\n" | ||||||
|  | "\n" | ||||||
|  | "This setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet)." | ||||||
|  | msgstr "" | ||||||
|  | "Määrittele CI-laajennoksen käyttöönotto\n" | ||||||
|  | "\n" | ||||||
|  | "Tällä asetuksella saadaan otettua käyttöön SAT>IP-laitteiden sisäinen CI-paikka (esim. Digital Devices OctopusNet)." | ||||||
|  |  | ||||||
|  | msgid "CI/CAM" | ||||||
|  | msgstr "CI/CAM" | ||||||
|  |  | ||||||
|  | msgid "" | ||||||
|  | "Define a desired CAM type for the CI slot.\n" | ||||||
|  | "\n" | ||||||
|  | "The '---' option lets SAT>IP hardware do the auto-selection." | ||||||
|  | msgstr "" | ||||||
|  | "Määrittele haluttu CAM-tyyppi CI-paikalle.\n" | ||||||
|  | "\n" | ||||||
|  | "Vaihtoehto '---' antaa SAT>IP-laitteen valita automaattisesti käytetyn CI-paikan." | ||||||
|  |  | ||||||
| msgid "Enable EPG scanning" | msgid "Enable EPG scanning" | ||||||
| msgstr "Käytä ohjelmaoppaan taustapäivitystä" | msgstr "Käytä ohjelmaoppaan taustapäivitystä" | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								rtcp.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								rtcp.c
									
									
									
									
									
								
							| @@ -25,7 +25,7 @@ cSatipRtcp::cSatipRtcp(cSatipTunerIf &tunerP) | |||||||
| cSatipRtcp::~cSatipRtcp() | cSatipRtcp::~cSatipRtcp() | ||||||
| { | { | ||||||
|   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); |   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); | ||||||
|   DELETE_POINTER(bufferM); |   FREE_POINTER(bufferM); | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipRtcp::GetFd(void) | int cSatipRtcp::GetFd(void) | ||||||
| @@ -50,7 +50,7 @@ int cSatipRtcp::GetApplicationOffset(int *lengthP) | |||||||
|         //unsigned int st = bufferM[offset] & 0x1F; |         //unsigned int st = bufferM[offset] & 0x1F; | ||||||
|         // Payload type |         // Payload type | ||||||
|         unsigned int pt = bufferM[offset + 1] & 0xFF; |         unsigned int pt = bufferM[offset + 1] & 0xFF; | ||||||
|         // Lenght |         // Length | ||||||
|         unsigned int length = ((bufferM[offset + 2] & 0xFF) << 8) | (bufferM[offset + 3] & 0xFF); |         unsigned int length = ((bufferM[offset + 2] & 0xFF) << 8) | (bufferM[offset + 3] & 0xFF); | ||||||
|         // Convert it to bytes |         // Convert it to bytes | ||||||
|         length = (length + 1) * 4; |         length = (length + 1) * 4; | ||||||
| @@ -89,8 +89,6 @@ void cSatipRtcp::Process(void) | |||||||
|            if (offset >= 0) |            if (offset >= 0) | ||||||
|               tunerM.ProcessApplicationData(bufferM + offset, length); |               tunerM.ProcessApplicationData(bufferM + offset, length); | ||||||
|            } |            } | ||||||
|      if (errno != EAGAIN && errno != EWOULDBLOCK) |  | ||||||
|         error("Error %d reading in %s", errno, *ToString()); |  | ||||||
|      } |      } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								rtcp.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								rtcp.h
									
									
									
									
									
								
							| @@ -20,7 +20,7 @@ private: | |||||||
|   cSatipTunerIf &tunerM; |   cSatipTunerIf &tunerM; | ||||||
|   unsigned int bufferLenM; |   unsigned int bufferLenM; | ||||||
|   unsigned char *bufferM; |   unsigned char *bufferM; | ||||||
|   int GetApplicationOffset(int *lenghtP); |   int GetApplicationOffset(int *lengthP); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|   cSatipRtcp(cSatipTunerIf &tunerP); |   cSatipRtcp(cSatipTunerIf &tunerP); | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								rtp.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								rtp.c
									
									
									
									
									
								
							| @@ -29,7 +29,7 @@ cSatipRtp::cSatipRtp(cSatipTunerIf &tunerP) | |||||||
| cSatipRtp::~cSatipRtp() | cSatipRtp::~cSatipRtp() | ||||||
| { | { | ||||||
|   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); |   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); | ||||||
|   DELETE_POINTER(bufferM); |   FREE_POINTER(bufferM); | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipRtp::GetFd(void) | int cSatipRtp::GetFd(void) | ||||||
| @@ -51,7 +51,7 @@ void cSatipRtp::Close(void) | |||||||
|      } |      } | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipRtp::GetHeaderLenght(unsigned char *bufferP, unsigned int lengthP) | int cSatipRtp::GetHeaderLength(unsigned char *bufferP, unsigned int lengthP) | ||||||
| { | { | ||||||
|   debug16("%s (, %d) [device %d]", __PRETTY_FUNCTION__, lengthP, tunerM.GetId()); |   debug16("%s (, %d) [device %d]", __PRETTY_FUNCTION__, lengthP, tunerM.GetId()); | ||||||
|   unsigned int headerlen = 0; |   unsigned int headerlen = 0; | ||||||
| @@ -88,7 +88,7 @@ int cSatipRtp::GetHeaderLenght(unsigned char *bufferP, unsigned int lengthP) | |||||||
|            } |            } | ||||||
|         else |         else | ||||||
|            sequenceNumberM = seq; |            sequenceNumberM = seq; | ||||||
|         // Header lenght |         // Header length | ||||||
|         headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t); |         headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t); | ||||||
|         // Check if extension |         // Check if extension | ||||||
|         if (x) { |         if (x) { | ||||||
| @@ -130,15 +130,12 @@ void cSatipRtp::Process(void) | |||||||
|        count = ReadMulti(bufferM, lenMsg, eRtpPacketReadCount, eMaxUdpPacketSizeB); |        count = ReadMulti(bufferM, lenMsg, eRtpPacketReadCount, eMaxUdpPacketSizeB); | ||||||
|        for (int i = 0; i < count; ++i) { |        for (int i = 0; i < count; ++i) { | ||||||
|            unsigned char *p = &bufferM[i * eMaxUdpPacketSizeB]; |            unsigned char *p = &bufferM[i * eMaxUdpPacketSizeB]; | ||||||
|            int headerlen = GetHeaderLenght(p, lenMsg[i]); |            int headerlen = GetHeaderLength(p, lenMsg[i]); | ||||||
|            if ((headerlen >= 0) && (headerlen < (int)lenMsg[i])) |            if ((headerlen >= 0) && (headerlen < (int)lenMsg[i])) | ||||||
|               tunerM.ProcessVideoData(p + headerlen, lenMsg[i] - headerlen); |               tunerM.ProcessVideoData(p + headerlen, lenMsg[i] - headerlen); | ||||||
|            } |            } | ||||||
|        } while (count >= eRtpPacketReadCount); |        } while (count >= eRtpPacketReadCount); | ||||||
|  |  | ||||||
|      if (errno != EAGAIN && errno != EWOULDBLOCK) |  | ||||||
|         error("Error %d reading in %s [device %d]", errno, *ToString(), tunerM.GetId()); |  | ||||||
|  |  | ||||||
|      elapsed = processing.Elapsed(); |      elapsed = processing.Elapsed(); | ||||||
|      if (elapsed > 1) |      if (elapsed > 1) | ||||||
|         debug6("%s %d read(s) took %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, count, elapsed, tunerM.GetId()); |         debug6("%s %d read(s) took %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, count, elapsed, tunerM.GetId()); | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								rtp.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								rtp.h
									
									
									
									
									
								
							| @@ -25,7 +25,7 @@ private: | |||||||
|   time_t lastErrorReportM; |   time_t lastErrorReportM; | ||||||
|   int packetErrorsM; |   int packetErrorsM; | ||||||
|   int sequenceNumberM; |   int sequenceNumberM; | ||||||
|   int GetHeaderLenght(unsigned char *bufferP, unsigned int lengthP); |   int GetHeaderLength(unsigned char *bufferP, unsigned int lengthP); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|   cSatipRtp(cSatipTunerIf &tunerP); |   cSatipRtp(cSatipTunerIf &tunerP); | ||||||
|   | |||||||
							
								
								
									
										193
									
								
								rtsp.c
									
									
									
									
									
								
							
							
						
						
									
										193
									
								
								rtsp.c
									
									
									
									
									
								
							| @@ -15,9 +15,14 @@ | |||||||
|  |  | ||||||
| cSatipRtsp::cSatipRtsp(cSatipTunerIf &tunerP) | cSatipRtsp::cSatipRtsp(cSatipTunerIf &tunerP) | ||||||
| : tunerM(tunerP), | : tunerM(tunerP), | ||||||
|  |   headerBufferM(), | ||||||
|  |   dataBufferM(), | ||||||
|   modeM(cmUnicast), |   modeM(cmUnicast), | ||||||
|   handleM(NULL), |   handleM(NULL), | ||||||
|   headerListM(NULL) |   headerListM(NULL), | ||||||
|  |   errorNoMoreM(""), | ||||||
|  |   errorOutOfRangeM(""), | ||||||
|  |   errorCheckSyntaxM("") | ||||||
| { | { | ||||||
|   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); |   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); | ||||||
|   Create(); |   Create(); | ||||||
| @@ -29,46 +34,26 @@ cSatipRtsp::~cSatipRtsp() | |||||||
|   Destroy(); |   Destroy(); | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t cSatipRtsp::HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP) | size_t cSatipRtsp::HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP) | ||||||
| { |  | ||||||
|   cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP); |  | ||||||
|   size_t len = sizeP * nmembP; |  | ||||||
|   debug16("%s len=%zu", __PRETTY_FUNCTION__, len); |  | ||||||
|  |  | ||||||
|   char *s, *p = (char *)ptrP; |  | ||||||
|   char *r = strtok_r(p, "\r\n", &s); |  | ||||||
|  |  | ||||||
|   while (obj && r) { |  | ||||||
|         debug16("%s (%zu): %s", __PRETTY_FUNCTION__, len, r); |  | ||||||
|         r = skipspace(r); |  | ||||||
|         if (strstr(r, "com.ses.streamID")) { |  | ||||||
|            int streamid = -1; |  | ||||||
|            if (sscanf(r, "com.ses.streamID:%11d", &streamid) == 1) |  | ||||||
|               obj->tunerM.SetStreamId(streamid); |  | ||||||
|            } |  | ||||||
|         else if (strstr(r, "Session:")) { |  | ||||||
|            int timeout = -1; |  | ||||||
|            char *session = NULL; |  | ||||||
|            if (sscanf(r, "Session:%m[^;];timeout=%11d", &session, &timeout) == 2) |  | ||||||
|               obj->tunerM.SetSessionTimeout(skipspace(session), timeout * 1000); |  | ||||||
|            else if (sscanf(r, "Session:%m[^;]", &session) == 1) |  | ||||||
|               obj->tunerM.SetSessionTimeout(skipspace(session), -1); |  | ||||||
|            FREE_POINTER(session); |  | ||||||
|            } |  | ||||||
|         r = strtok_r(NULL, "\r\n", &s); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|   return len; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| size_t cSatipRtsp::WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP) |  | ||||||
| { | { | ||||||
|   cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP); |   cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP); | ||||||
|   size_t len = sizeP * nmembP; |   size_t len = sizeP * nmembP; | ||||||
|   debug16("%s len=%zu", __PRETTY_FUNCTION__, len); |   debug16("%s len=%zu", __PRETTY_FUNCTION__, len); | ||||||
|  |  | ||||||
|   if (obj && (len > 0)) |   if (obj && (len > 0)) | ||||||
|      obj->tunerM.ProcessApplicationData((u_char*)ptrP, len); |      obj->headerBufferM.Add(ptrP, len); | ||||||
|  |  | ||||||
|  |   return len; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | size_t cSatipRtsp::DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP) | ||||||
|  | { | ||||||
|  |   cSatipRtsp *obj = reinterpret_cast<cSatipRtsp *>(dataP); | ||||||
|  |   size_t len = sizeP * nmembP; | ||||||
|  |   debug16("%s len=%zu", __PRETTY_FUNCTION__, len); | ||||||
|  |  | ||||||
|  |   if (obj) | ||||||
|  |      obj->dataBufferM.Add(ptrP, len); | ||||||
|  |  | ||||||
|   return len; |   return len; | ||||||
| } | } | ||||||
| @@ -216,10 +201,22 @@ bool cSatipRtsp::Setup(const char *uriP, int rtpPortP, int rtcpPortP) | |||||||
|      // Set header callback for catching the session and timeout |      // Set header callback for catching the session and timeout | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipRtsp::HeaderCallback); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, cSatipRtsp::HeaderCallback); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, this); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this); | ||||||
|      SATIP_CURL_EASY_PERFORM(handleM); |      SATIP_CURL_EASY_PERFORM(handleM); | ||||||
|      // Session id is now known - disable header parsing |      // Session id is now known - disable header parsing | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_HEADERFUNCTION, NULL); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, NULL); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEHEADER, NULL); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL); | ||||||
|  |      if (headerBufferM.Size() > 0) { | ||||||
|  |         ParseHeader(); | ||||||
|  |         headerBufferM.Reset(); | ||||||
|  |         } | ||||||
|  |      if (dataBufferM.Size() > 0) { | ||||||
|  |         ParseData(); | ||||||
|  |         dataBufferM.Reset(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|      result = ValidateLatestResponse(&rc); |      result = ValidateLatestResponse(&rc); | ||||||
|      debug5("%s (%s, %d, %d) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rtpPortP, rtcpPortP, rc, processing.Elapsed(), tunerM.GetId()); |      debug5("%s (%s, %d, %d) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rtpPortP, rtcpPortP, rc, processing.Elapsed(), tunerM.GetId()); | ||||||
| @@ -253,11 +250,15 @@ bool cSatipRtsp::Describe(const char *uriP) | |||||||
|  |  | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::WriteCallback); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this); | ||||||
|      SATIP_CURL_EASY_PERFORM(handleM); |      SATIP_CURL_EASY_PERFORM(handleM); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL); | ||||||
|  |      if (dataBufferM.Size() > 0) { | ||||||
|  |         tunerM.ProcessApplicationData((u_char *)dataBufferM.Data(), dataBufferM.Size()); | ||||||
|  |         dataBufferM.Reset(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|      result = ValidateLatestResponse(&rc); |      result = ValidateLatestResponse(&rc); | ||||||
|      debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId()); |      debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId()); | ||||||
| @@ -278,7 +279,15 @@ bool cSatipRtsp::Play(const char *uriP) | |||||||
|  |  | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this); | ||||||
|      SATIP_CURL_EASY_PERFORM(handleM); |      SATIP_CURL_EASY_PERFORM(handleM); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL); | ||||||
|  |      if (dataBufferM.Size() > 0) { | ||||||
|  |         ParseData(); | ||||||
|  |         dataBufferM.Reset(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|      result = ValidateLatestResponse(&rc); |      result = ValidateLatestResponse(&rc); | ||||||
|      debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId()); |      debug5("%s (%s) Response %ld in %" PRIu64 " ms [device %d]", __PRETTY_FUNCTION__, uriP, rc, processing.Elapsed(), tunerM.GetId()); | ||||||
| @@ -299,7 +308,15 @@ bool cSatipRtsp::Teardown(const char *uriP) | |||||||
|  |  | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_STREAM_URI, uriP); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, cSatipRtsp::DataCallback); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, this); | ||||||
|      SATIP_CURL_EASY_PERFORM(handleM); |      SATIP_CURL_EASY_PERFORM(handleM); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEFUNCTION, NULL); | ||||||
|  |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_WRITEDATA, NULL); | ||||||
|  |      if (dataBufferM.Size() > 0) { | ||||||
|  |         ParseData(); | ||||||
|  |         dataBufferM.Reset(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_CLIENT_CSEQ, 1L); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_CLIENT_CSEQ, 1L); | ||||||
|      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, NULL); |      SATIP_CURL_EASY_SETOPT(handleM, CURLOPT_RTSP_SESSION_ID, NULL); | ||||||
| @@ -311,24 +328,122 @@ bool cSatipRtsp::Teardown(const char *uriP) | |||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void cSatipRtsp::ParseHeader(void) | ||||||
|  | { | ||||||
|  |   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); | ||||||
|  |   char *s, *p = headerBufferM.Data(); | ||||||
|  |   char *r = strtok_r(p, "\r\n", &s); | ||||||
|  |  | ||||||
|  |   while (r) { | ||||||
|  |         debug16("%s (%zu): %s", __PRETTY_FUNCTION__, headerBufferM.Size(), r); | ||||||
|  |         r = skipspace(r); | ||||||
|  |         if (strstr(r, "com.ses.streamID")) { | ||||||
|  |            int streamid = -1; | ||||||
|  |            if (sscanf(r, "com.ses.streamID:%11d", &streamid) == 1) | ||||||
|  |               tunerM.SetStreamId(streamid); | ||||||
|  |            } | ||||||
|  |         else if (strstr(r, "Session:")) { | ||||||
|  |            int timeout = -1; | ||||||
|  |            char *session = NULL; | ||||||
|  |            if (sscanf(r, "Session:%m[^;];timeout=%11d", &session, &timeout) == 2) | ||||||
|  |               tunerM.SetSessionTimeout(skipspace(session), timeout * 1000); | ||||||
|  |            else if (sscanf(r, "Session:%m[^;]", &session) == 1) | ||||||
|  |               tunerM.SetSessionTimeout(skipspace(session), -1); | ||||||
|  |            FREE_POINTER(session); | ||||||
|  |            } | ||||||
|  |         r = strtok_r(NULL, "\r\n", &s); | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void cSatipRtsp::ParseData(void) | ||||||
|  | { | ||||||
|  |   debug1("%s [device %d]", __PRETTY_FUNCTION__, tunerM.GetId()); | ||||||
|  |   char *s, *p = dataBufferM.Data(); | ||||||
|  |   char *r = strtok_r(p, "\r\n", &s); | ||||||
|  |  | ||||||
|  |   while (r) { | ||||||
|  |         debug16("%s (%zu): %s", __PRETTY_FUNCTION__, dataBufferM.Size(), r); | ||||||
|  |         r = skipspace(r); | ||||||
|  |         if (strstr(r, "No-More:")) { | ||||||
|  |            char *tmp = NULL; | ||||||
|  |            if (sscanf(r, "No-More:%m[^;]", &tmp) == 1) { | ||||||
|  |               errorNoMoreM = skipspace(tmp); | ||||||
|  |               debug3("%s No-More: %s [device %d]", __PRETTY_FUNCTION__, *errorNoMoreM, tunerM.GetId()); | ||||||
|  |               } | ||||||
|  |            FREE_POINTER(tmp); | ||||||
|  |            } | ||||||
|  |         else if (strstr(r, "Out-of-Range:")) { | ||||||
|  |            char *tmp = NULL; | ||||||
|  |            if (sscanf(r, "Out-of-Range:%m[^;]", &tmp) == 1) { | ||||||
|  |               errorOutOfRangeM = skipspace(tmp); | ||||||
|  |               debug3("%s Out-of-Range: %s [device %d]", __PRETTY_FUNCTION__, *errorOutOfRangeM, tunerM.GetId()); | ||||||
|  |               } | ||||||
|  |            FREE_POINTER(tmp); | ||||||
|  |            } | ||||||
|  |         else if (strstr(r, "Check-Syntax:")) { | ||||||
|  |            char *tmp = NULL; | ||||||
|  |            if (sscanf(r, "Check-Syntax:%m[^;]", &tmp) == 1) { | ||||||
|  |               errorCheckSyntaxM = skipspace(tmp); | ||||||
|  |               debug3("%s Check-Syntax: %s [device %d]", __PRETTY_FUNCTION__, *errorCheckSyntaxM, tunerM.GetId()); | ||||||
|  |               } | ||||||
|  |            FREE_POINTER(tmp); | ||||||
|  |            } | ||||||
|  |         r = strtok_r(NULL, "\r\n", &s); | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
| bool cSatipRtsp::ValidateLatestResponse(long *rcP) | bool cSatipRtsp::ValidateLatestResponse(long *rcP) | ||||||
| { | { | ||||||
|   bool result = false; |   bool result = false; | ||||||
|  |  | ||||||
|   if (handleM) { |   if (handleM) { | ||||||
|  |      char *url = NULL; | ||||||
|      long rc = 0; |      long rc = 0; | ||||||
|      CURLcode res = CURLE_OK; |      CURLcode res = CURLE_OK; | ||||||
|      SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc); |      SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_RESPONSE_CODE, &rc); | ||||||
|      if (rc == 200) |      switch (rc) { | ||||||
|  |        case 200: | ||||||
|             result = true; |             result = true; | ||||||
|      else if (rc != 0) { |             break; | ||||||
|         char *url = NULL; |        case 400: | ||||||
|  |             // SETUP PLAY TEARDOWN | ||||||
|  |             // The message body of the response may contain the "Check-Syntax:" parameter followed | ||||||
|  |             // by the malformed syntax | ||||||
|  |             if (!isempty(*errorCheckSyntaxM)) { | ||||||
|  |                SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url); | ||||||
|  |                error("Check syntax: %s (error code %ld: %s) [device %d]", *errorCheckSyntaxM, rc, url, tunerM.GetId()); | ||||||
|  |                break; | ||||||
|  |                } | ||||||
|  |        case 403: | ||||||
|  |             // SETUP PLAY TEARDOWN | ||||||
|  |             // The message body of the response may contain the "Out-of-Range:" parameter followed | ||||||
|  |             // by a space-separated list of the attribute names that are not understood: | ||||||
|  |             // "src" "fe" "freq" "pol" "msys" "mtype" "plts" "ro" "sr" "fec" "pids" "addpids" "delpids" "mcast | ||||||
|  |             if (!isempty(*errorOutOfRangeM)) { | ||||||
|  |                SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url); | ||||||
|  |                error("Out of range: %s (error code %ld: %s) [device %d]", *errorOutOfRangeM, rc, url, tunerM.GetId()); | ||||||
|  |                break; | ||||||
|  |                } | ||||||
|  |        case 503: | ||||||
|  |             // SETUP PLAY | ||||||
|  |             // The message body of the response may contain the "No-More:" parameter followed | ||||||
|  |             // by a space-separated list of the missing ressources: “sessions” "frontends" "pids | ||||||
|  |             if (!isempty(*errorNoMoreM)) { | ||||||
|  |                SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url); | ||||||
|  |                error("No more: %s (error code %ld: %s) [device %d]", *errorNoMoreM, rc, url, tunerM.GetId()); | ||||||
|  |                break; | ||||||
|  |                } | ||||||
|  |        default: | ||||||
|             SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url); |             SATIP_CURL_EASY_GETINFO(handleM, CURLINFO_EFFECTIVE_URL, &url); | ||||||
|             error("Detected invalid status code %ld: %s [device %d]", rc, url, tunerM.GetId()); |             error("Detected invalid status code %ld: %s [device %d]", rc, url, tunerM.GetId()); | ||||||
|  |             break; | ||||||
|        } |        } | ||||||
|      if (rcP) |      if (rcP) | ||||||
|         *rcP = rc; |         *rcP = rc; | ||||||
|      } |      } | ||||||
|  |   errorNoMoreM = ""; | ||||||
|  |   errorOutOfRangeM = ""; | ||||||
|  |   errorCheckSyntaxM = ""; | ||||||
|   debug1("%s result=%s [device %d]", __PRETTY_FUNCTION__, result ? "ok" : "failed", tunerM.GetId()); |   debug1("%s result=%s [device %d]", __PRETTY_FUNCTION__, result ? "ok" : "failed", tunerM.GetId()); | ||||||
|  |  | ||||||
|   return result; |   return result; | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								rtsp.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								rtsp.h
									
									
									
									
									
								
							| @@ -15,12 +15,13 @@ | |||||||
| #error "libcurl is missing required RTSP support" | #error "libcurl is missing required RTSP support" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #include "common.h" | ||||||
| #include "tunerif.h" | #include "tunerif.h" | ||||||
|  |  | ||||||
| class cSatipRtsp { | class cSatipRtsp { | ||||||
| private: | private: | ||||||
|   static size_t HeaderCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP); |   static size_t HeaderCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP); | ||||||
|   static size_t WriteCallback(void *ptrP, size_t sizeP, size_t nmembP, void *dataP); |   static size_t DataCallback(char *ptrP, size_t sizeP, size_t nmembP, void *dataP); | ||||||
|   static int    DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP); |   static int    DebugCallback(CURL *handleP, curl_infotype typeP, char *dataP, size_t sizeP, void *userPtrP); | ||||||
|  |  | ||||||
|   enum { |   enum { | ||||||
| @@ -29,12 +30,19 @@ private: | |||||||
|   enum eCommunicationMode { cmUnicast, cmMulticast }; |   enum eCommunicationMode { cmUnicast, cmMulticast }; | ||||||
|  |  | ||||||
|   cSatipTunerIf &tunerM; |   cSatipTunerIf &tunerM; | ||||||
|  |   cSatipMemoryBuffer headerBufferM; | ||||||
|  |   cSatipMemoryBuffer dataBufferM; | ||||||
|   eCommunicationMode modeM; |   eCommunicationMode modeM; | ||||||
|   CURL *handleM; |   CURL *handleM; | ||||||
|   struct curl_slist *headerListM; |   struct curl_slist *headerListM; | ||||||
|  |   cString errorNoMoreM; | ||||||
|  |   cString errorOutOfRangeM; | ||||||
|  |   cString errorCheckSyntaxM; | ||||||
|  |  | ||||||
|   void Create(void); |   void Create(void); | ||||||
|   void Destroy(void); |   void Destroy(void); | ||||||
|  |   void ParseHeader(void); | ||||||
|  |   void ParseData(void); | ||||||
|   bool ValidateLatestResponse(long *rcP); |   bool ValidateLatestResponse(long *rcP); | ||||||
|  |  | ||||||
|   // to prevent copy constructor and assignment |   // to prevent copy constructor and assignment | ||||||
|   | |||||||
							
								
								
									
										111
									
								
								satip.c
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								satip.c
									
									
									
									
									
								
							| @@ -19,15 +19,15 @@ | |||||||
| #warning "CURL version >= 7.36.0 is recommended" | #warning "CURL version >= 7.36.0 is recommended" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if defined(APIVERSNUM) && APIVERSNUM < 20000 | #if defined(APIVERSNUM) && APIVERSNUM < 20200 | ||||||
| #error "VDR-2.0.0 API version or greater is required!" | #error "VDR-2.2.0 API version or greater is required!" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef GITVERSION | #ifndef GITVERSION | ||||||
| #define GITVERSION "" | #define GITVERSION "" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|        const char VERSION[]     = "1.0.0" GITVERSION; |        const char VERSION[]     = "2.2.2" GITVERSION; | ||||||
| static const char DESCRIPTION[] = trNOOP("SAT>IP Devices"); | static const char DESCRIPTION[] = trNOOP("SAT>IP Devices"); | ||||||
|  |  | ||||||
| class cPluginSatip : public cPlugin { | class cPluginSatip : public cPlugin { | ||||||
| @@ -35,6 +35,7 @@ private: | |||||||
|   unsigned int deviceCountM; |   unsigned int deviceCountM; | ||||||
|   cSatipDiscoverServers *serversM; |   cSatipDiscoverServers *serversM; | ||||||
|   void ParseServer(const char *paramP); |   void ParseServer(const char *paramP); | ||||||
|  |   int ParseCicams(const char *valueP, int *cicamsP); | ||||||
|   int ParseSources(const char *valueP, int *sourcesP); |   int ParseSources(const char *valueP, int *sourcesP); | ||||||
|   int ParseFilters(const char *valueP, int *filtersP); |   int ParseFilters(const char *valueP, int *filtersP); | ||||||
| public: | public: | ||||||
| @@ -61,7 +62,7 @@ public: | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
| cPluginSatip::cPluginSatip(void) | cPluginSatip::cPluginSatip(void) | ||||||
| : deviceCountM(1), | : deviceCountM(2), | ||||||
|   serversM(NULL) |   serversM(NULL) | ||||||
| { | { | ||||||
|   debug16("%s", __PRETTY_FUNCTION__); |   debug16("%s", __PRETTY_FUNCTION__); | ||||||
| @@ -81,8 +82,12 @@ const char *cPluginSatip::CommandLineHelp(void) | |||||||
|   debug1("%s", __PRETTY_FUNCTION__); |   debug1("%s", __PRETTY_FUNCTION__); | ||||||
|   // Return a string that describes all known command line options. |   // Return a string that describes all known command line options. | ||||||
|   return "  -d <num>, --devices=<number>  set number of devices to be created\n" |   return "  -d <num>, --devices=<number>  set number of devices to be created\n" | ||||||
|  |          "  -t <mode>, --trace=<mode>     set the tracing mode\n" | ||||||
|          "  -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n" |          "  -s <ipaddr>|<model>|<desc>, --server=<ipaddr1>|<model1>|<desc1>;<ipaddr2>|<model2>|<desc2>\n" | ||||||
|          "                                define hard-coded SAT>IP server(s)\n"; |          "                                define hard-coded SAT>IP server(s)\n" | ||||||
|  |          "  -D, --detach                  set the detached mode on\n" | ||||||
|  |          "  -S, --single                  set the single model server mode on\n" | ||||||
|  |          "  -n, --noquirks                disable all the server quirks\n"; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool cPluginSatip::ProcessArgs(int argc, char *argv[]) | bool cPluginSatip::ProcessArgs(int argc, char *argv[]) | ||||||
| @@ -93,11 +98,15 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[]) | |||||||
|     { "devices",  required_argument, NULL, 'd' }, |     { "devices",  required_argument, NULL, 'd' }, | ||||||
|     { "trace",    required_argument, NULL, 't' }, |     { "trace",    required_argument, NULL, 't' }, | ||||||
|     { "server",   required_argument, NULL, 's' }, |     { "server",   required_argument, NULL, 's' }, | ||||||
|  |     { "detach",   no_argument,       NULL, 'D' }, | ||||||
|  |     { "single",   no_argument,       NULL, 'S' }, | ||||||
|  |     { "noquirks", no_argument,       NULL, 'n' }, | ||||||
|     { NULL,       no_argument,       NULL,  0  } |     { NULL,       no_argument,       NULL,  0  } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |   cString server; | ||||||
|   int c; |   int c; | ||||||
|   while ((c = getopt_long(argc, argv, "d:t:s:", long_options, NULL)) != -1) { |   while ((c = getopt_long(argc, argv, "d:t:s:DSn", long_options, NULL)) != -1) { | ||||||
|     switch (c) { |     switch (c) { | ||||||
|       case 'd': |       case 'd': | ||||||
|            deviceCountM = strtol(optarg, NULL, 0); |            deviceCountM = strtol(optarg, NULL, 0); | ||||||
| @@ -106,12 +115,24 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[]) | |||||||
|            SatipConfig.SetTraceMode(strtol(optarg, NULL, 0)); |            SatipConfig.SetTraceMode(strtol(optarg, NULL, 0)); | ||||||
|            break; |            break; | ||||||
|       case 's': |       case 's': | ||||||
|            ParseServer(optarg); |            server = optarg; | ||||||
|  |            break; | ||||||
|  |       case 'D': | ||||||
|  |            SatipConfig.SetDetachedMode(true); | ||||||
|  |            break; | ||||||
|  |       case 'S': | ||||||
|  |            SatipConfig.SetUseSingleModelServers(true); | ||||||
|  |            break; | ||||||
|  |       case 'n': | ||||||
|  |            SatipConfig.SetDisableServerQuirks(true); | ||||||
|            break; |            break; | ||||||
|       default: |       default: | ||||||
|            return false; |            return false; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   // this must be done after all parameters are parsed | ||||||
|  |   if (!isempty(*server)) | ||||||
|  |      ParseServer(*server); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -121,7 +142,6 @@ bool cPluginSatip::Initialize(void) | |||||||
|   // Initialize any background activities the plugin shall perform. |   // Initialize any background activities the plugin shall perform. | ||||||
|   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) |   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) | ||||||
|      error("Unable to initialize CURL"); |      error("Unable to initialize CURL"); | ||||||
|   SatipConfig.SetConfigDirectory(cPlugin::ResourceDirectory(PLUGIN_NAME_I18N)); |  | ||||||
|   cSatipPoller::GetInstance()->Initialize(); |   cSatipPoller::GetInstance()->Initialize(); | ||||||
|   cSatipDiscover::GetInstance()->Initialize(serversM); |   cSatipDiscover::GetInstance()->Initialize(serversM); | ||||||
|   return cSatipDevice::Initialize(deviceCountM); |   return cSatipDevice::Initialize(deviceCountM); | ||||||
| @@ -197,7 +217,7 @@ void cPluginSatip::ParseServer(const char *paramP) | |||||||
| { | { | ||||||
|   debug1("%s (%s)", __PRETTY_FUNCTION__, paramP); |   debug1("%s (%s)", __PRETTY_FUNCTION__, paramP); | ||||||
|   int n = 0; |   int n = 0; | ||||||
|   char *s, *p = (char *)paramP; |   char *s, *p = strdup(paramP); | ||||||
|   char *r = strtok_r(p, ";", &s); |   char *r = strtok_r(p, ";", &s); | ||||||
|   while (r) { |   while (r) { | ||||||
|         r = skipspace(r); |         r = skipspace(r); | ||||||
| @@ -232,13 +252,32 @@ void cPluginSatip::ParseServer(const char *paramP) | |||||||
|         ++n; |         ++n; | ||||||
|         r = strtok_r(NULL, ";", &s); |         r = strtok_r(NULL, ";", &s); | ||||||
|         } |         } | ||||||
|  |   FREE_POINTER(p); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cPluginSatip::ParseCicams(const char *valueP, int *cicamsP) | ||||||
|  | { | ||||||
|  |   debug1("%s (%s,)", __PRETTY_FUNCTION__, valueP); | ||||||
|  |   int n = 0; | ||||||
|  |   char *s, *p = strdup(valueP); | ||||||
|  |   char *r = strtok_r(p, " ", &s); | ||||||
|  |   while (r) { | ||||||
|  |         r = skipspace(r); | ||||||
|  |         debug3("%s cicams[%d]=%s", __PRETTY_FUNCTION__, n, r); | ||||||
|  |         if (n < MAX_CICAM_COUNT) { | ||||||
|  |            cicamsP[n++] = atoi(r); | ||||||
|  |            } | ||||||
|  |         r = strtok_r(NULL, " ", &s); | ||||||
|  |         } | ||||||
|  |   FREE_POINTER(p); | ||||||
|  |   return n; | ||||||
| } | } | ||||||
|  |  | ||||||
| int cPluginSatip::ParseSources(const char *valueP, int *sourcesP) | int cPluginSatip::ParseSources(const char *valueP, int *sourcesP) | ||||||
| { | { | ||||||
|   debug1("%s (%s,)", __PRETTY_FUNCTION__, valueP); |   debug1("%s (%s,)", __PRETTY_FUNCTION__, valueP); | ||||||
|   int n = 0; |   int n = 0; | ||||||
|   char *s, *p = (char *)valueP; |   char *s, *p = strdup(valueP); | ||||||
|   char *r = strtok_r(p, " ", &s); |   char *r = strtok_r(p, " ", &s); | ||||||
|   while (r) { |   while (r) { | ||||||
|         r = skipspace(r); |         r = skipspace(r); | ||||||
| @@ -246,8 +285,9 @@ int cPluginSatip::ParseSources(const char *valueP, int *sourcesP) | |||||||
|         if (n < MAX_DISABLED_SOURCES_COUNT) { |         if (n < MAX_DISABLED_SOURCES_COUNT) { | ||||||
|            sourcesP[n++] = cSource::FromString(r); |            sourcesP[n++] = cSource::FromString(r); | ||||||
|            } |            } | ||||||
|         r = strtok_r(NULL, " \n", &s); |         r = strtok_r(NULL, " ", &s); | ||||||
|         } |         } | ||||||
|  |   FREE_POINTER(p); | ||||||
|   return n; |   return n; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -259,7 +299,7 @@ int cPluginSatip::ParseFilters(const char *valueP, int *filtersP) | |||||||
|   while (valueP && *valueP && (n < SECTION_FILTER_TABLE_SIZE)) { |   while (valueP && *valueP && (n < SECTION_FILTER_TABLE_SIZE)) { | ||||||
|     strn0cpy(buffer, valueP, sizeof(buffer)); |     strn0cpy(buffer, valueP, sizeof(buffer)); | ||||||
|     int i = atoi(buffer); |     int i = atoi(buffer); | ||||||
|     debug3(":%s filters[%d]=%d", __PRETTY_FUNCTION__, n, i); |     debug3("%s filters[%d]=%d", __PRETTY_FUNCTION__, n, i); | ||||||
|     if (i >= 0) |     if (i >= 0) | ||||||
|        filtersP[n++] = i; |        filtersP[n++] = i; | ||||||
|     if ((valueP = strchr(valueP, ' ')) != NULL) |     if ((valueP = strchr(valueP, ' ')) != NULL) | ||||||
| @@ -274,11 +314,21 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP) | |||||||
|   // Parse your own setup parameters and store their values. |   // Parse your own setup parameters and store their values. | ||||||
|   if (!strcasecmp(nameP, "OperatingMode")) |   if (!strcasecmp(nameP, "OperatingMode")) | ||||||
|      SatipConfig.SetOperatingMode(atoi(valueP)); |      SatipConfig.SetOperatingMode(atoi(valueP)); | ||||||
|  |   else if (!strcasecmp(nameP, "EnableCIExtension")) | ||||||
|  |      SatipConfig.SetCIExtension(atoi(valueP)); | ||||||
|  |   else if (!strcasecmp(nameP, "CICAM")) { | ||||||
|  |      int Cicams[MAX_CICAM_COUNT]; | ||||||
|  |      for (unsigned int i = 0; i < ELEMENTS(Cicams); ++i) | ||||||
|  |          Cicams[i] = 0; | ||||||
|  |      unsigned int CicamsCount = ParseCicams(valueP, Cicams); | ||||||
|  |      for (unsigned int i = 0; i < CicamsCount; ++i) | ||||||
|  |          SatipConfig.SetCICAM(i, Cicams[i]); | ||||||
|  |      } | ||||||
|   else if (!strcasecmp(nameP, "EnableEITScan")) |   else if (!strcasecmp(nameP, "EnableEITScan")) | ||||||
|      SatipConfig.SetEITScan(atoi(valueP)); |      SatipConfig.SetEITScan(atoi(valueP)); | ||||||
|   else if (!strcasecmp(nameP, "DisabledSources")) { |   else if (!strcasecmp(nameP, "DisabledSources")) { | ||||||
|      int DisabledSources[MAX_DISABLED_SOURCES_COUNT]; |      int DisabledSources[MAX_DISABLED_SOURCES_COUNT]; | ||||||
|      for (unsigned int i = 0; i < ARRAY_SIZE(DisabledSources); ++i) |      for (unsigned int i = 0; i < ELEMENTS(DisabledSources); ++i) | ||||||
|          DisabledSources[i] = cSource::stNone; |          DisabledSources[i] = cSource::stNone; | ||||||
|      unsigned int DisabledSourcesCount = ParseSources(valueP, DisabledSources); |      unsigned int DisabledSourcesCount = ParseSources(valueP, DisabledSources); | ||||||
|      for (unsigned int i = 0; i < DisabledSourcesCount; ++i) |      for (unsigned int i = 0; i < DisabledSourcesCount; ++i) | ||||||
| @@ -286,7 +336,7 @@ bool cPluginSatip::SetupParse(const char *nameP, const char *valueP) | |||||||
|      } |      } | ||||||
|   else if (!strcasecmp(nameP, "DisabledFilters")) { |   else if (!strcasecmp(nameP, "DisabledFilters")) { | ||||||
|      int DisabledFilters[SECTION_FILTER_TABLE_SIZE]; |      int DisabledFilters[SECTION_FILTER_TABLE_SIZE]; | ||||||
|      for (unsigned int i = 0; i < ARRAY_SIZE(DisabledFilters); ++i) |      for (unsigned int i = 0; i < ELEMENTS(DisabledFilters); ++i) | ||||||
|          DisabledFilters[i] = -1; |          DisabledFilters[i] = -1; | ||||||
|      unsigned int DisabledFiltersCount = ParseFilters(valueP, DisabledFilters); |      unsigned int DisabledFiltersCount = ParseFilters(valueP, DisabledFilters); | ||||||
|      for (unsigned int i = 0; i < DisabledFiltersCount; ++i) |      for (unsigned int i = 0; i < DisabledFiltersCount; ++i) | ||||||
| @@ -321,8 +371,12 @@ const char **cPluginSatip::SVDRPHelpPages(void) | |||||||
|     "    Lists status information of SAT>IP devices.\n", |     "    Lists status information of SAT>IP devices.\n", | ||||||
|     "CONT\n" |     "CONT\n" | ||||||
|     "    Shows SAT>IP device count.\n", |     "    Shows SAT>IP device count.\n", | ||||||
|     "OPER\n" |     "OPER [ off | low | normal | high ]\n" | ||||||
|     "    Toggles operating mode of SAT>IP devices.\n", |     "    Gets and(or sets operating mode of SAT>IP devices.\n", | ||||||
|  |     "ATTA\n" | ||||||
|  |     "    Attach active SAT>IP servers.\n", | ||||||
|  |     "DETA\n" | ||||||
|  |     "    Detachs active SAT>IP servers.\n", | ||||||
|     "TRAC [ <mode> ]\n" |     "TRAC [ <mode> ]\n" | ||||||
|     "    Gets and/or sets used tracing mode.\n", |     "    Gets and/or sets used tracing mode.\n", | ||||||
|     NULL |     NULL | ||||||
| @@ -389,8 +443,19 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in | |||||||
|      } |      } | ||||||
|   else if (strcasecmp(commandP, "OPER") == 0) { |   else if (strcasecmp(commandP, "OPER") == 0) { | ||||||
|      cString mode; |      cString mode; | ||||||
|      SatipConfig.ToggleOperatingMode(); |      unsigned int oper = SatipConfig.GetOperatingMode(); | ||||||
|      switch (SatipConfig.GetOperatingMode()) { |      if (optionP && *optionP) { | ||||||
|  |         if (strcasecmp(optionP, "off") == 0) | ||||||
|  |            oper = cSatipConfig::eOperatingModeOff; | ||||||
|  |         else if (strcasecmp(optionP, "low") == 0) | ||||||
|  |            oper = cSatipConfig::eOperatingModeLow; | ||||||
|  |         else if (strcasecmp(optionP, "normal") == 0) | ||||||
|  |            oper = cSatipConfig::eOperatingModeNormal; | ||||||
|  |         else if (strcasecmp(optionP, "high") == 0) | ||||||
|  |            oper = cSatipConfig::eOperatingModeHigh; | ||||||
|  |         SatipConfig.SetOperatingMode(oper); | ||||||
|  |      } | ||||||
|  |      switch (oper) { | ||||||
|        case cSatipConfig::eOperatingModeOff: |        case cSatipConfig::eOperatingModeOff: | ||||||
|             mode = "off"; |             mode = "off"; | ||||||
|             break; |             break; | ||||||
| @@ -409,6 +474,16 @@ cString cPluginSatip::SVDRPCommand(const char *commandP, const char *optionP, in | |||||||
|        } |        } | ||||||
|      return cString::sprintf("SATIP operating mode: %s\n", *mode); |      return cString::sprintf("SATIP operating mode: %s\n", *mode); | ||||||
|      } |      } | ||||||
|  |   else if (strcasecmp(commandP, "ATTA") == 0) { | ||||||
|  |      SatipConfig.SetDetachedMode(false); | ||||||
|  |      info("SATIP servers attached"); | ||||||
|  |      return cString("SATIP servers attached"); | ||||||
|  |      } | ||||||
|  |   else if (strcasecmp(commandP, "DETA") == 0) { | ||||||
|  |      SatipConfig.SetDetachedMode(true); | ||||||
|  |      info("SATIP servers detached"); | ||||||
|  |      return cString("SATIP servers detached"); | ||||||
|  |      } | ||||||
|   else if (strcasecmp(commandP, "TRAC") == 0) { |   else if (strcasecmp(commandP, "TRAC") == 0) { | ||||||
|      if (optionP && *optionP) |      if (optionP && *optionP) | ||||||
|         SatipConfig.SetTraceMode(strtol(optionP, NULL, 0)); |         SatipConfig.SetTraceMode(strtol(optionP, NULL, 0)); | ||||||
|   | |||||||
							
								
								
									
										370
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										370
									
								
								server.c
									
									
									
									
									
								
							| @@ -12,77 +12,140 @@ | |||||||
| #include "log.h" | #include "log.h" | ||||||
| #include "server.h" | #include "server.h" | ||||||
|  |  | ||||||
|  | // --- cSatipFrontend --------------------------------------------------------- | ||||||
|  |  | ||||||
|  | cSatipFrontend::cSatipFrontend(const int indexP, const char *descriptionP) | ||||||
|  | : indexM(indexP), | ||||||
|  |   transponderM(0), | ||||||
|  |   deviceIdM(-1), | ||||||
|  |   descriptionM(descriptionP) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | cSatipFrontend::~cSatipFrontend() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // --- cSatipFrontends -------------------------------------------------------- | ||||||
|  |  | ||||||
|  | bool cSatipFrontends::Matches(int deviceIdP, int transponderP) | ||||||
|  | { | ||||||
|  |   for (cSatipFrontend *f = First(); f; f = Next(f)) { | ||||||
|  |       if (f->Attached() && (f->DeviceId() == deviceIdP) && (f->Transponder() == transponderP)) | ||||||
|  |          return true; | ||||||
|  |       } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipFrontends::Assign(int deviceIdP, int transponderP) | ||||||
|  | { | ||||||
|  |   cSatipFrontend *tmp = NULL; | ||||||
|  |   // Prefer any unused one | ||||||
|  |   for (cSatipFrontend *f = First(); f; f = Next(f)) { | ||||||
|  |       if (!f->Attached() || (f->DeviceId() == deviceIdP)) { | ||||||
|  |          tmp = f; | ||||||
|  |          break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |   if (tmp) { | ||||||
|  |      tmp->SetTransponder(transponderP); | ||||||
|  |      return true; | ||||||
|  |      } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipFrontends::Attach(int deviceIdP, int transponderP) | ||||||
|  | { | ||||||
|  |   for (cSatipFrontend *f = First(); f; f = Next(f)) { | ||||||
|  |       if (f->Transponder() == transponderP) { | ||||||
|  |          f->Attach(deviceIdP); | ||||||
|  |          debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index()); | ||||||
|  |          return true; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipFrontends::Detach(int deviceIdP, int transponderP) | ||||||
|  | { | ||||||
|  |   for (cSatipFrontend *f = First(); f; f = Next(f)) { | ||||||
|  |       if (f->Transponder() == transponderP) { | ||||||
|  |          f->Detach(deviceIdP); | ||||||
|  |          debug9("%s (%d, %d) %s/#%d", __PRETTY_FUNCTION__, deviceIdP, transponderP, *f->Description(), f->Index()); | ||||||
|  |          return true; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
| // --- cSatipServer ----------------------------------------------------------- | // --- cSatipServer ----------------------------------------------------------- | ||||||
|  |  | ||||||
| cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP) | cSatipServer::cSatipServer(const char *addressP, const char *modelP, const char *descriptionP) | ||||||
| : addressM(addressP), | : addressM((addressP && *addressP) ? addressP : "0.0.0.0"), | ||||||
|   modelM(modelP), |   modelM((modelP && *modelP) ? modelP : "DVBS-1"), | ||||||
|   descriptionM(descriptionP), |   descriptionM(!isempty(descriptionP) ? descriptionP : "MyBrokenHardware"), | ||||||
|   modelTypeM(eSatipModelTypeNone), |   quirksM(""), | ||||||
|   quirkM(eSatipQuirkNone), |   quirkM(eSatipQuirkNone), | ||||||
|   useCountM(0), |   hasCiM(false), | ||||||
|   transponderM(0), |  | ||||||
|   createdM(time(NULL)), |   createdM(time(NULL)), | ||||||
|   lastSeenM(0) |   lastSeenM(0) | ||||||
| { | { | ||||||
|   memset(modelCountM, 0, sizeof(modelCountM)); |   if (!SatipConfig.GetDisableServerQuirks()) { | ||||||
|   if (isempty(*modelM)) |  | ||||||
|      modelM = "DVBS-1"; |  | ||||||
|   if (!isempty(*descriptionM)) { |  | ||||||
|      // These devices contain a session id bug: |      // These devices contain a session id bug: | ||||||
|      // Inverto Airscreen Server IDL 400 ? |      // Inverto Airscreen Server IDL 400 ? | ||||||
|      // Elgato EyeTV Netstream 4Sat ? |      // Elgato EyeTV Netstream 4Sat ? | ||||||
|      if (strstr(*descriptionM, "GSSBOX") ||             // Grundig Sat Systems GSS.box DSI 400 |      if (strstr(*descriptionM, "GSSBOX") ||             // Grundig Sat Systems GSS.box DSI 400 | ||||||
|          strstr(*descriptionM, "DIGIBIT") ||            // Telestar Digibit R1 |          strstr(*descriptionM, "DIGIBIT") ||            // Telestar Digibit R1 | ||||||
|          strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400 |          strstr(*descriptionM, "Triax SatIP Converter") // Triax TSS 400 | ||||||
|         ) |         ) { | ||||||
|         quirkM |= eSatipQuirkSessionId; |         quirkM |= eSatipQuirkSessionId; | ||||||
|      // These devices contain a play (add/delpids) parameter bug: |         quirksM = cString::sprintf("%s%sSessionId", *quirksM, isempty(*quirksM) ? "" : ","); | ||||||
|      if (strstr(*descriptionM, "fritzdvbc"))            // Fritz!WLAN Repeater DVB-C |  | ||||||
|         quirkM |= eSatipQuirkPlayPids; |  | ||||||
|      // These devices contain a frontend locking bug: |  | ||||||
|      if (strstr(*descriptionM, "fritzdvbc"))            // Fritz!WLAN Repeater DVB-C |  | ||||||
|         quirkM |= eSatipQuirkForceLock; |  | ||||||
|      if (quirkM != eSatipQuirkNone) |  | ||||||
|         info("Malfunctioning '%s' server detected! Please, fix the firmware.", *descriptionM); |  | ||||||
|         } |         } | ||||||
|  |      // These devices contain a play (add/delpids) parameter bug: | ||||||
|  |      if (strstr(*descriptionM, "fritzdvbc")             // Fritz!WLAN Repeater DVB-C | ||||||
|  |         ) { | ||||||
|  |         quirkM |= eSatipQuirkPlayPids; | ||||||
|  |         quirksM = cString::sprintf("%s%sPlayPids", *quirksM, isempty(*quirksM) ? "" : ","); | ||||||
|  |         } | ||||||
|  |      // These devices contain a frontend locking bug: | ||||||
|  |      if (strstr(*descriptionM, "fritzdvbc")             // Fritz!WLAN Repeater DVB-C | ||||||
|  |         ) { | ||||||
|  |         quirkM |= eSatipQuirkForceLock; | ||||||
|  |         quirksM = cString::sprintf("%s%sForceLock", *quirksM, isempty(*quirksM) ? "" : ","); | ||||||
|  |         } | ||||||
|  |      debug3("%s description=%s quirks=%s", __PRETTY_FUNCTION__, *descriptionM, *quirksM); | ||||||
|  |      } | ||||||
|  |   // These devices support the X_PMT protocol extension | ||||||
|  |   if (strstr(*descriptionM, "OctopusNet"))              // Digital Devices OctopusNet | ||||||
|  |      hasCiM = true; | ||||||
|   char *s, *p = strdup(*modelM); |   char *s, *p = strdup(*modelM); | ||||||
|   char *r = strtok_r(p, ",", &s); |   char *r = strtok_r(p, ",", &s); | ||||||
|   while (r) { |   while (r) { | ||||||
|         if (strstr(r, "DVBS2")) { |         char *c; | ||||||
|            modelTypeM |= cSatipServer::eSatipModelTypeDVBS2; |         if (c = strstr(r, "DVBS2-")) { | ||||||
|            if (char *c = strstr(r, "-")) |            int count = atoi(c + 6); | ||||||
|               modelCountM[eSatipModuleDVBS2] = atoi(++c); |            for (int i = 1; i <= count; ++i) | ||||||
|            else |                frontendsM[eSatipFrontendDVBS2].Add(new cSatipFrontend(i, "DVB-S2")); | ||||||
|               modelCountM[eSatipModuleDVBS2] = 1; |  | ||||||
|            } |            } | ||||||
|         if (strstr(r, "DVBT2")) { |         else if (c = strstr(r, "DVBT-")) { | ||||||
|            modelTypeM |= cSatipServer::eSatipModelTypeDVBT2; |            int count = atoi(c + 5); | ||||||
|            if (char *c = strstr(r, "-")) |            for (int i = 1; i <= count; ++i) | ||||||
|               modelCountM[eSatipModuleDVBT2] = atoi(++c); |                frontendsM[eSatipFrontendDVBT].Add(new cSatipFrontend(i, "DVB-T")); | ||||||
|            else |  | ||||||
|               modelCountM[eSatipModuleDVBT2] = 1; |  | ||||||
|            } |            } | ||||||
|         if (strstr(r, "DVBT")) { |         else if (c = strstr(r, "DVBT2-")) { | ||||||
|            modelTypeM |= cSatipServer::eSatipModelTypeDVBT; |            int count = atoi(c + 6); | ||||||
|            if (char *c = strstr(r, "-")) |            for (int i = 1; i <= count; ++i) | ||||||
|               modelCountM[eSatipModuleDVBT] = atoi(++c); |                frontendsM[eSatipFrontendDVBT2].Add(new cSatipFrontend(i, "DVB-T2")); | ||||||
|            else |  | ||||||
|               modelCountM[eSatipModuleDVBT] = 1; |  | ||||||
|            } |            } | ||||||
|         if (strstr(r, "DVBC2")) { |         else if (c = strstr(r, "DVBC-")) { | ||||||
|            modelTypeM |= cSatipServer::eSatipModelTypeDVBC2; |            int count = atoi(c + 5); | ||||||
|            if (char *c = strstr(r, "-")) |            for (int i = 1; i <= count; ++i) | ||||||
|               modelCountM[eSatipModuleDVBC2] = atoi(++c); |                frontendsM[eSatipFrontendDVBC].Add(new cSatipFrontend(i, "DVB-C")); | ||||||
|            else |  | ||||||
|               modelCountM[eSatipModuleDVBC2] = 1; |  | ||||||
|            } |            } | ||||||
|         if (strstr(r, "DVBC")) { |         else if (c = strstr(r, "DVBC2-")) { | ||||||
|            modelTypeM |= cSatipServer::eSatipModelTypeDVBC; |            int count = atoi(c + 6); | ||||||
|            if (char *c = strstr(r, "-")) |            for (int i = 1; i <= count; ++i) | ||||||
|               modelCountM[eSatipModuleDVBC] = atoi(++c); |                frontendsM[eSatipFrontendDVBC2].Add(new cSatipFrontend(i, "DVB-C2")); | ||||||
|            else |  | ||||||
|               modelCountM[eSatipModuleDVBC] = 1; |  | ||||||
|            } |            } | ||||||
|         r = strtok_r(NULL, ",", &s); |         r = strtok_r(NULL, ",", &s); | ||||||
|         } |         } | ||||||
| @@ -96,15 +159,105 @@ cSatipServer::~cSatipServer() | |||||||
| int cSatipServer::Compare(const cListObject &listObjectP) const | int cSatipServer::Compare(const cListObject &listObjectP) const | ||||||
| { | { | ||||||
|   const cSatipServer *s = (const cSatipServer *)&listObjectP; |   const cSatipServer *s = (const cSatipServer *)&listObjectP; | ||||||
|   return strcasecmp(*addressM, *s->addressM); |   int result = strcasecmp(*addressM, *s->addressM); | ||||||
|  |   if (!result) { | ||||||
|  |      result = strcasecmp(*modelM, *s->modelM); | ||||||
|  |      if (!result) | ||||||
|  |         result = strcasecmp(*descriptionM, *s->descriptionM); | ||||||
|  |      } | ||||||
|  |   return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipServer::Use(bool onOffP) | bool cSatipServer::Assign(int deviceIdP, int sourceP, int systemP, int transponderP) | ||||||
| { | { | ||||||
|   if (onOffP) |   bool result = false; | ||||||
|      ++useCountM; |   if (cSource::IsType(sourceP, 'S')) | ||||||
|  |      result = frontendsM[eSatipFrontendDVBS2].Assign(deviceIdP, transponderP); | ||||||
|  |   else if (cSource::IsType(sourceP, 'T')) { | ||||||
|  |      if (systemP) | ||||||
|  |         result = frontendsM[eSatipFrontendDVBT2].Assign(deviceIdP, transponderP); | ||||||
|      else |      else | ||||||
|      --useCountM; |         result = frontendsM[eSatipFrontendDVBT].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBT2].Assign(deviceIdP, transponderP); | ||||||
|  |      } | ||||||
|  |   else if (cSource::IsType(sourceP, 'C')) { | ||||||
|  |      if (systemP) | ||||||
|  |         result = frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP); | ||||||
|  |      else | ||||||
|  |         result = frontendsM[eSatipFrontendDVBC].Assign(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Assign(deviceIdP, transponderP); | ||||||
|  |      } | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipServer::Matches(int sourceP) | ||||||
|  | { | ||||||
|  |   if (cSource::IsType(sourceP, 'S')) | ||||||
|  |      return GetModulesDVBS2(); | ||||||
|  |   else if (cSource::IsType(sourceP, 'T')) | ||||||
|  |      return GetModulesDVBT() || GetModulesDVBT2(); | ||||||
|  |   else if (cSource::IsType(sourceP, 'C')) | ||||||
|  |      return GetModulesDVBC() || GetModulesDVBC2(); | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipServer::Matches(int deviceIdP, int sourceP, int systemP, int transponderP) | ||||||
|  | { | ||||||
|  |   bool result = false; | ||||||
|  |   if (cSource::IsType(sourceP, 'S')) | ||||||
|  |      result = frontendsM[eSatipFrontendDVBS2].Matches(deviceIdP, transponderP); | ||||||
|  |   else if (cSource::IsType(sourceP, 'T')) { | ||||||
|  |      if (systemP) | ||||||
|  |         result = frontendsM[eSatipFrontendDVBT2].Matches(deviceIdP, transponderP); | ||||||
|  |      else | ||||||
|  |         result = frontendsM[eSatipFrontendDVBT].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBT2].Matches(deviceIdP, transponderP); | ||||||
|  |      } | ||||||
|  |   else if (cSource::IsType(sourceP, 'C')) { | ||||||
|  |      if (systemP) | ||||||
|  |         result = frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP); | ||||||
|  |      else | ||||||
|  |         result = frontendsM[eSatipFrontendDVBC].Matches(deviceIdP, transponderP) || frontendsM[eSatipFrontendDVBC2].Matches(deviceIdP, transponderP); | ||||||
|  |      } | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void cSatipServer::Attach(int deviceIdP, int transponderP) | ||||||
|  | { | ||||||
|  |   for (int i = 0; i < eSatipFrontendCount; ++i) { | ||||||
|  |       if (frontendsM[i].Attach(deviceIdP, transponderP)) | ||||||
|  |          return; | ||||||
|  |       } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void cSatipServer::Detach(int deviceIdP, int transponderP) | ||||||
|  | { | ||||||
|  |   for (int i = 0; i < eSatipFrontendCount; ++i) { | ||||||
|  |       if (frontendsM[i].Detach(deviceIdP, transponderP)) | ||||||
|  |          return; | ||||||
|  |       } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cSatipServer::GetModulesDVBS2(void) | ||||||
|  | { | ||||||
|  |   return frontendsM[eSatipFrontendDVBS2].Count(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cSatipServer::GetModulesDVBT(void) | ||||||
|  | { | ||||||
|  |   return frontendsM[eSatipFrontendDVBT].Count(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cSatipServer::GetModulesDVBT2(void) | ||||||
|  | { | ||||||
|  |   return frontendsM[eSatipFrontendDVBT2].Count(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cSatipServer::GetModulesDVBC(void) | ||||||
|  | { | ||||||
|  |   return frontendsM[eSatipFrontendDVBC].Count(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int cSatipServer::GetModulesDVBC2(void) | ||||||
|  | { | ||||||
|  |   return frontendsM[eSatipFrontendDVBC2].Count(); | ||||||
| } | } | ||||||
|  |  | ||||||
| // --- cSatipServers ---------------------------------------------------------- | // --- cSatipServers ---------------------------------------------------------- | ||||||
| @@ -112,49 +265,32 @@ void cSatipServer::Use(bool onOffP) | |||||||
| cSatipServer *cSatipServers::Find(cSatipServer *serverP) | cSatipServer *cSatipServers::Find(cSatipServer *serverP) | ||||||
| { | { | ||||||
|   for (cSatipServer *s = First(); s; s = Next(s)) { |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|       if (s == serverP) |       if (s->Compare(*serverP) == 0) | ||||||
|          return s; |          return s; | ||||||
|       } |       } | ||||||
|   return NULL; |   return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| cSatipServer *cSatipServers::Find(int sourceP, int transponderP, int systemP) | cSatipServer *cSatipServers::Find(int sourceP) | ||||||
| { | { | ||||||
|   cSatipServer *result = NULL; |  | ||||||
|   int model = 0; |  | ||||||
|   if (cSource::IsType(sourceP, 'S')) |  | ||||||
|      model |= cSatipServer::eSatipModelTypeDVBS2; |  | ||||||
|   else if (cSource::IsType(sourceP, 'T')) { |  | ||||||
|      if (systemP < 0) |  | ||||||
|         model |= cSatipServer::eSatipModelTypeDVBT2 | cSatipServer::eSatipModelTypeDVBT; |  | ||||||
|      else |  | ||||||
|         model |= systemP ? cSatipServer::eSatipModelTypeDVBT2 : cSatipServer::eSatipModelTypeDVBT; |  | ||||||
|      } |  | ||||||
|   else if (cSource::IsType(sourceP, 'C')) |  | ||||||
|      model |= cSatipServer::eSatipModelTypeDVBC; |  | ||||||
|   for (cSatipServer *s = First(); s; s = Next(s)) { |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|       if (s->Match(model) && s->Used() && (s->Transponder() == transponderP)) |       if (s->Matches(sourceP)) | ||||||
|  |          return s; | ||||||
|  |       } | ||||||
|  |   return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | cSatipServer *cSatipServers::Assign(int deviceIdP, int sourceP, int transponderP, int systemP) | ||||||
|  | { | ||||||
|  |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|  |       if (s->Matches(deviceIdP, sourceP, systemP, transponderP)) | ||||||
|          return s; |          return s; | ||||||
|       } |       } | ||||||
|   for (cSatipServer *s = First(); s; s = Next(s)) { |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|       if (s->Match(model)) { |       if (s->Assign(deviceIdP, sourceP, systemP, transponderP)) | ||||||
|          result = s; |          return s; | ||||||
|          if (!s->Used()) { |  | ||||||
|             break; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
|       } |  | ||||||
|   return result; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void cSatipServers::SetTransponder(cSatipServer *serverP, bool transponderP) |  | ||||||
| { |  | ||||||
|   for (cSatipServer *s = First(); s; s = Next(s)) { |  | ||||||
|       if (s == serverP) { |  | ||||||
|          s->SetTransponder(transponderP); |  | ||||||
|          break; |  | ||||||
|          } |  | ||||||
|       } |       } | ||||||
|  |   return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| cSatipServer *cSatipServers::Update(cSatipServer *serverP) | cSatipServer *cSatipServers::Update(cSatipServer *serverP) | ||||||
| @@ -168,16 +304,50 @@ cSatipServer *cSatipServers::Update(cSatipServer *serverP) | |||||||
|   return NULL; |   return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| void cSatipServers::Use(cSatipServer *serverP, bool onOffP) | void cSatipServers::Attach(cSatipServer *serverP, int deviceIdP, int transponderP) | ||||||
| { | { | ||||||
|   for (cSatipServer *s = First(); s; s = Next(s)) { |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|       if (s == serverP) { |       if (s == serverP) { | ||||||
|          s->Use(onOffP); |          s->Attach(deviceIdP, transponderP); | ||||||
|          break; |          break; | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void cSatipServers::Detach(cSatipServer *serverP, int deviceIdP, int transponderP) | ||||||
|  | { | ||||||
|  |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|  |       if (s == serverP) { | ||||||
|  |          s->Detach(deviceIdP, transponderP); | ||||||
|  |          break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipServers::IsQuirk(cSatipServer *serverP, int quirkP) | ||||||
|  | { | ||||||
|  |   bool result = false; | ||||||
|  |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|  |       if (s == serverP) { | ||||||
|  |          result = s->Quirk(quirkP); | ||||||
|  |          break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool cSatipServers::HasCI(cSatipServer *serverP) | ||||||
|  | { | ||||||
|  |   bool result = false; | ||||||
|  |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|  |       if (s == serverP) { | ||||||
|  |          result = s->HasCI(); | ||||||
|  |          break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  |  | ||||||
| void cSatipServers::Cleanup(uint64_t intervalMsP) | void cSatipServers::Cleanup(uint64_t intervalMsP) | ||||||
| { | { | ||||||
|   for (cSatipServer *s = First(); s; s = Next(s)) { |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
| @@ -188,6 +358,18 @@ void cSatipServers::Cleanup(uint64_t intervalMsP) | |||||||
|       } |       } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | cString cSatipServers::GetAddress(cSatipServer *serverP) | ||||||
|  | { | ||||||
|  |   cString address = ""; | ||||||
|  |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|  |       if (s == serverP) { | ||||||
|  |          address = s->Address(); | ||||||
|  |          break; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |   return address; | ||||||
|  | } | ||||||
|  |  | ||||||
| cString cSatipServers::GetString(cSatipServer *serverP) | cString cSatipServers::GetString(cSatipServer *serverP) | ||||||
| { | { | ||||||
|   cString list = ""; |   cString list = ""; | ||||||
| @@ -213,13 +395,15 @@ int cSatipServers::NumProvidedSystems(void) | |||||||
|   int count = 0; |   int count = 0; | ||||||
|   for (cSatipServer *s = First(); s; s = Next(s)) { |   for (cSatipServer *s = First(); s; s = Next(s)) { | ||||||
|       // DVB-S2: qpsk, 8psk, 16apsk, 32apsk |       // DVB-S2: qpsk, 8psk, 16apsk, 32apsk | ||||||
|       count += s->Satellite() * 4; |       count += s->GetModulesDVBS2() * 4; | ||||||
|       // DVB-T2: qpsk, qam16, qam64, qam256 |  | ||||||
|       // DVB-T: qpsk, qam16, qam64 |       // DVB-T: qpsk, qam16, qam64 | ||||||
|       count += s->Terrestrial2() ? s->Terrestrial2() * 4 : s->Terrestrial() * 3; |       count += s->GetModulesDVBT() * 3; | ||||||
|       // DVB-C2: qam16, qam32, qam64, qam128, qam256 |       // DVB-T2: qpsk, qam16, qam64, qam256 | ||||||
|  |       count += s->GetModulesDVBT2() * 4; | ||||||
|       // DVB-C: qam64, qam128, qam256 |       // DVB-C: qam64, qam128, qam256 | ||||||
|       count += s->Cable2() ? s->Cable2() * 5 : s->Cable() * 3; |       count += s->GetModulesDVBC() * 3; | ||||||
|  |       // DVB-C2: qam16, qam32, qam64, qam128, qam256 | ||||||
|  |       count += s->GetModulesDVBC2() * 5; | ||||||
|       } |       } | ||||||
|   return count; |   return count; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										102
									
								
								server.h
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								server.h
									
									
									
									
									
								
							| @@ -8,26 +8,59 @@ | |||||||
| #ifndef __SATIP_SERVER_H | #ifndef __SATIP_SERVER_H | ||||||
| #define __SATIP_SERVER_H | #define __SATIP_SERVER_H | ||||||
|  |  | ||||||
|  | class cSatipServer; | ||||||
|  |  | ||||||
|  | // --- cSatipFrontend --------------------------------------------------------- | ||||||
|  |  | ||||||
|  | class cSatipFrontend : public cListObject { | ||||||
|  | private: | ||||||
|  |   int indexM; | ||||||
|  |   int transponderM; | ||||||
|  |   int deviceIdM; | ||||||
|  |   cString descriptionM; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |   cSatipFrontend(const int indexP, const char *descriptionP); | ||||||
|  |   virtual ~cSatipFrontend(); | ||||||
|  |   void Attach(int deviceIdP) { deviceIdM = deviceIdP; } | ||||||
|  |   void Detach(int deviceIdP) { if (deviceIdP == deviceIdM) deviceIdM = -1; } | ||||||
|  |   cString Description(void) { return descriptionM; } | ||||||
|  |   bool Attached(void) { return (deviceIdM >= 0); } | ||||||
|  |   int Index(void) { return indexM; } | ||||||
|  |   int Transponder(void) { return transponderM; } | ||||||
|  |   int DeviceId(void) { return deviceIdM; } | ||||||
|  |   void SetTransponder(int transponderP) { transponderM = transponderP; } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // --- cSatipFrontends -------------------------------------------------------- | ||||||
|  |  | ||||||
|  | class cSatipFrontends : public cList<cSatipFrontend> { | ||||||
|  | public: | ||||||
|  |   bool Matches(int deviceIdP, int transponderP); | ||||||
|  |   bool Assign(int deviceIdP, int transponderP); | ||||||
|  |   bool Attach(int deviceIdP, int transponderP); | ||||||
|  |   bool Detach(int deviceIdP, int transponderP); | ||||||
|  | }; | ||||||
|  |  | ||||||
| // --- cSatipServer ----------------------------------------------------------- | // --- cSatipServer ----------------------------------------------------------- | ||||||
|  |  | ||||||
| class cSatipServer : public cListObject { | class cSatipServer : public cListObject { | ||||||
| private: | private: | ||||||
|   enum eSatipModule { |   enum eSatipFrontend { | ||||||
|     eSatipModuleDVBS2 = 0, |     eSatipFrontendDVBS2 = 0, | ||||||
|     eSatipModuleDVBT, |     eSatipFrontendDVBT, | ||||||
|     eSatipModuleDVBT2, |     eSatipFrontendDVBT2, | ||||||
|     eSatipModuleDVBC, |     eSatipFrontendDVBC, | ||||||
|     eSatipModuleDVBC2, |     eSatipFrontendDVBC2, | ||||||
|     eSatipModuleCount |     eSatipFrontendCount | ||||||
|   }; |   }; | ||||||
|   cString addressM; |   cString addressM; | ||||||
|   cString modelM; |   cString modelM; | ||||||
|   cString descriptionM; |   cString descriptionM; | ||||||
|   int modelCountM[eSatipModuleCount]; |   cString quirksM; | ||||||
|   int modelTypeM; |   cSatipFrontends frontendsM[eSatipFrontendCount]; | ||||||
|   int quirkM; |   int quirkM; | ||||||
|   int useCountM; |   bool hasCiM; | ||||||
|   int transponderM; |  | ||||||
|   time_t createdM; |   time_t createdM; | ||||||
|   cTimeMs lastSeenM; |   cTimeMs lastSeenM; | ||||||
|  |  | ||||||
| @@ -39,33 +72,26 @@ public: | |||||||
|     eSatipQuirkForceLock = 0x04, |     eSatipQuirkForceLock = 0x04, | ||||||
|     eSatipQuirkMask      = 0x0F |     eSatipQuirkMask      = 0x0F | ||||||
|   }; |   }; | ||||||
|   enum eSatipModelType { |  | ||||||
|     eSatipModelTypeNone  = 0x00, |  | ||||||
|     eSatipModelTypeDVBS2 = 0x01, |  | ||||||
|     eSatipModelTypeDVBT  = 0x02, |  | ||||||
|     eSatipModelTypeDVBT2 = 0x04, |  | ||||||
|     eSatipModelTypeDVBC  = 0x08, |  | ||||||
|     eSatipModelTypeDVBC2 = 0x10, |  | ||||||
|     eSatipModelTypeMask  = 0xFF |  | ||||||
|   }; |  | ||||||
|   cSatipServer(const char *addressP, const char *modelP, const char *descriptionP); |   cSatipServer(const char *addressP, const char *modelP, const char *descriptionP); | ||||||
|   virtual ~cSatipServer(); |   virtual ~cSatipServer(); | ||||||
|   virtual int Compare(const cListObject &listObjectP) const; |   virtual int Compare(const cListObject &listObjectP) const; | ||||||
|   void Use(bool onOffP); |   bool Assign(int deviceIdP, int sourceP, int systemP, int transponderP); | ||||||
|   void SetTransponder(const int transponderP) { transponderM = transponderP; } |   bool Matches(int sourceP); | ||||||
|   int Transponder(void)     { return transponderM; } |   bool Matches(int deviceIdP, int sourceP, int systemP, int transponderP); | ||||||
|   bool Used(void)           { return !!useCountM; } |   void Attach(int deviceIdP, int transponderP); | ||||||
|   const char *Address()     { return *addressM; } |   void Detach(int deviceIdP, int transponderP); | ||||||
|  |   int GetModulesDVBS2(void); | ||||||
|  |   int GetModulesDVBT(void); | ||||||
|  |   int GetModulesDVBT2(void); | ||||||
|  |   int GetModulesDVBC(void); | ||||||
|  |   int GetModulesDVBC2(void); | ||||||
|  |   const char *Address(void)     { return *addressM; } | ||||||
|   const char *Model(void)       { return *modelM; } |   const char *Model(void)       { return *modelM; } | ||||||
|   const char *Description() { return *descriptionM; } |   const char *Description(void) { return *descriptionM; } | ||||||
|  |   const char *Quirks(void)      { return *quirksM; } | ||||||
|   bool Quirk(int quirkP)        { return ((quirkP & eSatipQuirkMask) & quirkM); } |   bool Quirk(int quirkP)        { return ((quirkP & eSatipQuirkMask) & quirkM); } | ||||||
|   int ModelType(void)       { return modelTypeM; } |   bool HasQuirk(void)           { return (quirkM != eSatipQuirkNone); } | ||||||
|   bool Match(int modelP)    { return ((modelP & eSatipModelTypeMask) & modelTypeM); } |   bool HasCI(void)              { return hasCiM; } | ||||||
|   int Cable()               { return Match(eSatipModelTypeDVBC)  ? modelCountM[eSatipModuleDVBC]  : 0; } |  | ||||||
|   int Cable2()              { return Match(eSatipModelTypeDVBC2) ? modelCountM[eSatipModuleDVBC2] : 0; } |  | ||||||
|   int Satellite()           { return Match(eSatipModelTypeDVBS2) ? modelCountM[eSatipModuleDVBS2] : 0; } |  | ||||||
|   int Terrestrial()         { return Match(eSatipModelTypeDVBT)  ? modelCountM[eSatipModuleDVBT]  : 0; } |  | ||||||
|   int Terrestrial2()        { return Match(eSatipModelTypeDVBT2) ? modelCountM[eSatipModuleDVBT2] : 0; } |  | ||||||
|   void Update(void)             { lastSeenM.Set(); } |   void Update(void)             { lastSeenM.Set(); } | ||||||
|   uint64_t LastSeen(void)       { return lastSeenM.Elapsed(); } |   uint64_t LastSeen(void)       { return lastSeenM.Elapsed(); } | ||||||
|   time_t Created(void)          { return createdM; } |   time_t Created(void)          { return createdM; } | ||||||
| @@ -76,11 +102,15 @@ public: | |||||||
| class cSatipServers : public cList<cSatipServer> { | class cSatipServers : public cList<cSatipServer> { | ||||||
| public: | public: | ||||||
|   cSatipServer *Find(cSatipServer *serverP); |   cSatipServer *Find(cSatipServer *serverP); | ||||||
|   cSatipServer *Find(int sourceP, int transponderP, int systemP); |   cSatipServer *Find(int sourceP); | ||||||
|   void SetTransponder(cSatipServer *serverP, bool transponderP); |   cSatipServer *Assign(int deviceIdP, int sourceP, int transponderP, int systemP); | ||||||
|   cSatipServer *Update(cSatipServer *serverP); |   cSatipServer *Update(cSatipServer *serverP); | ||||||
|   void Use(cSatipServer *serverP, bool onOffP); |   void Attach(cSatipServer *serverP, int deviceIdP, int transponderP); | ||||||
|  |   void Detach(cSatipServer *serverP, int deviceIdP, int transponderP); | ||||||
|  |   bool IsQuirk(cSatipServer *serverP, int quirkP); | ||||||
|  |   bool HasCI(cSatipServer *serverP); | ||||||
|   void Cleanup(uint64_t intervalMsP = 0); |   void Cleanup(uint64_t intervalMsP = 0); | ||||||
|  |   cString GetAddress(cSatipServer *serverP); | ||||||
|   cString GetString(cSatipServer *serverP); |   cString GetString(cSatipServer *serverP); | ||||||
|   cString List(void); |   cString List(void); | ||||||
|   int NumProvidedSystems(void); |   int NumProvidedSystems(void); | ||||||
|   | |||||||
							
								
								
									
										50
									
								
								setup.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								setup.c
									
									
									
									
									
								
							| @@ -89,6 +89,7 @@ private: | |||||||
|   cString addressM; |   cString addressM; | ||||||
|   cString modelM; |   cString modelM; | ||||||
|   cString descriptionM; |   cString descriptionM; | ||||||
|  |   cString ciExtensionM; | ||||||
|   uint64_t createdM; |   uint64_t createdM; | ||||||
|   void Setup(void); |   void Setup(void); | ||||||
|  |  | ||||||
| @@ -103,6 +104,7 @@ cSatipServerInfo::cSatipServerInfo(cSatipServer *serverP) | |||||||
|   addressM(serverP ? serverP->Address() : "---"), |   addressM(serverP ? serverP->Address() : "---"), | ||||||
|   modelM(serverP ? serverP->Model() : "---"), |   modelM(serverP ? serverP->Model() : "---"), | ||||||
|   descriptionM(serverP ? serverP->Description() : "---"), |   descriptionM(serverP ? serverP->Description() : "---"), | ||||||
|  |   ciExtensionM(serverP && serverP->HasCI() ? trVDR("yes") : trVDR("no")), | ||||||
|   createdM(serverP ? serverP->Created() : 0) |   createdM(serverP ? serverP->Created() : 0) | ||||||
| { | { | ||||||
|   SetMenuCategory(mcSetupPlugins); |   SetMenuCategory(mcSetupPlugins); | ||||||
| @@ -119,6 +121,7 @@ void cSatipServerInfo::Setup(void) | |||||||
|   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Address"),       *addressM),              osUnknown, false)); |   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Address"),       *addressM),              osUnknown, false)); | ||||||
|   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Model"),         *modelM),                osUnknown, false)); |   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Model"),         *modelM),                osUnknown, false)); | ||||||
|   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Description"),   *descriptionM),          osUnknown, false)); |   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Description"),   *descriptionM),          osUnknown, false)); | ||||||
|  |   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("CI extension"),  *ciExtensionM),          osUnknown, false)); | ||||||
|   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Creation date"), *DayDateTime(createdM)), osUnknown, false)); |   Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Creation date"), *DayDateTime(createdM)), osUnknown, false)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -327,8 +330,10 @@ eOSState cSatipMenuInfo::ProcessKey(eKeys keyP) | |||||||
| // --- cSatipPluginSetup ------------------------------------------------------ | // --- cSatipPluginSetup ------------------------------------------------------ | ||||||
|  |  | ||||||
| cSatipPluginSetup::cSatipPluginSetup() | cSatipPluginSetup::cSatipPluginSetup() | ||||||
| : deviceCountM(0), | : detachedModeM(SatipConfig.GetDetachedMode()), | ||||||
|  |   deviceCountM(0), | ||||||
|   operatingModeM(SatipConfig.GetOperatingMode()), |   operatingModeM(SatipConfig.GetOperatingMode()), | ||||||
|  |   ciExtensionM(SatipConfig.GetCIExtension()), | ||||||
|   eitScanM(SatipConfig.GetEITScan()), |   eitScanM(SatipConfig.GetEITScan()), | ||||||
|   numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()), |   numDisabledSourcesM(SatipConfig.GetDisabledSourcesCount()), | ||||||
|   numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount()) |   numDisabledFiltersM(SatipConfig.GetDisabledFiltersCount()) | ||||||
| @@ -338,6 +343,10 @@ cSatipPluginSetup::cSatipPluginSetup() | |||||||
|   operatingModeTextsM[cSatipConfig::eOperatingModeLow]    = tr("low"); |   operatingModeTextsM[cSatipConfig::eOperatingModeLow]    = tr("low"); | ||||||
|   operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal"); |   operatingModeTextsM[cSatipConfig::eOperatingModeNormal] = tr("normal"); | ||||||
|   operatingModeTextsM[cSatipConfig::eOperatingModeHigh]   = tr("high"); |   operatingModeTextsM[cSatipConfig::eOperatingModeHigh]   = tr("high"); | ||||||
|  |   for (unsigned int i = 0; i < ELEMENTS(cicamsM); ++i) | ||||||
|  |       cicamsM[i] = SatipConfig.GetCICAM(i); | ||||||
|  |   for (unsigned int i = 0; i < ELEMENTS(ca_systems_table); ++i) | ||||||
|  |       cicamTextsM[i] = ca_systems_table[i].description; | ||||||
|   if (numDisabledSourcesM > MAX_DISABLED_SOURCES_COUNT) |   if (numDisabledSourcesM > MAX_DISABLED_SOURCES_COUNT) | ||||||
|      numDisabledSourcesM = MAX_DISABLED_SOURCES_COUNT; |      numDisabledSourcesM = MAX_DISABLED_SOURCES_COUNT; | ||||||
|   for (int i = 0; i < MAX_DISABLED_SOURCES_COUNT; ++i) |   for (int i = 0; i < MAX_DISABLED_SOURCES_COUNT; ++i) | ||||||
| @@ -364,6 +373,14 @@ void cSatipPluginSetup::Setup(void) | |||||||
|   helpM.Append(tr("Define the used operating mode for all SAT>IP devices:\n\noff - devices are disabled\nlow - devices are working at the lowest priority\nnormal - devices are working within normal parameters\nhigh - devices are working at the highest priority")); |   helpM.Append(tr("Define the used operating mode for all SAT>IP devices:\n\noff - devices are disabled\nlow - devices are working at the lowest priority\nnormal - devices are working within normal parameters\nhigh - devices are working at the highest priority")); | ||||||
|  |  | ||||||
|   if (operatingModeM) { |   if (operatingModeM) { | ||||||
|  |      Add(new cMenuEditBoolItem(tr("Enable CI extension"), &ciExtensionM)); | ||||||
|  |      helpM.Append(tr("Define whether a CI extension shall be used.\n\nThis setting enables integrated CI/CAM handling found in some SAT>IP hardware (e.g. Digital Devices OctopusNet).")); | ||||||
|  |  | ||||||
|  |      for (unsigned int i = 0; ciExtensionM && i < ELEMENTS(cicamsM); ++i) { | ||||||
|  |          Add(new cMenuEditStraItem(*cString::sprintf(" %s #%d", tr("CI/CAM"), i + 1), &cicamsM[i], ELEMENTS(cicamTextsM), cicamTextsM)); | ||||||
|  |          helpM.Append(tr("Define a desired CAM type for the CI slot.\n\nThe '---' option lets SAT>IP hardware do the auto-selection.")); | ||||||
|  |          } | ||||||
|  |  | ||||||
|      Add(new cMenuEditBoolItem(tr("Enable EPG scanning"), &eitScanM)); |      Add(new cMenuEditBoolItem(tr("Enable EPG scanning"), &eitScanM)); | ||||||
|      helpM.Append(tr("Define whether the EPG background scanning shall be used.\n\nThis setting disables the automatic EIT scanning functionality for all SAT>IP devices.")); |      helpM.Append(tr("Define whether the EPG background scanning shall be used.\n\nThis setting disables the automatic EIT scanning functionality for all SAT>IP devices.")); | ||||||
|  |  | ||||||
| @@ -386,12 +403,15 @@ void cSatipPluginSetup::Setup(void) | |||||||
|   Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false)); |   Add(new cOsdItem(tr("Active SAT>IP servers:"), osUnknown, false)); | ||||||
|   helpM.Append(""); |   helpM.Append(""); | ||||||
|  |  | ||||||
|  |   detachedModeM = SatipConfig.GetDetachedMode(); | ||||||
|  |   if (!detachedModeM) { | ||||||
|      cSatipServers *servers = cSatipDiscover::GetInstance()->GetServers(); |      cSatipServers *servers = cSatipDiscover::GetInstance()->GetServers(); | ||||||
|      deviceCountM = servers->Count(); |      deviceCountM = servers->Count(); | ||||||
|      for (cSatipServer *s = servers->First(); s; s = servers->Next(s)) { |      for (cSatipServer *s = servers->First(); s; s = servers->Next(s)) { | ||||||
|          Add(new cSatipServerItem(s)); |          Add(new cSatipServerItem(s)); | ||||||
|          helpM.Append(""); |          helpM.Append(""); | ||||||
|          } |          } | ||||||
|  |      } | ||||||
|  |  | ||||||
|   SetCurrent(Get(current)); |   SetCurrent(Get(current)); | ||||||
|   Display(); |   Display(); | ||||||
| @@ -440,6 +460,7 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP) | |||||||
| { | { | ||||||
|   bool hadSubMenu = HasSubMenu(); |   bool hadSubMenu = HasSubMenu(); | ||||||
|   int oldOperatingMode = operatingModeM; |   int oldOperatingMode = operatingModeM; | ||||||
|  |   int oldCiExtension = ciExtensionM; | ||||||
|   int oldNumDisabledSources = numDisabledSourcesM; |   int oldNumDisabledSources = numDisabledSourcesM; | ||||||
|   int oldNumDisabledFilters = numDisabledFiltersM; |   int oldNumDisabledFilters = numDisabledFiltersM; | ||||||
|   eOSState state = cMenuSetupPage::ProcessKey(keyP); |   eOSState state = cMenuSetupPage::ProcessKey(keyP); | ||||||
| @@ -463,7 +484,7 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP) | |||||||
|   if ((keyP == kNone) && (cSatipDiscover::GetInstance()->GetServers()->Count() != deviceCountM)) |   if ((keyP == kNone) && (cSatipDiscover::GetInstance()->GetServers()->Count() != deviceCountM)) | ||||||
|      Setup(); |      Setup(); | ||||||
|  |  | ||||||
|   if ((keyP != kNone) && ((numDisabledSourcesM != oldNumDisabledSources) || (numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != oldOperatingMode))) { |   if ((keyP != kNone) && ((numDisabledSourcesM != oldNumDisabledSources) || (numDisabledFiltersM != oldNumDisabledFilters) || (operatingModeM != oldOperatingMode) || (ciExtensionM != oldCiExtension) || (detachedModeM != SatipConfig.GetDetachedMode()))) { | ||||||
|      while ((numDisabledSourcesM < oldNumDisabledSources) && (oldNumDisabledSources > 0)) |      while ((numDisabledSourcesM < oldNumDisabledSources) && (oldNumDisabledSources > 0)) | ||||||
|            disabledSourcesM[--oldNumDisabledSources] = cSource::stNone; |            disabledSourcesM[--oldNumDisabledSources] = cSource::stNone; | ||||||
|      while ((numDisabledFiltersM < oldNumDisabledFilters) && (oldNumDisabledFilters > 0)) |      while ((numDisabledFiltersM < oldNumDisabledFilters) && (oldNumDisabledFilters > 0)) | ||||||
| @@ -474,6 +495,22 @@ eOSState cSatipPluginSetup::ProcessKey(eKeys keyP) | |||||||
|   return state; |   return state; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void cSatipPluginSetup::StoreCicams(const char *nameP, int *cicamsP) | ||||||
|  | { | ||||||
|  |   cString buffer = ""; | ||||||
|  |   int n = 0; | ||||||
|  |   for (int i = 0; i < MAX_CICAM_COUNT; ++i) { | ||||||
|  |       if (cicamsP[i] < 0) | ||||||
|  |          break; | ||||||
|  |       if (n++ > 0) | ||||||
|  |          buffer = cString::sprintf("%s %d", *buffer, cicamsP[i]); | ||||||
|  |       else | ||||||
|  |          buffer = cString::sprintf("%d", cicamsP[i]); | ||||||
|  |       } | ||||||
|  |   debug3("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer); | ||||||
|  |   SetupStore(nameP, *buffer); | ||||||
|  | } | ||||||
|  |  | ||||||
| void cSatipPluginSetup::StoreSources(const char *nameP, int *sourcesP) | void cSatipPluginSetup::StoreSources(const char *nameP, int *sourcesP) | ||||||
| { | { | ||||||
|   cString buffer = ""; |   cString buffer = ""; | ||||||
| @@ -486,7 +523,7 @@ void cSatipPluginSetup::StoreSources(const char *nameP, int *sourcesP) | |||||||
|       else |       else | ||||||
|          buffer = cString::sprintf("%s", *cSource::ToString(sourcesP[i])); |          buffer = cString::sprintf("%s", *cSource::ToString(sourcesP[i])); | ||||||
|       } |       } | ||||||
|   debug1("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer); |   debug3("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer); | ||||||
|   SetupStore(nameP, *buffer); |   SetupStore(nameP, *buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -502,7 +539,7 @@ void cSatipPluginSetup::StoreFilters(const char *nameP, int *valuesP) | |||||||
|       else |       else | ||||||
|          buffer = cString::sprintf("%d", valuesP[i]); |          buffer = cString::sprintf("%d", valuesP[i]); | ||||||
|       } |       } | ||||||
|   debug1("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer); |   debug3("%s (%s, %s)", __PRETTY_FUNCTION__, nameP, *buffer); | ||||||
|   SetupStore(nameP, *buffer); |   SetupStore(nameP, *buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -510,12 +547,17 @@ void cSatipPluginSetup::Store(void) | |||||||
| { | { | ||||||
|   // Store values into setup.conf |   // Store values into setup.conf | ||||||
|   SetupStore("OperatingMode", operatingModeM); |   SetupStore("OperatingMode", operatingModeM); | ||||||
|  |   SetupStore("EnableCIExtension", ciExtensionM); | ||||||
|   SetupStore("EnableEITScan", eitScanM); |   SetupStore("EnableEITScan", eitScanM); | ||||||
|  |   StoreCicams("CICAM", cicamsM); | ||||||
|   StoreSources("DisabledSources", disabledSourcesM); |   StoreSources("DisabledSources", disabledSourcesM); | ||||||
|   StoreFilters("DisabledFilters", disabledFilterIndexesM); |   StoreFilters("DisabledFilters", disabledFilterIndexesM); | ||||||
|   // Update global config |   // Update global config | ||||||
|   SatipConfig.SetOperatingMode(operatingModeM); |   SatipConfig.SetOperatingMode(operatingModeM); | ||||||
|  |   SatipConfig.SetCIExtension(ciExtensionM); | ||||||
|   SatipConfig.SetEITScan(eitScanM); |   SatipConfig.SetEITScan(eitScanM); | ||||||
|  |   for (int i = 0; i < MAX_CICAM_COUNT; ++i) | ||||||
|  |       SatipConfig.SetCICAM(i, cicamsM[i]); | ||||||
|   for (int i = 0; i < MAX_DISABLED_SOURCES_COUNT; ++i) |   for (int i = 0; i < MAX_DISABLED_SOURCES_COUNT; ++i) | ||||||
|       SatipConfig.SetDisabledSources(i, disabledSourcesM[i]); |       SatipConfig.SetDisabledSources(i, disabledSourcesM[i]); | ||||||
|   for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) |   for (int i = 0; i < SECTION_FILTER_TABLE_SIZE; ++i) | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								setup.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								setup.h
									
									
									
									
									
								
							| @@ -15,9 +15,13 @@ | |||||||
| class cSatipPluginSetup : public cMenuSetupPage | class cSatipPluginSetup : public cMenuSetupPage | ||||||
| { | { | ||||||
| private: | private: | ||||||
|  |   bool detachedModeM; | ||||||
|   int deviceCountM; |   int deviceCountM; | ||||||
|   int operatingModeM; |   int operatingModeM; | ||||||
|   const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount]; |   const char *operatingModeTextsM[cSatipConfig::eOperatingModeCount]; | ||||||
|  |   int ciExtensionM; | ||||||
|  |   int cicamsM[MAX_CICAM_COUNT]; | ||||||
|  |   const char *cicamTextsM[CA_SYSTEMS_TABLE_SIZE]; | ||||||
|   int eitScanM; |   int eitScanM; | ||||||
|   int numDisabledSourcesM; |   int numDisabledSourcesM; | ||||||
|   int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT]; |   int disabledSourcesM[MAX_DISABLED_SOURCES_COUNT]; | ||||||
| @@ -31,6 +35,7 @@ private: | |||||||
|   eOSState ShowDeviceStatus(void); |   eOSState ShowDeviceStatus(void); | ||||||
|   eOSState ShowInfo(void); |   eOSState ShowInfo(void); | ||||||
|   void Setup(void); |   void Setup(void); | ||||||
|  |   void StoreCicams(const char *nameP, int *cicamsP); | ||||||
|   void StoreSources(const char *nameP, int *sourcesP); |   void StoreSources(const char *nameP, int *sourcesP); | ||||||
|   void StoreFilters(const char *nameP, int *valuesP); |   void StoreFilters(const char *nameP, int *valuesP); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								socket.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								socket.c
									
									
									
									
									
								
							| @@ -129,18 +129,24 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP) | |||||||
|     if (len > 0) |     if (len > 0) | ||||||
|        return len; |        return len; | ||||||
|     } while (len > 0); |     } while (len > 0); | ||||||
|   ERROR_IF_RET(len < 0 && errno != EAGAIN, "recvmsg()", return -1); |   ERROR_IF_RET(len < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmsg()", return -1); | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRecvSizeP, unsigned int elementCountP, unsigned int elementBufferSizeP) | int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRecvSizeP, unsigned int elementCountP, unsigned int elementBufferSizeP) | ||||||
| { | { | ||||||
|   debug16("%s (, , %d, %d)", __PRETTY_FUNCTION__, elementCountP, elementBufferSizeP); |   debug16("%s (, , %d, %d)", __PRETTY_FUNCTION__, elementCountP, elementBufferSizeP); | ||||||
|  |   int count = -1; | ||||||
|   // Error out if socket not initialized |   // Error out if socket not initialized | ||||||
|   if (socketDescM <= 0) { |   if (socketDescM <= 0) { | ||||||
|      error("%s Invalid socket", __PRETTY_FUNCTION__); |      error("%s Invalid socket", __PRETTY_FUNCTION__); | ||||||
|      return -1; |      return -1; | ||||||
|      } |      } | ||||||
|  |   if (!bufferAddrP || !elementRecvSizeP || !elementCountP || !elementBufferSizeP) { | ||||||
|  |      error("%s Invalid parameter(s)", __PRETTY_FUNCTION__); | ||||||
|  |      return -1; | ||||||
|  |      } | ||||||
|  | #if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,12) | ||||||
|   // Initialize iov and msgh structures |   // Initialize iov and msgh structures | ||||||
|   struct mmsghdr mmsgh[elementCountP]; |   struct mmsghdr mmsgh[elementCountP]; | ||||||
|   struct iovec iov[elementCountP]; |   struct iovec iov[elementCountP]; | ||||||
| @@ -153,12 +159,21 @@ int cSatipSocket::ReadMulti(unsigned char *bufferAddrP, unsigned int *elementRec | |||||||
|       } |       } | ||||||
|  |  | ||||||
|   // Read data from socket as a set |   // Read data from socket as a set | ||||||
|   int count = -1; |  | ||||||
|   if (socketDescM && bufferAddrP && elementRecvSizeP && (elementCountP > 0) && (elementBufferSizeP > 0)) |  | ||||||
|   count = (int)recvmmsg(socketDescM, mmsgh, elementCountP, MSG_DONTWAIT, NULL); |   count = (int)recvmmsg(socketDescM, mmsgh, elementCountP, MSG_DONTWAIT, NULL); | ||||||
|   ERROR_IF_RET(count < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmmsg()", return -1); |   ERROR_IF_RET(count < 0 && errno != EAGAIN && errno != EWOULDBLOCK, "recvmmsg()", return -1); | ||||||
|   for (int i = 0; i < count; ++i) |   for (int i = 0; i < count; ++i) | ||||||
|       elementRecvSizeP[i] = mmsgh[i].msg_len; |       elementRecvSizeP[i] = mmsgh[i].msg_len; | ||||||
|  | #else | ||||||
|  |   count = 0; | ||||||
|  |   while (count < (int)elementCountP) { | ||||||
|  |         int len = Read(bufferAddrP + count * elementBufferSizeP, elementBufferSizeP); | ||||||
|  |         if (len < 0) | ||||||
|  |            return -1; | ||||||
|  |         else if (len == 0) | ||||||
|  |            break; | ||||||
|  |         elementRecvSizeP[count++] = len; | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|   debug16("%s Received %d packets size[0]=%d", __PRETTY_FUNCTION__, count, elementRecvSizeP[0]); |   debug16("%s Received %d packets size[0]=%d", __PRETTY_FUNCTION__, count, elementRecvSizeP[0]); | ||||||
|  |  | ||||||
|   return count; |   return count; | ||||||
|   | |||||||
							
								
								
									
										77
									
								
								tuner.c
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								tuner.c
									
									
									
									
									
								
							| @@ -25,8 +25,8 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP) | |||||||
|   rtcpM(*this), |   rtcpM(*this), | ||||||
|   streamAddrM(""), |   streamAddrM(""), | ||||||
|   streamParamM(""), |   streamParamM(""), | ||||||
|   currentServerM(NULL), |   currentServerM(NULL, deviceP.GetId(), 0), | ||||||
|   nextServerM(NULL), |   nextServerM(NULL, deviceP.GetId(), 0), | ||||||
|   mutexM(), |   mutexM(), | ||||||
|   reConnectM(), |   reConnectM(), | ||||||
|   keepAliveM(), |   keepAliveM(), | ||||||
| @@ -40,7 +40,9 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP) | |||||||
|   hasLockM(false), |   hasLockM(false), | ||||||
|   signalStrengthM(-1), |   signalStrengthM(-1), | ||||||
|   signalQualityM(-1), |   signalQualityM(-1), | ||||||
|  |   frontendIdM(-1), | ||||||
|   streamIdM(-1), |   streamIdM(-1), | ||||||
|  |   pmtPidM(-1), | ||||||
|   addPidsM(), |   addPidsM(), | ||||||
|   delPidsM(), |   delPidsM(), | ||||||
|   pidsM() |   pidsM() | ||||||
| @@ -117,7 +119,7 @@ void cSatipTuner::Action(void) | |||||||
|                // Read reception statistics via DESCRIBE and RTCP |                // Read reception statistics via DESCRIBE and RTCP | ||||||
|                if (hasLockM || ReadReceptionStatus()) { |                if (hasLockM || ReadReceptionStatus()) { | ||||||
|                   // Quirk for devices without valid reception data |                   // Quirk for devices without valid reception data | ||||||
|                   if (currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkForceLock)) { |                   if (currentServerM.IsQuirk(cSatipServer::eSatipQuirkForceLock)) { | ||||||
|                      hasLockM = true; |                      hasLockM = true; | ||||||
|                      signalStrengthM = eDefaultSignalStrength; |                      signalStrengthM = eDefaultSignalStrength; | ||||||
|                      signalQualityM = eDefaultSignalQuality; |                      signalQualityM = eDefaultSignalQuality; | ||||||
| @@ -186,8 +188,6 @@ bool cSatipTuner::Connect(void) | |||||||
|      // Just retune |      // Just retune | ||||||
|      if (streamIdM >= 0) { |      if (streamIdM >= 0) { | ||||||
|         cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM); |         cString uri = cString::sprintf("%sstream=%d?%s", *connectionUri, streamIdM, *streamParamM); | ||||||
|         //if (pidsM.Size()) |  | ||||||
|         //   uri = cString::sprintf("%s&pids=%s", *uri, *pidsM.ListPids()); |  | ||||||
|         debug1("%s Retuning [device %d]", __PRETTY_FUNCTION__, deviceIdM); |         debug1("%s Retuning [device %d]", __PRETTY_FUNCTION__, deviceIdM); | ||||||
|         if (rtspM.Play(*uri)) { |         if (rtspM.Play(*uri)) { | ||||||
|            keepAliveM.Set(timeoutM); |            keepAliveM.Set(timeoutM); | ||||||
| @@ -197,15 +197,15 @@ bool cSatipTuner::Connect(void) | |||||||
|      else if (rtspM.Options(*connectionUri)) { |      else if (rtspM.Options(*connectionUri)) { | ||||||
|         cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM); |         cString uri = cString::sprintf("%s?%s", *connectionUri, *streamParamM); | ||||||
|         // Flush any old content |         // Flush any old content | ||||||
|         rtpM.Flush(); |         //rtpM.Flush(); | ||||||
|         rtcpM.Flush(); |         //rtcpM.Flush(); | ||||||
|         if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port())) { |         if (rtspM.Setup(*uri, rtpM.Port(), rtcpM.Port())) { | ||||||
|            keepAliveM.Set(timeoutM); |            keepAliveM.Set(timeoutM); | ||||||
|            if (nextServerM) { |            if (nextServerM.IsValid()) { | ||||||
|               cSatipDiscover::GetInstance()->UseServer(nextServerM, true); |  | ||||||
|               currentServerM = nextServerM; |               currentServerM = nextServerM; | ||||||
|               nextServerM = NULL; |               nextServerM.Reset(); | ||||||
|               } |               } | ||||||
|  |            currentServerM.Attach(); | ||||||
|            return true; |            return true; | ||||||
|            } |            } | ||||||
|         } |         } | ||||||
| @@ -226,6 +226,8 @@ bool cSatipTuner::Disconnect(void) | |||||||
|   if (!isempty(*streamAddrM) && (streamIdM >= 0)) { |   if (!isempty(*streamAddrM) && (streamIdM >= 0)) { | ||||||
|      cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM); |      cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM); | ||||||
|      rtspM.Teardown(*uri); |      rtspM.Teardown(*uri); | ||||||
|  |      // some devices requires a teardown for TCP connection also | ||||||
|  |      rtspM.Reset(); | ||||||
|      streamIdM = -1; |      streamIdM = -1; | ||||||
|      } |      } | ||||||
|  |  | ||||||
| @@ -233,11 +235,12 @@ bool cSatipTuner::Disconnect(void) | |||||||
|   hasLockM = false; |   hasLockM = false; | ||||||
|   signalStrengthM = -1; |   signalStrengthM = -1; | ||||||
|   signalQualityM = -1; |   signalQualityM = -1; | ||||||
|  |   frontendIdM = -1; | ||||||
|  |  | ||||||
|   if (currentServerM) |   currentServerM.Detach(); | ||||||
|      cSatipDiscover::GetInstance()->UseServer(currentServerM, false); |  | ||||||
|   statusUpdateM.Set(0); |   statusUpdateM.Set(0); | ||||||
|   timeoutM = eMinKeepAliveIntervalMs; |   timeoutM = eMinKeepAliveIntervalMs; | ||||||
|  |   pmtPidM = -1; | ||||||
|   addPidsM.Clear(); |   addPidsM.Clear(); | ||||||
|   delPidsM.Clear(); |   delPidsM.Clear(); | ||||||
|  |  | ||||||
| @@ -283,6 +286,9 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP) | |||||||
|      if (c)  { |      if (c)  { | ||||||
|         int value; |         int value; | ||||||
|  |  | ||||||
|  |         // feID: | ||||||
|  |         frontendIdM = atoi(c + 7); | ||||||
|  |  | ||||||
|         // level: |         // level: | ||||||
|         // Numerical value between 0 and 255 |         // Numerical value between 0 and 255 | ||||||
|         // An incoming L-band satellite signal of |         // An incoming L-band satellite signal of | ||||||
| @@ -290,7 +296,7 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP) | |||||||
|         // -65dBm corresponds to 32 |         // -65dBm corresponds to 32 | ||||||
|         // No signal corresponds to 0 |         // No signal corresponds to 0 | ||||||
|         c = strstr(c, ","); |         c = strstr(c, ","); | ||||||
|         value = atoi(++c); |         value = min(atoi(++c), 255); | ||||||
|         // Scale value to 0-100 |         // Scale value to 0-100 | ||||||
|         signalStrengthM = (value >= 0) ? (value * 100 / 255) : -1; |         signalStrengthM = (value >= 0) ? (value * 100 / 255) : -1; | ||||||
|  |  | ||||||
| @@ -308,7 +314,7 @@ void cSatipTuner::ProcessApplicationData(u_char *bufferP, int lengthP) | |||||||
|         // -a BER lower than 2x10-4 after Viterbi for DVB-S |         // -a BER lower than 2x10-4 after Viterbi for DVB-S | ||||||
|         // -a PER lower than 10-7 for DVB-S2 |         // -a PER lower than 10-7 for DVB-S2 | ||||||
|         c = strstr(c, ","); |         c = strstr(c, ","); | ||||||
|         value = atoi(++c); |         value = min(atoi(++c), 15); | ||||||
|         // Scale value to 0-100 |         // Scale value to 0-100 | ||||||
|         signalQualityM = (hasLockM && (value >= 0)) ? (value * 100 / 15) : 0; |         signalQualityM = (hasLockM && (value >= 0)) ? (value * 100 / 15) : 0; | ||||||
|         } |         } | ||||||
| @@ -328,7 +334,7 @@ void cSatipTuner::SetSessionTimeout(const char *sessionP, int timeoutP) | |||||||
|   cMutexLock MutexLock(&mutexM); |   cMutexLock MutexLock(&mutexM); | ||||||
|   debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, sessionP, timeoutP, deviceIdM); |   debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, sessionP, timeoutP, deviceIdM); | ||||||
|   sessionM = sessionP; |   sessionM = sessionP; | ||||||
|   if (nextServerM && nextServerM->Quirk(cSatipServer::eSatipQuirkSessionId) && !isempty(*sessionM) && startswith(*sessionM, "0")) |   if (nextServerM.IsQuirk(cSatipServer::eSatipQuirkSessionId) && !isempty(*sessionM) && startswith(*sessionM, "0")) | ||||||
|      rtspM.SetSession(SkipZeroes(*sessionM)); |      rtspM.SetSession(SkipZeroes(*sessionM)); | ||||||
|   timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs; |   timeoutM = (timeoutP > eMinKeepAliveIntervalMs) ? timeoutP : eMinKeepAliveIntervalMs; | ||||||
| } | } | ||||||
| @@ -339,15 +345,15 @@ int cSatipTuner::GetId(void) | |||||||
|   return deviceIdM; |   return deviceIdM; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool cSatipTuner::SetSource(cSatipServer *serverP, const char *parameterP, const int indexP) | bool cSatipTuner::SetSource(cSatipServer *serverP, const int transponderP, const char *parameterP, const int indexP) | ||||||
| { | { | ||||||
|   debug1("%s (%s, %d) [device %d]", __PRETTY_FUNCTION__, parameterP, indexP, deviceIdM); |   debug1("%s (%d, %s, %d) [device %d]", __PRETTY_FUNCTION__, transponderP, parameterP, indexP, deviceIdM); | ||||||
|   cMutexLock MutexLock(&mutexM); |   cMutexLock MutexLock(&mutexM); | ||||||
|   if (serverP) { |   if (serverP) { | ||||||
|      nextServerM = cSatipDiscover::GetInstance()->GetServer(serverP); |      nextServerM.Set(serverP, transponderP); | ||||||
|      if (nextServerM && !isempty(nextServerM->Address()) && !isempty(parameterP)) { |      if (!isempty(*nextServerM.GetAddress()) && !isempty(parameterP)) { | ||||||
|         // Update stream address and parameter |         // Update stream address and parameter | ||||||
|         streamAddrM = rtspM.RtspUnescapeString(nextServerM->Address()); |         streamAddrM = rtspM.RtspUnescapeString(*nextServerM.GetAddress()); | ||||||
|         streamParamM = rtspM.RtspUnescapeString(parameterP); |         streamParamM = rtspM.RtspUnescapeString(parameterP); | ||||||
|         // Reconnect |         // Reconnect | ||||||
|         RequestState(tsSet, smExternal); |         RequestState(tsSet, smExternal); | ||||||
| @@ -375,8 +381,7 @@ bool cSatipTuner::SetPid(int pidP, int typeP, bool onP) | |||||||
|      delPidsM.AddPid(pidP); |      delPidsM.AddPid(pidP); | ||||||
|      addPidsM.RemovePid(pidP); |      addPidsM.RemovePid(pidP); | ||||||
|      } |      } | ||||||
|   debug9("%s (%d, %d, %d) pids=%s [device %d]", __PRETTY_FUNCTION__, pidP, typeP, onP, *pidsM.ListPids(), deviceIdM); |   debug12("%s (%d, %d, %d) pids=%s [device %d]", __PRETTY_FUNCTION__, pidP, typeP, onP, *pidsM.ListPids(), deviceIdM); | ||||||
|   pidUpdateCacheM.Set(ePidUpdateIntervalMs); |  | ||||||
|   sleepM.Signal(); |   sleepM.Signal(); | ||||||
|  |  | ||||||
|   return true; |   return true; | ||||||
| @@ -389,7 +394,8 @@ bool cSatipTuner::UpdatePids(bool forceP) | |||||||
|   if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) && |   if (((forceP && pidsM.Size()) || (pidUpdateCacheM.TimedOut() && (addPidsM.Size() || delPidsM.Size()))) && | ||||||
|       !isempty(*streamAddrM) && (streamIdM > 0)) { |       !isempty(*streamAddrM) && (streamIdM > 0)) { | ||||||
|      cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM); |      cString uri = cString::sprintf("rtsp://%s/stream=%d", *streamAddrM, streamIdM); | ||||||
|      bool usedummy = !!(currentServerM && currentServerM->Quirk(cSatipServer::eSatipQuirkPlayPids)); |      bool useci = (SatipConfig.GetCIExtension() && currentServerM.HasCI()); | ||||||
|  |      bool usedummy = currentServerM.IsQuirk(cSatipServer::eSatipQuirkPlayPids); | ||||||
|      if (forceP || usedummy) { |      if (forceP || usedummy) { | ||||||
|         if (pidsM.Size()) |         if (pidsM.Size()) | ||||||
|            uri = cString::sprintf("%s?pids=%s", *uri, *pidsM.ListPids()); |            uri = cString::sprintf("%s?pids=%s", *uri, *pidsM.ListPids()); | ||||||
| @@ -402,6 +408,23 @@ bool cSatipTuner::UpdatePids(bool forceP) | |||||||
|         if (delPidsM.Size()) |         if (delPidsM.Size()) | ||||||
|            uri = cString::sprintf("%s%sdelpids=%s", *uri, addPidsM.Size() ? "&" : "?", *delPidsM.ListPids()); |            uri = cString::sprintf("%s%sdelpids=%s", *uri, addPidsM.Size() ? "&" : "?", *delPidsM.ListPids()); | ||||||
|         } |         } | ||||||
|  |      if (useci) { | ||||||
|  |         // CI extension parameters: | ||||||
|  |         // - x_pmt : specifies the PMT of the service you want the CI to decode | ||||||
|  |         // - x_ci  : specfies which CI slot (1..n) to use | ||||||
|  |         //           value 0 releases the CI slot | ||||||
|  |         //           CI slot released automatically if the stream is released, | ||||||
|  |         //           but not when used retuning to another channel | ||||||
|  |         int pid = deviceM->GetPmtPid(); | ||||||
|  |         if ((pid > 0) && (pid != pmtPidM)) { | ||||||
|  |            int slot = deviceM->GetCISlot(); | ||||||
|  |            uri = cString::sprintf("%s&x_pmt=%d", *uri, pid); | ||||||
|  |            if (slot > 0) | ||||||
|  |               uri = cString::sprintf("%s&x_ci=%d", *uri, slot); | ||||||
|  |            } | ||||||
|  |         pmtPidM = pid; | ||||||
|  |         } | ||||||
|  |      pidUpdateCacheM.Set(ePidUpdateIntervalMs); | ||||||
|      if (!rtspM.Play(*uri)) |      if (!rtspM.Play(*uri)) | ||||||
|         return false; |         return false; | ||||||
|      addPidsM.Clear(); |      addPidsM.Clear(); | ||||||
| @@ -539,6 +562,12 @@ const char *cSatipTuner::TunerStateString(eTunerState stateP) | |||||||
|   return "---"; |   return "---"; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int cSatipTuner::FrontendId(void) | ||||||
|  | { | ||||||
|  |   debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM); | ||||||
|  |   return frontendIdM; | ||||||
|  | } | ||||||
|  |  | ||||||
| int cSatipTuner::SignalStrength(void) | int cSatipTuner::SignalStrength(void) | ||||||
| { | { | ||||||
|   debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM); |   debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM); | ||||||
| @@ -560,7 +589,7 @@ bool cSatipTuner::HasLock(void) | |||||||
| cString cSatipTuner::GetSignalStatus(void) | cString cSatipTuner::GetSignalStatus(void) | ||||||
| { | { | ||||||
|   debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM); |   debug16("%s [device %d]", __PRETTY_FUNCTION__, deviceIdM); | ||||||
|   return cString::sprintf("lock=%d strength=%d quality=%d", HasLock(), SignalStrength(), SignalQuality()); |   return cString::sprintf("lock=%d strength=%d quality=%d frontend=%d", HasLock(), SignalStrength(), SignalQuality(), FrontendId()); | ||||||
| } | } | ||||||
|  |  | ||||||
| cString cSatipTuner::GetInformation(void) | cString cSatipTuner::GetInformation(void) | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								tuner.h
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								tuner.h
									
									
									
									
									
								
							| @@ -12,6 +12,7 @@ | |||||||
| #include <vdr/tools.h> | #include <vdr/tools.h> | ||||||
|  |  | ||||||
| #include "deviceif.h" | #include "deviceif.h" | ||||||
|  | #include "discover.h" | ||||||
| #include "rtp.h" | #include "rtp.h" | ||||||
| #include "rtcp.h" | #include "rtcp.h" | ||||||
| #include "rtsp.h" | #include "rtsp.h" | ||||||
| @@ -20,14 +21,6 @@ | |||||||
|  |  | ||||||
| class cSatipPid : public cVector<int> { | class cSatipPid : public cVector<int> { | ||||||
| private: | private: | ||||||
|   int PidIndex(const int &pidP) |  | ||||||
|   { |  | ||||||
|     for (int i = 0; i < Size(); ++i) { |  | ||||||
|         if (pidP == At(i)) |  | ||||||
|            return i; |  | ||||||
|         } |  | ||||||
|     return -1; |  | ||||||
|   } |  | ||||||
|   static int PidCompare(const void *aPidP, const void *bPidP) |   static int PidCompare(const void *aPidP, const void *bPidP) | ||||||
|   { |   { | ||||||
|     return (*(int*)aPidP - *(int*)bPidP); |     return (*(int*)aPidP - *(int*)bPidP); | ||||||
| @@ -36,19 +29,14 @@ private: | |||||||
| public: | public: | ||||||
|   void RemovePid(const int &pidP) |   void RemovePid(const int &pidP) | ||||||
|   { |   { | ||||||
|     int i = PidIndex(pidP); |     if (RemoveElement(pidP)) | ||||||
|     if (i >= 0) { |  | ||||||
|        Remove(i); |  | ||||||
|        Sort(PidCompare); |        Sort(PidCompare); | ||||||
|   } |   } | ||||||
|   } |  | ||||||
|   void AddPid(int pidP) |   void AddPid(int pidP) | ||||||
|   { |   { | ||||||
|     if (PidIndex(pidP) < 0) { |     if (AppendUnique(pidP)) | ||||||
|        Append(pidP); |  | ||||||
|        Sort(PidCompare); |        Sort(PidCompare); | ||||||
|   } |   } | ||||||
|   } |  | ||||||
|   cString ListPids(void) |   cString ListPids(void) | ||||||
|   { |   { | ||||||
|     cString list = ""; |     cString list = ""; | ||||||
| @@ -61,6 +49,29 @@ public: | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | class cSatipTunerServer | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |   cSatipServer *serverM; | ||||||
|  |   int deviceIdM; | ||||||
|  |   int transponderM; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |   cSatipTunerServer(cSatipServer *serverP, const int deviceIdP, const int transponderP) : serverM(serverP), deviceIdM(deviceIdP), transponderM(transponderP) {} | ||||||
|  |   ~cSatipTunerServer() {} | ||||||
|  |   cSatipTunerServer(const cSatipTunerServer &objP) { serverM = NULL; deviceIdM = -1; transponderM = 0; } | ||||||
|  |   cSatipTunerServer& operator= (const cSatipTunerServer &objP) { serverM = objP.serverM; deviceIdM = objP.deviceIdM; transponderM = objP.transponderM; return *this; } | ||||||
|  |   bool IsValid(void) { return !!serverM; } | ||||||
|  |   bool IsQuirk(int quirkP) { return (serverM && cSatipDiscover::GetInstance()->IsServerQuirk(serverM, quirkP)); } | ||||||
|  |   bool HasCI(void) { return (serverM && cSatipDiscover::GetInstance()->HasServerCI(serverM)); } | ||||||
|  |   void Attach(void) { if (serverM) cSatipDiscover::GetInstance()->AttachServer(serverM, deviceIdM, transponderM); } | ||||||
|  |   void Detach(void) { if (serverM) cSatipDiscover::GetInstance()->DetachServer(serverM, deviceIdM, transponderM); } | ||||||
|  |   void Set(cSatipServer *serverP, const int transponderP) { serverM = serverP; transponderM = transponderP; } | ||||||
|  |   void Reset(void) { serverM = NULL; transponderM = 0; } | ||||||
|  |   cString GetAddress(void) { return serverM ? cSatipDiscover::GetInstance()->GetServerAddress(serverM) : ""; } | ||||||
|  |   cString GetInfo(void) { return cString::sprintf("server=%s deviceid=%d transponder=%d", serverM ? "assigned" : "null", deviceIdM, transponderM); } | ||||||
|  | }; | ||||||
|  |  | ||||||
| class cSatipTuner : public cThread, public cSatipTunerStatistics, public cSatipTunerIf | class cSatipTuner : public cThread, public cSatipTunerStatistics, public cSatipTunerIf | ||||||
| { | { | ||||||
| private: | private: | ||||||
| @@ -68,7 +79,7 @@ private: | |||||||
|     eDummyPid               = 100, |     eDummyPid               = 100, | ||||||
|     eDefaultSignalStrength  = 15, |     eDefaultSignalStrength  = 15, | ||||||
|     eDefaultSignalQuality   = 224, |     eDefaultSignalQuality   = 224, | ||||||
|     eSleepTimeoutMs         = 1000,  // in milliseconds |     eSleepTimeoutMs         = 250,   // in milliseconds | ||||||
|     eStatusUpdateTimeoutMs  = 1000,  // in milliseconds |     eStatusUpdateTimeoutMs  = 1000,  // in milliseconds | ||||||
|     ePidUpdateIntervalMs    = 250,   // in milliseconds |     ePidUpdateIntervalMs    = 250,   // in milliseconds | ||||||
|     eConnectTimeoutMs       = 5000,  // in milliseconds |     eConnectTimeoutMs       = 5000,  // in milliseconds | ||||||
| @@ -85,8 +96,8 @@ private: | |||||||
|   cSatipRtcp rtcpM; |   cSatipRtcp rtcpM; | ||||||
|   cString streamAddrM; |   cString streamAddrM; | ||||||
|   cString streamParamM; |   cString streamParamM; | ||||||
|   cSatipServer *currentServerM; |   cSatipTunerServer currentServerM; | ||||||
|   cSatipServer *nextServerM; |   cSatipTunerServer nextServerM; | ||||||
|   cMutex mutexM; |   cMutex mutexM; | ||||||
|   cTimeMs reConnectM; |   cTimeMs reConnectM; | ||||||
|   cTimeMs keepAliveM; |   cTimeMs keepAliveM; | ||||||
| @@ -100,7 +111,9 @@ private: | |||||||
|   bool hasLockM; |   bool hasLockM; | ||||||
|   int signalStrengthM; |   int signalStrengthM; | ||||||
|   int signalQualityM; |   int signalQualityM; | ||||||
|  |   int frontendIdM; | ||||||
|   int streamIdM; |   int streamIdM; | ||||||
|  |   int pmtPidM; | ||||||
|   cSatipPid addPidsM; |   cSatipPid addPidsM; | ||||||
|   cSatipPid delPidsM; |   cSatipPid delPidsM; | ||||||
|   cSatipPid pidsM; |   cSatipPid pidsM; | ||||||
| @@ -123,10 +136,11 @@ public: | |||||||
|   cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP); |   cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP); | ||||||
|   virtual ~cSatipTuner(); |   virtual ~cSatipTuner(); | ||||||
|   bool IsTuned(void) const { return (currentStateM >= tsTuned); } |   bool IsTuned(void) const { return (currentStateM >= tsTuned); } | ||||||
|   bool SetSource(cSatipServer *serverP, const char *parameterP, const int indexP); |   bool SetSource(cSatipServer *serverP, const int transponderP, const char *parameterP, const int indexP); | ||||||
|   bool SetPid(int pidP, int typeP, bool onP); |   bool SetPid(int pidP, int typeP, bool onP); | ||||||
|   bool Open(void); |   bool Open(void); | ||||||
|   bool Close(void); |   bool Close(void); | ||||||
|  |   int FrontendId(void); | ||||||
|   int SignalStrength(void); |   int SignalStrength(void); | ||||||
|   int SignalQuality(void); |   int SignalQuality(void); | ||||||
|   bool HasLock(void); |   bool HasLock(void); | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ class cSatipTunerIf { | |||||||
| public: | public: | ||||||
|   cSatipTunerIf() {} |   cSatipTunerIf() {} | ||||||
|   virtual ~cSatipTunerIf() {} |   virtual ~cSatipTunerIf() {} | ||||||
|   virtual void ProcessVideoData(u_char *bufferP, int lenghtP) = 0; |   virtual void ProcessVideoData(u_char *bufferP, int lengthP) = 0; | ||||||
|   virtual void ProcessApplicationData(u_char *bufferP, int lenghtP) = 0; |   virtual void ProcessApplicationData(u_char *bufferP, int lengthP) = 0; | ||||||
|   virtual void SetStreamId(int streamIdP) = 0; |   virtual void SetStreamId(int streamIdP) = 0; | ||||||
|   virtual void SetSessionTimeout(const char *sessionP, int timeoutP) = 0; |   virtual void SetSessionTimeout(const char *sessionP, int timeoutP) = 0; | ||||||
|   virtual int GetId(void) = 0; |   virtual int GetId(void) = 0; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user