diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2017-08-06 13:34:44 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2017-08-06 13:34:44 +0100 |
commit | 661856d0e138e5f1bc6809341b66e69eff903b1b (patch) | |
tree | 7fbf3491052ad94ed64fd49f9a14f19a9928cb54 /p2pvr/devices | |
parent | Drop out local file hanlde for AdHoc's (diff) | |
download | p2pvr-661856d0e138e5f1bc6809341b66e69eff903b1b.tar.bz2 p2pvr-661856d0e138e5f1bc6809341b66e69eff903b1b.tar.xz p2pvr-661856d0e138e5f1bc6809341b66e69eff903b1b.zip |
Unify local/global devices and tuners into a single coherent service
Diffstat (limited to 'p2pvr/devices')
-rw-r--r-- | p2pvr/devices/devices.cpp | 258 | ||||
-rw-r--r-- | p2pvr/devices/devices.h | 69 | ||||
-rw-r--r-- | p2pvr/devices/frontend.cpp | 8 | ||||
-rw-r--r-- | p2pvr/devices/frontend.h | 8 | ||||
-rw-r--r-- | p2pvr/devices/frontends/ofdm.cpp | 18 | ||||
-rw-r--r-- | p2pvr/devices/localDevices.cpp | 195 | ||||
-rw-r--r-- | p2pvr/devices/localDevices.h | 67 | ||||
-rw-r--r-- | p2pvr/devices/mockTuner.cpp | 61 | ||||
-rw-r--r-- | p2pvr/devices/mockTuner.h | 38 | ||||
-rw-r--r-- | p2pvr/devices/tuner.cpp | 103 | ||||
-rw-r--r-- | p2pvr/devices/tuner.h | 37 | ||||
-rw-r--r-- | p2pvr/devices/tunerSendSi.cpp | 2 | ||||
-rw-r--r-- | p2pvr/devices/tunerSendSi.h | 2 | ||||
-rw-r--r-- | p2pvr/devices/tunerSendTs.cpp | 2 | ||||
-rw-r--r-- | p2pvr/devices/tunerSendTs.h | 2 |
15 files changed, 456 insertions, 414 deletions
diff --git a/p2pvr/devices/devices.cpp b/p2pvr/devices/devices.cpp new file mode 100644 index 0000000..541cfa5 --- /dev/null +++ b/p2pvr/devices/devices.cpp @@ -0,0 +1,258 @@ +#include "devices.h" +#include <Ice/Ice.h> +#include "tuner.h" +#include "bindTimerTask.h" +#include <lockHelpers.h> + +namespace P2PVR { +template<typename T> +T * +get_pointer(const IceInternal::Handle<T> & t) BOOST_NOEXCEPT +{ + return t.get(); +} + +class DLL_PRIVATE OpenTuner { + public: + OpenTuner(DVBSI::DeliveryPtr, TunerPtr); + + const DVBSI::DeliveryPtr delivery; + const TunerPtr tuner; + + unsigned int clients; +}; + +DevicesI::Options::Options() : + IceTray::Options("P2PVR Devices") +{ +} + +ICETRAY_OPTIONS(DevicesI::Options, + ("p2pvr.localdevices.frontend", boost::program_options::value(&devices), "Frontend of DVB device(s) to use (/dev/dvb/adapterX/frontendY)") +); + +IceTray::Logging::LoggerPtr DevicesI::logger(LOGMANAGER()->getLogger<DevicesI>()); + +DevicesI::DevicesI() +{ + devices = options->devices; + logger->message(LOG::DEBUG, __PRETTY_FUNCTION__); +} + +DevicesI::~DevicesI() +{ + logger->message(LOG::DEBUG, __PRETTY_FUNCTION__); +} + +TunerPtr +DevicesI::getTuner() +{ + if (devices.empty()) { + throw NoSuitableDeviceAvailable(); + } + for (auto devItr = devices.begin(); devItr != devices.end(); devItr++) { + try { + return new DVB::TunerI(*devItr); + } + catch (...) { + logger->messagebf(LOG::DEBUG, "%s: Failed to open device %s", __PRETTY_FUNCTION__, + *devItr); + } + } + throw NoSuitableDeviceAvailable(); +} + +TunerPtr +DevicesI::getTuner(const DVBSI::DeliveryPtr & delivery) +{ + logger->messagebf(LOG::DEBUG, "%s: Searching for an open sharable tuner (frequency %d)", __PRETTY_FUNCTION__, delivery->Frequency); + Lock(lock); + // Check for an already open tuner which is correctly tuned. + auto existingItr = openDevices.find(delivery->TransportStreamId); + if (existingItr != openDevices.end()) { + existingItr->second->clients += 1; + return existingItr->second->tuner; + } + // Open a tuner and tune it as required. + if (devices.empty()) { + throw NoSuitableDeviceAvailable(); + } + for (auto devItr = devices.begin(); devItr != devices.end(); devItr++) { + try { + TunerPtr tuner = new DVB::TunerI(*devItr); + tuner->TuneTo(delivery); + openDevices.insert({ delivery->TransportStreamId, OpenTunerPtr(new OpenTuner(delivery, tuner)) }); + devices.erase(devItr); + return tuner; + } + catch (...) { + logger->messagebf(LOG::DEBUG, "%s: Failed to open and tune device %s to frequency %d", __PRETTY_FUNCTION__, + *devItr, delivery->Frequency); + } + } + logger->messagebf(LOG::DEBUG, "%s: Failed to open and tune any device to frequency %d", __PRETTY_FUNCTION__, + delivery->Frequency); + throw NoSuitableDeviceAvailable(); +} + +TunerPtr +DevicesI::getTuner(const DeliveryProvider & provider) +{ + ScopeLock(lock) { + if (!openDevices.empty()) { + auto openDevice = openDevices.begin()->second; + openDevice->clients++; + return openDevice->tuner; + } + + } + return getTuner(provider()); +} + +void +DevicesI::releaseTuner(const TunerPtr & tuner) +{ + Lock(lock); + logger->messagebf(LOG::DEBUG, "%s", __PRETTY_FUNCTION__); + auto openTuner = std::find_if(openDevices.begin(), openDevices.end(), [&tuner](const auto & ot) { + return ot.second->tuner == tuner; + }); + if (openTuner == openDevices.end()) { + logger->messagebf(LOG::DEBUG, "%s: Not one of mine", __PRETTY_FUNCTION__); + throw DeviceError(); + } + logger->messagebf(LOG::DEBUG, "%s: Locally owned deivce %s", __PRETTY_FUNCTION__, openTuner->first); + openTuner->second->clients -= 1; + if (openTuner->second->clients == 0) { + openDevices.erase(openTuner); + devices.push_back(openTuner->second->tuner->GetDevice()); + } +} + +void +DevicesI::Scan(const std::string &, const Ice::Current &) +{ + Lock(lock); +} + +void +DevicesI::Add(const std::string & frontend, const Ice::Current &) +{ + Lock(lock); + devices.push_back(frontend); +} + +void +DevicesI::Remove(const std::string & frontend, const Ice::Current &) +{ + Lock(lock); + devices.erase(std::remove(devices.begin(), devices.end(), frontend), devices.end()); +} + +::Ice::Int +DevicesI::TunerCount(const Ice::Current &) +{ + Lock(lock); + return devices.size() + openDevices.size(); +} + +OpenTuner::OpenTuner(DVBSI::DeliveryPtr d, TunerPtr t) : + delivery(d), + tuner(t), + clients(1) +{ +} + +void +DevicesI::finiteTunerOperation(TunerPtr && tuner, const Target & target) +{ + try { + target(tuner); + releaseTuner(tuner); + } + catch (...) { + releaseTuner(tuner); + throw; + } +} + +void +DevicesI::ScanAndSendNetworkInformation(const RawDataClientPrx & target, const ::Ice::Current&) +{ + finiteTunerOperation(getTuner(), boost::bind(&Tuner::ScanAndSendNetworkInformation, _1, target)); +} + +void +DevicesI::SendNetworkInformation(const ::DVBSI::DeliveryPtr & del, const RawDataClientPrx & target, const ::Ice::Current&) +{ + finiteTunerOperation(getTuner(del), boost::bind(&Tuner::SendNetworkInformation, _1, target)); +} + +void +DevicesI::SendBouquetAssociations(const ::DVBSI::DeliveryPtr & del, const RawDataClientPrx & target, const ::Ice::Current &) +{ + finiteTunerOperation(getTuner(del), boost::bind(&Tuner::SendBouquetAssociations, _1, target)); +} + +void +DevicesI::SendServiceDescriptions(const ::DVBSI::DeliveryPtr & del, const RawDataClientPrx & target, const ::Ice::Current&) +{ + finiteTunerOperation(getTuner(del), boost::bind(&Tuner::SendServiceDescriptions, _1, target)); +} + +void +DevicesI::SendProgramAssociationTable(const ::DVBSI::DeliveryPtr & del, const RawDataClientPrx & target, const ::Ice::Current&) +{ + finiteTunerOperation(getTuner(del), boost::bind(&Tuner::SendProgramAssociationTable, _1, target)); +} + +void +DevicesI::SendProgramMap(const ::DVBSI::DeliveryPtr & del, ::Ice::Int pids, const RawDataClientPrx & target, const ::Ice::Current&) +{ + finiteTunerOperation(getTuner(del), boost::bind(&Tuner::SendProgramMap, _1, pids, target)); +} + +void +DevicesI::SendEventInformation(const ::DVBSI::DeliveryPtr & del, const RawDataClientPrx & target, const ::Ice::Current&) +{ + finiteTunerOperation(getTuner(del), boost::bind(&Tuner::SendEventInformation, _1, target)); +} + +::Ice::Int +DevicesI::StartSendingTS(const ::DVBSI::DeliveryPtr & del, const PacketIds & pids, const RawDataClientPrx & target, const ::Ice::Current&) +{ + auto tuner = getTuner(del); + try { + return backgroundOperations.insert({ tuner->StartSendingTS(pids, target), tuner }).first->first; + } + catch (...) { + releaseTuner(tuner); + throw; + } +} + +::Ice::Int +DevicesI::StartSendingSection(const ::DVBSI::DeliveryPtr & del, ::Ice::Int sid, const RawDataClientPrx & target, const ::Ice::Current&) +{ + auto tuner = getTuner(del); + try { + return backgroundOperations.insert({ tuner->StartSendingSection(sid, target), tuner }).first->first; + } + catch (...) { + releaseTuner(tuner); + throw; + } +} + +void +DevicesI::StopSending(::Ice::Int handle, const ::Ice::Current&) +{ + auto tunerItr = backgroundOperations.find(handle); + if (tunerItr != backgroundOperations.end()) { + tunerItr->second->StopSending(handle); + backgroundOperations.erase(handle); + } +} + +} + diff --git a/p2pvr/devices/devices.h b/p2pvr/devices/devices.h new file mode 100644 index 0000000..0d8af11 --- /dev/null +++ b/p2pvr/devices/devices.h @@ -0,0 +1,69 @@ +#ifndef LOCALDEVICES_H +#define LOCALDEVICES_H + +// Local devices implements a device collection (Devices) for any devices physically +// attached to the local machine; that is, can be accessed directly through /dev/dvb/adapterX + +#include <dvb.h> +#include <options.h> +#include <mutex> +#include <visibility.h> +#include <logger.h> +#include <boost/filesystem/path.hpp> + +namespace P2PVR { +class OpenTuner; +class DLL_PUBLIC DevicesI : public Tuners { + public: + class Options : public IceTray::Options { + public: + Options(); + + ICETRAY_OPTIONS_DECLARE; + + std::vector<boost::filesystem::path> devices; + }; + + DevicesI(); + ~DevicesI(); + + virtual void ScanAndSendNetworkInformation(const RawDataClientPrx&, const ::Ice::Current&) override; + virtual void SendNetworkInformation(const ::DVBSI::DeliveryPtr&, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual void SendBouquetAssociations(const ::DVBSI::DeliveryPtr&, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual void SendServiceDescriptions(const ::DVBSI::DeliveryPtr&, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual void SendProgramAssociationTable(const ::DVBSI::DeliveryPtr&, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual void SendProgramMap(const ::DVBSI::DeliveryPtr&, ::Ice::Int, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual void SendEventInformation(const ::DVBSI::DeliveryPtr&, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual ::Ice::Int StartSendingTS(const ::DVBSI::DeliveryPtr&, const PacketIds&, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual ::Ice::Int StartSendingSection(const ::DVBSI::DeliveryPtr&, ::Ice::Int, const RawDataClientPrx&, const ::Ice::Current&) override; + virtual void StopSending(::Ice::Int, const ::Ice::Current&) override; + + void Scan(const std::string & path, const Ice::Current &) override; + void Add(const std::string & frontend, const Ice::Current &) override; + void Remove(const std::string & frontend, const Ice::Current &) override; + ::Ice::Int TunerCount(const Ice::Current &) override; + + private: + typedef boost::function<DVBSI::DeliveryPtr()> DeliveryProvider; + TunerPtr getTuner(); + TunerPtr getTuner(const DeliveryProvider &); + TunerPtr getTuner(const DVBSI::DeliveryPtr &); + void releaseTuner(const TunerPtr &); + + typedef boost::function<void(TunerPtr)> Target; + void finiteTunerOperation(TunerPtr && tuner, const Target &); + + typedef boost::shared_ptr<OpenTuner> OpenTunerPtr; + typedef std::map<Ice::Int, OpenTunerPtr> OpenDevices; + OpenDevices openDevices; + typedef std::map<Ice::Int, TunerPtr> BackgroundOperations; + BackgroundOperations backgroundOperations; + std::vector<boost::filesystem::path> devices; + std::mutex lock; + static IceTray::Logging::LoggerPtr logger; + IceTray::OptionsResolver<Options> options; +}; +} + +#endif + diff --git a/p2pvr/devices/frontend.cpp b/p2pvr/devices/frontend.cpp index c6f258b..1026a20 100644 --- a/p2pvr/devices/frontend.cpp +++ b/p2pvr/devices/frontend.cpp @@ -6,7 +6,7 @@ namespace P2PVR { namespace DVB { -Frontend::Frontend(Tuner * t, const struct dvb_frontend_info & i, IceTray::Logging::LoggerPtr log) : +Frontend::Frontend(TunerI * t, const struct dvb_frontend_info & i, IceTray::Logging::LoggerPtr log) : tuner(t), fe_info(i), logger(log) @@ -28,8 +28,8 @@ Frontend::GetStatus() const { fe_status_t status; if (ioctl(tuner->frontendFD, FE_READ_STATUS, &status) < 0) { - logger->messagebf(LOG::ERR, "Reading frontend %s status failed (%s:%d)", tuner->Device(), strerror(errno), errno); - throw P2PVR::DeviceError(tuner->Device(), strerror(errno), errno); + logger->messagebf(LOG::ERR, "Reading frontend %s status failed (%s:%d)", tuner->GetDevice(), strerror(errno), errno); + throw P2PVR::DeviceError(tuner->GetDevice(), strerror(errno), errno); } return status; } @@ -42,5 +42,5 @@ Frontend::FactoryKey(fe_type t) } } -INSTANTIATEFACTORY(P2PVR::DVB::Frontend, P2PVR::DVB::Tuner *, const struct dvb_frontend_info &); +INSTANTIATEFACTORY(P2PVR::DVB::Frontend, P2PVR::DVB::TunerI *, const struct dvb_frontend_info &); diff --git a/p2pvr/devices/frontend.h b/p2pvr/devices/frontend.h index 4e47c10..63b000d 100644 --- a/p2pvr/devices/frontend.h +++ b/p2pvr/devices/frontend.h @@ -8,12 +8,12 @@ namespace P2PVR { namespace DVB { -class Tuner; +class TunerI; class Frontend { public: typedef boost::function<bool(long)> OnFrequencyFound; - Frontend(Tuner *, const struct dvb_frontend_info &, IceTray::Logging::LoggerPtr); + Frontend(TunerI *, const struct dvb_frontend_info &, IceTray::Logging::LoggerPtr); virtual ~Frontend(); fe_status_t GetStatus() const; @@ -25,12 +25,12 @@ class Frontend { static std::string FactoryKey(fe_type); protected: - const Tuner * tuner; + TunerI * const tuner; const struct dvb_frontend_info fe_info; IceTray::Logging::LoggerPtr logger; }; -typedef AdHoc::Factory<Frontend, Tuner *, const struct dvb_frontend_info &> FrontendFactory; +typedef AdHoc::Factory<Frontend, TunerI *, const struct dvb_frontend_info &> FrontendFactory; typedef boost::shared_ptr<Frontend> FrontendPtr; } } diff --git a/p2pvr/devices/frontends/ofdm.cpp b/p2pvr/devices/frontends/ofdm.cpp index 991996d..e6c3979 100644 --- a/p2pvr/devices/frontends/ofdm.cpp +++ b/p2pvr/devices/frontends/ofdm.cpp @@ -11,7 +11,7 @@ namespace DVB { namespace Frontends { class OFDM : public Frontend { public: - OFDM(Tuner * t, const struct dvb_frontend_info & i) : + OFDM(TunerI * t, const struct dvb_frontend_info & i) : Frontend(t, i, LOGMANAGER()->getLogger<OFDM>()) { } @@ -42,8 +42,8 @@ class OFDM : public Frontend { dvb_frontend_parameters feparams; memset(&feparams, 0, sizeof(dvb_frontend_parameters)); if (ioctl(tuner->frontendFD, FE_GET_FRONTEND, &feparams) < 0) { - logger->messagebf(LOG::ERR, "Reading frontend parameters failed (%s:%d)", tuner->Device(), strerror(errno), errno); - throw P2PVR::DeviceError(tuner->Device(), strerror(errno), errno); + logger->messagebf(LOG::ERR, "Reading frontend parameters failed (%s:%d)", tuner->GetDevice(), strerror(errno), errno); + throw P2PVR::DeviceError(tuner->GetDevice(), strerror(errno), errno); } return feparams; } @@ -57,24 +57,24 @@ class OFDM : public Frontend { } // Was it useful? if (!(status & (FE_HAS_SIGNAL | FE_HAS_CARRIER))) { - logger->messagebf(LOG::ERR, "Tuning of device %s failed (No signal or carrier: 0x%02x)", tuner->Device(), status); - throw P2PVR::DeviceError(tuner->Device(), "No carrier", 0); + logger->messagebf(LOG::ERR, "Tuning of device %s failed (No signal or carrier: 0x%02x)", tuner->GetDevice(), status); + throw P2PVR::DeviceError(tuner->GetDevice(), "No carrier", 0); } // Wait for lock for (int x = tuner->options->LockTimeout / 10; x > 0 && ((status = GetStatus()) & FE_HAS_LOCK) == 0; x -= 1) { usleep(10000); } if (!(status & FE_HAS_LOCK)) { - logger->messagebf(LOG::ERR, "Tuning of device %s failed (%s)", tuner->Device(), "No lock"); - throw P2PVR::DeviceError(tuner->Device(), "No lock", 0); + logger->messagebf(LOG::ERR, "Tuning of device %s failed (%s)", tuner->GetDevice(), "No lock"); + throw P2PVR::DeviceError(tuner->GetDevice(), "No lock", 0); } } void SetParameters(const dvb_frontend_parameters & feparams) const { if (ioctl(tuner->frontendFD, FE_SET_FRONTEND, &feparams) < 0) { - logger->messagebf(LOG::ERR, "Tuning of device %s failed (%s:%d)", tuner->Device(), strerror(errno), errno); - throw P2PVR::DeviceError(tuner->Device(), strerror(errno), errno); + logger->messagebf(LOG::ERR, "Tuning of device %s failed (%s:%d)", tuner->GetDevice(), strerror(errno), errno); + throw P2PVR::DeviceError(tuner->GetDevice(), strerror(errno), errno); } } diff --git a/p2pvr/devices/localDevices.cpp b/p2pvr/devices/localDevices.cpp deleted file mode 100644 index ac13a29..0000000 --- a/p2pvr/devices/localDevices.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include "localDevices.h" -#include <Ice/Ice.h> -#include "tuner.h" -#include "bindTimerTask.h" - -namespace P2PVR { -LocalDevicesI::Devices LocalDevicesI::devices; -std::mutex LocalDevicesI::lock; - -LocalDevicesI::Options::Options() : - IceTray::Options("P2PVR Devices") -{ -} - -ICETRAY_OPTIONS(LocalDevicesI::Options, - ("p2pvr.localdevices.frontend", boost::program_options::value(&devices), "Frontend of DVB device(s) to use (/dev/dvb/adapterX/frontendY)") -); - -IceTray::Logging::LoggerPtr LocalDevicesI::logger(LOGMANAGER()->getLogger<LocalDevicesI>()); - -LocalDevicesI::LocalDevicesI(Ice::ObjectAdapterPtr adapter, IceUtil::TimerPtr t) : - timer(t), - clientCheck(new BindTimerTask(boost::bind(&LocalDevicesI::ClientCheck, this, adapter))) -{ - for (auto & device : options->devices) { - devices.insert({ device, nullptr }); - } - logger->message(LOG::DEBUG, __PRETTY_FUNCTION__); - timer->scheduleRepeated(clientCheck, IceUtil::Time::seconds(30)); -} - -LocalDevicesI::~LocalDevicesI() -{ - logger->message(LOG::DEBUG, __PRETTY_FUNCTION__); - timer->cancel(clientCheck); -} - -void -LocalDevicesI::ClientCheck(Ice::ObjectAdapterPtr adapter) -{ - std::lock_guard<std::mutex> g(lock); - for (auto & device : devices) { - if (device.second && device.second->tuner->GetLastUsedTime() < time(NULL) - 30) { - logger->messagebf(LOG::DEBUG, "%s: Device %s no longer in use", __PRETTY_FUNCTION__, device.first); - auto id = device.second->tuner->ice_getIdentity(); - if (adapter->find(id)) { - adapter->remove(id); - } - device.second.reset(); - } - } -} - -TunerPrx -LocalDevicesI::GetTunerSpecific(const DVBSI::DeliveryPtr & delivery, const Ice::Current & ice) -{ - std::lock_guard<std::mutex> g(lock); - logger->messagebf(LOG::DEBUG, "%s: Searching for an open sharable tuner (frequency %d)", __PRETTY_FUNCTION__, delivery->Frequency); - auto openTuner = std::find_if(devices.begin(), devices.end(), [delivery](const Devices::value_type & ot) { - return ot.second && !ot.second->openedPrivate && ot.second->delivery && ot.second->delivery->Frequency == delivery->Frequency; - }); - if (openTuner != devices.end()) { - openTuner->second->clients += 1; - return openTuner->second->tuner; - } - - openTuner = std::find_if(devices.begin(), devices.end(), [](const Devices::value_type & ot) { return !ot.second; }); - if (openTuner == devices.end()) { - logger->messagebf(LOG::DEBUG, "%s: None suitable and none free (frequency %d)", - __PRETTY_FUNCTION__, delivery->Frequency); - throw NoSuitableDeviceAvailable(); - } - - logger->messagebf(LOG::DEBUG, "%s: Opening a sharable tuner (frequency %d, frontend %s)", - __PRETTY_FUNCTION__, delivery->Frequency, openTuner->first); - PrivateTunerPtr t = new DVB::Tuner(openTuner->first); - t->TuneTo(delivery, ice); - auto tuner = PrivateTunerPrx::checkedCast(ice.adapter->addWithUUID(t)); - openTuner->second = OpenTunerPtr(new OpenTuner(delivery, tuner, false)); - - logger->messagebf(LOG::DEBUG, "%s: Tuned, returning (frequency %d, frontend %s)", - __PRETTY_FUNCTION__, delivery->Frequency, openTuner->first); - return tuner; -} - -TunerPrx -LocalDevicesI::GetTunerAny(const DVBSI::DeliveryPtr & delivery, const Ice::Current & ice) -{ - std::lock_guard<std::mutex> g(lock); - logger->messagebf(LOG::DEBUG, "%s: Searching for an open sharable tuner any frequency", __PRETTY_FUNCTION__); - auto openTuner = std::find_if(devices.begin(), devices.end(), [delivery](const Devices::value_type & ot) { - return ot.second && !ot.second->openedPrivate && ot.second->delivery; - }); - if (openTuner != devices.end()) { - openTuner->second->clients += 1; - return openTuner->second->tuner; - } - - openTuner = std::find_if(devices.begin(), devices.end(), [](const Devices::value_type & ot) { return !ot.second; }); - if (openTuner == devices.end()) { - logger->messagebf(LOG::DEBUG, "%s: None suitable and none free (frequency %d)", - __PRETTY_FUNCTION__, delivery->Frequency); - throw NoSuitableDeviceAvailable(); - } - - logger->messagebf(LOG::DEBUG, "%s: Opening a sharable tuner (frequency %d, frontend %s)", - __PRETTY_FUNCTION__, delivery->Frequency, openTuner->first); - PrivateTunerPtr t = new DVB::Tuner(openTuner->first); - t->TuneTo(delivery, ice); - auto tuner = PrivateTunerPrx::checkedCast(ice.adapter->addWithUUID(t)); - openTuner->second = OpenTunerPtr(new OpenTuner(delivery, tuner, false)); - - logger->messagebf(LOG::DEBUG, "%s: Tuned, returning (frequency %d, frontend %s)", - __PRETTY_FUNCTION__, delivery->Frequency, openTuner->first); - return tuner; -} - -PrivateTunerPrx -LocalDevicesI::GetPrivateTuner(short , const Ice::Current & ice) -{ - std::lock_guard<std::mutex> g(lock); - logger->messagebf(LOG::DEBUG, "%s: Opening a private tuner", __PRETTY_FUNCTION__); - auto openTuner = std::find_if(devices.begin(), devices.end(), [](const Devices::value_type & ot) { return !ot.second; }); - if (openTuner == devices.end()) { - logger->messagebf(LOG::DEBUG, "%s: None free", __PRETTY_FUNCTION__); - throw NoSuitableDeviceAvailable(); - } - - logger->messagebf(LOG::DEBUG, "%s: Opening a private tuner (frontend %s)", - __PRETTY_FUNCTION__, openTuner->first); - auto tuner = PrivateTunerPrx::checkedCast(ice.adapter->addWithUUID(new DVB::Tuner(openTuner->first))); - openTuner->second = OpenTunerPtr(new OpenTuner(NULL, tuner, true)); - - return tuner; -} - -void -LocalDevicesI::ReleaseTuner(const TunerPrx & tuner, const Ice::Current & ice) -{ - std::lock_guard<std::mutex> g(lock); - logger->messagebf(LOG::DEBUG, "%s", __PRETTY_FUNCTION__); - auto openTuner = std::find_if(devices.begin(), devices.end(), [tuner](const Devices::value_type & ot) { - return ot.second && ot.second->tuner == tuner; - }); - if (openTuner == devices.end()) { - logger->messagebf(LOG::DEBUG, "%s: Not one of mine", __PRETTY_FUNCTION__); - return; - } - logger->messagebf(LOG::DEBUG, "%s: Locally owned deivce %s", __PRETTY_FUNCTION__, openTuner->first); - openTuner->second->clients -= 1; - if (openTuner->second->clients == 0) { - auto id = tuner->ice_getIdentity(); - if (ice.adapter->find(id)) { - ice.adapter->remove(id); - } - openTuner->second.reset(); - } -} - -int -LocalDevicesI::TunerCount(const Ice::Current &) -{ - std::lock_guard<std::mutex> g(lock); - return devices.size(); -} - -void -LocalDevicesI::Scan(const Ice::Current &) -{ - std::lock_guard<std::mutex> g(lock); -} - -void -LocalDevicesI::Add(const std::string & frontend, const Ice::Current &) -{ - std::lock_guard<std::mutex> g(lock); - devices.insert(Devices::value_type(frontend, OpenTunerPtr())); -} - -void -LocalDevicesI::Remove(const std::string & frontend, const Ice::Current &) -{ - std::lock_guard<std::mutex> g(lock); - devices.erase(frontend); -} - -LocalDevicesI::OpenTuner::OpenTuner(DVBSI::DeliveryPtr d, PrivateTunerPrx t, bool op) : - openedPrivate(op), - delivery(d), - tuner(t), - clients(1) -{ -} -} - diff --git a/p2pvr/devices/localDevices.h b/p2pvr/devices/localDevices.h deleted file mode 100644 index 0fd4ad2..0000000 --- a/p2pvr/devices/localDevices.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef LOCALDEVICES_H -#define LOCALDEVICES_H - -// Local devices implements a device collection (Devices) for any devices physically -// attached to the local machine; that is, can be accessed directly through /dev/dvb/adapterX - -#include <dvb.h> -#include <options.h> -#include <mutex> -#include <visibility.h> -#include <IceUtil/Timer.h> -#include <logger.h> - -namespace P2PVR { -class DLL_PUBLIC LocalDevicesI : public LocalDevices { - public: - class Options : public IceTray::Options { - public: - Options(); - - ICETRAY_OPTIONS_DECLARE; - - std::vector<std::string> devices; - }; - - LocalDevicesI(Ice::ObjectAdapterPtr adapter, IceUtil::TimerPtr); - ~LocalDevicesI(); - - TunerPrx GetTunerSpecific(const DVBSI::DeliveryPtr &, const Ice::Current &); - TunerPrx GetTunerAny(const DVBSI::DeliveryPtr &, const Ice::Current &); - PrivateTunerPrx GetPrivateTuner(short type, const Ice::Current &); - void ReleaseTuner(const TunerPrx &, const Ice::Current &); - int TunerCount(const Ice::Current &); - - void Scan(const Ice::Current &); - void Add(const std::string & frontend, const Ice::Current &); - void Remove(const std::string & frontend, const Ice::Current &); - - private: - // Reference to global timer - IceUtil::TimerPtr timer; - IceUtil::TimerTaskPtr clientCheck; - - // Check that registered clients haven't silently gone away - DLL_PRIVATE void ClientCheck(Ice::ObjectAdapterPtr adapter); - - class DLL_PRIVATE OpenTuner { - public: - OpenTuner(DVBSI::DeliveryPtr, PrivateTunerPrx, bool); - - const bool openedPrivate; - const DVBSI::DeliveryPtr delivery; - const PrivateTunerPrx tuner; - - unsigned int clients; - }; - typedef boost::shared_ptr<OpenTuner> OpenTunerPtr; - typedef std::map<std::string, OpenTunerPtr> Devices; - static Devices devices; - static std::mutex lock; - static IceTray::Logging::LoggerPtr logger; - IceTray::OptionsResolver<Options> options; -}; -} - -#endif - diff --git a/p2pvr/devices/mockTuner.cpp b/p2pvr/devices/mockTuner.cpp index 4430bc4..1316b6d 100644 --- a/p2pvr/devices/mockTuner.cpp +++ b/p2pvr/devices/mockTuner.cpp @@ -31,6 +31,7 @@ ResourceFile(pmt); ResourceFile(vid); int MockTuner::eventSet = 0; +int MockTuner::senderId = 1; IceTray::Logging::LoggerPtr MockTuner::logger = LOGMANAGER()->getLogger<MockTuner>(); @@ -40,16 +41,21 @@ MockTuner::SetEventsSet(int n) eventSet = n; } -MockTuner::MockTuner() : - senderId(1) +MockTuner::MockTuner(Ice::CommunicatorPtr c) : + ic(c) { } -void MockTuner::TuneTo(const DVBSI::DeliveryPtr &, const Ice::Current&) +void MockTuner::TuneTo(const DVBSI::DeliveryPtr &) { } -int MockTuner::GetStatus(const Ice::Current&) +int MockTuner::GetStatus() +{ + return 0; +} + +std::string MockTuner::GetDevice() { return 0; } @@ -80,11 +86,11 @@ Ice::ByteSeq MockTuner::Decompress(const Ice::ByteSeq & dataxz) return data; } -void MockTuner::DecompressAndSendPackets(const Ice::ByteSeq & dataxz, const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) const +void MockTuner::DecompressAndSendPackets(const Ice::ByteSeq & dataxz, const P2PVR::RawDataClientPrx & client) const { logger->messagebf(LOG::DEBUG, "%s: deserialize", __PRETTY_FUNCTION__); std::list<Ice::ByteSeq> packets; - auto istrm = Ice::createInputStream(ice.adapter->getCommunicator(), Decompress(dataxz)); + auto istrm = Ice::createInputStream(ic, Decompress(dataxz)); istrm->read(packets); logger->messagebf(LOG::DEBUG, "%s: send", __PRETTY_FUNCTION__); @@ -95,42 +101,42 @@ void MockTuner::DecompressAndSendPackets(const Ice::ByteSeq & dataxz, const P2PV logger->messagebf(LOG::DEBUG, "%s: complete", __PRETTY_FUNCTION__); } -void MockTuner::ScanAndSendNetworkInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +void MockTuner::ScanAndSendNetworkInformation(const P2PVR::RawDataClientPrx & client) { - DecompressAndSendPackets(network, client, ice); + DecompressAndSendPackets(network, client); } -void MockTuner::SendNetworkInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +void MockTuner::SendNetworkInformation(const P2PVR::RawDataClientPrx & client) { - DecompressAndSendPackets(network, client, ice); + DecompressAndSendPackets(network, client); } -void MockTuner::SendBouquetAssociations(const P2PVR::RawDataClientPrx &, const Ice::Current&) +void MockTuner::SendBouquetAssociations(const P2PVR::RawDataClientPrx &) { } -void MockTuner::SendServiceDescriptions(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +void MockTuner::SendServiceDescriptions(const P2PVR::RawDataClientPrx & client) { - DecompressAndSendPackets(services, client, ice); + DecompressAndSendPackets(services, client); } -void MockTuner::SendProgramMap(Ice::Int, const P2PVR::RawDataClientPrx &, const Ice::Current&) +void MockTuner::SendProgramMap(Ice::Int, const P2PVR::RawDataClientPrx &) { } -void MockTuner::SendProgramAssociationTable(const P2PVR::RawDataClientPrx &, const Ice::Current&) +void MockTuner::SendProgramAssociationTable(const P2PVR::RawDataClientPrx &) { } -void MockTuner::SendEventInformation(const P2PVR::RawDataClientPrx & client, const Ice::Current & ice) +void MockTuner::SendEventInformation(const P2PVR::RawDataClientPrx & client) { - DecompressAndSendPackets(eventSet == 0 ? events1 : events2, client, ice); + DecompressAndSendPackets(eventSet == 0 ? events1 : events2, client); } -void MockTuner::SendLoop(const P2PVR::RawDataClientPrx & t, const Ice::ByteSeq & dataxz, const Ice::Current & ice) const +void MockTuner::SendLoop(const P2PVR::RawDataClientPrx & t, const Ice::ByteSeq & dataxz) const { std::list<Ice::ByteSeq> packets; - auto istrm = Ice::createInputStream(ice.adapter->getCommunicator(), Decompress(dataxz)); + auto istrm = Ice::createInputStream(ic, Decompress(dataxz)); istrm->read(packets); logger->messagebf(LOG::DEBUG, "%s: loop over %d packets", __PRETTY_FUNCTION__, packets.size()); auto p = packets.begin(); @@ -149,23 +155,23 @@ void MockTuner::SendLoop(const P2PVR::RawDataClientPrx & t, const Ice::ByteSeq & } -int MockTuner::StartSendingTS(const P2PVR::PacketIds &, const P2PVR::RawDataClientPrx & t, const Ice::Current & ice) +int MockTuner::StartSendingTS(const P2PVR::PacketIds &, const P2PVR::RawDataClientPrx & t) { - return senders.insert({senderId++, new boost::thread(&MockTuner::SendLoop, this, t, vid, ice)}).first->first; + return senders.insert({senderId++, new boost::thread(&MockTuner::SendLoop, this, t, vid)}).first->first; } -int MockTuner::StartSendingSection(Ice::Int sid, const P2PVR::RawDataClientPrx & t, const Ice::Current & ice) +int MockTuner::StartSendingSection(Ice::Int sid, const P2PVR::RawDataClientPrx & t) { switch (sid) { case 0: // pat - return senders.insert({senderId++, new boost::thread(&MockTuner::SendLoop, this, t, pat, ice)}).first->first; + return senders.insert({senderId++, new boost::thread(&MockTuner::SendLoop, this, t, pat)}).first->first; case 100: // sample pmt - return senders.insert({senderId++, new boost::thread(&MockTuner::SendLoop, this, t, pmt, ice)}).first->first; + return senders.insert({senderId++, new boost::thread(&MockTuner::SendLoop, this, t, pmt)}).first->first; } throw std::runtime_error("I don't have a sample for that"); } -void MockTuner::StopSending(int s, const Ice::Current &) +void MockTuner::StopSending(int s) { logger->messagebf(LOG::DEBUG, "%s: stop %d", __PRETTY_FUNCTION__, s); auto sitr = senders.find(s); @@ -175,11 +181,6 @@ void MockTuner::StopSending(int s, const Ice::Current &) senders.erase(sitr); } } - -Ice::Long MockTuner::GetLastUsedTime(const Ice::Current&) -{ - return time(NULL); -} } } diff --git a/p2pvr/devices/mockTuner.h b/p2pvr/devices/mockTuner.h index 73ab27c..d0db11e 100644 --- a/p2pvr/devices/mockTuner.h +++ b/p2pvr/devices/mockTuner.h @@ -9,38 +9,38 @@ namespace P2PVR { namespace Testing { -class DLL_PUBLIC MockTuner : public PrivateTuner { +class DLL_PUBLIC MockTuner : public Tuner { public: - MockTuner(); + MockTuner(Ice::CommunicatorPtr); - void TuneTo(const DVBSI::DeliveryPtr &, const Ice::Current&); - int GetStatus(const Ice::Current&); + void TuneTo(const DVBSI::DeliveryPtr &) override; + int GetStatus() override; + std::string GetDevice() override; - void ScanAndSendNetworkInformation(const RawDataClientPrx & client, const Ice::Current&); - void SendNetworkInformation(const RawDataClientPrx & client, const Ice::Current&); - void SendBouquetAssociations(const RawDataClientPrx & client, const Ice::Current&); - void SendServiceDescriptions(const RawDataClientPrx & client, const Ice::Current&); - void SendProgramMap(Ice::Int pid, const RawDataClientPrx & client, const Ice::Current&); - void SendProgramAssociationTable(const RawDataClientPrx & client, const Ice::Current&); - void SendEventInformation(const RawDataClientPrx & client, const Ice::Current&); + void ScanAndSendNetworkInformation(const RawDataClientPrx & client) override; + void SendNetworkInformation(const RawDataClientPrx & client) override; + void SendBouquetAssociations(const RawDataClientPrx & client) override; + void SendServiceDescriptions(const RawDataClientPrx & client) override; + void SendProgramMap(Ice::Int pid, const RawDataClientPrx & client) override; + void SendProgramAssociationTable(const RawDataClientPrx & client) override; + void SendEventInformation(const RawDataClientPrx & client) override; - int StartSendingTS(const PacketIds & pids, const RawDataClientPrx & client, const Ice::Current &); - int StartSendingSection(Ice::Int pid, const RawDataClientPrx & client, const Ice::Current &); - void StopSending(int handle, const Ice::Current &); - - Ice::Long GetLastUsedTime(const Ice::Current&); + int StartSendingTS(const PacketIds & pids, const RawDataClientPrx & client) override; + int StartSendingSection(Ice::Int pid, const RawDataClientPrx & client) override; + void StopSending(int handle) override; static void SetEventsSet(int n); protected: static Ice::ByteSeq Decompress(const Ice::ByteSeq &); static void LZMA_ASSERT(int ret_xz); - void DecompressAndSendPackets(const Ice::ByteSeq &, const RawDataClientPrx &, const Ice::Current&) const; - void SendLoop(const RawDataClientPrx & t, const Ice::ByteSeq & dataxz, const Ice::Current & ice) const; + void DecompressAndSendPackets(const Ice::ByteSeq &, const RawDataClientPrx &) const; + void SendLoop(const RawDataClientPrx & t, const Ice::ByteSeq & dataxz) const; static int eventSet; std::map<int, boost::thread *> senders; - int senderId; + static int senderId; + Ice::CommunicatorPtr ic; static IceTray::Logging::LoggerPtr logger; }; diff --git a/p2pvr/devices/tuner.cpp b/p2pvr/devices/tuner.cpp index 73dcd67..bb27a44 100644 --- a/p2pvr/devices/tuner.cpp +++ b/p2pvr/devices/tuner.cpp @@ -8,19 +8,19 @@ #include <linux/dvb/dmx.h> #include <boost/tuple/tuple.hpp> #include <cxxabi.h> +#include <lockHelpers.h> #include "tunerSendSi.h" #include "tunerSendTs.h" namespace P2PVR { namespace DVB { -IceTray::Logging::LoggerPtr Tuner::logger = LOGMANAGER()->getLogger<Tuner>(); +IceTray::Logging::LoggerPtr TunerI::logger = LOGMANAGER()->getLogger<TunerI>(); -Tuner::Tuner(const boost::filesystem::path & df) : +TunerI::TunerI(const boost::filesystem::path & df) : deviceFrontend(df), deviceRoot(df.branch_path()), frontendFD(deviceFrontend, O_RDWR), - backgroundThread(NULL), - lastUsedTime(time(NULL)) + backgroundThread(NULL) { struct dvb_frontend_info fe_info; if (ioctl(frontendFD, FE_GET_INFO, &fe_info) < 0) { @@ -31,7 +31,7 @@ Tuner::Tuner(const boost::filesystem::path & df) : deviceRoot, frontend->Info().name, frontend->Type()); } -Tuner::~Tuner() +TunerI::~TunerI() { { std::lock_guard<std::mutex> g(lock); @@ -47,27 +47,25 @@ Tuner::~Tuner() } void -Tuner::TuneTo(const DVBSI::DeliveryPtr & mp, const Ice::Current&) +TunerI::TuneTo(const DVBSI::DeliveryPtr & mp) { frontend->TuneTo(mp); } int -Tuner::GetStatus(const Ice::Current &) +TunerI::GetStatus() { - time(&lastUsedTime); return frontend->GetStatus(); } std::string -Tuner::Device() const +TunerI::GetDevice() { - time(&lastUsedTime); return deviceRoot.string(); } int -Tuner::OpenDemux() const +TunerI::OpenDemux() const { int demux = open((deviceRoot / "demux0").string().c_str(), O_RDWR | O_NONBLOCK); if (demux < 0) { @@ -77,12 +75,11 @@ Tuner::OpenDemux() const } void -Tuner::ScanAndSendNetworkInformation(const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::ScanAndSendNetworkInformation(const RawDataClientPrx & client) { - time(&lastUsedTime); - frontend->FrequencyScan([this, &client, &ice](long) { + frontend->FrequencyScan([this, &client](long) { try { - return (SendPID(0x10, client, ice) > 0); + return (SendPID(0x10, client) > 0); } catch (const std::exception & ex) { char * buf = __cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL); @@ -98,57 +95,53 @@ Tuner::ScanAndSendNetworkInformation(const RawDataClientPrx & client, const Ice: } void -Tuner::SendNetworkInformation(const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::SendNetworkInformation(const RawDataClientPrx & client) { - SendPID(0x10, client, ice); + SendPID(0x10, client); } void -Tuner::SendBouquetAssociations(const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::SendBouquetAssociations(const RawDataClientPrx & client) { - SendPID(0x11, client, ice); + SendPID(0x11, client); } void -Tuner::SendServiceDescriptions(const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::SendServiceDescriptions(const RawDataClientPrx & client) { - SendPID(0x11, client, ice); + SendPID(0x11, client); } void -Tuner::SendProgramMap(Ice::Int pid, const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::SendProgramMap(Ice::Int pid, const RawDataClientPrx & client) { - SendPID(pid, client, ice); + SendPID(pid, client); } void -Tuner::SendProgramAssociationTable(const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::SendProgramAssociationTable(const RawDataClientPrx & client) { - SendPID(0x00, client, ice); + SendPID(0x00, client); } void -Tuner::SendEventInformation(const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::SendEventInformation(const RawDataClientPrx & client) { - SendPID(0x12, client, ice); + SendPID(0x12, client); } uint64_t -Tuner::SendPID(int pid, const RawDataClientPrx & client, const Ice::Current & ice) const +TunerI::SendPID(int pid, const RawDataClientPrx & client) const { - time(&lastUsedTime); logger->messagebf(LOG::DEBUG, "%s: pid = 0x%x", __PRETTY_FUNCTION__, pid); - if (ice.con) { - ice.con->createProxy(client->ice_getIdentity()); - } AdHoc::FileUtils::FileHandle demux(OpenDemux()); RequestPID(pid, demux); return ReadDemuxAndSend(demux, client); } void -Tuner::RequestPID(int pid, int demux) const +TunerI::RequestPID(int pid, int demux) const { setBufferSize(demux, options->DemuxTableBufferSize); struct dmx_sct_filter_params sctFilterParams; @@ -162,7 +155,7 @@ Tuner::RequestPID(int pid, int demux) const } uint64_t -Tuner::ReadDemuxAndSend(int demux, const RawDataClientPrx & _client) const +TunerI::ReadDemuxAndSend(int demux, const RawDataClientPrx & _client) const { logger->messagebf(LOG::DEBUG, "%s: begin", __PRETTY_FUNCTION__); struct pollfd ufd; @@ -194,7 +187,6 @@ Tuner::ReadDemuxAndSend(int demux, const RawDataClientPrx & _client) const buf.resize(n); client->NewData(buf); - time(&lastUsedTime); } while (!client->IsFinished()); auto packetsSent = client->PacketsSent(); @@ -204,12 +196,11 @@ Tuner::ReadDemuxAndSend(int demux, const RawDataClientPrx & _client) const } int -Tuner::StartSendingSection(int pid, const RawDataClientPrx & client, const Ice::Current &) +TunerI::StartSendingSection(int pid, const RawDataClientPrx & client) { - time(&lastUsedTime); logger->message(LOG::DEBUG, __PRETTY_FUNCTION__); - std::lock_guard<std::mutex> g(lock); + Lock(lock); int demux = backgroundClients.insert(BackgroundClients::value_type(OpenDemux(), BackgroundClient(new SendSi(client)))).first->first; RequestPID(pid, demux); @@ -218,18 +209,14 @@ Tuner::StartSendingSection(int pid, const RawDataClientPrx & client, const Ice:: } int -Tuner::StartSendingTS(const PacketIds & pids, const RawDataClientPrx & client, const Ice::Current & ice) +TunerI::StartSendingTS(const PacketIds & pids, const RawDataClientPrx & client) { - time(&lastUsedTime); logger->message(LOG::DEBUG, __PRETTY_FUNCTION__); if (pids.empty()) { throw DeviceError("demux", "Packet Id list cannot be empty", 0); } - if (ice.con) { - ice.con->createProxy(client->ice_getIdentity()); - } - std::lock_guard<std::mutex> g(lock); + Lock(lock); int demux = backgroundClients.insert(BackgroundClients::value_type(OpenDemux(), BackgroundClient(new SendTs(client)))).first->first; @@ -270,7 +257,7 @@ Tuner::StartSendingTS(const PacketIds & pids, const RawDataClientPrx & client, c } void -Tuner::setBufferSize(int demux, unsigned long size) +TunerI::setBufferSize(int demux, unsigned long size) { if (ioctl(demux, DMX_SET_BUFFER_SIZE, size)) { logger->messagebf(LOG::ERR, "%s: DMX_SET_BUFFER_SIZE to %d failed (%d: %s)", __PRETTY_FUNCTION__, size, errno, strerror(errno)); @@ -280,9 +267,8 @@ Tuner::setBufferSize(int demux, unsigned long size) } void -Tuner::StopSending(int handle, const Ice::Current &) +TunerI::StopSending(int handle) { - time(&lastUsedTime); logger->message(LOG::DEBUG, __PRETTY_FUNCTION__); std::lock_guard<std::mutex> g(lock); if (backgroundClients.find(handle) != backgroundClients.end()) { @@ -292,15 +278,15 @@ Tuner::StopSending(int handle, const Ice::Current &) } void -Tuner::startSenderThread() +TunerI::startSenderThread() { if (!backgroundThread) { - backgroundThread = new std::thread(&Tuner::senderThread, this); + backgroundThread = new std::thread(&TunerI::senderThread, this); } } void -Tuner::senderThread() +TunerI::senderThread() { lock.lock(); while (!backgroundClients.empty()) { @@ -311,7 +297,6 @@ Tuner::senderThread() FD_SET(c.first, &rfds); } lock.unlock(); - time(&lastUsedTime); struct timeval tv { 2, 0 }; switch (select(n, &rfds, NULL, NULL, &tv)) { @@ -361,38 +346,32 @@ Tuner::senderThread() backgroundThread = NULL; logger->messagebf(LOG::DEBUG, "%s: Unlocking", __PRETTY_FUNCTION__); lock.unlock(); -} - -Ice::Long -Tuner::GetLastUsedTime(const Ice::Current &) -{ - return lastUsedTime; } -Tuner::IDataSender::IDataSender(const RawDataClientPrx & c) : +TunerI::IDataSender::IDataSender(const RawDataClientPrx & c) : _packetsSent(0), client(c) { } -Tuner::IDataSender::~IDataSender() +TunerI::IDataSender::~IDataSender() { } uint64_t -Tuner::IDataSender::PacketsSent() const +TunerI::IDataSender::PacketsSent() const { return _packetsSent; } -Tuner::Options::Options() : +TunerI::Options::Options() : IceTray::Options("P2PVR Tuner Options") { } namespace po = boost::program_options; -ICETRAY_OPTIONS(Tuner::Options, +ICETRAY_OPTIONS(TunerI::Options, ("p2pvr.tuner.tuningtimeout", po::value(&TuningTimeout)->default_value(500), "Timeout for a DVB frontend to tune (ms, default 500ms)") ("p2pvr.tuner.locktimeout", po::value(&LockTimeout)->default_value(2000), diff --git a/p2pvr/devices/tuner.h b/p2pvr/devices/tuner.h index b4d92b3..695b322 100644 --- a/p2pvr/devices/tuner.h +++ b/p2pvr/devices/tuner.h @@ -20,7 +20,7 @@ namespace Frontends { class OFDM; } -class Tuner : public PrivateTuner { +class TunerI : public Tuner { public: class IDataSender { public: @@ -38,30 +38,28 @@ class Tuner : public PrivateTuner { typedef boost::shared_ptr<IDataSender> BackgroundClient; typedef std::map<int, BackgroundClient> BackgroundClients; - Tuner(const boost::filesystem::path & deviceFrontend); - ~Tuner(); + TunerI(const boost::filesystem::path & deviceFrontend); + ~TunerI(); - void TuneTo(const DVBSI::DeliveryPtr &, const Ice::Current&); - int GetStatus(const Ice::Current&); - std::string Device() const; + void TuneTo(const DVBSI::DeliveryPtr &) override; + int GetStatus() override; + std::string GetDevice() override; - void ScanAndSendNetworkInformation(const RawDataClientPrx & client, const Ice::Current&); - void SendNetworkInformation(const RawDataClientPrx & client, const Ice::Current&); - void SendBouquetAssociations(const RawDataClientPrx & client, const Ice::Current&); - void SendServiceDescriptions(const RawDataClientPrx & client, const Ice::Current&); - void SendProgramMap(Ice::Int pid, const RawDataClientPrx & client, const Ice::Current&); - void SendProgramAssociationTable(const RawDataClientPrx & client, const Ice::Current&); - void SendEventInformation(const RawDataClientPrx & client, const Ice::Current&); + void ScanAndSendNetworkInformation(const RawDataClientPrx & client) override; + void SendNetworkInformation(const RawDataClientPrx & client) override; + void SendBouquetAssociations(const RawDataClientPrx & client) override; + void SendServiceDescriptions(const RawDataClientPrx & client) override; + void SendProgramMap(Ice::Int pid, const RawDataClientPrx & client) override; + void SendProgramAssociationTable(const RawDataClientPrx & client) override; + void SendEventInformation(const RawDataClientPrx & client) override; - int StartSendingTS(const PacketIds & pids, const RawDataClientPrx & client, const Ice::Current &); - int StartSendingSection(Ice::Int pid, const RawDataClientPrx & client, const Ice::Current &); - void StopSending(int handle, const Ice::Current &); - - Ice::Long GetLastUsedTime(const Ice::Current&); + int StartSendingTS(const PacketIds & pids, const RawDataClientPrx & client) override; + int StartSendingSection(Ice::Int pid, const RawDataClientPrx & client) override; + void StopSending(int handle) override; private: int OpenDemux() const; - uint64_t SendPID(int pid, const RawDataClientPrx & client, const Ice::Current &) const; + uint64_t SendPID(int pid, const RawDataClientPrx & client) const; void RequestPID(int pid, int fd) const; uint64_t ReadDemuxAndSend(int fd, const RawDataClientPrx & client) const; void startSenderThread(); @@ -75,7 +73,6 @@ class Tuner : public PrivateTuner { std::thread * backgroundThread; std::mutex lock; - mutable time_t lastUsedTime; FrontendPtr frontend; static IceTray::Logging::LoggerPtr logger; diff --git a/p2pvr/devices/tunerSendSi.cpp b/p2pvr/devices/tunerSendSi.cpp index 0215e47..3e09aaf 100644 --- a/p2pvr/devices/tunerSendSi.cpp +++ b/p2pvr/devices/tunerSendSi.cpp @@ -8,7 +8,7 @@ namespace DVB { IceTray::Logging::LoggerPtr SendSi::logger(LOGMANAGER()->getLogger<SendSi>()); SendSi::SendSi(const RawDataClientPrx & c) : - Tuner::IDataSender(c->ice_collocationOptimized(false)) + TunerI::IDataSender(c->ice_collocationOptimized(false)) { } diff --git a/p2pvr/devices/tunerSendSi.h b/p2pvr/devices/tunerSendSi.h index 8b146ff..688fb2a 100644 --- a/p2pvr/devices/tunerSendSi.h +++ b/p2pvr/devices/tunerSendSi.h @@ -6,7 +6,7 @@ namespace P2PVR { namespace DVB { -class SendSi : public Tuner::IDataSender { +class SendSi : public TunerI::IDataSender { public: SendSi(const P2PVR::RawDataClientPrx &); ~SendSi(); diff --git a/p2pvr/devices/tunerSendTs.cpp b/p2pvr/devices/tunerSendTs.cpp index 8005311..fef418f 100644 --- a/p2pvr/devices/tunerSendTs.cpp +++ b/p2pvr/devices/tunerSendTs.cpp @@ -11,7 +11,7 @@ namespace DVB { IceTray::Logging::LoggerPtr SendTs::logger(LOGMANAGER()->getLogger<SendTs>()); SendTs::SendTs(const RawDataClientPrx & c) : - Tuner::IDataSender(c->ice_collocationOptimized(false)) + TunerI::IDataSender(c->ice_collocationOptimized(false)) { buffer.reserve(TARGET_BUFFER_SIZE); } diff --git a/p2pvr/devices/tunerSendTs.h b/p2pvr/devices/tunerSendTs.h index cd74198..bbec0a9 100644 --- a/p2pvr/devices/tunerSendTs.h +++ b/p2pvr/devices/tunerSendTs.h @@ -6,7 +6,7 @@ namespace P2PVR { namespace DVB { -class SendTs : public Tuner::IDataSender { +class SendTs : public TunerI::IDataSender { public: SendTs(const P2PVR::RawDataClientPrx &); ~SendTs(); |