/// <summary> /// Cleans up the controller /// </summary> public void DeInit() { Log.Info("Controller: DeInit."); try { if (heartBeatMonitorThread != null) { if (!Service1.HasThreadCausedAnUnhandledException(heartBeatMonitorThread)) { if (heartBeatMonitorThread.IsAlive) { Log.Info("Controller: HeartBeat monitor stopped..."); try { heartBeatMonitorThread.Abort(); } catch (Exception) {} } } } //stop the RTSP streamer server if (_streamer != null) { Log.Info("Controller: stop streamer..."); _streamer.Stop(); _streamer = null; Log.Info("Controller: streamer stopped..."); } //stop the recording scheduler if (_scheduler != null) { Log.Info("Controller: stop scheduler..."); _scheduler.Stop(); _scheduler = null; Log.Info("Controller: scheduler stopped..."); } //stop the epg grabber if (_epgGrabber != null) { Log.Info("Controller: stop epg grabber..."); _epgGrabber.Stop(); _epgGrabber = null; Log.Info("Controller: epg stopped..."); } //clean up the tv cards FreeCards(); Gentle.Common.CacheManager.Clear(); if (GlobalServiceProvider.Instance.IsRegistered<ITvServerEvent>()) { GlobalServiceProvider.Instance.Remove<ITvServerEvent>(); } } catch (Exception ex) { Log.Error("TvController: Deinit failed - {0}", ex.Message); } }
/// <summary> /// Initalizes the controller. /// It will update the database with the cards found on this system /// start the epg grabber and scheduler /// and check if its supposed to be a master or slave controller /// </summary> private bool InitController() { if (GlobalServiceProvider.Instance.IsRegistered<ITvServerEvent>()) { GlobalServiceProvider.Instance.Remove<ITvServerEvent>(); } GlobalServiceProvider.Instance.Add<ITvServerEvent>(this); try { //string threadname = Thread.CurrentThread.Name; //if (string.IsNullOrEmpty(threadname)) // Thread.CurrentThread.Name = "TVController"; //load the database connection string from the config file Log.Info(@"{0}\gentle.config", PathManager.GetDataPath); string connectionString, provider; GetDatabaseConnectionString(out connectionString, out provider); string ConnectionLog = connectionString.Remove(connectionString.IndexOf(@"Password="******"Controller: using {0} database connection: {1}", provider, ConnectionLog); Gentle.Framework.ProviderFactory.SetDefaultProviderConnectionString(connectionString); _cards = new Dictionary<int, ITvCardHandler>(); _localCardCollection = new TvCardCollection(this); //log all local ip adresses, usefull for debugging problems Log.Write("Controller: started at {0}", Dns.GetHostName()); IPHostEntry local = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress ipaddress in local.AddressList) { // Show only IPv4 family addresses if (ipaddress.AddressFamily == AddressFamily.InterNetwork) { Log.Info("Controller: local ip address:{0}", ipaddress.ToString()); } } //get all registered servers from the database IList<Server> servers; try { servers = Server.ListAll(); } catch (Exception ex) { Log.Error("Controller: Failed to fetch tv servers from database - {0}", Utils.BlurConnectionStringPassword(ex.Message)); return false; } // find ourself foreach (Server server in servers) { if (IsLocal(server.HostName)) { Log.Info("Controller: server running on {0}", server.HostName); _ourServer = server; break; } } //we do not exist yet? if (_ourServer == null) { //then add ourself to the server if (servers.Count == 0) { //there are no other servers so we are the master one. Log.Info("Controller: create new server in database"); _ourServer = new Server(false, Dns.GetHostName(), RtspStreaming.DefaultPort); _ourServer.IsMaster = true; _isMaster = true; _ourServer.Persist(); Log.Info("Controller: new server created for {0} master:{1} ", Dns.GetHostName(), _isMaster); } else { Log.Error( "Controller: sorry, master/slave server setups are not supported. Since there is already another server in the db, we exit here."); return false; } } _isMaster = _ourServer.IsMaster; //enumerate all tv cards in this pc... TvBusinessLayer layer = new TvBusinessLayer(); _maxFreeCardsToTry = Int32.Parse(layer.GetSetting("timeshiftMaxFreeCardsToTry", "0").Value); for (int i = 0; i < _localCardCollection.Cards.Count; ++i) { //for each card, check if its already mentioned in the database bool found = false; IList<Card> cards = _ourServer.ReferringCard(); foreach (Card card in cards) { if (card.DevicePath == _localCardCollection.Cards[i].DevicePath) { found = true; break; } } if (!found) { // card is not yet in the database, so add it Log.Info("Controller: add card:{0}", _localCardCollection.Cards[i].Name); layer.AddCard(_localCardCollection.Cards[i].Name, _localCardCollection.Cards[i].DevicePath, _ourServer); } } //notify log about cards from the database which are removed from the pc IList<Card> cardsInDbs = Card.ListAll(); int cardsInstalled = _localCardCollection.Cards.Count; foreach (Card dbsCard in cardsInDbs) { if (dbsCard.ReferencedServer().IdServer == _ourServer.IdServer) { bool found = false; for (int cardNumber = 0; cardNumber < cardsInstalled; ++cardNumber) { if (dbsCard.DevicePath == _localCardCollection.Cards[cardNumber].DevicePath) { Card cardDB = layer.GetCardByDevicePath(_localCardCollection.Cards[cardNumber].DevicePath); bool cardEnabled = cardDB.Enabled; bool cardPresent = _localCardCollection.Cards[cardNumber].CardPresent; if (cardEnabled && cardPresent) { ITVCard unknownCard = _localCardCollection.Cards[cardNumber]; if (unknownCard is TvCardBase) { TvCardBase card = (TvCardBase)unknownCard; if (card.PreloadCard) { try { Log.Info("Controller: preloading card :{0}", card.Name); card.BuildGraph(); if (unknownCard is TvCardAnalog) { ((TvCardAnalog)unknownCard).ReloadCardConfiguration(); } } catch (Exception ex) { Log.Error("failed to preload card '{0}', ex = {1}", card.Name, ex); } } else { Log.Info("Controller: NOT preloading card :{0}", card.Name); } } else { Log.Info("Controller: NOT preloading card :{0}", unknownCard.Name); } } found = true; break; } } if (!found) { Log.Info("Controller: card not found :{0}", dbsCard.Name); for (int i = 0; i < _localCardCollection.Cards.Count; ++i) { if (_localCardCollection.Cards[i].DevicePath == dbsCard.DevicePath) { _localCardCollection.Cards[i].CardPresent = false; break; } } // Fix mantis 0002790: Bad behavior when card count for IPTV = 0 if (dbsCard.Name.StartsWith("MediaPortal IPTV Source Filter")) { CardRemove(dbsCard.IdCard); } } } } Dictionary<int, ITVCard> localcards = new Dictionary<int, ITVCard>(); cardsInDbs = Card.ListAll(); foreach (Card card in cardsInDbs) { if (IsLocal(card.ReferencedServer().HostName)) { for (int x = 0; x < _localCardCollection.Cards.Count; ++x) { if (_localCardCollection.Cards[x].DevicePath == card.DevicePath) { localcards[card.IdCard] = _localCardCollection.Cards[x]; break; } } } } Log.Info("Controller: setup hybrid cards"); IList<CardGroup> cardgroups = CardGroup.ListAll(); foreach (CardGroup group in cardgroups) { IList<CardGroupMap> cards = group.CardGroupMaps(); HybridCardGroup hybridCardGroup = new HybridCardGroup(); foreach (CardGroupMap card in cards) { if (localcards.ContainsKey(card.IdCard)) { localcards[card.IdCard].IsHybrid = true; Log.WriteFile("Hybrid card: " + localcards[card.IdCard].Name + " (" + group.Name + ")"); HybridCard hybridCard = hybridCardGroup.Add(card.IdCard, localcards[card.IdCard]); localcards[card.IdCard] = hybridCard; } } } cardsInDbs = Card.ListAll(); foreach (Card dbsCard in cardsInDbs) { if (localcards.ContainsKey(dbsCard.IdCard)) { ITVCard card = localcards[dbsCard.IdCard]; TvCardHandler tvcard = new TvCardHandler(dbsCard, card); _cards[dbsCard.IdCard] = tvcard; } // remove any old timeshifting TS files try { string TimeShiftPath = dbsCard.TimeShiftFolder; if (string.IsNullOrEmpty(dbsCard.TimeShiftFolder)) { TimeShiftPath = String.Format(@"{0}\Team MediaPortal\MediaPortal TV Server\timeshiftbuffer", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); } if (!Directory.Exists(TimeShiftPath)) { Log.Info("Controller: creating timeshifting folder {0} for card \"{1}\"", TimeShiftPath, dbsCard.Name); Directory.CreateDirectory(TimeShiftPath); } Log.Debug("Controller: card {0}: current timeshiftpath = {1}", dbsCard.Name, TimeShiftPath); if (TimeShiftPath != null) { string[] files = Directory.GetFiles(TimeShiftPath); foreach (string file in files) { try { FileInfo fInfo = new FileInfo(file); bool delFile = (fInfo.Extension.ToUpperInvariant().IndexOf(".TSBUFFER") == 0); if (!delFile) { delFile = (fInfo.Extension.ToUpperInvariant().IndexOf(".TS") == 0) && (fInfo.Name.ToUpperInvariant().IndexOf("TSBUFFER") > 0); } if (delFile) File.Delete(fInfo.FullName); } catch (IOException) {} } } } catch (Exception exd) { Log.Info("Controller: Error cleaning old ts buffer - {0}", exd.Message); } } Log.Info("Controller: setup streaming"); _streamer = new RtspStreaming(_ourServer.HostName, _ourServer.RtspPort); if (_isMaster) { _epgGrabber = new EpgGrabber(this); _epgGrabber.Start(); _scheduler = new Scheduler(this); _scheduler.Start(); } SetupHeartbeatThread(); ExecutePendingDeletions(); // Re-evaluate program states Log.Info("Controller: recalculating program states"); TvDatabase.Program.ResetAllStates(); Schedule.SynchProgramStatesForAll(); } catch (Exception ex) { Log.Write("TvControllerException: {0}\r\n{1}", ex.ToString(), ex.StackTrace); return false; } Log.Info("Controller: initalized"); return true; }