[dvbapp] Apply multistream patch for zero4k.
[vuplus_openvuplus_3.0] / meta-bsp / recipes-vuplus / enigma2 / enigma2 / enigma2_vuplus_mis_pls.patch
1 diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp
2 index ca435464..6eb8c8d4 100755
3 --- a/lib/dvb/db.cpp
4 +++ b/lib/dvb/db.cpp
5 @@ -378,11 +378,17 @@ void eDVBDB::loadServicelist(const char *file)
6                                         system=eDVBFrontendParametersSatellite::System_DVB_S,
7                                         modulation=eDVBFrontendParametersSatellite::Modulation_QPSK,
8                                         rolloff=eDVBFrontendParametersSatellite::RollOff_alpha_0_35,
9 -                                       pilot=eDVBFrontendParametersSatellite::Pilot_Unknown;
10 +                                       pilot=eDVBFrontendParametersSatellite::Pilot_Unknown,
11 +                                       is_id = NO_STREAM_ID_FILTER,
12 +                                       pls_code = 1,
13 +                                       pls_mode = eDVBFrontendParametersSatellite::PLS_Root;
14                                 if (version == 3)
15                                         sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &system, &modulation, &rolloff, &pilot);
16                                 else
17 -                                       sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &flags, &system, &modulation, &rolloff, &pilot);
18 +                                       sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
19 +                                               &frequency, &symbol_rate, &polarisation, &fec, &orbital_position,
20 +                                               &inversion, &flags, &system, &modulation, &rolloff, &pilot,
21 +                                               &is_id, &pls_code, &pls_mode);
22                                 sat.frequency = frequency;
23                                 sat.symbol_rate = symbol_rate;
24                                 sat.polarisation = polarisation;
25 @@ -394,6 +400,9 @@ void eDVBDB::loadServicelist(const char *file)
26                                 sat.modulation = modulation;
27                                 sat.rolloff = rolloff;
28                                 sat.pilot = pilot;
29 +                               sat.is_id = is_id;
30 +                               sat.pls_mode = pls_mode & 3;
31 +                               sat.pls_code = pls_code & 0x3FFFF;
32                                 feparm->setDVBS(sat);
33                                 feparm->setFlags(flags);
34                         } else if (line[1]=='t')
35 @@ -512,27 +521,23 @@ void eDVBDB::saveServicelist(const char *file)
36                 ch.m_frontendParameters->getFlags(flags);
37                 if (!ch.m_frontendParameters->getDVBS(sat))
38                 {
39 +                       fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d",
40 +                               sat.frequency, sat.symbol_rate, sat.polarisation, sat.fec,
41 +                               sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
42 +                               sat.inversion, flags);
43 +
44                         if ((sat.system == eDVBFrontendParametersSatellite::System_DVB_S2) || (sat.system == eDVBFrontendParametersSatellite::System_DVB_S2X))
45                         {
46 -                               fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
47 -                                       sat.frequency, sat.symbol_rate,
48 -                                       sat.polarisation, sat.fec,
49 -                                       sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
50 -                                       sat.inversion,
51 -                                       flags,
52 -                                       sat.system,
53 -                                       sat.modulation,
54 -                                       sat.rolloff,
55 -                                       sat.pilot);
56 -                       }
57 -                       else
58 -                       {
59 -                               fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d\n",
60 -                                       sat.frequency, sat.symbol_rate,
61 -                                       sat.polarisation, sat.fec,
62 -                                       sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
63 -                                       sat.inversion, flags);
64 +                               fprintf(f, ":%d:%d:%d:%d", sat.system, sat.modulation, sat.rolloff, sat.pilot);
65 +
66 +                               if (static_cast<unsigned int>(sat.is_id) != NO_STREAM_ID_FILTER ||
67 +                                       (sat.pls_code & 0x3FFFF) != 1 ||
68 +                                       (sat.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Root)
69 +                               {
70 +                                       fprintf(f, ":%d:%d:%d", sat.is_id, sat.pls_code & 0x3FFFF, sat.pls_mode & 3);
71 +                               }
72                         }
73 +                       fprintf(f, "\n");
74                 }
75                 else if (!ch.m_frontendParameters->getDVBT(ter))
76                 {
77 @@ -792,7 +797,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
78                 return Py_False;
79         }
80         int tmp, *dest = NULL,
81 -               modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, tsid, onid;
82 +               modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, is_id, pls_code, pls_mode, tsid, onid;
83         char *end_ptr;
84         const Attribute *at;
85         std::string name;
86 @@ -857,6 +862,9 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
87                                 inv = eDVBFrontendParametersSatellite::Inversion_Unknown;
88                                 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
89                                 rolloff = eDVBFrontendParametersSatellite::RollOff_alpha_0_35;
90 +                               is_id = NO_STREAM_ID_FILTER;
91 +                               pls_code = 1;
92 +                               pls_mode = eDVBFrontendParametersSatellite::PLS_Root;
93                                 tsid = -1;
94                                 onid = -1;
95  
96 @@ -874,6 +882,9 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
97                                         else if (name == "inversion") dest = &inv;
98                                         else if (name == "rolloff") dest = &rolloff;
99                                         else if (name == "pilot") dest = &pilot;
100 +                                       else if (name == "is_id") dest = &is_id;
101 +                                       else if (name == "pls_code") dest = &pls_code;
102 +                                       else if (name == "pls_mode") dest = &pls_mode;
103                                         else if (name == "tsid") dest = &tsid;
104                                         else if (name == "onid") dest = &onid;
105                                         else continue;
106 @@ -887,7 +898,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
107                                 }
108                                 if (freq && sr && pol != -1)
109                                 {
110 -                                       tuple = PyTuple_New(12);
111 +                                       tuple = PyTuple_New(15);
112                                         PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
113                                         PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
114                                         PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(sr));
115 @@ -898,8 +909,11 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
116                                         PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(inv));
117                                         PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(rolloff));
118                                         PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(pilot));
119 -                                       PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(tsid));
120 -                                       PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(onid));
121 +                                       PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(is_id));
122 +                                       PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(pls_mode & 3));
123 +                                       PyTuple_SET_ITEM(tuple, 12, PyInt_FromLong(pls_code & 0x3FFFF));
124 +                                       PyTuple_SET_ITEM(tuple, 13, PyInt_FromLong(tsid));
125 +                                       PyTuple_SET_ITEM(tuple, 14, PyInt_FromLong(onid));
126                                         PyList_Append(tplist, tuple);
127                                         Py_DECREF(tuple);
128                                 }
129 diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
130 index 67c3aa98..5ebf10c2 100644
131 --- a/lib/dvb/dvb.cpp
132 +++ b/lib/dvb/dvb.cpp
133 @@ -447,6 +447,18 @@ bool eDVBResourceManager::frontendIsCompatible(int index, const char *type)
134         return false;
135  }
136  
137 +bool eDVBResourceManager::frontendIsMultistream(int index)
138 +{
139 +       for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
140 +       {
141 +               if (i->m_frontend->getSlotID() == index)
142 +               {
143 +                       return i->m_frontend->is_multistream();
144 +               }
145 +       }
146 +       return false;
147 +}
148 +
149  void eDVBResourceManager::setFrontendType(int index, const char *type)
150  {
151         eDebug("[eDVBResourceManager::setFrontendType] index : %d, type : %s", index, type);
152 diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h
153 index 3e9fc7fd..f470fe13 100644
154 --- a/lib/dvb/dvb.h
155 +++ b/lib/dvb/dvb.h
156 @@ -224,6 +224,7 @@ public:
157         SWIG_VOID(RESULT) allocateRawChannel(eUsePtr<iDVBChannel> &SWIG_OUTPUT, int slot_index);
158         PyObject *setFrontendSlotInformations(SWIG_PYOBJECT(ePyObject) list);
159         bool frontendIsCompatible(int index, const char *type);
160 +       bool frontendIsMultistream(int index);
161         void setFrontendType(int index, const char *type);
162  };
163  SWIG_TEMPLATE_TYPEDEF(ePtr<eDVBResourceManager>, eDVBResourceManager);
164 diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp
165 index a2eb0e82..1fb40315 100755
166 --- a/lib/dvb/frontend.cpp
167 +++ b/lib/dvb/frontend.cpp
168 @@ -129,12 +129,15 @@ void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescripto
169                 orbital_position = 3600 - orbital_position;
170         system = descriptor.getModulationSystem();
171         modulation = descriptor.getModulation();
172 -       if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
173 +       if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation != eDVBFrontendParametersSatellite::Modulation_QPSK)
174         {
175                 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
176                 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
177         }
178         rolloff = descriptor.getRollOff();
179 +       is_id = NO_STREAM_ID_FILTER;
180 +       pls_mode = eDVBFrontendParametersSatellite::PLS_Root;
181 +       pls_code = 1;
182         if (system == eDVBFrontendParametersSatellite::System_DVB_S)
183         {
184                 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
185 @@ -145,13 +148,16 @@ void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescripto
186         }
187         else // System_DVB_S2 or System_DVB_S2X
188         {
189 -               eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
190 +               eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d, is_id %d, pls_mode %d, pls_code %d",
191                         frequency,
192                         polarisation ? "hor" : "vert",
193                         orbital_position,
194                         symbol_rate, fec,
195                         modulation,
196 -                       rolloff);
197 +                       rolloff,
198 +                       is_id,
199 +                       pls_mode,
200 +                       pls_code);
201         }
202  }
203  
204 @@ -323,6 +329,12 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
205                         diff = 1<<29;
206                 else if (sat.polarisation != osat.polarisation)
207                         diff = 1<<28;
208 +               else if (sat.is_id != osat.is_id)
209 +                       diff = 1<<27;
210 +               else if (sat.pls_mode != osat.pls_mode)
211 +                       diff = 1<<27;
212 +               else if (sat.pls_code != osat.pls_code)
213 +                       diff = 1<<27;
214                 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
215                         diff = 1<<27;
216                 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
217 @@ -494,7 +506,6 @@ int eDVBFrontend::openFrontend()
218         m_state=stateIdle;
219         m_tuning=0;
220  
221 -       dvb_frontend_info fe_info;
222         if (!m_simulate)
223         {
224                 eDebug("opening frontend %d", m_dvbid);
225 @@ -512,6 +523,13 @@ int eDVBFrontend::openFrontend()
226  
227                 if (m_delsys.empty())
228                 {
229 +                       if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
230 +                       {
231 +                               eWarning("ioctl FE_GET_INFO failed");
232 +                               ::close(m_fd);
233 +                               m_fd = -1;
234 +                               return -1;
235 +                       }
236  #ifdef DTV_ENUM_DELSYS
237                         struct dtv_property p[1];
238                         p[0].cmd = DTV_ENUM_DELSYS;
239 @@ -528,48 +546,46 @@ int eDVBFrontend::openFrontend()
240                                         m_delsys[delsys] = true;
241                                 }
242                         }
243 +                       else
244  #else
245 -                       if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
246 +                       /* no DTV_ENUM_DELSYS support */
247 +                       if (1)
248 +#endif
249                         {
250 -                               eWarning("ioctl FE_GET_INFO failed");
251 -                               ::close(m_fd);
252 -                               m_fd = -1;
253 -                               return -1;
254 -                       }
255                         /* old DVB API, fill delsys map with some defaults */
256 -                       switch (fe_info.type)
257 -                       {
258 -                               case FE_QPSK:
259 +                               switch (fe_info.type)
260                                 {
261 -                                       m_delsys[SYS_DVBS] = true;
262 +                                       case FE_QPSK:
263 +                                       {
264 +                                               m_delsys[SYS_DVBS] = true;
265  #if DVB_API_VERSION >= 5
266 -                                       if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
267 +                                               if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
268  #endif
269 -                                       break;
270 -                               }
271 -                               case FE_QAM:
272 -                               {
273 +                                               break;
274 +                                       }
275 +                                       case FE_QAM:
276 +                                       {
277  #if defined SYS_DVBC_ANNEX_A
278 -                                       m_delsys[SYS_DVBC_ANNEX_A] = true;
279 +                                               m_delsys[SYS_DVBC_ANNEX_A] = true;
280  #else
281 -                                       m_delsys[SYS_DVBC_ANNEX_AC] = true;
282 +                                               m_delsys[SYS_DVBC_ANNEX_AC] = true;
283  #endif
284 -                                       break;
285 -                               }
286 -                               case FE_OFDM:
287 -                               {
288 -                                       m_delsys[SYS_DVBT] = true;
289 +                                               break;
290 +                                       }
291 +                                       case FE_OFDM:
292 +                                       {
293 +                                               m_delsys[SYS_DVBT] = true;
294  #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
295 -                                       if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
296 +                                               if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
297  #endif
298 -                                       break;
299 -                               }
300 -                               case FE_ATSC:   // placeholder to prevent warning
301 -                               {
302 -                                       break;
303 +                                               break;
304 +                                       }
305 +                                       case FE_ATSC:   // placeholder to prevent warning
306 +                                       {
307 +                                               break;
308 +                                       }
309                                 }
310                         }
311 -#endif
312                 }
313  
314                 if (m_simulate_fe)
315 @@ -580,6 +596,26 @@ int eDVBFrontend::openFrontend()
316                 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
317                 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
318         }
319 +       else
320 +       {
321 +               fe_info.frequency_min = 900000;
322 +               fe_info.frequency_max = 2200000;
323 +
324 +               eDebug("[eDVBFrontend] opening frontend %d", m_dvbid);
325 +               int tmp_fd = ::open(m_filename, O_RDONLY | O_NONBLOCK);
326 +               if (tmp_fd < 0)
327 +               {
328 +                       eWarning("[eDVBFrontend] opening %s failed: %m", m_filename);
329 +               }
330 +               else
331 +               {
332 +                       if (::ioctl(tmp_fd, FE_GET_INFO, &fe_info) < 0)
333 +                       {
334 +                               eWarning("[eDVBFrontend] ioctl FE_GET_INFO on frontend %s failed: %m", m_filename);
335 +                       }
336 +                       ::close(tmp_fd);
337 +               }
338 +       }
339  
340         setTone(iDVBFrontend::toneOff);
341         setVoltage(iDVBFrontend::voltageOff);
342 @@ -1025,6 +1061,9 @@ void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &fe
343         {
344                 PutToDict(dict, "rolloff", feparm.rolloff);
345                 PutToDict(dict, "pilot", feparm.pilot);
346 +               PutToDict(dict, "is_id", feparm.is_id);
347 +               PutToDict(dict, "pls_mode", feparm.pls_mode);
348 +               PutToDict(dict, "pls_code", feparm.pls_code);
349         }
350         PutToDict(dict, "system", feparm.system);
351  }
352 @@ -1058,7 +1097,7 @@ void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
353         PutToDict(dict, "fec_inner", feparm.fec_inner);
354  }
355  
356 -static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, int orbital_position, int polarization)
357 +static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, eDVBFrontendParametersSatellite &feparm)
358  {
359         long tmp=0;
360         int p_system = p[0].u.data;
361 @@ -1069,12 +1108,13 @@ static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, lo
362         int p_inner_fec = p[5].u.data;
363         int p_rolloff = p[6].u.data;
364         int p_pilot = p[7].u.data;
365 +       int p_stream_id = p[8].u.data;
366  
367         int frequency = p_frequency + freq_offset;
368         PutToDict(dict, "frequency", frequency);
369         PutToDict(dict, "symbol_rate", p_symbolrate);
370 -       PutToDict(dict, "orbital_position", orbital_position);
371 -       PutToDict(dict, "polarization", polarization);
372 +       PutToDict(dict, "orbital_position", feparm.orbital_position);
373 +       PutToDict(dict, "polarization", feparm.polarisation);
374  
375         switch(p_inner_fec)
376         {
377 @@ -1121,6 +1161,10 @@ static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, lo
378                 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
379                 }
380                 PutToDict(dict, "pilot", tmp);
381 +
382 +               PutToDict(dict, "is_id", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.is_id : (p_stream_id & 0xFF));
383 +               PutToDict(dict, "pls_mode", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.pls_mode : ((p_stream_id >> 26) & 0x3));
384 +               PutToDict(dict, "pls_code", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.pls_code : ((p_stream_id >> 8) & 0x3FFFF));
385         }
386  
387         switch (p_modulation)
388 @@ -1398,6 +1442,7 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
389                         p[cmdseq.num++].cmd = DTV_INNER_FEC;
390                         p[cmdseq.num++].cmd = DTV_ROLLOFF;
391                         p[cmdseq.num++].cmd = DTV_PILOT;
392 +                       p[cmdseq.num++].cmd = DTV_STREAM_ID;
393                 }
394                 else if(type == feCable)
395                 {
396 @@ -1457,13 +1502,12 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
397                 }
398                 else
399                 {
400 -                       FRONTENDPARAMETERS &parm = front;
401                         switch(type)
402                         {
403                                 case feSatellite:
404                                         eDVBFrontendParametersSatellite sparm;
405                                         oparm.getDVBS(sparm);
406 -                                       fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
407 +                                       fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm);
408                                         break;
409                                 case feCable:
410                                         fillDictWithCableData(dest, p);
411 @@ -2004,7 +2048,7 @@ void eDVBFrontend::setFrontend(bool recvEvents)
412                         case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
413                         case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
414                         };
415 -                       struct dtv_property p[10];
416 +                       struct dtv_property p[11];
417                         struct dtv_properties cmdseq;
418                         cmdseq.props = p;
419                         p[0].cmd = DTV_CLEAR;
420 @@ -2018,8 +2062,9 @@ void eDVBFrontend::setFrontend(bool recvEvents)
421                         {
422                                 p[7].cmd = DTV_ROLLOFF,         p[7].u.data = rolloff;
423                                 p[8].cmd = DTV_PILOT,           p[8].u.data = pilot;
424 -                               p[9].cmd = DTV_TUNE;
425 -                               cmdseq.num = 10;
426 +                               p[9].cmd = DTV_STREAM_ID,       p[9].u.data = sparm.is_id | (sparm.pls_code << 8) | (sparm.pls_mode << 26);
427 +                               p[10].cmd = DTV_TUNE;
428 +                               cmdseq.num = 11;
429                         }
430                         else
431                         {
432 @@ -2128,7 +2173,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
433         res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
434         if (!res)
435         {
436 -               eDebugNoSimulate("prepare_sat Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d",
437 +               eDebugNoSimulate("prepare_sat Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d, is_id %d, pls_mode %d, pls_code %d",
438                         feparm.frequency,
439                         feparm.polarisation,
440                         feparm.symbol_rate,
441 @@ -2138,7 +2183,10 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
442                         feparm.system,
443                         feparm.modulation,
444                         feparm.pilot,
445 -                       feparm.rolloff);
446 +                       feparm.rolloff,
447 +                       feparm.is_id,
448 +                       feparm.pls_mode,
449 +                       feparm.pls_code);
450                 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
451                 switch (feparm.inversion)
452                 {
453 @@ -2861,12 +2909,23 @@ int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
454                 {
455                         return 0;
456                 }
457 +               bool multistream = (static_cast<unsigned int>(sat_parm.is_id) != NO_STREAM_ID_FILTER || (sat_parm.pls_code & 0x3FFFF) != 1 ||
458 +                                       (sat_parm.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Root);
459 +               if (((sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2)||(sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2X)) && multistream && !is_multistream())
460 +               {
461 +                       return 0;
462 +               }
463                 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
464                 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
465                 {
466                         /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
467                         score--;
468                 }
469 +               if (score > 1 && is_multistream() && !multistream)
470 +               {
471 +                       /* prefer to use a non multistream tuner, try to keep multistream tuners free for multistream transponders */
472 +                       score--;
473 +               }
474         }
475  
476         else if (type == eDVBFrontend::feCable)
477 @@ -3001,3 +3060,9 @@ arg_error:
478                 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");
479         return false;
480  }
481 +
482 +bool eDVBFrontend::is_multistream()
483 +{
484 +       return fe_info.caps & FE_CAN_MULTISTREAM;
485 +}
486 +
487 diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h
488 index 6a8c39d6..39d125a9 100644
489 --- a/lib/dvb/frontend.h
490 +++ b/lib/dvb/frontend.h
491 @@ -87,6 +87,7 @@ private:
492         std::map<fe_delivery_system_t, bool> m_delsys, m_delsys_whitelist;
493         char m_filename[128];
494         char m_description[128];
495 +       dvb_frontend_info fe_info;
496         FRONTENDPARAMETERS parm;
497         eDVBFrontendParameters oparm;
498  
499 @@ -163,6 +164,7 @@ public:
500         bool isLoopTimerActive() { return m_tuneTimer->isActive(); }
501         bool isScheduledSendDiseqc();
502         void setUSBTuner(bool yesno) { m_is_usbtuner = yesno; }
503 +       bool is_multistream();
504  };
505  
506  #endif // SWIG
507 diff --git a/lib/dvb/frontendparms.h b/lib/dvb/frontendparms.h
508 index c941ca69..1d8f2eeb 100644
509 --- a/lib/dvb/frontendparms.h
510 +++ b/lib/dvb/frontendparms.h
511 @@ -45,9 +45,13 @@ struct eDVBFrontendParametersSatellite
512                 Pilot_Off, Pilot_On, Pilot_Unknown
513         };
514  
515 +       enum {
516 +               PLS_Root, PLS_Gold, PLS_Combo, PLS_Unknown
517 +       };
518 +
519         bool no_rotor_command_on_tune;
520         unsigned int frequency, symbol_rate;
521 -       int polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot;
522 +       int polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot, is_id, pls_mode, pls_code;
523  };
524  SWIG_ALLOW_OUTPUT_SIMPLE(eDVBFrontendParametersSatellite);
525  
526 diff --git a/lib/python/Components/NimManager.py b/lib/python/Components/NimManager.py
527 index d726fece..2d524702 100755
528 --- a/lib/python/Components/NimManager.py
529 +++ b/lib/python/Components/NimManager.py
530 @@ -603,7 +603,16 @@ class NIM(object):
531         # empty tuners are supported!
532         def isSupported(self):
533                 return (self.frontend_id is not None) or self.__is_empty
534 -       
535 +
536 +       def isMultistream(self):
537 +               multistream = self.frontend_id is not None and eDVBResourceManager.getInstance().frontendIsMultistream(self.frontend_id) or False
538 +               # HACK due to poor support for VTUNER_SET_FE_INFO
539 +               # When vtuner does not accept fe_info we have to fallback to detection using tuner name
540 +               # More tuner names will be added when confirmed as multistream (FE_CAN_MULTISTREAM)
541 +               if not multistream and "TBS" in self.description:
542 +                       multistream = True
543 +               return multistream
544 +
545         # returns dict {<slotid>: <type>}
546         def getMultiTypeList(self):
547                 return self.multi_type
548 diff --git a/lib/python/Components/ServiceScan.py b/lib/python/Components/ServiceScan.py
549 index 74123861..3a405f23 100644
550 --- a/lib/python/Components/ServiceScan.py
551 +++ b/lib/python/Components/ServiceScan.py
552 @@ -71,6 +71,8 @@ class ServiceScan:
553                                                                 tp.FEC_13_18 : "13/18", tp.FEC_26_45 : "26/45", tp.FEC_28_45 : "28/45", tp.FEC_7_9 : "7/9", tp.FEC_77_90 : "77/90",
554                                                                 tp.FEC_32_45 : "32/45", tp.FEC_11_15 : "11/15", tp.FEC_1_2_L : "1/2-L", tp.FEC_8_15_L : "8/15-L", tp.FEC_3_5_L : "3/5-L",
555                                                                 tp.FEC_2_3_L : "2/3-L", tp.FEC_5_9_L : "5/9-L", tp.FEC_26_45_L : "26/45-L"}.get(tp.fec, tp.FEC_Auto))
556 +                                               if tp.is_id > -1 and tp.system in (tp.System_DVB_S2, tp.System_DVB_S2X):
557 +                                                       tp_text = ("%s IS %d") % (tp_text, tp.is_id)
558                                         elif tp_type == iDVBFrontend.feCable:
559                                                 network = _("Cable")
560                                                 tp = transponder.getDVBC()
561 diff --git a/lib/python/Components/TuneTest.py b/lib/python/Components/TuneTest.py
562 index 44b19091..61c80636 100644
563 --- a/lib/python/Components/TuneTest.py
564 +++ b/lib/python/Components/TuneTest.py
565 @@ -5,8 +5,7 @@ class Tuner:
566                 self.frontend = frontend
567                 self.ignore_rotor = ignore_rotor
568  
569 -       # transponder = (frequency, symbolrate, polarisation, fec, inversion, orbpos, system, modulation, rolloff, pilot, tsid, onid)
570 -       #                    0         1             2         3       4         5       6        7          8       9      10    11
571 +       # transponder = (0:frequency 1:symbolrate 2:polarisation 3:fec 4:inversion 5:orbpos 6:system 7:modulation 8:rolloff 9:pilot 10:is_id 11:pls_mode 12:pls_code 13:tsid 14:onid)
572         def tune(self, transponder):
573                 if self.frontend:
574                         print "tuning to transponder with data", transponder
575 @@ -21,6 +20,14 @@ class Tuner:
576                         parm.modulation = transponder[7]
577                         parm.rolloff = transponder[8]
578                         parm.pilot = transponder[9]
579 +                       if len(transponder) > 12:
580 +                               parm.is_id = transponder[10]
581 +                               parm.pls_mode = transponder[11]
582 +                               parm.pls_code = transponder[12]
583 +                       else:
584 +                               parm.is_id = -1
585 +                               parm.pls_mode = 0
586 +                               parm.pls_code = 1
587                         feparm = eDVBFrontendParameters()
588                         feparm.setDVBS(parm, self.ignore_rotor)
589                         self.lastparm = feparm
590 @@ -103,8 +110,8 @@ class TuneTest:
591                                 pidsFailed = False
592                                 if self.checkPIDs:
593                                         if self.currTuned is not None:
594 -                                               if self.tsid != self.currTuned[10] or self.onid != self.currTuned[11]:
595 -                                                       self.failedTune.append([self.currTuned, self.oldTuned, "pids_failed", {"real": (self.tsid, self.onid), "expected": (self.currTuned[10], self.currTuned[11])}, dict])  # last parameter is the frontend status
596 +                                               if self.tsid != self.currTuned[13] or self.onid != self.currTuned[14]:
597 +                                                       self.failedTune.append([self.currTuned, self.oldTuned, "pids_failed", {"real": (self.tsid, self.onid), "expected": (self.currTuned[13], self.currTuned[14])}, dict])  # last parameter is the frontend status
598                                                         pidsFailed = True
599                                                 else:
600                                                         self.successfullyTune.append([self.currTuned, self.oldTuned, dict])  # 3rd parameter is the frontend status
601 @@ -141,7 +148,7 @@ class TuneTest:
602                         # check for tsid != -1 and onid != -1 
603                         print "index:", index
604                         print "len(self.transponderlist):", len(self.transponderlist)
605 -                       while (index < len(self.transponderlist) and (self.transponderlist[index][10] == -1 or self.transponderlist[index][11] == -1)):
606 +                       while (index < len(self.transponderlist) and (self.transponderlist[index][13] == -1 or self.transponderlist[index][14] == -1)):
607                                 index += 1
608                 print "FirstTransponder final index:", index
609                 return index
610 @@ -154,7 +161,7 @@ class TuneTest:
611                         # check for tsid != -1 and onid != -1 
612                         print "index:", index
613                         print "len(self.transponderlist):", len(self.transponderlist)
614 -                       while (index < len(self.transponderlist) and (self.transponderlist[index][10] == -1 or self.transponderlist[index][11] == -1)):
615 +                       while (index < len(self.transponderlist) and (self.transponderlist[index][13] == -1 or self.transponderlist[index][14] == -1)):
616                                 index += 1
617  
618                 print "next transponder index:", index
619 @@ -204,8 +211,7 @@ class TuneTest:
620                 self.progressCallback((self.getProgressLength(), self.tuningtransponder, self.STATUS_START, self.currTuned))
621                 self.timer.start(100, True)
622         
623 -       # transponder = (frequency, symbolrate, polarisation, fec, inversion, orbpos, <system>, <modulation>, <rolloff>, <pilot>, <tsid>, <onid>)
624 -       #                    0         1             2         3       4         5       6        7              8         9        10       11
625 +       # transponder = (0:frequency 1:symbolrate 2:polarisation 3:fec 4:inversion 5:orbpos 6:system 7:modulation 8:rolloff 9:pilot 10:is_id 11:pls_mode 12:pls_code 13:tsid 14:onid)
626         def addTransponder(self, transponder):
627                 self.transponderlist.append(transponder)
628                 
629 diff --git a/lib/python/Plugins/SystemPlugins/Blindscan/plugin.py b/lib/python/Plugins/SystemPlugins/Blindscan/plugin.py
630 index 5215a4b8..582f2f5c 100644
631 --- a/lib/python/Plugins/SystemPlugins/Blindscan/plugin.py
632 +++ b/lib/python/Plugins/SystemPlugins/Blindscan/plugin.py
633 @@ -546,6 +546,9 @@ class Blindscan(ConfigListScreen, Screen):
634                                                 parm.fec = fec[data[7]]
635                                                 parm.modulation = qam[data[8]]
636                                                 parm.rolloff = roll[data[9]]
637 +                                               parm.is_id = -1
638 +                                               parm.pls_mode = 0
639 +                                               parm.pls_code = 1
640                                                 self.tmp_tplist.append(parm)
641                                         except: pass
642                 self.blindscan_session.close(True)
643 diff --git a/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py b/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
644 index 4dcf6c6b..acb2a2da 100644
645 --- a/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
646 +++ b/lib/python/Plugins/SystemPlugins/DiseqcTester/plugin.py
647 @@ -281,7 +281,7 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
648                 for sat in nimmanager.getSatListForNim(self.feid):
649                         for transponder in nimmanager.getTransponders(sat[0]):
650                                 #print transponder
651 -                               mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[7], sat[0], transponder[5], transponder[6], transponder[8], transponder[9], transponder[10], transponder[11])
652 +                               mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[7], sat[0], transponder[5], transponder[6], transponder[8], transponder[9], transponder[10], transponder[11], transponder[12], transponder[13], transponder[14])
653                                 self.analyseTransponder(mytransponder)
654  
655         def getIndexForTransponder(self, transponder):
656 diff --git a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
657 old mode 100644
658 new mode 100755
659 index b94a8819..32dc8649
660 --- a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
661 +++ b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
662 @@ -10,11 +10,13 @@ from Plugins.Plugin import PluginDescriptor
663  from Components.Label import Label
664  from Components.ConfigList import ConfigList
665  from Components.TunerInfo import TunerInfo
666 -from Components.ActionMap import ActionMap
667 +from Components.ActionMap import NumberActionMap, ActionMap
668  from Components.NimManager import nimmanager
669  from Components.MenuList import MenuList
670  from Components.config import ConfigSatlist, ConfigNothing, ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, getConfigListEntry
671  from Components.TuneTest import Tuner
672 +from Components.ConfigList import ConfigListScreen
673 +from Components.config import config, ConfigSubsection, ConfigSelection, ConfigInteger, getConfigListEntry
674  from Tools.Transponder import ConvertToHumanReadable
675  
676  from time import sleep
677 @@ -88,7 +90,10 @@ class PositionerSetup(Screen):
678                         cur.get("system", eDVBFrontendParametersSatellite.System_DVB_S),
679                         cur.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK),
680                         cur.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35),
681 -                       cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown))
682 +                       cur.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown),
683 +                       cur.get("is_id", 0),
684 +                       cur.get("pls_mode", eDVBFrontendParametersSatellite.PLS_Root),
685 +                       cur.get("pls_code", 1))
686  
687                 self.tuner.tune(tp)
688                 self.createConfig()
689 @@ -406,9 +411,7 @@ class Diseqc:
690                                 sleep(0.05)
691                                 self.frontend.sendDiseqc(cmd) # send 2nd time
692  
693 -tuning = None
694 -
695 -class TunerScreen(ScanSetup):
696 +class TunerScreen(ConfigListScreen, Screen):
697         skin = """
698                 <screen position="90,100" size="520,400" title="Tune">
699                         <widget name="config" position="20,10" size="460,350" scrollbarMode="showOnDemand" />
700 @@ -418,29 +421,38 @@ class TunerScreen(ScanSetup):
701         def __init__(self, session, feid, fe_data):
702                 self.feid = feid
703                 self.fe_data = fe_data
704 -               ScanSetup.__init__(self, session)
705 -               self["introduction"].setText("")
706 +               Screen.__init__(self, session)
707 +               ConfigListScreen.__init__(self, None)
708 +               self.createConfig(fe_data)
709 +               self.createSetup()
710 +               self.tuning.sat.addNotifier(self.tuningSatChanged)
711 +               self.tuning.type.addNotifier(self.tuningTypeChanged)
712 +               self.scan_sat.system.addNotifier(self.systemChanged)
713 +               self.scan_sat.system_dvbs2x.addNotifier(self.systemChanged)
714 +               self.scan_sat.is_id_bool.addNotifier(self.isIdChanged, initial_call = False)
715 +
716 +               self["actions"] = NumberActionMap(["SetupActions"],
717 +               {
718 +                       "ok": self.keyGo,
719 +                       "cancel": self.keyCancel,
720 +               }, -2)
721 +
722 +               self["introduction"] = Label(_(" "))
723  
724         def createSetup(self):
725 -               self.typeOfTuningEntry = None
726 -               self.satEntry = None
727                 self.list = []
728 -               self.typeOfTuningEntry = getConfigListEntry(_('Tune'), tuning.type)
729 -               self.list.append(self.typeOfTuningEntry)
730 -               self.satEntry = getConfigListEntry(_('Satellite'), tuning.sat)
731 -               self.list.append(self.satEntry)
732 +               self.list.append(getConfigListEntry(_('Tune'), self.tuning.type) )
733 +               self.list.append(getConfigListEntry(_('Satellite'), self.tuning.sat)    )
734 +
735 +               self.is_id_boolEntry = None
736                 nim = nimmanager.nim_slots[self.feid]
737 -               self.systemEntry = None
738 -               
739 -               if tuning.type.value == "manual_transponder":
740 +               if self.tuning.type.value == "manual_transponder":
741                         scan_sat_system_value = self.scan_sat.system.value
742                         if nim.isCompatible("DVB-S2X"):
743                                 scan_sat_system_value = self.scan_sat.system_dvbs2x.value
744 -                               self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system_dvbs2x)
745 -                               self.list.append(self.systemEntry)
746 +                               self.list.append(getConfigListEntry(_('System'), self.scan_sat.system_dvbs2x))
747                         elif nim.isCompatible("DVB-S2"):
748 -                               self.systemEntry = getConfigListEntry(_('System'), self.scan_sat.system)
749 -                               self.list.append(self.systemEntry)
750 +                               self.list.append(getConfigListEntry(_('System'), self.scan_sat.system))
751                         else:
752                                 # downgrade to dvb-s, in case a -s2 config was active
753                                 self.scan_sat.system.value = eDVBFrontendParametersSatellite.System_DVB_S
754 @@ -471,44 +483,233 @@ class TunerScreen(ScanSetup):
755                                 self.list.append(self.modulationEntry)
756                                 self.list.append(getConfigListEntry(_('Roll-off'), self.scan_sat.rolloff))
757                                 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
758 -               elif tuning.type.value == "predefined_transponder":
759 -                       self.list.append(getConfigListEntry(_("Transponder"), tuning.transponder))
760 +                       if scan_sat_system_value in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X):
761 +                               if nim.isMultistream():
762 +                                       self.is_id_boolEntry = getConfigListEntry(_('Transport Stream Type'), self.scan_sat.is_id_bool)
763 +                                       self.list.append(self.is_id_boolEntry)
764 +                                       if self.scan_sat.is_id_bool.value:
765 +                                               self.list.append(getConfigListEntry(_('Input Stream ID'), self.scan_sat.is_id))
766 +                                               self.list.append(getConfigListEntry(_('PLS Mode'), self.scan_sat.pls_mode))
767 +                                               self.list.append(getConfigListEntry(_('PLS Code'), self.scan_sat.pls_code))
768 +                                       else:
769 +                                               self.scan_sat.is_id.value = self.NO_STREAM_ID_FILTER
770 +                                               self.scan_sat.pls_mode.value = eDVBFrontendParametersSatellite.PLS_Root
771 +                                               self.scan_sat.pls_code.value = 1
772 +               elif self.tuning.type.value == "predefined_transponder":
773 +                       self.list.append(getConfigListEntry(_("Transponder"), self.tuning.transponder))
774                 self["config"].list = self.list
775                 self["config"].l.setList(self.list)
776  
777 -       def newConfig(self):
778 -               cur = self["config"].getCurrent()
779 -               if cur in (self.typeOfTuningEntry, self.satEntry, self.systemEntry) or \
780 -                       (self.modulationEntry and (cur == self.modulationEntry) and \
781 -                       self.systemEntry and (self.systemEntry[1].value == eDVBFrontendParametersSatellite.System_DVB_S2X)):
782 -                       self.createSetup()
783 -
784 -       def createConfig(self, foo):
785 -               global tuning
786 -               if not tuning:
787 -                       tuning = ConfigSubsection()
788 -                       tuning.type = ConfigSelection(
789 -                               default = "manual_transponder",
790 -                               choices = { "manual_transponder" : _("Manual transponder"),
791 -                                                       "predefined_transponder" : _("Predefined transponder") } )
792 -                       tuning.sat = ConfigSatlist(list=nimmanager.getRotorSatListForNim(self.feid))
793 -                       tuning.sat.addNotifier(self.tuningSatChanged)
794 -                       self.updateTransponders()
795 +       def createConfig(self, frontendData):
796 +               satlist = nimmanager.getRotorSatListForNim(self.feid)
797                 orb_pos = self.fe_data.get("orbital_position", None)
798 +               self.tuning = ConfigSubsection()
799 +               self.tuning.type = ConfigSelection(
800 +                       default = "manual_transponder",
801 +                       choices = { "manual_transponder" : _("Manual transponder"),
802 +                                               "predefined_transponder" : _("Predefined transponder") } )
803 +               self.tuning.sat = ConfigSatlist(list = satlist)
804                 if orb_pos is not None:
805 -                       for x in nimmanager.getRotorSatListForNim(self.feid):
806 +                       for x in satlist:
807                                 opos = str(orb_pos)
808 -                               if x[0] == orb_pos and tuning.sat.value != opos:
809 -                                       tuning.sat.value = opos
810 +                               if x[0] == orb_pos and self.tuning.sat.value != opos:
811 +                                       self.tuning.sat.value = opos
812                         del self.fe_data["orbital_position"]
813 -               ScanSetup.createConfig(self, self.fe_data)
814 +
815 +               self.updateTransponders()
816 +
817 +               self.NO_STREAM_ID_FILTER = -1
818 +               defaultSat = {
819 +                       "orbpos": 192,
820 +                       "system": eDVBFrontendParametersSatellite.System_DVB_S,
821 +                       "frequency": 11836,
822 +                       "inversion": eDVBFrontendParametersSatellite.Inversion_Unknown,
823 +                       "symbolrate": 27500,
824 +                       "polarization": eDVBFrontendParametersSatellite.Polarisation_Horizontal,
825 +                       "fec": eDVBFrontendParametersSatellite.FEC_Auto,
826 +                       "fec_s2": eDVBFrontendParametersSatellite.FEC_9_10,
827 +                       "fec_s2x_qpsk": eDVBFrontendParametersSatellite.FEC_13_45,
828 +                       "fec_s2x_8psk": eDVBFrontendParametersSatellite.FEC_23_36,
829 +                       "fec_s2x_8apsk": eDVBFrontendParametersSatellite.FEC_5_9_L,
830 +                       "fec_s2x_16apsk": eDVBFrontendParametersSatellite.FEC_1_2_L,
831 +                       "fec_s2x_32apsk": eDVBFrontendParametersSatellite.FEC_2_3_L,
832 +                       "modulation": eDVBFrontendParametersSatellite.Modulation_QPSK,
833 +                       "modulation_s2x": eDVBFrontendParametersSatellite.Modulation_QPSK,
834 +                       "is_id": self.NO_STREAM_ID_FILTER,
835 +                       "pls_mode": eDVBFrontendParametersSatellite.PLS_Root,
836 +                       "pls_code": 1 }
837 +
838 +               if frontendData is not None:
839 +                       ttype = frontendData.get("tuner_type", "UNKNOWN")
840 +                       defaultSat["system"] = frontendData.get("system", eDVBFrontendParametersSatellite.System_DVB_S)
841 +                       defaultSat["frequency"] = frontendData.get("frequency", 0) / 1000
842 +                       defaultSat["inversion"] = frontendData.get("inversion", eDVBFrontendParametersSatellite.Inversion_Unknown)
843 +                       defaultSat["symbolrate"] = frontendData.get("symbol_rate", 0) / 1000
844 +                       defaultSat["polarization"] = frontendData.get("polarization", eDVBFrontendParametersSatellite.Polarisation_Horizontal)
845 +                       defaultSat["orbpos"] = frontendData.get("orbital_position", 0)
846 +
847 +                       defaultSat["modulation"] = frontendData.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
848 +                       defaultSat["modulation_s2x"] = frontendData.get("modulation", eDVBFrontendParametersSatellite.Modulation_QPSK)
849 +
850 +                       if defaultSat["modulation"] > eDVBFrontendParametersSatellite.Modulation_8PSK:
851 +                               defaultSat["modulation"] = eDVBFrontendParametersSatellite.Modulation_8PSK
852 +
853 +                       if defaultSat["system"] == eDVBFrontendParametersSatellite.System_DVB_S2:
854 +                               defaultSat["fec_s2"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
855 +                       elif defaultSat["system"] == eDVBFrontendParametersSatellite.System_DVB_S2X:
856 +                               if defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_QPSK:
857 +                                       defaultSat["fec_s2x_qpsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_13_45)
858 +                               elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_8PSK:
859 +                                       defaultSat["fec_s2x_8psk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_23_36)
860 +                               elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_8APSK:
861 +                                       defaultSat["fec_s2x_8apsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_5_9_L)
862 +                               elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_16APSK:
863 +                                       defaultSat["fec_s2x_16apsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_1_2_L)
864 +                               elif defaultSat["modulation_s2x"] == eDVBFrontendParametersSatellite.Modulation_32APSK:
865 +                                       defaultSat["fec_s2x_32apsk"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_2_3_L)
866 +                       else:
867 +                               defaultSat["fec"] = frontendData.get("fec_inner", eDVBFrontendParametersSatellite.FEC_Auto)
868 +
869 +                       if defaultSat["system"] in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X):
870 +                               defaultSat["rolloff"] = frontendData.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35)
871 +                               defaultSat["pilot"] = frontendData.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)
872 +                               defaultSat["is_id"] = frontendData.get("is_id", defaultSat["is_id"])
873 +                               defaultSat["pls_mode"] = frontendData.get("pls_mode", defaultSat["pls_mode"])
874 +                               defaultSat["pls_code"] = frontendData.get("pls_code", defaultSat["pls_code"])
875 +
876 +               self.scan_sat = ConfigSubsection()
877 +
878 +               sat_choices = [
879 +                               (eDVBFrontendParametersSatellite.System_DVB_S, _("DVB-S")),
880 +                               (eDVBFrontendParametersSatellite.System_DVB_S2, _("DVB-S2"))]
881 +
882 +               sat_choices_dvbs2x = [
883 +                       (eDVBFrontendParametersSatellite.System_DVB_S, _("DVB-S")),
884 +                       (eDVBFrontendParametersSatellite.System_DVB_S2, _("DVB-S2")),
885 +                       (eDVBFrontendParametersSatellite.System_DVB_S2X, _("DVB-S2X"))]
886 +
887 +               self.scan_sat.system = ConfigSelection(default = defaultSat["system"], choices = sat_choices)
888 +               self.scan_sat.system_dvbs2x = ConfigSelection(default = defaultSat["system"], choices = sat_choices_dvbs2x)
889 +               self.scan_sat.frequency = ConfigInteger(default = defaultSat["frequency"], limits = (1, 99999))
890 +               self.scan_sat.inversion = ConfigSelection(default = defaultSat["inversion"], choices = [
891 +                       (eDVBFrontendParametersSatellite.Inversion_Off, _("Off")),
892 +                       (eDVBFrontendParametersSatellite.Inversion_On, _("On")),
893 +                       (eDVBFrontendParametersSatellite.Inversion_Unknown, _("Auto"))])
894 +               self.scan_sat.symbolrate = ConfigInteger(default = defaultSat["symbolrate"], limits = (1, 99999))
895 +               self.scan_sat.polarization = ConfigSelection(default = defaultSat["polarization"], choices = [
896 +                       (eDVBFrontendParametersSatellite.Polarisation_Horizontal, _("horizontal")),
897 +                       (eDVBFrontendParametersSatellite.Polarisation_Vertical, _("vertical")),
898 +                       (eDVBFrontendParametersSatellite.Polarisation_CircularLeft, _("circular left")),
899 +                       (eDVBFrontendParametersSatellite.Polarisation_CircularRight, _("circular right"))])
900 +               self.scan_sat.fec = ConfigSelection(default = defaultSat["fec"], choices = [
901 +                       (eDVBFrontendParametersSatellite.FEC_Auto, _("Auto")),
902 +                       (eDVBFrontendParametersSatellite.FEC_1_2, "1/2"),
903 +                       (eDVBFrontendParametersSatellite.FEC_2_3, "2/3"),
904 +                       (eDVBFrontendParametersSatellite.FEC_3_4, "3/4"),
905 +                       (eDVBFrontendParametersSatellite.FEC_5_6, "5/6"),
906 +                       (eDVBFrontendParametersSatellite.FEC_7_8, "7/8"),
907 +                       (eDVBFrontendParametersSatellite.FEC_None, _("None"))])
908 +               self.scan_sat.fec_s2 = ConfigSelection(default = defaultSat["fec_s2"], choices = [
909 +                       (eDVBFrontendParametersSatellite.FEC_1_2, "1/2"),
910 +                       (eDVBFrontendParametersSatellite.FEC_2_3, "2/3"),
911 +                       (eDVBFrontendParametersSatellite.FEC_3_4, "3/4"),
912 +                       (eDVBFrontendParametersSatellite.FEC_3_5, "3/5"),
913 +                       (eDVBFrontendParametersSatellite.FEC_4_5, "4/5"),
914 +                       (eDVBFrontendParametersSatellite.FEC_5_6, "5/6"),
915 +                       (eDVBFrontendParametersSatellite.FEC_7_8, "7/8"),
916 +                       (eDVBFrontendParametersSatellite.FEC_8_9, "8/9"),
917 +                       (eDVBFrontendParametersSatellite.FEC_9_10, "9/10")])
918 +               self.scan_sat.fec_s2x_qpsk = ConfigSelection(default = defaultSat["fec_s2x_qpsk"], choices = [
919 +                       (eDVBFrontendParametersSatellite.FEC_13_45, "13/45"),
920 +                       (eDVBFrontendParametersSatellite.FEC_9_20, "9/20"),
921 +                       (eDVBFrontendParametersSatellite.FEC_11_20, "11/20")])
922 +
923 +               self.scan_sat.fec_s2x_8psk = ConfigSelection(default = defaultSat["fec_s2x_8psk"], choices = [
924 +                       (eDVBFrontendParametersSatellite.FEC_23_36, "23/36"),
925 +                       (eDVBFrontendParametersSatellite.FEC_25_36, "25/36"),
926 +                       (eDVBFrontendParametersSatellite.FEC_13_18, "13/28")])
927 +
928 +               self.scan_sat.fec_s2x_8apsk = ConfigSelection(default = defaultSat["fec_s2x_8apsk"], choices = [
929 +                       (eDVBFrontendParametersSatellite.FEC_5_9_L, "5/9-L"),
930 +                       (eDVBFrontendParametersSatellite.FEC_26_45_L, "26/45-L")])
931 +
932 +               self.scan_sat.fec_s2x_16apsk = ConfigSelection(default = defaultSat["fec_s2x_16apsk"], choices = [
933 +                       (eDVBFrontendParametersSatellite.FEC_1_2_L, "1/2-L"),
934 +                       (eDVBFrontendParametersSatellite.FEC_8_15_L, "8/15-L"),
935 +                       (eDVBFrontendParametersSatellite.FEC_5_9_L, "5/9-L"),
936 +                       (eDVBFrontendParametersSatellite.FEC_26_45, "26/45"),
937 +                       (eDVBFrontendParametersSatellite.FEC_3_5, "3/5"),
938 +                       (eDVBFrontendParametersSatellite.FEC_3_5_L, "3/5-L"),
939 +                       (eDVBFrontendParametersSatellite.FEC_28_45, "28/45"),
940 +                       (eDVBFrontendParametersSatellite.FEC_23_36, "23/36"),
941 +                       (eDVBFrontendParametersSatellite.FEC_2_3_L, "2/3-L"),
942 +                       (eDVBFrontendParametersSatellite.FEC_25_36, "25/36"),
943 +                       (eDVBFrontendParametersSatellite.FEC_13_18, "13/18"),
944 +                       (eDVBFrontendParametersSatellite.FEC_7_9, "7/9"),
945 +                       (eDVBFrontendParametersSatellite.FEC_77_90, "77/90")])
946 +
947 +               self.scan_sat.fec_s2x_32apsk = ConfigSelection(default = defaultSat["fec_s2x_32apsk"], choices = [
948 +                       (eDVBFrontendParametersSatellite.FEC_2_3_L, "2/3-L"),
949 +                       (eDVBFrontendParametersSatellite.FEC_32_45, "32/45"),
950 +                       (eDVBFrontendParametersSatellite.FEC_11_15, "11/15"),
951 +                       (eDVBFrontendParametersSatellite.FEC_7_9, "7/9")])
952 +               self.scan_sat.modulation = ConfigSelection(default = defaultSat["modulation"], choices = [
953 +                       (eDVBFrontendParametersSatellite.Modulation_QPSK, "QPSK"),
954 +                       (eDVBFrontendParametersSatellite.Modulation_8PSK, "8PSK")])
955 +               self.scan_sat.modulation_dvbs2x = ConfigSelection(default = defaultSat["modulation_s2x"], choices = [
956 +                       (eDVBFrontendParametersSatellite.Modulation_QPSK, "QPSK"),
957 +                       (eDVBFrontendParametersSatellite.Modulation_8PSK, "8PSK"),
958 +                       (eDVBFrontendParametersSatellite.Modulation_8APSK, "8APSK"),
959 +                       (eDVBFrontendParametersSatellite.Modulation_16APSK, "16APSK"),
960 +                       (eDVBFrontendParametersSatellite.Modulation_32APSK, "32APSK")])
961 +               self.scan_sat.rolloff = ConfigSelection(default = defaultSat.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35), choices = [
962 +                       (eDVBFrontendParametersSatellite.RollOff_alpha_0_35, "0.35"),
963 +                       (eDVBFrontendParametersSatellite.RollOff_alpha_0_25, "0.25"),
964 +                       (eDVBFrontendParametersSatellite.RollOff_alpha_0_20, "0.20")])
965 +               self.scan_sat.pilot = ConfigSelection(default = defaultSat.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown), choices = [
966 +                       (eDVBFrontendParametersSatellite.Pilot_Off, _("Off")),
967 +                       (eDVBFrontendParametersSatellite.Pilot_On, _("On")),
968 +                       (eDVBFrontendParametersSatellite.Pilot_Unknown, _("Auto"))])
969 +               self.scan_sat.is_id = ConfigInteger(default = defaultSat["is_id"], limits = (self.NO_STREAM_ID_FILTER, 255))
970 +               self.scan_sat.is_id_bool = ConfigSelection(default = defaultSat["is_id"] != self.NO_STREAM_ID_FILTER, choices = [(True, _("Multistream")),(False, _("Ordinary"))])
971 +               self.scan_sat.pls_mode = ConfigSelection(default = defaultSat["pls_mode"], choices = [
972 +                       (eDVBFrontendParametersSatellite.PLS_Root, _("Root")),
973 +                       (eDVBFrontendParametersSatellite.PLS_Gold, _("Gold")),
974 +                       (eDVBFrontendParametersSatellite.PLS_Combo, _("Combo"))])
975 +               self.scan_sat.pls_code = ConfigInteger(default = defaultSat["pls_code"], limits = (0, 262142))
976 +
977 +               self.is_id_memory = self.scan_sat.is_id.value # used to prevent is_id value being lost when self.scan_sat.is_id_bool state changes
978 +               self.pls_mode_memory = self.scan_sat.pls_mode.value
979 +               self.pls_code_memory = self.scan_sat.pls_code.value
980  
981         def tuningSatChanged(self, *parm):
982                 self.updateTransponders()
983 +               self.createSetup()
984 +
985 +       def tuningTypeChanged(self, *parm):
986 +               self.createSetup()
987 +
988 +       def systemChanged(self, *parm):
989 +               self.createSetup()
990 +
991 +       def isIdChanged(self, *parm):
992 +               if self.is_id_boolEntry:
993 +                       if self.is_id_boolEntry[1].value:
994 +                               self.scan_sat.is_id.value = 0 if self.is_id_memory < 0 else self.is_id_memory
995 +                               self.scan_sat.pls_mode.value = self.pls_mode_memory
996 +                               self.scan_sat.pls_code.value = self.pls_code_memory
997 +                       else:
998 +                               self.is_id_memory = self.scan_sat.is_id.value
999 +                               self.pls_mode_memory = self.scan_sat.pls_mode.value
1000 +                               self.pls_code_memory = self.scan_sat.pls_code.value
1001 +                               self.scan_sat.is_id.value = self.NO_STREAM_ID_FILTER
1002 +                               self.scan_sat.pls_mode.value = eDVBFrontendParametersSatellite.PLS_Root
1003 +                               self.scan_sat.pls_code.value = 1
1004 +               self.createSetup()
1005  
1006         def updateTransponders(self):
1007 -               if len(tuning.sat.choices):
1008 -                       transponderlist = nimmanager.getTransponders(int(tuning.sat.value))
1009 +               if len(self.tuning.sat.choices):
1010 +                       transponderlist = nimmanager.getTransponders(int(self.tuning.sat.value))
1011                         tps = []
1012                         cnt=0
1013                         for x in transponderlist:
1014 @@ -534,13 +735,19 @@ class TunerScreen(ScanSetup):
1015                                 else:
1016                                         fec = fec_desc[x[4]]
1017                                 tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
1018 -                       tuning.transponder = ConfigSelection(choices=tps)
1019 +                       self.tuning.transponder = ConfigSelection(choices=tps)
1020 +
1021 +       def keyLeft(self):
1022 +               ConfigListScreen.keyLeft(self)
1023 +
1024 +       def keyRight(self):
1025 +               ConfigListScreen.keyRight(self)
1026  
1027         def keyGo(self):
1028 -               returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
1029 -               satpos = int(tuning.sat.value)
1030 +               returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1)
1031 +               satpos = int(self.tuning.sat.value)
1032                 nim = nimmanager.nim_slots[self.feid]
1033 -               if tuning.type.value == "manual_transponder":
1034 +               if self.tuning.type.value == "manual_transponder":
1035                         system = self.scan_sat.system.value
1036                         modulation = self.scan_sat.modulation.value
1037                         if nim.isCompatible("DVB-S2X"):
1038 @@ -563,7 +770,7 @@ class TunerScreen(ScanSetup):
1039                                 elif modulation == eDVBFrontendParametersSatellite.Modulation_32APSK:
1040                                         fec = self.scan_sat.fec_s2x_32apsk.value
1041                         else:
1042 -                               fec = self.scan_sat.fec_s2.value
1043 +                               fec = self.scan_sat.fec.value
1044  
1045                         returnvalue = (
1046                                 self.scan_sat.frequency.value,
1047 @@ -575,11 +782,14 @@ class TunerScreen(ScanSetup):
1048                                 system,
1049                                 modulation,
1050                                 self.scan_sat.rolloff.value,
1051 -                               self.scan_sat.pilot.value)
1052 -               elif tuning.type.value == "predefined_transponder":
1053 -                       transponder = nimmanager.getTransponders(satpos)[tuning.transponder.index]
1054 +                               self.scan_sat.pilot.value,
1055 +                               self.scan_sat.is_id.value,
1056 +                               self.scan_sat.pls_mode.value,
1057 +                               self.scan_sat.pls_code.value)
1058 +               elif self.tuning.type.value == "predefined_transponder":
1059 +                       transponder = nimmanager.getTransponders(satpos)[self.tuning.transponder.index]
1060                         returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
1061 -                               transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
1062 +                               transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9], transponder[10], transponder[11], transponder[12])
1063                 self.close(returnvalue)
1064  
1065         def keyCancel(self):
1066 diff --git a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
1067 index a87ca26f..402c8770 100644
1068 --- a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
1069 +++ b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
1070 @@ -59,17 +59,15 @@ class Satfinder(ScanSetup):
1071         def createSetup(self):
1072                 self.typeOfTuningEntry = None
1073                 self.satEntry = None
1074 -               
1075 +               self.systemEntry = None
1076 +               self.is_id_boolEntry = None
1077                 self.list = []
1078 -
1079                 self.typeOfTuningEntry = getConfigListEntry(_('Tune'), self.tuning_type)
1080                 self.list.append(self.typeOfTuningEntry)
1081                 self.satEntry = getConfigListEntry(_('Satellite'), self.tuning_sat)
1082                 self.list.append(self.satEntry)
1083  
1084                 nim = nimmanager.nim_slots[self.feid]
1085 -
1086 -               self.systemEntry = None
1087                 if self.tuning_type.value == "manual_transponder":
1088                         scan_sat_system_value = self.scan_sat.system.value
1089                         if nim.isCompatible("DVB-S2X"):
1090 @@ -109,6 +107,18 @@ class Satfinder(ScanSetup):
1091                                 self.list.append(self.modulationEntry)
1092                                 self.list.append(getConfigListEntry(_('Roll-off'), self.scan_sat.rolloff))
1093                                 self.list.append(getConfigListEntry(_('Pilot'), self.scan_sat.pilot))
1094 +                       if scan_sat_system_value in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X):
1095 +                               if nim.isMultistream():
1096 +                                       self.is_id_boolEntry = getConfigListEntry(_('Transport Stream Type'), self.scan_sat.is_id_bool)
1097 +                                       self.list.append(self.is_id_boolEntry)
1098 +                                       if self.scan_sat.is_id_bool.value:
1099 +                                               self.list.append(getConfigListEntry(_('Input Stream ID'), self.scan_sat.is_id))
1100 +                                               self.list.append(getConfigListEntry(_('PLS Mode'), self.scan_sat.pls_mode))
1101 +                                               self.list.append(getConfigListEntry(_('PLS Code'), self.scan_sat.pls_code))
1102 +                               else:
1103 +                                       self.scan_sat.is_id.value = self.NO_STREAM_ID_FILTER
1104 +                                       self.scan_sat.pls_mode.value = eDVBFrontendParametersSatellite.PLS_Root
1105 +                                       self.scan_sat.pls_code.value = 1
1106                 elif self.tuning_transponder and self.tuning_type.value == "predefined_transponder":
1107                         self.list.append(getConfigListEntry(_("Transponder"), self.tuning_transponder))
1108                 self["config"].list = self.list
1109 @@ -124,13 +134,26 @@ class Satfinder(ScanSetup):
1110                 elif self.modulationEntry and (cur == self.modulationEntry) and \
1111                         self.systemEntry and (self.systemEntry[1].value == eDVBFrontendParametersSatellite.System_DVB_S2X):
1112                         self.createSetup()
1113 +               elif cur == self.is_id_boolEntry:
1114 +                       if self.is_id_boolEntry[1].value:
1115 +                               self.scan_sat.is_id.value = 0 if self.is_id_memory < 0 else self.is_id_memory
1116 +                               self.scan_sat.pls_mode.value = self.pls_mode_memory
1117 +                               self.scan_sat.pls_code.value = self.pls_code_memory
1118 +                       else:
1119 +                               self.is_id_memory = self.scan_sat.is_id.value
1120 +                               self.pls_mode_memory = self.scan_sat.pls_mode.value
1121 +                               self.pls_code_memory = self.scan_sat.pls_code.value
1122 +                               self.scan_sat.is_id.value = self.NO_STREAM_ID_FILTER
1123 +                               self.scan_sat.pls_mode.value = eDVBFrontendParametersSatellite.PLS_Root
1124 +                               self.scan_sat.pls_code.value = 1
1125 +                       self.createSetup()
1126  
1127         def sat_changed(self, config_element):
1128                 self.newConfig()
1129                 self.retune(config_element)
1130  
1131         def retune(self, configElement):
1132 -               returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
1133 +               returnvalue = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1)
1134                 satpos = int(self.tuning_sat.value)
1135                 nim = nimmanager.nim_slots[self.feid]
1136                 if self.tuning_type.value == "manual_transponder":
1137 @@ -165,7 +188,10 @@ class Satfinder(ScanSetup):
1138                                 system,
1139                                 modulation,
1140                                 self.scan_sat.rolloff.value,
1141 -                               self.scan_sat.pilot.value)
1142 +                               self.scan_sat.pilot.value,
1143 +                               self.scan_sat.is_id.value,
1144 +                               self.scan_sat.pls_mode.value,
1145 +                               self.scan_sat.pls_code.value)
1146                         self.tune(returnvalue)
1147                 elif self.tuning_type.value == "predefined_transponder":
1148                         tps = nimmanager.getTransponders(satpos)
1149 @@ -173,7 +199,7 @@ class Satfinder(ScanSetup):
1150                         if l > self.tuning_transponder.index:
1151                                 transponder = tps[self.tuning_transponder.index]
1152                                 returnvalue = (transponder[1] / 1000, transponder[2] / 1000,
1153 -                                       transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9])
1154 +                                       transponder[3], transponder[4], 2, satpos, transponder[5], transponder[6], transponder[8], transponder[9], transponder[10], transponder[11], transponder[12])
1155                                 self.tune(returnvalue)
1156  
1157         def createConfig(self, foo):
1158 @@ -188,7 +214,8 @@ class Satfinder(ScanSetup):
1159                         self.scan_sat.inversion, self.scan_sat.symbolrate,
1160                         self.scan_sat.polarization, self.scan_sat.fec, self.scan_sat.pilot,
1161                         self.scan_sat.fec_s2, self.scan_sat.fec, self.scan_sat.modulation,
1162 -                       self.scan_sat.rolloff, self.scan_sat.system]
1163 +                       self.scan_sat.rolloff, self.scan_sat.system,
1164 +                       self.scan_sat.is_id, self.scan_sat.pls_mode, self.scan_sat.pls_code]
1165  
1166                 nim = nimmanager.nim_slots[self.feid]
1167                 if nim.isCompatible("DVB-S2X"):
1168 diff --git a/lib/python/Screens/ScanSetup.py b/lib/python/Screens/ScanSetup.py
1169 index b7f57887..e1844458 100644
1170 --- a/lib/python/Screens/ScanSetup.py
1171 +++ b/lib/python/Screens/ScanSetup.py
1172 @@ -49,6 +49,9 @@ def getInitialTransponderList(tlist, pos):
1173                         parm.modulation = x[6]
1174                         parm.rolloff = x[8]
1175                         parm.pilot = x[9]
1176 +                       parm.is_id = x[10]
1177 +                       parm.pls_mode = x[11]
1178 +                       parm.pls_code = x[12]
1179                         tlist.append(parm)
1180  
1181  def getInitialCableTransponderList(tlist, nim):
1182 @@ -587,6 +590,7 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1183                 self.typeOfScanEntry = None
1184                 self.systemEntry = None
1185                 self.modulationEntry = None
1186 +               self.is_id_boolEntry = None
1187                 nim = nimmanager.nim_slots[index_to_scan]
1188                 if nim.isCompatible("DVB-S"):
1189                         self.typeOfScanEntry = getConfigListEntry(_("Type of scan"), self.scan_type)
1190 @@ -647,6 +651,18 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1191                                         elif self.scan_sat.modulation_dvbs2x.value == eDVBFrontendParametersSatellite.Modulation_32APSK:
1192                                                 self.list.append(getConfigListEntry(_("FEC"), self.scan_sat.fec_s2x_32apsk))
1193  
1194 +                               if scan_sat_system_value in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X):
1195 +                                       if nim.isMultistream():
1196 +                                               self.is_id_boolEntry = getConfigListEntry(_('Transport Stream Type'), self.scan_sat.is_id_bool)
1197 +                                               self.list.append(self.is_id_boolEntry)
1198 +                                               if self.scan_sat.is_id_bool.value:
1199 +                                                       self.list.append(getConfigListEntry(_('Input Stream ID'), self.scan_sat.is_id))
1200 +                                                       self.list.append(getConfigListEntry(_('PLS Mode'), self.scan_sat.pls_mode))
1201 +                                                       self.list.append(getConfigListEntry(_('PLS Code'), self.scan_sat.pls_code))
1202 +                                       else:
1203 +                                               self.scan_sat.is_id.value = self.NO_STREAM_ID_FILTER
1204 +                                               self.scan_sat.pls_mode.value = eDVBFrontendParametersSatellite.PLS_Root
1205 +                                               self.scan_sat.pls_code.value = 1
1206                         elif self.scan_type.value == "single_satellite":
1207                                 self.updateSatList()
1208                                 print self.scan_satselection[index_to_scan]
1209 @@ -723,8 +739,22 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1210                         (self.systemEntry[1].value in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X)) and \
1211                         cur == self.modulationEntry):
1212                         self.createSetup()
1213 +               elif cur == self.is_id_boolEntry:
1214 +                       if self.is_id_boolEntry[1].value:
1215 +                               self.scan_sat.is_id.value = 0 if self.is_id_memory < 0 else self.is_id_memory
1216 +                               self.scan_sat.pls_mode.value = self.pls_mode_memory
1217 +                               self.scan_sat.pls_code.value = self.pls_code_memory
1218 +                       else:
1219 +                               self.is_id_memory = self.scan_sat.is_id.value
1220 +                               self.pls_mode_memory = self.scan_sat.pls_mode.value
1221 +                               self.pls_code_memory = self.scan_sat.pls_code.value
1222 +                               self.scan_sat.is_id.value = self.NO_STREAM_ID_FILTER
1223 +                               self.scan_sat.pls_mode.value = eDVBFrontendParametersSatellite.PLS_Root
1224 +                               self.scan_sat.pls_code.value = 1
1225 +                       self.createSetup()
1226  
1227         def createConfig(self, frontendData):
1228 +                       self.NO_STREAM_ID_FILTER = -1
1229                         defaultSat = {
1230                                 "orbpos": 192,
1231                                 "system": eDVBFrontendParametersSatellite.System_DVB_S,
1232 @@ -740,7 +770,10 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1233                                 "fec_s2x_16apsk": eDVBFrontendParametersSatellite.FEC_1_2_L,
1234                                 "fec_s2x_32apsk": eDVBFrontendParametersSatellite.FEC_2_3_L,
1235                                 "modulation": eDVBFrontendParametersSatellite.Modulation_QPSK,
1236 -                               "modulation_s2x": eDVBFrontendParametersSatellite.Modulation_QPSK}
1237 +                               "modulation_s2x": eDVBFrontendParametersSatellite.Modulation_QPSK,
1238 +                               "is_id": self.NO_STREAM_ID_FILTER,
1239 +                               "pls_mode": eDVBFrontendParametersSatellite.PLS_Root,
1240 +                               "pls_code": 1 }
1241                         defaultCab = {
1242                                 "frequency": 466,
1243                                 "inversion": eDVBFrontendParametersCable.Inversion_Unknown,
1244 @@ -795,6 +828,9 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1245                                         if defaultSat["system"] in (eDVBFrontendParametersSatellite.System_DVB_S2, eDVBFrontendParametersSatellite.System_DVB_S2X):
1246                                                 defaultSat["rolloff"] = frontendData.get("rolloff", eDVBFrontendParametersSatellite.RollOff_alpha_0_35)
1247                                                 defaultSat["pilot"] = frontendData.get("pilot", eDVBFrontendParametersSatellite.Pilot_Unknown)
1248 +                                               defaultSat["is_id"] = frontendData.get("is_id", defaultSat["is_id"])
1249 +                                               defaultSat["pls_mode"] = frontendData.get("pls_mode", defaultSat["pls_mode"])
1250 +                                               defaultSat["pls_code"] = frontendData.get("pls_code", defaultSat["pls_code"])
1251  
1252                                 elif ttype == "DVB-C":
1253                                         defaultCab["frequency"] = frontendData.get("frequency", 0) / 1000
1254 @@ -943,6 +979,17 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1255                                 (eDVBFrontendParametersSatellite.Pilot_Off, _("Off")),
1256                                 (eDVBFrontendParametersSatellite.Pilot_On, _("On")),
1257                                 (eDVBFrontendParametersSatellite.Pilot_Unknown, _("Auto"))])
1258 +                       self.scan_sat.is_id = ConfigInteger(default = defaultSat["is_id"], limits = (self.NO_STREAM_ID_FILTER, 255))
1259 +                       self.scan_sat.is_id_bool = ConfigSelection(default = defaultSat["is_id"] != self.NO_STREAM_ID_FILTER, choices = [(True, _("Multistream")),(False, _("Ordinary"))])
1260 +                       self.scan_sat.pls_mode = ConfigSelection(default = defaultSat["pls_mode"], choices = [
1261 +                               (eDVBFrontendParametersSatellite.PLS_Root, _("Root")),
1262 +                               (eDVBFrontendParametersSatellite.PLS_Gold, _("Gold")),
1263 +                               (eDVBFrontendParametersSatellite.PLS_Combo, _("Combo"))])
1264 +                       self.scan_sat.pls_code = ConfigInteger(default = defaultSat["pls_code"], limits = (0, 262142))
1265 +                       
1266 +                       self.is_id_memory = self.scan_sat.is_id.value # used to prevent is_id value being lost when self.scan_sat.is_id_bool state changes
1267 +                       self.pls_mode_memory = self.scan_sat.pls_mode.value
1268 +                       self.pls_code_memory = self.scan_sat.pls_code.value
1269  
1270                         # cable
1271                         self.scan_cab.frequency = ConfigInteger(default = defaultCab["frequency"], limits = (50, 999))
1272 @@ -1092,8 +1139,8 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1273         def updateStatus(self):
1274                 print "updatestatus"
1275  
1276 -       def addSatTransponder(self, tlist, frequency, symbol_rate, polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot):
1277 -               print "Add Sat: frequ: " + str(frequency) + " symbol: " + str(symbol_rate) + " pol: " + str(polarisation) + " fec: " + str(fec) + " inversion: " + str(inversion) + " modulation: " + str(modulation) + " system: " + str(system) + " rolloff" + str(rolloff) + " pilot" + str(pilot)
1278 +       def addSatTransponder(self, tlist, frequency, symbol_rate, polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot, is_id, pls_mode, pls_code):
1279 +               print "Add Sat: frequ: " + str(frequency) + " symbol: " + str(symbol_rate) + " pol: " + str(polarisation) + " fec: " + str(fec) + " inversion: " + str(inversion) + " modulation: " + str(modulation) + " system: " + str(system) + " rolloff" + str(rolloff) + " pilot" + str(pilot) + " is_id" + str(is_id) + " pls_mode" + str(pls_mode) + " pls_code" + str(pls_code)
1280                 print "orbpos: " + str(orbital_position)
1281                 parm = eDVBFrontendParametersSatellite()
1282                 parm.modulation = modulation
1283 @@ -1106,6 +1153,9 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1284                 parm.orbital_position = orbital_position
1285                 parm.rolloff = rolloff
1286                 parm.pilot = pilot
1287 +               parm.is_id = is_id
1288 +               parm.pls_mode = pls_mode
1289 +               parm.pls_code = pls_code
1290                 tlist.append(parm)
1291  
1292         def addCabTransponder(self, tlist, frequency, symbol_rate, modulation, fec, inversion):
1293 @@ -1188,7 +1238,10 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport, Terrest
1294                                                                 system,
1295                                                                 modulation,
1296                                                                 self.scan_sat.rolloff.value,
1297 -                                                               self.scan_sat.pilot.value)
1298 +                                                               self.scan_sat.pilot.value,
1299 +                                                               self.scan_sat.is_id.value,
1300 +                                                               self.scan_sat.pls_mode.value,
1301 +                                                               self.scan_sat.pls_code.value)
1302                                 removeAll = False
1303                         elif self.scan_type.value == "single_satellite":
1304                                 sat = self.satList[index_to_scan][self.scan_satselection[index_to_scan].index]
1305 diff --git a/lib/python/Screens/ServiceInfo.py b/lib/python/Screens/ServiceInfo.py
1306 index ffd288f3..5a52028c 100644
1307 --- a/lib/python/Screens/ServiceInfo.py
1308 +++ b/lib/python/Screens/ServiceInfo.py
1309 @@ -198,7 +198,10 @@ class ServiceInfo(Screen):
1310                                                 (_("Inversion"), frontendData["inversion"], TYPE_TEXT),
1311                                                 (_("FEC"), frontendData["fec_inner"], TYPE_TEXT),
1312                                                 (_("Pilot"), frontendData.get("pilot", None), TYPE_TEXT),
1313 -                                               (_("Roll-off"), frontendData.get("rolloff", None), TYPE_TEXT))
1314 +                                               (_("Roll-off"), frontendData.get("rolloff", None), TYPE_TEXT),
1315 +                                               (_("Input Stream ID"), frontendData.get("is_id", 0), TYPE_VALUE_DEC),
1316 +                                               (_("PLS Mode"), frontendData.get("pls_mode", None), TYPE_TEXT),
1317 +                                               (_("PLS Code"), frontendData.get("pls_code", 0), TYPE_VALUE_DEC))
1318                         elif frontendDataOrg["tuner_type"] == "DVB-C":
1319                                 return ((_("NIM"), chr(ord('A')+int(frontendData["tuner_number"])), TYPE_TEXT),
1320                                                 (_("Type"), frontendData["tuner_type"], TYPE_TEXT),
1321 diff --git a/lib/python/Tools/Transponder.py b/lib/python/Tools/Transponder.py
1322 index 2b46d0e6..08109b63 100644
1323 --- a/lib/python/Tools/Transponder.py
1324 +++ b/lib/python/Tools/Transponder.py
1325 @@ -69,6 +69,17 @@ def ConvertToHumanReadable(tp, type = None):
1326                                 eDVBFrontendParametersSatellite.Pilot_Unknown : _("Auto"),
1327                                 eDVBFrontendParametersSatellite.Pilot_On : _("On"),
1328                                 eDVBFrontendParametersSatellite.Pilot_Off : _("Off")}[tp["pilot"]]
1329 +                       ret["pls_mode"] = {
1330 +                               eDVBFrontendParametersSatellite.PLS_Root : _("Root"),
1331 +                               eDVBFrontendParametersSatellite.PLS_Gold : _("Gold"),
1332 +                               eDVBFrontendParametersSatellite.PLS_Combo : _("Combo"),
1333 +                               eDVBFrontendParametersSatellite.PLS_Unknown : _("Unknown")}.get(tp.get("pls_mode"))
1334 +                       #ret["is_id"] = tp.get("is_id")
1335 +                       #ret["pls_code"] = tp.get("pls_code")
1336 +               else:
1337 +                       ret["pls_mode"] = None
1338 +                       ret["is_id"] = None
1339 +                       ret["pls_code"] = None
1340         elif type == "DVB-C":
1341                 ret["tuner_type"] = _("Cable")
1342                 ret["modulation"] = {