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 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
236 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
238 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
239 if (i->m_channel_id == channelid)
241 // eDebug("found shared channel..");
242 channel = i->m_channel;
247 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
249 /* allocate a frontend. */
251 ePtr<eDVBAllocatedFrontend> fe;
253 if (allocateFrontend(channelid, fe))
254 return errNoFrontend;
256 ePtr<eDVBAllocatedDemux> demux;
258 if (allocateDemux(*fe, demux))
263 ch = new eDVBChannel(this, fe, demux);
265 ePtr<iDVBFrontend> myfe;
266 if (!ch->getFrontend(myfe))
269 res = ch->setChannel(channelid);
273 return errChidNotFound;
280 RESULT eDVBResourceManager::allocateRawChannel(ePtr<iDVBChannel> &channel)
282 ePtr<eDVBAllocatedFrontend> fe;
284 if (allocateFrontend(eDVBChannelID(), fe))
285 return errNoFrontend;
287 ePtr<eDVBAllocatedDemux> demux;
289 if (allocateDemux(*fe, demux))
293 ch = new eDVBChannel(this, fe, demux);
295 ePtr<iDVBFrontend> myfe;
296 if (!ch->getFrontend(myfe))
303 RESULT eDVBResourceManager::allocatePVRChannel(int caps)
305 return -1; // will nicht, mag nicht, und das interface ist auch kaputt
308 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
310 eDebug("add channel %p", ch);
311 m_active_channels.push_back(active_channel(chid, ch));
315 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
318 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
320 if (i->m_channel == ch)
322 i = m_active_channels.erase(i);
333 DEFINE_REF(eDVBChannel);
335 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend, eDVBAllocatedDemux *demux): m_state(state_idle), m_mgr(mgr)
337 m_frontend = frontend;
341 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
344 eDVBChannel::~eDVBChannel()
347 m_mgr->removeChannel(this);
350 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
352 eDebug("fe state changed!");
353 int state, ourstate = 0;
354 if (fe->getState(state))
357 if (state == iDVBFrontend::stateLock)
359 eDebug("OURSTATE: ok");
361 } else if (state == iDVBFrontend::stateTuning)
363 eDebug("OURSTATE: tuning");
364 ourstate = state_tuning;
365 } else if (state == iDVBFrontend::stateFailed)
367 eDebug("OURSTATE: failed/unavailable");
368 ourstate = state_unavailable;
370 eFatal("state unknown");
372 if (ourstate != m_state)
375 m_stateChanged(this);
379 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid)
382 m_mgr->removeChannel(this);
387 ePtr<iDVBChannelList> list;
389 if (m_mgr->getChannelList(list))
391 eDebug("no channel list set!");
395 eDebug("tuning to chid: ns: %08x tsid %04x onid %04x",
396 channelid.dvbnamespace.get(), channelid.transport_stream_id.get(), channelid.original_network_id.get());
398 ePtr<iDVBFrontendParameters> feparm;
399 if (list->getChannelFrontendData(channelid, feparm))
401 eDebug("channel not found!");
404 eDebug("allocateChannel: channel found..");
408 eDebug("no frontend to tune!");
412 m_channel_id = channelid;
413 m_mgr->addChannel(channelid, this);
414 m_state = state_tuning;
415 return m_frontend->get().tune(*feparm);
418 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
420 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
424 RESULT eDVBChannel::getState(int &state)
430 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
435 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux)
437 demux = &m_demux->get();
441 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
443 frontend = &m_frontend->get();