#include "../maintenance.h" #include #include #include #include #include #include namespace P2PVR { class SiNetworkInformationMerger : public DVBSI::SiNetworkInformationParser { public: SiNetworkInformationMerger(DB::Connection * d, IceTray::Logging::LoggerPtr l) : dbc(d), logger(l) { } bool HandleTable(const ::DVBSI::NetworkPtr & n) { logger->messagebf(LOG::DEBUG, "Network Id: %d Name: %s", n->NetworkId, *n->Name); for (const auto & ts : n->TransportStreams) { logger->messagebf(LOG::DEBUG, "\tTransport Stream Id: %d Original Network Id: %d", ts->TransportStreamId, ts->OriginalNetworkId); for (const auto & s : ts->Services) { logger->messagebf(LOG::DEBUG, "\t\tService Id: %d Service Type: %d", s.ServiceId, s.Type); } if (ts->Terrestrial) { logger->messagebf(LOG::DEBUG, "\t\tDVB-T: Frequency: %d", ts->Terrestrial->Frequency); } } DB::TablePatch mergeNetwork; mergeNetwork.dest = "networks"; Slicer::SerializeAny(n, dbc, mergeNetwork); DB::TablePatch mergeTransportStreams; mergeTransportStreams.dest = "transportstreams"; Slicer::SerializeAny(n->TransportStreams, dbc, mergeTransportStreams); mergeDelivery<::DVBSI::TerrestrialDeliveryPtr, &::DVBSI::NetworkTransportStream::Terrestrial>("delivery_dvbt", n); mergeDelivery<::DVBSI::SatelliteDeliveryPtr, &::DVBSI::NetworkTransportStream::Satellite>("delivery_dvbs", n); mergeDelivery<::DVBSI::CableDeliveryPtr, &::DVBSI::NetworkTransportStream::Cable>("delivery_dvbc", n); ::DVBSI::NetworkServiceList services; for (const auto & ts : n->TransportStreams) { for (const auto & s : ts->Services) { if (std::find_if(services.begin(), services.end(), [&s](const auto & es) { return es.ServiceId == s.ServiceId; }) == services.end()) { services.push_back(s); } } } DB::TablePatch mergeServices; mergeServices.dest = "services"; Slicer::SerializeAny(services, dbc, mergeServices); return false; } private: typedef ::DVBSI::NetworkTransportStream NTS; template void mergeDelivery(const std::string & table, ::DVBSI::NetworkPtr n) { DB::TablePatch tp; tp.dest = table; std::vector dels; for (const auto & s : n->TransportStreams) { if (auto d = s.get()->*member) { if (std::find_if(dels.begin(), dels.end(), [&d](const auto & ed) { return ed->Frequency == d->Frequency; }) == dels.end()) { dels.push_back(d); } } } Slicer::SerializeAny(dels, dbc, tp); } DB::Connection * dbc; IceTray::Logging::LoggerPtr logger; }; void MaintenanceI::UpdateNetwork(short, const Ice::Current & ice) { auto dbc = db->get(); auto ic = ice.adapter->getCommunicator(); auto devs = TunersPrx::checkedCast(ice.adapter->createProxy(ic->stringToIdentity("Devices"))); auto si = SIPrx::checkedCast(ice.adapter->createProxy(ic->stringToIdentity("SI"))); auto siparser = new SiNetworkInformationMerger(dbc.get(), logger); TemporaryIceAdapterObject parser(ice.adapter, siparser); if (!devs) { throw std::runtime_error("bad proxy(s)"); } DB::TransactionScope tx(dbc.get()); auto transport = si->GetDeliveryForSi(); if (transport) { devs->SendNetworkInformation(transport, parser); return; } // If we can't do that, do a complete scan devs->ScanAndSendNetworkInformation(parser); } }