1 #include <lib/dvb/idvb.h>
2 #include <lib/base/eerror.h>
3 #include <lib/dvb/dvb.h>
4 #include <lib/dvb/sec.h>
11 DEFINE_REF(eDVBRegisteredFrontend);
12 DEFINE_REF(eDVBRegisteredDemux);
14 DEFINE_REF(eDVBAllocatedFrontend);
16 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
21 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
26 DEFINE_REF(eDVBAllocatedDemux);
28 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
33 eDVBAllocatedDemux::~eDVBAllocatedDemux()
38 DEFINE_REF(eDVBResourceManager);
40 eDVBResourceManager *eDVBResourceManager::instance;
42 eDVBResourceManager::eDVBResourceManager()
46 m_sec = new eDVBSatelliteEquipmentControl;
50 /* search available adapters... */
55 while (eDVBAdapterLinux::exist(num_adapter))
57 addAdapter(new eDVBAdapterLinux(num_adapter));
61 eDebug("found %d adapter, %d frontends and %d demux",
62 m_adapter.size(), m_frontend.size(), m_demux.size());
66 DEFINE_REF(eDVBAdapterLinux);
67 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
72 eDebug("scanning for frontends..");
77 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
78 if (stat(filename, &s))
80 ePtr<eDVBFrontend> fe;
83 fe = new eDVBFrontend(m_nr, num_fe, ok);
85 m_frontend.push_back(fe);
95 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
96 if (stat(filename, &s))
98 ePtr<eDVBDemux> demux;
100 demux = new eDVBDemux(m_nr, num_demux);
101 m_demux.push_back(demux);
107 int eDVBAdapterLinux::getNumDemux()
109 return m_demux.size();
112 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
114 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
115 while (nr && (i != m_demux.end()))
121 if (i != m_demux.end())
129 int eDVBAdapterLinux::getNumFrontends()
131 return m_frontend.size();
134 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
136 eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
137 while (nr && (i != m_frontend.end()))
143 if (i != m_frontend.end())
151 int eDVBAdapterLinux::exist(int nr)
155 sprintf(filename, "/dev/dvb/adapter%d", nr);
156 if (!stat(filename, &s))
161 eDVBResourceManager::~eDVBResourceManager()
163 if (instance == this)
168 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
170 int num_fe = adapter->getNumFrontends();
171 int num_demux = adapter->getNumDemux();
173 m_adapter.push_back(adapter);
176 for (i=0; i<num_demux; ++i)
178 ePtr<eDVBDemux> demux;
179 if (!adapter->getDemux(demux, i))
180 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
183 for (i=0; i<num_fe; ++i)
185 ePtr<eDVBFrontend> frontend;
186 if (!adapter->getFrontend(frontend, i))
187 m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
191 RESULT eDVBResourceManager::allocateFrontend(const eDVBChannelID &chid, ePtr<eDVBAllocatedFrontend> &fe)
193 /* find first unused frontend. we ignore compatibility for now. */
194 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
197 fe = new eDVBAllocatedFrontend(i);
203 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux)
205 /* find first unused demux which is on same adapter as frontend */
206 for (eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin()); i != m_demux.end(); ++i)
207 if ((!i->m_inuse) && (i->m_adapter == fe->m_adapter))
209 demux = new eDVBAllocatedDemux(i);
215 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
221 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
231 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, ePtr<iDVBChannel> &channel)
233 /* first, check if a channel is already existing. */
235 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
237 if (i->m_channel_id == channelid)
239 channel = i->m_channel;
244 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
246 /* allocate a frontend. */
248 ePtr<eDVBAllocatedFrontend> fe;
250 if (allocateFrontend(channelid, fe))
251 return errNoFrontend;
253 ePtr<eDVBAllocatedDemux> demux;
255 if (allocateDemux(*fe, demux))
260 ch = new eDVBChannel(this, fe, demux);
262 ePtr<iDVBFrontend> myfe;
263 if (!ch->getFrontend(myfe))
266 res = ch->setChannel(channelid);
270 return errChidNotFound;
277 RESULT eDVBResourceManager::allocateRawChannel(ePtr<iDVBChannel> &channel)
279 ePtr<eDVBAllocatedFrontend> fe;
281 if (allocateFrontend(eDVBChannelID(), fe))
282 return errNoFrontend;
284 ePtr<eDVBAllocatedDemux> demux;
286 if (allocateDemux(*fe, demux))
290 ch = new eDVBChannel(this, fe, demux);
292 ePtr<iDVBFrontend> myfe;
293 if (!ch->getFrontend(myfe))
300 RESULT eDVBResourceManager::allocatePVRChannel(int caps)
302 return -1; // will nicht, mag nicht, und das interface ist auch kaputt
305 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
307 eDebug("add channel %p", ch);
308 m_active_channels.push_back(active_channel(chid, ch));
312 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
315 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
317 if (i->m_channel == ch)
319 i = m_active_channels.erase(i);
330 DEFINE_REF(eDVBChannel);
332 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend, eDVBAllocatedDemux *demux): m_state(state_idle), m_mgr(mgr)
334 m_frontend = frontend;
338 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
341 eDVBChannel::~eDVBChannel()
344 m_mgr->removeChannel(this);
347 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
349 eDebug("fe state changed!");
350 int state, ourstate = 0;
351 if (fe->getState(state))
354 if (state == iDVBFrontend::stateLock)
356 eDebug("OURSTATE: ok");
358 } else if (state == iDVBFrontend::stateTuning)
360 eDebug("OURSTATE: tuning");
361 ourstate = state_tuning;
362 } else if (state == iDVBFrontend::stateFailed)
364 eDebug("OURSTATE: failed/unavailable");
365 ourstate = state_unavailable;
367 eFatal("state unknown");
369 if (ourstate != m_state)
372 m_stateChanged(this);
376 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid)
379 m_mgr->removeChannel(this);
384 ePtr<iDVBChannelList> list;
386 if (m_mgr->getChannelList(list))
388 eDebug("no channel list set!");
392 eDebug("tuning to chid: ns: %08x tsid %04x onid %04x",
393 channelid.dvbnamespace.get(), channelid.transport_stream_id.get(), channelid.original_network_id.get());
395 ePtr<iDVBFrontendParameters> feparm;
396 if (list->getChannelFrontendData(channelid, feparm))
398 eDebug("channel not found!");
401 eDebug("allocateChannel: channel found..");
405 eDebug("no frontend to tune!");
409 m_channel_id = channelid;
410 m_mgr->addChannel(channelid, this);
411 m_state = state_tuning;
412 return m_frontend->get().tune(*feparm);
415 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
417 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
421 RESULT eDVBChannel::getState(int &state)
427 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
432 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux)
434 demux = &m_demux->get();
438 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
440 frontend = &m_frontend->get();