protected virtual bool CanCardTuneChannel(ITvCardHandler cardHandler, Channel dbChannel, IChannel tuningDetail) { int cardId = cardHandler.DataBaseCard.IdCard; bool isCardEnabled = IsCardEnabled(cardHandler); if (!isCardEnabled) { //not enabled, so skip the card if (LogEnabled) { Log.Info("CanCardTuneChannel: card:{0} type:{1} is disabled", cardId, cardHandler.Type); } return(false); } bool isCardPresent = IsCardPresent(cardId); if (!isCardPresent) { Log.Error("CanCardTuneChannel: unable to connect to slave controller at:{0}", cardHandler.DataBaseCard.ReferencedServer().HostName); return(false); } if (!cardHandler.Tuner.CanTune(tuningDetail)) { //card cannot tune to this channel, so skip it if (LogEnabled) { Log.Info("CanCardTuneChannel: card:{0} type:{1} cannot tune to channel", cardId, cardHandler.Type); } return(false); } //check if channel is mapped to this card and that the mapping is not for "Epg Only" bool isChannelMappedToCard = CardAllocationCache.IsChannelMappedToCard(dbChannel, cardHandler.DataBaseCard); if (!isChannelMappedToCard) { if (LogEnabled) { Log.Info("CanCardTuneChannel: card:{0} type:{1} channel not mapped", cardId, cardHandler.Type); } return(false); } return(true); }
private void DoSetChannelStates(IDictionary<int, ITvCardHandler> cards, ICollection<Channel> channels, ICollection<IUser> allUsers, IController tvController) { lock (_lock) { Stopwatch stopwatch = Stopwatch.StartNew(); try { //construct list of all cards we can use to tune to the new channel Log.Debug("Controller: DoSetChannelStates for {0} channels", channels.Count); if (allUsers == null || allUsers.Count == 0) { return; // no users, no point in continuing. } IDictionary<int, ChannelState> timeshiftingAndRecordingStates = null; ICollection<ITvCardHandler> cardHandlers = cards.Values; foreach (Channel ch in channels) { if (!ch.VisibleInGuide) { UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } ICollection<IChannel> tuningDetails = CardAllocationCache.GetTuningDetailsByChannelId(ch); bool isValidTuningDetails = IsValidTuningDetails(tuningDetails); if (!isValidTuningDetails) { UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } foreach (IChannel tuningDetail in tuningDetails) { foreach (ITvCardHandler cardHandler in cardHandlers) { //check if card is enabled if (!cardHandler.DataBaseCard.Enabled) { //not enabled, so skip the card UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } if (!cardHandler.Tuner.CanTune(tuningDetail)) { //card cannot tune to this channel, so skip it UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } //check if channel is mapped to this card and that the mapping is not for "Epg Only" bool isChannelMappedToCard = CardAllocationCache.IsChannelMappedToCard(ch, cardHandler.DataBaseCard);//, channelMapping); if (!isChannelMappedToCard) { UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } if (!tuningDetail.FreeToAir && !cardHandler.DataBaseCard.CAM) { UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } //ok card could be used to tune to this channel //now we check if its free... CheckTransponderAllUsers(ch, allUsers, cardHandler, tuningDetail); } //while card end } //foreach tuningdetail end //only query once if (timeshiftingAndRecordingStates == null) { Stopwatch stopwatchTimeshiftingAndRecording = Stopwatch.StartNew(); timeshiftingAndRecordingStates = tvController.GetAllTimeshiftingAndRecordingChannels(); stopwatchTimeshiftingAndRecording.Stop(); Log.Info("ChannelStates.GetAllTimeshiftingAndRecordingChannels took {0} msec", stopwatchTimeshiftingAndRecording.ElapsedMilliseconds); } UpdateRecOrTSChannelStateForUsers(ch, allUsers, timeshiftingAndRecordingStates); } RemoveAllTunableChannelStates(allUsers); } catch (ThreadAbortException) { Log.Info("ChannelState.DoSetChannelStates: thread obsolete and aborted."); } catch (InvalidOperationException tex) { Log.Error("ChannelState.DoSetChannelStates: Possible race condition occured setting channel states - {0}", tex); } catch (Exception ex) { Log.Error("ChannelState.DoSetChannelStates: An unknown error occured while setting channel states - {0}\n{1}", ex.Message, ex); } finally { stopwatch.Stop(); Log.Info("ChannelStates.DoSetChannelStates took {0} msec", stopwatch.ElapsedMilliseconds); } } }
/// <summary> /// Gets a list of all available cards which can receive the channel specified /// List is sorted. /// </summary> /// <returns>list containg all cards which can receive the channel</returns> public List <CardDetail> GetAvailableCardsForChannel(IDictionary <int, ITvCardHandler> cards, Channel dbChannel, ref IUser user, out IDictionary <int, TvResult> cardsUnAvailable) { Stopwatch stopwatch = Stopwatch.StartNew(); cardsUnAvailable = new Dictionary <int, TvResult>(); try { //Log.Info("GetAvailableCardsForChannel st {0}", Environment.StackTrace); //construct list of all cards we can use to tune to the new channel var cardsAvailable = new List <CardDetail>(); if (LogEnabled) { Log.Info("GetAvailableCardsForChannel: find card for channel {0}", dbChannel.DisplayName); } else { Log.Debug("GetAvailableCardsForChannel: find card for channel {0}", dbChannel.DisplayName); } //get the tuning details for the channel ICollection <IChannel> tuningDetails = CardAllocationCache.GetTuningDetailsByChannelId(dbChannel);// _businessLayer.GetTuningChannelsByDbChannel(dbChannel); bool isValidTuningDetails = IsValidTuningDetails(tuningDetails); if (!isValidTuningDetails) { //no tuning details?? if (LogEnabled) { Log.Info("GetAvailableCardsForChannel: No tuning details for channel:{0}", dbChannel.DisplayName); } return(cardsAvailable); } if (LogEnabled) { Log.Info("GetAvailableCardsForChannel: got {0} tuning details for {1}", tuningDetails.Count, dbChannel.DisplayName); } int number = 0; ICollection <ITvCardHandler> cardHandlers = cards.Values; foreach (IChannel tuningDetail in tuningDetails) { cardsUnAvailable.Clear(); number++; if (LogEnabled) { Log.Info("GetAvailableCardsForChannel: channel #{0} {1} ", number, tuningDetail.ToString()); } foreach (ITvCardHandler cardHandler in cardHandlers) { int cardId = cardHandler.DataBaseCard.IdCard; if (cardsUnAvailable.ContainsKey(cardId)) { if (LogEnabled) { Log.Info("GetAvailableCardsForChannel: card:{0} has already been queried, skipping.", cardId); } continue; } if (!CanCardTuneChannel(cardHandler, dbChannel, tuningDetail)) { AddCardUnAvailable(ref cardsUnAvailable, cardId, TvResult.ChannelNotMappedToAnyCard); continue; } if (!CanCardDecodeChannel(cardHandler, tuningDetail)) { AddCardUnAvailable(ref cardsUnAvailable, cardId, TvResult.ChannelIsScrambled); continue; } //ok card could be used to tune to this channel //Check if card is currently tuned to same transponder bool isSameTransponder = IsSameTransponder(cardHandler, tuningDetail); if (LogEnabled) { Log.Info("GetAvailableCardsForChannel: card:{0} type:{1} can tune to channel", cardId, cardHandler.Type); } int nrOfOtherUsers = NumberOfOtherUsersOnCurrentCard(cardHandler, user); var cardInfo = new CardDetail(cardId, cardHandler.DataBaseCard, tuningDetail, isSameTransponder, nrOfOtherUsers); cardsAvailable.Add(cardInfo); } } //sort cards cardsAvailable.SortStable(); if (LogEnabled) { Log.Info("GetAvailableCardsForChannel: found {0} card(s) for channel", cardsAvailable.Count); } return(cardsAvailable); } catch (Exception ex) { Log.Write(ex); return(null); } finally { stopwatch.Stop(); Log.Debug("GetAvailableCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds); } }