+void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
+{
+ int num_fe = adapter->getNumFrontends();
+ int num_demux = adapter->getNumDemux();
+
+ m_adapter.push_back(adapter);
+
+ int i;
+ for (i=0; i<num_demux; ++i)
+ {
+ ePtr<eDVBDemux> demux;
+ if (!adapter->getDemux(demux, i))
+ m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
+ }
+
+ ePtr<eDVBRegisteredFrontend> prev_dvbt_frontend;
+ for (i=0; i<num_fe; ++i)
+ {
+ ePtr<eDVBFrontend> frontend;
+ if (!adapter->getFrontend(frontend, i))
+ {
+ int frontendType=0;
+ frontend->getFrontendType(frontendType);
+ eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
+ CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
+ m_frontend.push_back(new_fe);
+ frontend->setSEC(m_sec);
+ // we must link all dvb-t frontends ( for active antenna voltage )
+ if (frontendType == iDVBFrontend::feTerrestrial)
+ {
+ if (prev_dvbt_frontend)
+ {
+ prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (int)new_fe);
+ frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (int)&(*prev_dvbt_frontend));
+ }
+ prev_dvbt_frontend = new_fe;
+ }
+ }
+ }
+}
+
+PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
+{
+ if (!PyList_Check(list))
+ {
+ PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list");
+ return NULL;
+ }
+ if ((unsigned int)PyList_Size(list) != m_frontend.size())
+ {
+ char blasel[256];
+ sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations list size incorrect %d frontends avail, but %d entries in slotlist",
+ m_frontend.size(), PyList_Size(list));
+ PyErr_SetString(PyExc_StandardError, blasel);
+ return NULL;
+ }
+ int pos=0;
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
+ {
+ ePyObject obj = PyList_GET_ITEM(list, pos++);
+ if (!i->m_frontend->setSlotInfo(obj))
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
+{
+ ePtr<eDVBRegisteredFrontend> best;
+ int bestval = 0;
+
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
+ if (!i->m_inuse)
+ {
+ int c = i->m_frontend->isCompatibleWith(feparm);
+ if (c > bestval)
+ {
+ bestval = c;
+ best = i;
+ }
+ }
+
+ if (best)
+ {
+ fe = new eDVBAllocatedFrontend(best);
+ return 0;
+ }
+
+ fe = 0;
+
+ return -1;
+}
+
+RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int slot_index)
+{
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
+ if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index)
+ {
+ // check if another slot linked to this is in use
+ eDVBRegisteredFrontend *satpos_depends_to_fe =
+ (eDVBRegisteredFrontend*) i->m_frontend->m_data[eDVBFrontend::SATPOS_DEPENDS_PTR];
+ if ( (int)satpos_depends_to_fe != -1 )
+ {
+ if (satpos_depends_to_fe->m_inuse)
+ {
+ eDebug("another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!");
+ goto alloc_fe_by_id_not_possible;
+ }
+ }
+ else // check linked tuners
+ {
+ eDVBRegisteredFrontend *next =
+ (eDVBRegisteredFrontend *) i->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR];
+ while ( (int)next != -1 )
+ {
+ if (next->m_inuse)
+ {
+ eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
+ goto alloc_fe_by_id_not_possible;
+ }
+ next = (eDVBRegisteredFrontend *)next->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR];
+ }
+ eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)
+ i->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR];
+ while ( (int)prev != -1 )
+ {
+ if (prev->m_inuse)
+ {
+ eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
+ goto alloc_fe_by_id_not_possible;
+ }
+ prev = (eDVBRegisteredFrontend *)prev->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR];
+ }
+ }
+ fe = new eDVBAllocatedFrontend(i);
+ return 0;
+ }
+alloc_fe_by_id_not_possible:
+ fe = 0;
+ return -1;
+}
+
+RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
+{
+ /* find first unused demux which is on same adapter as frontend (or any, if PVR)
+ never use the first one unless we need a decoding demux. */
+
+ eDebug("allocate demux");
+ eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
+
+ if (i == m_demux.end())
+ return -1;
+
+ int n=0;
+ /* FIXME: hardware demux policy */
+ if (!(cap & iDVBChannel::capDecode))
+ {
+ if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
+ {
+ ++i, ++n;
+ ++i, ++n;
+ }
+ }
+
+ for (; i != m_demux.end(); ++i, ++n)
+ {
+ int is_decode = n < 2;
+
+ int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
+
+ if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
+ {
+ if ((cap & iDVBChannel::capDecode) && !is_decode)
+ continue;
+
+ demux = new eDVBAllocatedDemux(i);
+ if (fe)
+ demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
+ else
+ demux->get().setSourcePVR(0);
+ return 0;
+ }
+ }
+ eDebug("demux not found");
+ return -1;
+}
+