2 #include <lib/dvb/fbc.h>
3 #include <lib/dvb/dvb.h>
4 #include <lib/dvb/sec.h>
5 #include <lib/base/object.h>
13 #define eFecDebug(arg...) eDebug(arg)
15 #define eFecDebug(arg...)
18 static int getProcData(const char* filename)
21 FILE *fp = fopen(filename,"r");
24 fscanf(fp, "%d", &res);
29 eFecDebug("[*][eFBCTunerManager::getProcData] open failed, %s: %m", filename);
34 static void setProcData(const char* filename, int value)
36 eDebug("[*] setProcData %s -> %d", filename, value);
37 FILE *fp = fopen(filename, "w");
40 fprintf(fp, "%d", value);
45 eFecDebug("[*][eFBCTunerManager::setProcData] open failed, %s: %m", filename);
49 static void loadConnectChoices(const char* filename, bool *connect_choices)
51 FILE *fp = fopen(filename,"r");
55 while(EOF != (c = fgetc(fp)))
58 connect_choices[c - '0'] = true;
64 eFecDebug("[*][eFBCTunerManager::LoadFbcRootChoices] open failed, %s: %m", filename);
69 DEFINE_REF(eFBCTunerManager);
71 eFBCTunerManager* eFBCTunerManager::m_instance = (eFBCTunerManager*)0;
73 eFBCTunerManager* eFBCTunerManager::getInstance()
78 eFBCTunerManager::eFBCTunerManager(ePtr<eDVBResourceManager> res_mgr)
84 eSmartPtrList<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_frontend;
85 eSmartPtrList<eDVBRegisteredFrontend> &frontends_simulate = m_res_mgr->m_simulate_frontend;
86 /* each FBC set has 8 tuners. */
87 /* first set : 0, 1, 2, 3, 4, 5, 6, 7 */
88 /* second set : 8, 9, 10, 11, 12, 13, 14, 15 */
89 /* first, second frontend is top on a set */
96 int prevFbcSetID = -1;
97 char procFileName[128];
99 bool connect_choices[32] = {false};
101 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); ++it)
103 // continue for DVB-C FBC Tuner
104 if (!(it->m_frontend->supportsDeliverySystem(SYS_DVBS, false) || it->m_frontend->supportsDeliverySystem(SYS_DVBS2, false)))
107 fe_id = feSlotID(it);
108 snprintf(procFileName, sizeof(procFileName), "/proc/stb/frontend/%d/fbc_set_id", fe_id);
109 fbcSetID = getProcData(procFileName);
112 if (prevFbcSetID != fbcSetID)
114 prevFbcSetID = fbcSetID;
115 memset(connect_choices, 0, sizeof(connect_choices));
116 snprintf(procFileName, sizeof(procFileName), "/proc/stb/frontend/%d/fbc_connect_choices", fe_id);
117 loadConnectChoices(procFileName, connect_choices);
118 fbcIndex =0; // reset
122 if (fbcIndex < sizeof(connect_choices)/sizeof(connect_choices[0]))
124 isRoot = connect_choices[fbcIndex];
127 initFbcId = isRoot ? fbcIndex : 0;
129 FBC_TUNER elem = {fbcSetID, fbcIndex, isRoot, initFbcId};
130 m_fbc_tuners[fe_id] = elem;
132 /* set default fbc ID */
133 setProcFBCID(fe_id, initFbcId, false);
135 /* enable fbc tuner */
136 it->m_frontend->setFBCTuner(true);
142 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends_simulate.begin()); it != frontends_simulate.end(); ++it)
144 // continue for DVB-C FBC Tuner
145 if (!(it->m_frontend->supportsDeliverySystem(SYS_DVBS, false) || it->m_frontend->supportsDeliverySystem(SYS_DVBS2, false)))
148 fe_id = feSlotID(it);
149 snprintf(procFileName, sizeof(procFileName), "/proc/stb/frontend/%d/fbc_set_id", fe_id);
150 fbcSetID = getProcData(procFileName);
153 /* enable fbc tuner */
154 it->m_frontend->setFBCTuner(true);
159 eFBCTunerManager::~eFBCTunerManager()
161 if (m_instance == this)
165 int eFBCTunerManager::setProcFBCID(int fe_id, int fbc_connect, bool is_linked)
167 eFecDebug("[*][eFBCTunerManager::setProcFBCID] %d -> %d", fe_id, fbc_connect);
171 sprintf(filename, "/proc/stb/frontend/%d/fbc_connect", fe_id);
172 setProcData(filename, fbc_connect);
175 sprintf(filename, "/proc/stb/frontend/%d/fbc_link", fe_id);
176 setProcData(filename, (int)is_linked);
182 int eFBCTunerManager::feSlotID(const eDVBRegisteredFrontend *fe) const
184 return fe->m_frontend->getSlotID();
187 void eFBCTunerManager::setDefaultFBCID(eDVBRegisteredFrontend *fe)
189 int fe_id = feSlotID(fe);
190 setProcFBCID(fe_id, getDefaultFBCID(fe_id), isLinked(fe));
193 void eFBCTunerManager::updateFBCID(eDVBRegisteredFrontend *next_fe, eDVBRegisteredFrontend *prev_fe)
195 setProcFBCID(feSlotID(next_fe), getFBCID(feSlotID(getTop(prev_fe))), isLinked(next_fe));
198 bool eFBCTunerManager::isLinked(eDVBRegisteredFrontend *fe) const
201 long linked_prev_ptr = -1;
202 fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
203 return (linked_prev_ptr != -1);
206 bool eFBCTunerManager::isUnicable(eDVBRegisteredFrontend *fe) const
208 int slot_idx = feSlotID(fe);
209 bool is_unicable = false;
211 ePtr<eDVBSatelliteEquipmentControl> sec = eDVBSatelliteEquipmentControl::getInstance();
212 for (int idx=0; idx <= sec->m_lnbidx; ++idx )
214 eDVBSatelliteLNBParameters &lnb_param = sec->m_lnbs[idx];
215 if ( lnb_param.m_slot_mask & (1 << slot_idx) )
217 is_unicable = lnb_param.SatCR_idx != -1;
224 bool eFBCTunerManager::isFeUsed(eDVBRegisteredFrontend *fe, bool a_simulate) const
229 bool simulate = !a_simulate;
231 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend;
232 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); ++it)
234 if (feSlotID(it) == feSlotID(fe))
236 return (it->m_inuse >0);
240 eDebug("[*][eFBCTunerManager::isFeUsed] ERROR! can not found fe ptr (feid : %d, simulate : %d)", feSlotID(fe), simulate);
244 bool eFBCTunerManager::isSameFbcSet(int fe_a, int fe_b)
246 return m_fbc_tuners[fe_a].fbcSetID == m_fbc_tuners[fe_b].fbcSetID;
249 bool eFBCTunerManager::isRootFe(eDVBRegisteredFrontend *fe)
251 return m_fbc_tuners[feSlotID(fe)].isRoot;
254 int eFBCTunerManager::getFBCID(int fe_id)
256 return m_fbc_tuners[fe_id].fbcIndex;
259 int eFBCTunerManager::getDefaultFBCID(int fe_id)
261 return m_fbc_tuners[fe_id].initFbcId;
264 int eFBCTunerManager::getFBCSetID(int fe_id)
266 return m_fbc_tuners[fe_id].fbcSetID;
269 eDVBRegisteredFrontend *eFBCTunerManager::getPrev(eDVBRegisteredFrontend *fe) const
271 eDVBRegisteredFrontend *prev_fe = NULL;
272 long linked_prev_ptr = -1;
273 fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
274 if (linked_prev_ptr != -1)
275 prev_fe = (eDVBRegisteredFrontend *)linked_prev_ptr;
279 eDVBRegisteredFrontend *eFBCTunerManager::getNext(eDVBRegisteredFrontend *fe) const
281 eDVBRegisteredFrontend *next_fe = NULL;
282 long linked_next_ptr = -1;
283 fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr);
284 if (linked_next_ptr != -1)
285 next_fe = (eDVBRegisteredFrontend *)linked_next_ptr;
289 eDVBRegisteredFrontend *eFBCTunerManager::getTop(eDVBRegisteredFrontend *fe) const
291 eDVBRegisteredFrontend *prev_fe = fe;
292 long linked_prev_ptr = -1;
293 fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
294 while(linked_prev_ptr != -1)
296 prev_fe = (eDVBRegisteredFrontend *)linked_prev_ptr;
297 prev_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
302 eDVBRegisteredFrontend *eFBCTunerManager::getLast(eDVBRegisteredFrontend *fe) const
304 eDVBRegisteredFrontend *next_fe = fe;
305 long linked_next_ptr = -1;
306 fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr);
307 while(linked_next_ptr != -1)
309 next_fe = (eDVBRegisteredFrontend *)linked_next_ptr;
310 next_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr);
315 eDVBRegisteredFrontend *eFBCTunerManager::getSimulFe(eDVBRegisteredFrontend *fe) const
317 eSmartPtrList<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_simulate_frontend;
319 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); it++)
320 if (feSlotID(*it) == feSlotID(fe))
323 return((eDVBRegisteredFrontend *)0);
326 void eFBCTunerManager::connectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate)
329 eFecDebug(" [*][eFBCTunerManager::connectLink] connect %d->%d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), feSlotID(next_fe), simulate?"(simulate)":"");
331 eFecDebug(" [*][eFBCTunerManager::connectLink] connect %d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), simulate?"(simulate)":"");
333 prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)link_fe);
334 link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe);
337 link_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)next_fe);
338 next_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)link_fe);
342 void eFBCTunerManager::disconnectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate)
345 eFecDebug(" [*][eFBCTunerManager::disconnectLink] disconnect %d->%d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), feSlotID(next_fe), simulate?"(simulate)":"");
347 eFecDebug(" [*][eFBCTunerManager::disconnectLink] disconnect %d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), simulate?"(simulate)":"");
351 prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)next_fe);
352 next_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe);
354 link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)-1);
355 link_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)-1);
359 prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)-1);
360 link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)-1);
364 int eFBCTunerManager::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm, eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *&fbc_fe, bool simulate)
368 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend;
369 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); ++it)
371 if (!it->m_frontend->is_FBCTuner())
377 if(!it->m_frontend->getEnabled())
380 if(!isSameFbcSet(feSlotID(link_fe), feSlotID(it)))
383 if(it->m_inuse == 0) // No link to a fe not in use.
386 if(isLinked(*it)) // No link to a fe linked to another.
392 eDVBRegisteredFrontend *top_fe = *it;
393 eDVBRegisteredFrontend *prev_fe = getLast(top_fe);
396 connectLink(link_fe, prev_fe, NULL, simulate);
398 /* enable linked fe */
399 link_fe->m_frontend->setEnabled(true);
402 updateLNBSlotMask(feSlotID(link_fe), feSlotID(*it), false);
405 int c = link_fe->m_frontend->isCompatibleWith(feparm);
409 fbc_fe = (eDVBRegisteredFrontend *)*it;
412 eFecDebug("[*][eFBCTunerManager::isCompatibleWith] score : %d (%d->%d)", c, feSlotID(it), feSlotID(link_fe));
414 ASSERT(!getNext(link_fe));
415 ASSERT(getPrev(link_fe));
416 ASSERT(getLast(top_fe) == link_fe);
418 /* disconnect link */
419 disconnectLink(link_fe, prev_fe, NULL, simulate);
421 /* disable linked fe */
422 link_fe->m_frontend->setEnabled(false);
424 /* remove slot mask*/
425 updateLNBSlotMask(feSlotID(link_fe), feSlotID(top_fe), true);
428 eFecDebug("[*][eFBCTunerManager::isCompatibleWith] fe : %p(%d), score : %d %s", link_fe, feSlotID(link_fe), best_score, simulate?"(simulate)":"");
433 /* attach link_fe to tail of fe linked list */
434 void eFBCTunerManager::addLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe, bool simulate)
436 //printLinks(link_fe);
438 eFecDebug(" [*][eFBCTunerManager::addLink] addLink : %p(%d)->%p(%d) %s", top_fe, feSlotID(top_fe), link_fe, feSlotID(link_fe), simulate?"(simulate)":"");
440 eDVBRegisteredFrontend *next_fe = NULL;
441 eDVBRegisteredFrontend *prev_fe = NULL;
443 if(isRootFe(link_fe) || !isRootFe(top_fe))
446 /* search prev/next fe */
451 next_fe = getNext(prev_fe);
452 if ((next_fe == NULL) || (feSlotID(next_fe) > feSlotID(link_fe)))
457 connectLink(link_fe, prev_fe, next_fe, simulate);
459 /* enable linked fe */
460 link_fe->m_frontend->setEnabled(true);
462 /* simulate connect */
465 eDVBRegisteredFrontend *simulate_prev_fe = NULL;
466 eDVBRegisteredFrontend *simulate_link_fe = NULL;
467 eDVBRegisteredFrontend *simulate_next_fe = NULL;
469 simulate_prev_fe = getSimulFe(prev_fe);
470 simulate_link_fe = getSimulFe(link_fe);
473 simulate_next_fe = getSimulFe(next_fe);
475 eFecDebug(" [*][eFBCTunerManager::addLink] simulate fe : %p -> %p -> %p", simulate_prev_fe, simulate_link_fe, simulate_next_fe);
477 connectLink(simulate_link_fe, simulate_prev_fe, simulate_next_fe, !simulate);
479 /* enable simulate linked fe */
480 simulate_link_fe->m_frontend->setEnabled(true);
483 /* set proc fbc_id */
485 setProcFBCID(feSlotID(link_fe), getFBCID(feSlotID(top_fe)), isLinked(link_fe));
488 updateLNBSlotMask(feSlotID(link_fe), feSlotID(top_fe), false);
490 //printLinks(link_fe);
493 /* if fe, fe_simulated is unused, unlink current frontend from linked things. */
494 /* all unused linked fbc fe must be unlinked! */
495 void eFBCTunerManager::unLink(eDVBRegisteredFrontend *link_fe)
497 bool simulate = link_fe->m_frontend->is_simulate();
498 eFecDebug(" [*][eFBCTunerManager::unLink] fe id : %p(%d) %s", link_fe, feSlotID(link_fe), simulate?"(simulate)":"");
500 if (isRootFe(link_fe) || isFeUsed(link_fe, simulate) || isUnicable(link_fe) || !isLinked(link_fe))
502 eFecDebug(" [*][eFBCTunerManager::unLink] skip..");
506 //printLinks(link_fe);
508 eDVBRegisteredFrontend *prev_fe = getPrev(link_fe);
509 eDVBRegisteredFrontend *next_fe = getNext(link_fe);
513 disconnectLink(link_fe, prev_fe, next_fe, simulate);
515 /* disable linked fe */
516 link_fe->m_frontend->setEnabled(false);
518 /* simulate disconnect */
521 eDVBRegisteredFrontend *simulate_prev_fe = NULL;
522 eDVBRegisteredFrontend *simulate_link_fe = NULL;
523 eDVBRegisteredFrontend *simulate_next_fe = NULL;
525 simulate_prev_fe = getSimulFe(prev_fe);
526 simulate_link_fe = getSimulFe(link_fe);
529 simulate_next_fe = getSimulFe(next_fe);
531 disconnectLink(simulate_link_fe, simulate_prev_fe, simulate_next_fe, !simulate);
533 /* enable simulate linked fe */
534 simulate_link_fe->m_frontend->setEnabled(false);
537 /* set default proc fbc_id */
538 //setDefaultFBCID(link_fe);
540 /* remove slot mask*/
541 updateLNBSlotMask(feSlotID(link_fe), feSlotID(getTop(prev_fe)), true);
543 //printLinks(link_fe);
546 int eFBCTunerManager::updateLNBSlotMask(int dest_slot, int src_slot, bool remove)
548 ePtr<eDVBSatelliteEquipmentControl> sec = eDVBSatelliteEquipmentControl::getInstance();
550 int sec_lnbidx = sec->m_lnbidx;
553 for (int idx=0; idx <= sec_lnbidx; ++idx )
555 eDVBSatelliteLNBParameters &lnb_param = sec->m_lnbs[idx];
556 if ( lnb_param.m_slot_mask & (1 << src_slot) )
558 eFecDebug("[*][eFBCTunerManager::updateLNBSlotMask] m_slot_mask : %d", lnb_param.m_slot_mask);
561 lnb_param.m_slot_mask |= (1 << dest_slot);
563 lnb_param.m_slot_mask &= ~(1 << dest_slot);
565 eFecDebug("[*][eFBCTunerManager::updateLNBSlotMask] changed m_slot_mask : %d", lnb_param.m_slot_mask);
571 eFecDebug("[*][eFBCTunerManager::updateLNBSlotMask] src %d not found", src_slot);
576 bool eFBCTunerManager::canLink(eDVBRegisteredFrontend *fe)
578 return !(isRootFe(fe) || getPrev(fe) || getNext(fe) || isUnicable(fe));
581 int eFBCTunerManager::getLinkedSlotID(int fe_id) const
584 eSmartPtrList<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_frontend;
585 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); ++it)
587 if(it->m_frontend->getSlotID() == fe_id)
590 it->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, prev_ptr);
593 eDVBRegisteredFrontend *prev_fe = (eDVBRegisteredFrontend *)prev_ptr;
594 link = feSlotID(prev_fe);
600 eFecDebug(" [*][eFBCTunerManager::getLinkedSlotID] fe_id : %d, link : %d", fe_id, link);
605 bool eFBCTunerManager::isFBCLink(int fe_id)
608 std::map<int, FBC_TUNER>::iterator it = m_fbc_tuners.find(fe_id);
609 if (it != m_fbc_tuners.end())
611 res = !it->second.isRoot;
616 void eFBCTunerManager::printLinks(eDVBRegisteredFrontend *fe) const
618 long linked_prev_ptr = -1;
619 eDVBRegisteredFrontend *linked_prev_fe = fe;
620 fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr);
621 while (linked_prev_ptr != -1)
623 linked_prev_fe = (eDVBRegisteredFrontend*) linked_prev_ptr;
624 linked_prev_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr);
627 long linked_next_ptr = -1;
628 eDVBRegisteredFrontend *linked_next_fe = linked_prev_fe;
629 eFecDebug(" [*][eFBCTunerManager::printLinks] fe id : %d (%p), inuse : %d, enabled : %d, fbc : %d", feSlotID(linked_next_fe), linked_next_fe, linked_next_fe->m_inuse, linked_next_fe->m_frontend->getEnabled(), linked_next_fe->m_frontend->is_FBCTuner());
630 linked_prev_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr);
631 while (linked_next_ptr != -1)
633 linked_next_fe = (eDVBRegisteredFrontend*) linked_next_ptr;
634 eFecDebug(" [*][eFBCTunerManager::printLinks] fe id : %d (%p), inuse : %d, enabled : %d, fbc : %d", feSlotID(linked_next_fe), linked_next_fe, linked_next_fe->m_inuse, linked_next_fe->m_frontend->getEnabled(), linked_next_fe->m_frontend->is_FBCTuner());
635 linked_next_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, (long&)linked_next_ptr);
638 eSmartPtrList<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_frontend;
639 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); ++it)
645 it->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, prev_ptr);
646 it->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, next_ptr);
649 eDVBRegisteredFrontend *prev_fe = (eDVBRegisteredFrontend *)prev_ptr;
650 prev = feSlotID(prev_fe);
655 eDVBRegisteredFrontend *next_fe = (eDVBRegisteredFrontend *)next_ptr;
656 next = feSlotID(next_fe);
659 eFecDebug(" [*][eFBCTunerManager::printLinks] fe_id : %2d, inuse : %d, enabled : %d, fbc : %d, prev : %2d, cur : %2d, next : %2d", feSlotID(it), it->m_inuse, it->m_frontend->getEnabled(), it->m_frontend->is_FBCTuner(), prev, feSlotID(it), next);
662 eSmartPtrList<eDVBRegisteredFrontend> &simulate_frontends = m_res_mgr->m_simulate_frontend;
663 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(simulate_frontends.begin()); it != simulate_frontends.end(); ++it)
669 it->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, prev_ptr);
670 it->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, next_ptr);
673 eDVBRegisteredFrontend *prev_fe = (eDVBRegisteredFrontend *)prev_ptr;
674 prev = feSlotID(prev_fe);
679 eDVBRegisteredFrontend *next_fe = (eDVBRegisteredFrontend *)next_ptr;
680 next = feSlotID(next_fe);
683 eFecDebug(" [*][eFBCTunerManager::printLinks] fe_id : %2d, inuse : %d, enabled : %d, fbc : %d, prev : %2d, cur : %2d, next : %2d (simulate)", feSlotID(it), it->m_inuse, it->m_frontend->getEnabled(), it->m_frontend->is_FBCTuner(), prev, feSlotID(it), next);