private void DoSetChannelStates(Dictionary<int, ITvCardHandler> cards, ICollection<Channel> channels, bool checkTransponders, IList<IUser> allUsers, TVController tvController) { 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. } TvBusinessLayer layer = new TvBusinessLayer(); Dictionary<int, ChannelState> TSandRecStates = null; Dictionary<int, ITvCardHandler>.ValueCollection cardHandlers = cards.Values; IDictionary<int, IList<int>> channelMapping = GetChannelMapping(); IDictionary<int, IList<IChannel>> tuningChannelMapping = GetTuningChannels(); foreach (Channel ch in channels) { if (!ch.VisibleInGuide) { UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } //get the tuning details for the channel IList<IChannel> tuningDetails; tuningChannelMapping.TryGetValue(ch.IdChannel, out tuningDetails); bool isValidTuningDetails = IsValidTuningDetails(tuningDetails); if (!isValidTuningDetails) { UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } foreach (IChannel tuningDetail in tuningDetails) { foreach (ITvCardHandler cardHandler in cardHandlers) { int cardId = cardHandler.DataBaseCard.IdCard; //check if card is enabled if (!cardHandler.DataBaseCard.Enabled) { //not enabled, so skip the card //Log.Info("Controller: card:{0} type:{1} is disabled", cardId, tvcard.Type); UpdateChannelStateUsers(allUsers, ChannelState.nottunable, ch.IdChannel); continue; } if (!cardHandler.Tuner.CanTune(tuningDetail)) { //card cannot tune to this channel, so skip it //Log.Info("Controller: card:{0} type:{1} cannot tune to channel", cardId, tvcard.Type); 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 = 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... int decryptLimit = cardHandler.DataBaseCard.DecryptLimit; CheckTransponderAllUsers(ch, allUsers, cards, cardHandler, decryptLimit, cardId, tuningDetail, checkTransponders); } //while card end } //foreach tuningdetail end //only query once if (TSandRecStates == null) { Stopwatch stopwatchTsRec = Stopwatch.StartNew(); TSandRecStates = tvController.GetAllTimeshiftingAndRecordingChannels(); stopwatchTsRec.Stop(); Log.Info("ChannelStates.GetAllTimeshiftingAndRecordingChannels took {0} msec", stopwatchTsRec.ElapsedMilliseconds); } UpdateRecOrTSChannelStateForUsers(ch, allUsers, TSandRecStates); } RemoveAllTunableChannelStates(allUsers); } catch (InvalidOperationException tex) { Log.Error("ChannelState: Possible race condition occured setting channel states - {0}", tex.StackTrace); } catch (Exception ex) { Log.Error("ChannelState: An unknown error occured while setting channel states - {0}\n{1}", ex.Message, ex.StackTrace); } finally { stopwatch.Stop(); Log.Info("ChannelStates.DoSetChannelStates took {0} msec", stopwatch.ElapsedMilliseconds); } }