#include "../maintenance.h" #include #include #include #include #include #include class SiNetworkInformationMerger : public SiNetworkInformationParser { public: SiNetworkInformationMerger(DB::Connection * d, IceTray::Logging::LoggerPtr l) : dbc(d), logger(l) { } bool HandleTable(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("delivery_dvbt", n); mergeDelivery("delivery_dvbs", n); mergeDelivery("delivery_dvbc", n); DVBSI::NetworkServiceList services; for (const auto & ts : n->TransportStreams) { for (const auto & s : ts->Services) { services.push_back(s); } } DB::TablePatch mergeServices; mergeServices.dest = "services"; Slicer::SerializeAny(services, dbc, mergeServices); return false; } private: 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) { dels.push_back(d); } } Slicer::SerializeAny(dels, dbc, tp); } DB::Connection * dbc; IceTray::Logging::LoggerPtr logger; }; void Maintenance::UpdateNetwork(short type, const Ice::Current & ice) { auto dbc = db->get(); auto ic = ice.adapter->getCommunicator(); auto devs = P2PVR::DevicesPrx::checkedCast(ice.adapter->createProxy(ic->stringToIdentity("GlobalDevices"))); auto si = P2PVR::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) { P2PVR::TunerPrx tuner; try { tuner = devs->GetTunerAny(transport); tuner->SendNetworkInformation(parser); devs->ReleaseTuner(tuner); return; } catch (const P2PVR::NoSuitableDeviceAvailable &) { logger->messagebf(LOG::WARNING, "%s: Failed to get a suitable tuner", __PRETTY_FUNCTION__); throw; } catch (const std::exception & ex) { logger->messagebf(LOG::WARNING, "%s: Failed to fetch network information: %s", __PRETTY_FUNCTION__, ex.what()); devs->ReleaseTuner(tuner); throw; } catch (...) { logger->messagebf(LOG::WARNING, "%s: Failed to fetch network information", __PRETTY_FUNCTION__); devs->ReleaseTuner(tuner); throw; } } // If we can't do that, do a complete scan auto tuner = devs->GetPrivateTuner(type); tuner->ScanAndSendNetworkInformation(parser); devs->ReleaseTuner(tuner); }