Beispiel #1
0
 private static void SetTunedCardState(ITvCardHandler tvcard)
 {
     lock (tvcard.Tuner.CardReservationsLock)
     {
         tvcard.Tuner.CardTuneState = CardTuneState.Tuned;
     }
 }
Beispiel #2
0
        public TvResult Tune(ITvCardHandler tvcard, ref IUser user, IChannel channel, int idChannel, ICardTuneReservationTicket ticket)
        {
            TvResult tvResult = TvResult.AllCardsBusy;
            bool     ticketFound;
            bool     isTuningPending = CardReservationHelper.GetIsTuningPending(tvcard, ticket, out ticketFound);

            try
            {
                if (isTuningPending && ticketFound)
                {
                    tvResult = tvcard.Tuner.Tune(ref user, channel, idChannel);

                    bool succes = (tvResult == TvResult.Succeeded);
                    if (succes)
                    {
                        if (!OnStartTune(user))
                        {
                            tvResult = TvResult.AllCardsBusy;
                        }
                    }
                    CardReservationHelper.SetCardStateBasedOnTVresult(tvcard, tvResult);
                }
                else // state is not tuning, some other card tune session is busy.
                {
                }
            }
            finally
            {
                CardReservationHelper.RemoveTuneTicket(tvcard, ticket, ticketFound);
                tvcard.Tuner.CleanUpPendingTune(ticket.PendingSubchannel);
            }
            return(tvResult);
        }
Beispiel #3
0
        private bool IsCamAbleToDecryptChannel(IUser user, ITvCardHandler tvcard, IChannel tuningDetail, int decryptLimit)
        {
            if (!tuningDetail.FreeToAir)
            {
                bool isCamAbleToDecryptChannel = true;
                if (decryptLimit > 0)
                {
                    int camDecrypting = NumberOfChannelsDecrypting(tvcard);

                    //Check if the user is currently occupying a decoding slot and subtract that from the number of channels it is decoding.
                    if (user.CardId == tvcard.DataBaseCard.IdCard)
                    {
                        bool isFreeToAir = IsFreeToAir(tvcard, ref user);
                        if (!isFreeToAir)
                        {
                            int numberOfUsersOnCurrentChannel = GetNumberOfUsersOnCurrentChannel(tvcard, user);

                            //Only subtract the slot the user is currently occupying if he is the only user occupying the slot.
                            if (numberOfUsersOnCurrentChannel == 1)
                            {
                                --camDecrypting;
                            }
                        }
                    }
                    //check if cam is capable of descrambling an extra channel
                    isCamAbleToDecryptChannel = (camDecrypting < decryptLimit);
                }

                return(isCamAbleToDecryptChannel);
            }
            return(true);
        }
Beispiel #4
0
        public static bool GetIsTuningPending(ITvCardHandler tvcard, ICardTuneReservationTicket ticket, out bool ticketFound)
        {
            bool isTuningPending;
            bool cardStopStateIdle;

            lock (tvcard.Tuner.CardReservationsLock)
            {
                cardStopStateIdle = (tvcard.Tuner.CardStopState == CardStopState.Idle);
                isTuningPending   = (tvcard.Tuner.CardTuneState == CardTuneState.TunePending);

                ticketFound = (tvcard.Tuner.ReservationsForTune.Contains(ticket));

                if (isTuningPending && cardStopStateIdle)
                {
                    if (ticketFound)
                    {
                        tvcard.Tuner.CardTuneState = CardTuneState.Tuning;
                    }
                    else
                    {
                        //_cardTuneState = CardTuneState.TunePending;
                    }
                }
            }

            if (ticket == null)
            {
                Log.Debug("GetIsTuningPending: ticket is null!");
            }

            return(isTuningPending && cardStopStateIdle);
        }
        private void CheckTransponderAllUsers(Channel ch, IList <IUser> allUsers, Dictionary <int, ITvCardHandler> cards,
                                              ITvCardHandler tvcard,
                                              int decryptLimit, int cardId, IChannel tuningDetail,
                                              bool checkTransponders)
        {
            for (int i = 0; i < allUsers.Count; i++)
            {
                IUser user = allUsers[i];

                //ignore admin users, like scheduler
                if (user.IsAdmin)
                {
                    continue;
                }

                bool checkTransponder = CheckTransponder(user, tvcard, decryptLimit, tvcard.DataBaseCard.IdCard, tuningDetail);
                if (checkTransponder)
                {
                    UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
                }
                else
                {
                    UpdateChannelStateUser(user, ChannelState.nottunable, ch.IdChannel);
                }
            } //foreach allusers end
        }
    private bool IsCamAbleToDecryptChannel(IUser user, ITvCardHandler tvcard, IChannel tuningDetail, int decryptLimit)
    {
      if (!tuningDetail.FreeToAir)
      {
        bool isCamAbleToDecryptChannel = true;
        if (decryptLimit > 0)
        {
          int camDecrypting = NumberOfChannelsDecrypting(tvcard);

          //Check if the user is currently occupying a decoding slot and subtract that from the number of channels it is decoding.
          if (user.CardId == tvcard.DataBaseCard.IdCard)
          {
            bool isFreeToAir = IsFreeToAir(tvcard, ref user);
            if (!isFreeToAir)
            {
              int numberOfUsersOnCurrentChannel = GetNumberOfUsersOnCurrentChannel(tvcard, user);

              //Only subtract the slot the user is currently occupying if he is the only user occupying the slot.
              if (numberOfUsersOnCurrentChannel == 1)
              {
                --camDecrypting;
              }
            }
          }
          //check if cam is capable of descrambling an extra channel
          isCamAbleToDecryptChannel = (camDecrypting < decryptLimit);
        }

        return isCamAbleToDecryptChannel;
      }
      return true;
    }
        public void TestNoTuningDetailsChannel()
        {
            Dictionary <int, ITvCardHandler> cards = new Dictionary <int, ITvCardHandler>();
            List <IChannel> tuningDetails          = new List <IChannel>();

            IUser           user          = Fakes.FakeUser();
            TvBusinessLayer businessLayer = Fakes.FakeTvBusinessLayer();;
            TVController    controller    = Fakes.FakeTVController();

            DVBCardMocks   dvbCardMocks = GetCardMockByCardType(CardType.DvbC, tuningDetails, user);
            ITvCardHandler cardHandler1 = dvbCardMocks.GetMockedCardHandler();

            cards.Add(dvbCardMocks.CardId, cardHandler1);


            ChannelMap channelMap;
            Channel    channel = ChannelMocks.GetChannel(out channelMap);

            Isolate.WhenCalled(() => businessLayer.GetTuningChannelsByDbChannel(channel)).WillReturn(tuningDetails);
            TVControllerMocks.CardPresent(cardHandler1.DataBaseCard.IdCard, controller);

            SetupChannelMapping(cardHandler1, channelMap, businessLayer, channel);

            AdvancedCardAllocation allocation = new AdvancedCardAllocation(businessLayer, controller);

            TvResult          result;
            List <CardDetail> availCards = allocation.GetFreeCardsForChannel(cards, channel, ref user, out result);

            Assert.AreEqual(0, availCards.Count, "The number of cards returned is not as expected");
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Recording"/> class.
        /// </summary>
        /// <param name="cardHandler">The card handler.</param>
        public Recorder(ITvCardHandler cardHandler) : base(cardHandler)
        {
            var layer = new TvBusinessLayer();

            _cardHandler = cardHandler;
            _timeshiftingEpgGrabberEnabled = (layer.GetSetting("timeshiftingEpgGrabberEnabled", "no").Value == "yes");
        }
 private static void SetTunedCardState(ITvCardHandler tvcard)
 {
   lock (tvcard.Tuner.CardReservationsLock)
   {
     tvcard.Tuner.CardTuneState = CardTuneState.Tuned;        
   }
 }
        //TODO: move these helpers to other static classes

        private void SetupChannelMapping(ITvCardHandler cardHandler1, ChannelMap channelMap, TvBusinessLayer businessLayer, Channel channel)
        {
            Isolate.WhenCalled(() => channelMap.EpgOnly).WillReturn(false);
            Isolate.WhenCalled(() => channelMap.ReferencedCard().DevicePath).WillReturn(cardHandler1.DataBaseCard.DevicePath);

            TvDatabase.Card card = cardHandler1.DataBaseCard;
            Isolate.WhenCalled(() => businessLayer.IsChannelMappedToCard(channel, card, false)).WillReturn(true);
        }
        /// <summary>
        /// Gets a list of all free cards which can receive the channel specified
        /// List is sorted.
        /// </summary>
        /// <returns>list containg all free cards which can receive the channel</returns>
        public List <CardDetail> GetFreeCardsForChannel(IDictionary <int, ITvCardHandler> cards, Channel dbChannel,
                                                        ref IUser user, out TvResult result)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            try
            {
                //Log.Info("GetFreeCardsForChannel st {0}", Environment.StackTrace);
                //construct list of all cards we can use to tune to the new channel
                if (LogEnabled)
                {
                    Log.Info("Controller: find free card for channel {0}", dbChannel.DisplayName);
                }
                var cardsAvailable = new List <CardDetail>();

                IDictionary <int, TvResult> cardsUnAvailable;
                List <CardDetail>           cardDetails = GetAvailableCardsForChannel(cards, dbChannel, ref user, out cardsUnAvailable);
                foreach (CardDetail cardDetail in cardDetails)
                {
                    ITvCardHandler tvCardHandler    = cards[cardDetail.Card.IdCard];
                    bool           checkTransponder = CheckTransponder(user, tvCardHandler, cardDetail.TuningDetail);
                    if (checkTransponder)
                    {
                        cardsAvailable.Add(cardDetail);
                    }
                }

                //sort cards
                cardsAvailable.SortStable();

                if (cardsAvailable.Count > 0)
                {
                    result = TvResult.Succeeded;
                }
                else
                {
                    TvResult resultNoCards = GetResultNoCards(cardsUnAvailable);
                    result = cardDetails.Count == 0 ? resultNoCards : TvResult.AllCardsBusy;
                }
                if (LogEnabled)
                {
                    Log.Info("Controller: found {0} free card(s)", cardsAvailable.Count);
                }

                return(cardsAvailable);
            }
            catch (Exception ex)
            {
                result = TvResult.UnknownError;
                Log.Write(ex);
                return(null);
            }
            finally
            {
                stopwatch.Stop();
                Log.Info("AdvancedCardAllocation.GetFreeCardsForChannel took {0} msec", stopwatch.ElapsedMilliseconds);
            }
        }
Beispiel #12
0
        public static void AddUserIfRecording(ITvCardHandler tvcard, ref IUser u, List <IUser> recUsers)
        {
            bool isUserRec = tvcard.Recorder.IsRecording(ref u);

            if (isUserRec)
            {
                recUsers.Add(u);
            }
        }
Beispiel #13
0
        public static void AddUserIfTimeshifting(ITvCardHandler tvcard, ref IUser u, List <IUser> tsUsers)
        {
            bool isUserTS = tvcard.TimeShifter.IsTimeShifting(ref u);

            if (isUserTS)
            {
                tsUsers.Add(u);
            }
        }
 private static void ResetCardTuneStateToIdle(ITvCardHandler tvcard)
 {
   bool hasRes4Tune = (tvcard.Tuner.ReservationsForTune.Count > 0);
   if (!hasRes4Tune /*&& tvcard.Card.SubChannels.Length == 0*/)
   {
     tvcard.Tuner.CardTuneState = CardTuneState.Idle;
     tvcard.Tuner.ActiveCardTuneReservationTicket = null;        
   }
 }
 private static void ResetCardStopStateToIdle(ITvCardHandler tvcard)
 {
   bool hasRes4Stop = (tvcard.Tuner.ReservationsForStop.Count > 0);
   
   if (!hasRes4Stop /*&& tvcard.Card.SubChannels.Length == 0*/)
   {
     tvcard.Tuner.CardStopState = CardStopState.Idle;        
   }
 }
Beispiel #16
0
        private static void ResetCardStopStateToIdle(ITvCardHandler tvcard)
        {
            bool hasRes4Stop = (tvcard.Tuner.ReservationsForStop.Count > 0);

            if (!hasRes4Stop /*&& tvcard.Card.SubChannels.Length == 0*/)
            {
                tvcard.Tuner.CardStopState = CardStopState.Idle;
            }
        }
Beispiel #17
0
        private IUser GetBlockingUser(ITvCardHandler tvcard)
        {
            IUser blockingUser = null;

            if (tvcard.Tuner.ActiveCardTuneReservationTicket != null)
            {
                blockingUser = tvcard.Tuner.ActiveCardTuneReservationTicket.User;
            }
            return(blockingUser);
        }
Beispiel #18
0
    private ITvSubChannel _subchannel; // the active sub channel to record

    /// <summary>
    /// Initializes a new instance of the <see cref="Recording"/> class.
    /// </summary>
    /// <param name="cardHandler">The card handler.</param>
    public Recorder(ITvCardHandler cardHandler)
    {
      _eventAudio = new ManualResetEvent(false);
      _eventVideo = new ManualResetEvent(false);

      TvBusinessLayer layer = new TvBusinessLayer();
      _cardHandler = cardHandler;
      _timeshiftingEpgGrabberEnabled = (layer.GetSetting("timeshiftingEpgGrabberEnabled", "no").Value == "yes");
      _waitForTimeshifting = Int32.Parse(layer.GetSetting("timeshiftWaitForTimeshifting", "15").Value);
    }
Beispiel #19
0
        private static void ResetCardTuneStateToIdle(ITvCardHandler tvcard)
        {
            bool hasRes4Tune = (tvcard.Tuner.ReservationsForTune.Count > 0);

            if (!hasRes4Tune /*&& tvcard.Card.SubChannels.Length == 0*/)
            {
                tvcard.Tuner.CardTuneState = CardTuneState.Idle;
                tvcard.Tuner.ActiveCardTuneReservationTicket = null;
            }
        }
Beispiel #20
0
        protected override bool IsSameTransponder(ITvCardHandler tvcard, IChannel tuningDetail)
        {
            bool isSameTransponder            = false;
            ICardTuneReservationTicket ticket = GetCardTuneReservationTicket(tvcard.DataBaseCard.IdCard);

            if (ticket != null)
            {
                isSameTransponder = ticket.IsSameTransponder;
            }
            return(isSameTransponder);
        }
Beispiel #21
0
        protected override int NumberOfOtherUsersOnCurrentCard(ITvCardHandler tvcard, IUser user)
        {
            int numberOfOtherUsersOnCurrentCard = 0;
            ICardTuneReservationTicket ticket   = GetCardTuneReservationTicket(tvcard.DataBaseCard.IdCard);

            if (ticket != null)
            {
                numberOfOtherUsersOnCurrentCard = ticket.NumberOfOtherUsersOnCurrentCard;
            }
            return(numberOfOtherUsersOnCurrentCard);
        }
        private ITvSubChannel _subchannel;              // the active sub channel to record

        /// <summary>
        /// Initializes a new instance of the <see cref="Recording"/> class.
        /// </summary>
        /// <param name="cardHandler">The card handler.</param>
        public Recorder(ITvCardHandler cardHandler)
        {
            _eventAudio = new ManualResetEvent(false);
            _eventVideo = new ManualResetEvent(false);

            TvBusinessLayer layer = new TvBusinessLayer();

            _cardHandler = cardHandler;
            _timeshiftingEpgGrabberEnabled = (layer.GetSetting("timeshiftingEpgGrabberEnabled", "no").Value == "yes");
            _waitForTimeshifting           = Int32.Parse(layer.GetSetting("timeshiftWaitForTimeshifting", "15").Value);
        }
Beispiel #23
0
        protected override int NumberOfChannelsDecrypting(ITvCardHandler tvcard)
        {
            int numberOfChannelsDecrypting    = 0;
            ICardTuneReservationTicket ticket = GetCardTuneReservationTicket(tvcard.DataBaseCard.IdCard);

            if (ticket != null)
            {
                numberOfChannelsDecrypting = (ticket.NumberOfChannelsDecrypting);
            }
            return(numberOfChannelsDecrypting);
        }
 private static int NumberOfOtherUsersOnCard(ITvCardHandler card, IUser user)
 {
   //determine how many other users are using this card
   int nrOfOtherUsers = 0;
   IUser[] users = card.Users.GetUsers();
   if (users != null)
   {
     nrOfOtherUsers = users.Count(t => t.Name != user.Name && !t.Name.Equals("epg"));
   }
   return nrOfOtherUsers;
 }
Beispiel #25
0
        protected override bool IsFreeToAir(ITvCardHandler tvcard, ref IUser user)
        {
            bool isFreeToAir = true;
            ICardTuneReservationTicket ticket = GetCardTuneReservationTicket(tvcard.DataBaseCard.IdCard);

            if (ticket != null)
            {
                isFreeToAir = (ticket.IsFreeToAir);
            }
            return(isFreeToAir);
        }
Beispiel #26
0
        private static bool IsCardAvail(ITvCardHandler tvcard)
        {
            bool isCardStopStateIdle    = (tvcard.Tuner.CardStopState == CardStopState.Idle);
            bool isCardStopStateStopped = (tvcard.Tuner.CardStopState == CardStopState.Stopped);

            bool isCardTuneStateIdle  = (tvcard.Tuner.CardTuneState == CardTuneState.Idle);
            bool isCardTuneStateTuned = (tvcard.Tuner.CardTuneState == CardTuneState.Tuned);

            bool isCardAvail = (isCardStopStateIdle || isCardStopStateStopped) && (isCardTuneStateIdle || isCardTuneStateTuned);

            return(isCardAvail);
        }
Beispiel #27
0
        protected override int GetNumberOfUsersOnCurrentChannel(ITvCardHandler tvcard, IUser user)
        {
            int numberOfUsersOnCurrentChannel = 0;
            ICardTuneReservationTicket ticket = GetCardTuneReservationTicket(tvcard.DataBaseCard.IdCard);

            if (ticket != null)
            {
                //TODO: check code
                numberOfUsersOnCurrentChannel = ticket.NumberOfUsersOnSameCurrentChannel;
            }
            return(numberOfUsersOnCurrentChannel);
        }
Beispiel #28
0
 private static void RemoveStopTicket(ITvCardHandler tvcard, ICardStopReservationTicket ticket, bool ticketFound)
 {
     if (ticketFound)
     {
         lock (tvcard.Tuner.CardReservationsLock)
         {
             Log.Debug("CardReservation.RemoveStopTicket: removed STOP reservation with id={0}", ticket.Id);
             tvcard.Tuner.ReservationsForStop.Remove(ticket);
             ResetCardStopStateToIdle(tvcard);
         }
     }
 }
Beispiel #29
0
        protected override bool IsCamAlreadyDecodingChannel(ITvCardHandler tvcard, IChannel tuningDetail)
        {
            bool isCamAlreadyDecodingChannel  = false;
            ICardTuneReservationTicket ticket = GetCardTuneReservationTicket(tvcard.DataBaseCard.IdCard);

            if (ticket != null)
            {
                //TODO: check code
                isCamAlreadyDecodingChannel = (ticket.IsCamAlreadyDecodingChannel);
            }
            return(isCamAlreadyDecodingChannel);
        }
Beispiel #30
0
 private void LogNumberOfOtherUsersFound(CardDetail cardDetail)
 {
     if (LogEnabled && cardDetail.Card.IdCard > 0)
     {
         var tvController = _controller as TVController;
         if (tvController != null)
         {
             ITvCardHandler card = tvController.CardCollection[cardDetail.Card.IdCard];
             Log.Info("Controller:    card:{0} type:{1} users: {2}", cardDetail.Card.IdCard, card.Type, cardDetail.NumberOfOtherUsers);
         }
     }
 }
        private static int NumberOfOtherUsersOnCard(ITvCardHandler card, IUser user)
        {
            //determine how many other users are using this card
            int nrOfOtherUsers = 0;

            IUser[] users = card.Users.GetUsers();
            if (users != null)
            {
                nrOfOtherUsers = users.Count(t => t.Name != user.Name && !t.Name.Equals("epg"));
            }
            return(nrOfOtherUsers);
        }
Beispiel #32
0
 public static void RemoveTuneTicket(ITvCardHandler tvcard, ICardTuneReservationTicket ticket, bool ticketFound)
 {
     if (ticketFound)
     {
         lock (tvcard.Tuner.CardReservationsLock)
         {
             Log.Debug("CardReservation.RemoveTuneTicket: removed reservation with id={0}, tuningdetails={1}", ticket.Id, ticket.TuningDetail);
             tvcard.Tuner.ReservationsForTune.Remove(ticket);
             ResetCardTuneStateToIdle(tvcard);
         }
     }
 }
        private static bool CanCardDecodeChannel(ITvCardHandler cardHandler, IChannel tuningDetail)
        {
            bool canCardDecodeChannel = true;
            int  cardId = cardHandler.DataBaseCard.IdCard;

            if (!tuningDetail.FreeToAir && !cardHandler.DataBaseCard.CAM)
            {
                Log.Info("Controller:    card:{0} type:{1} channel is encrypted but card has no CAM", cardId, cardHandler.Type);
                canCardDecodeChannel = false;
            }
            return(canCardDecodeChannel);
        }
        private void TestWrongTuningDetailForCardForFTAChannel(CardType cardType)
        {
            Dictionary <int, ITvCardHandler> cards = new Dictionary <int, ITvCardHandler>();
            List <IChannel> tuningDetails          = new List <IChannel>();

            IUser           user          = Fakes.FakeUser();
            TvBusinessLayer businessLayer = Fakes.FakeTvBusinessLayer();;
            TVController    controller    = Fakes.FakeTVController();

            //we need to pick a different cardtype here-
            CardType cardTypeDifferent = cardType;

            switch (cardType)
            {
            case CardType.DvbT:
                cardTypeDifferent = CardType.DvbC;
                break;

            case CardType.DvbC:
                cardTypeDifferent = CardType.DvbS;
                break;

            case CardType.DvbS:
                cardTypeDifferent = CardType.DvbT;
                break;
            }
            IChannel tuningDetail1 = GetFTATuningDetailBasedOnCardType(cardTypeDifferent);

            tuningDetails.Add(tuningDetail1);

            DVBCardMocks   dvbCardMocks = GetCardMockByCardType(cardType, tuningDetails, user);
            ITvCardHandler cardHandler1 = dvbCardMocks.GetMockedCardHandler();

            //ITvCardHandler cardHandler1 = DVBTCardMocks.AddIdleFTADVBTCard(tuningDetail1, user);
            cards.Add(dvbCardMocks.CardId, cardHandler1);


            ChannelMap channelMap;
            Channel    channel = ChannelMocks.GetChannel(out channelMap);

            Isolate.WhenCalled(() => businessLayer.GetTuningChannelsByDbChannel(channel)).WillReturn(tuningDetails);
            TVControllerMocks.CardPresent(cardHandler1.DataBaseCard.IdCard, controller);

            SetupChannelMapping(cardHandler1, channelMap, businessLayer, channel);

            AdvancedCardAllocation allocation = new AdvancedCardAllocation(businessLayer, controller);

            TvResult          result;
            List <CardDetail> availCards = allocation.GetFreeCardsForChannel(cards, channel, ref user, out result);

            Assert.AreEqual(0, availCards.Count, "The number of cards returned is not as expected");
        }
Beispiel #35
0
        private static ICardStopReservationTicket RequestCardStopReservation(ITvCardHandler tvcard, IUser user)
        {
            ICardStopReservationTicket cardStopReservation = null;

            CardTuneState cardTuneState;
            bool          hasMoreStopReservations;

            lock (tvcard.Tuner.CardReservationsLock)
            {
                bool isCardIdle          = (tvcard.Tuner.CardTuneState == CardTuneState.Idle);
                bool isCardTuned         = (tvcard.Tuner.CardTuneState == CardTuneState.Tuned);
                bool isCardTunePending   = (tvcard.Tuner.CardTuneState == CardTuneState.TunePending);
                bool isCardTuneCancelled = (tvcard.Tuner.CardTuneState == CardTuneState.TuneCancelled);

                bool isCardStopIdle = (tvcard.Tuner.CardStopState == CardStopState.Idle);
                bool isCardStopped  = (tvcard.Tuner.CardStopState == CardStopState.Stopped);

                bool isCardAvail = (isCardIdle || isCardTuned || isCardTunePending || isCardTuneCancelled) && (isCardStopped || isCardStopIdle);

                if (isCardAvail)
                {
                    tvcard.Tuner.CardStopState = CardStopState.StopPending;
                    cardStopReservation        = new CardStopReservationTicket();
                    tvcard.Tuner.ReservationsForStop.Add(cardStopReservation);
                }

                cardTuneState           = tvcard.Tuner.CardTuneState;
                hasMoreStopReservations = (tvcard.Tuner.ReservationsForStop.Count > 0);
            }

            if (cardStopReservation != null)
            {
                Log.Debug("CardTuner.RequestCardStopReservation: placed reservation with id={0}, user={1}", cardStopReservation.Id, user.Name);
            }
            else
            {
                if (hasMoreStopReservations)
                {
                    Log.Debug(
                        "CardTuner.RequestCardStopReservation: failed reservation user={0}, cardstate={1}, res id blocking={2}",
                        user.Name, cardTuneState, "n/a");
                }
                else
                {
                    Log.Debug(
                        "CardTuner.RequestCardStopReservation: failed reservation user={0}, cardstate={1}",
                        user.Name, cardTuneState);
                }
            }

            return(cardStopReservation);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeShifter"/> class.
        /// </summary>
        /// <param name="cardHandler">The card handler.</param>
        public TimeShifter(ITvCardHandler cardHandler) : base(cardHandler)
        {
            _cardHandler = cardHandler;
            var layer = new TvBusinessLayer();

            _linkageScannerEnabled = (layer.GetSetting("linkageScannerEnabled", "no").Value == "yes");

            _linkageGrabber = new ChannelLinkageGrabber(cardHandler.Card);
            _timeshiftingEpgGrabberEnabled = (layer.GetSetting("timeshiftingEpgGrabberEnabled", "no").Value == "yes");

            _timeAudioEvent = DateTime.MinValue;
            _timeVideoEvent = DateTime.MinValue;
        }
Beispiel #37
0
    /// <summary>
    /// Initializes a new instance of the <see cref="TimeShifter"/> class.
    /// </summary>
    /// <param name="cardHandler">The card handler.</param>
    public TimeShifter(ITvCardHandler cardHandler) : base(cardHandler)
    {
      

      _cardHandler = cardHandler;
      var layer = new TvBusinessLayer();
      _linkageScannerEnabled = (layer.GetSetting("linkageScannerEnabled", "no").Value == "yes");

      _linkageGrabber = new ChannelLinkageGrabber(cardHandler.Card);
      _timeshiftingEpgGrabberEnabled = (layer.GetSetting("timeshiftingEpgGrabberEnabled", "no").Value == "yes");

      _timeAudioEvent = DateTime.MinValue;
      _timeVideoEvent = DateTime.MinValue;
    }    
    protected virtual int NumberOfOtherUsersOnCurrentCard(ITvCardHandler card, IUser user)
    {
      //determine how many other users are using this card
      int nrOfOtherUsers = 0;
      IUser[] users = card.Users.GetUsers();
      if (users != null)
      {
        nrOfOtherUsers = users.Count(t => t.Name != user.Name && !t.Name.Equals("epg"));
      }

      if (LogEnabled)
      {
        Log.Info("Controller:    card:{0} type:{1} users: {2}", card.DataBaseCard.IdCard, card.Type, nrOfOtherUsers);
      }

      return nrOfOtherUsers;
    }           
    /// <summary>
    /// Initializes a new instance of the <see cref="TimeShifter"/> class.
    /// </summary>
    /// <param name="cardHandler">The card handler.</param>
    public TimeShifter(ITvCardHandler cardHandler)
    {
      _eventAudio.Reset();
      _eventVideo.Reset();

      _cardHandler = cardHandler;
      TvBusinessLayer layer = new TvBusinessLayer();
      _linkageScannerEnabled = (layer.GetSetting("linkageScannerEnabled", "no").Value == "yes");

      _linkageGrabber = new ChannelLinkageGrabber(cardHandler.Card);
      _timeshiftingEpgGrabberEnabled = (layer.GetSetting("timeshiftingEpgGrabberEnabled", "no").Value == "yes");

      _waitForTimeshifting = Int32.Parse(layer.GetSetting("timeshiftWaitForTimeshifting", "15").Value);

      _timeAudioEvent = DateTime.MinValue;
      _timeVideoEvent = DateTime.MinValue;
    }
 private static void SetCurrentCardState(ITvCardHandler tvcard)
 {
   lock (tvcard.Tuner.CardReservationsLock)
   {
     if (tvcard.Card.SubChannels.Length > 0)
     {
       tvcard.Tuner.CardTuneState = CardTuneState.Tuned;          
     }
     else if (tvcard.Tuner.ReservationsForTune.Count > 1)
     {
       tvcard.Tuner.CardTuneState = CardTuneState.TunePending;                   
     }
     else
     {          
       tvcard.Tuner.CardTuneState = CardTuneState.TuneFailed;         
     }
   }
 }
    protected ITvSubChannel _subchannel; // the active sub channel to record        

    protected TimeShifterBase(ITvCardHandler cardHandler)
    {
      _eventAudio.Reset();
      _eventVideo.Reset();

      var layer = new TvBusinessLayer();
      _waitForTimeshifting = Int32.Parse(layer.GetSetting("timeshiftWaitForTimeshifting", "15").Value);

      if (_cardHandler != null && _cardHandler.Tuner != null)
      {
        _cardHandler.Tuner.OnAfterCancelTuneEvent += Tuner_OnAfterCancelTuneEvent;
      }

      if (_cardHandler != null && _cardHandler.Tuner != null)
      {
        _cardHandler.Tuner.OnAfterCancelTuneEvent += new CardTuner.OnAfterCancelTuneDelegate(Tuner_OnAfterCancelTuneEvent);
      }
    }
    protected bool IsCamAbleToDecryptChannel(IUser user, ITvCardHandler tvcard, IChannel tuningDetail, int decryptLimit)
    {
      if (!tuningDetail.FreeToAir)
      {
        bool isCamAbleToDecryptChannel = true;
        if (decryptLimit > 0)
        {
          int camDecrypting = tvcard.NumberOfChannelsDecrypting;

          //Check if the user is currently occupying a decoding slot and subtract that from the number of channels it is decoding.
          if (user.CardId == tvcard.DataBaseCard.IdCard)
          {
            IChannel currentUserCh = tvcard.CurrentChannel(ref user);
            if (currentUserCh != null && !currentUserCh.FreeToAir)
            {
              int currentChannelId = tvcard.CurrentDbChannel(ref user);
              int numberOfUsersOnCurrentChannel = 0;
              foreach (IUser aUser in tvcard.Users.GetUsers())
              {
                if (aUser.IdChannel == currentChannelId)
                {
                  ++numberOfUsersOnCurrentChannel;
                }
              }

              //Only subtract the slot the user is currently occupying if he is the only user occupying the slot.
              if (numberOfUsersOnCurrentChannel == 1)
              {
                --camDecrypting;
              }
            }
          }
          //check if cam is capable of descrambling an extra channel
          isCamAbleToDecryptChannel = (camDecrypting < decryptLimit);
        }

        return isCamAbleToDecryptChannel;
      }
      return true;
    }
 private static void UpdateChannelStateUserBasedOnCardOwnership(ITvCardHandler tvcard, IList<IUser> allUsers,
                                                                Channel ch)
 {
   for (int i = 0; i < allUsers.Count; i++)
   {
     IUser user = allUsers[i];
     if (user.IsAdmin)
     {
       continue;
     }
     if (!tvcard.Users.IsOwner(user))
     {
       //no
       //Log.Info("Controller:    card:{0} type:{1} is tuned to different transponder", cardId, tvcard.Type);
       //allow admin users like the scheduler to use this card anyway          
       UpdateChannelStateUser(user, ChannelState.nottunable, ch.IdChannel);
     }
     else
     {
       UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
     }
     allUsers[i] = user;
   }
 }
 private void CheckTransponder(ITvCardHandler tvcard, IChannel tuningDetail, TvBusinessLayer layer, IUser user)
 {
   var cardAlloc = new AdvancedCardAllocation(layer, _tvController);
   cardAlloc.CheckTransponder(user, tvcard, tuningDetail);
 }      
 private IUser GetBlockingUser (ITvCardHandler tvcard)
 {
   IUser blockingUser = null;
   if (tvcard.Tuner.ActiveCardTuneReservationTicket != null)
   {
     blockingUser = tvcard.Tuner.ActiveCardTuneReservationTicket.User;
   }
   return blockingUser;
 }
    private static bool IsCardAvail(ITvCardHandler tvcard)
    {
      bool isCardStopStateIdle = (tvcard.Tuner.CardStopState == CardStopState.Idle);
      bool isCardStopStateStopped = (tvcard.Tuner.CardStopState == CardStopState.Stopped);

      bool isCardTuneStateIdle = (tvcard.Tuner.CardTuneState == CardTuneState.Idle);
      bool isCardTuneStateTuned = (tvcard.Tuner.CardTuneState == CardTuneState.Tuned);

      bool isCardAvail = (isCardStopStateIdle || isCardStopStateStopped) && (isCardTuneStateIdle || isCardTuneStateTuned);
      return isCardAvail;
    }
    public ICardTuneReservationTicket RequestCardTuneReservation(ITvCardHandler tvcard, IChannel tuningDetail, IUser user)
    {
      ICardTuneReservationTicket cardTuneReservationTicket = null;
      var layer = new TvBusinessLayer();

      CardTuneState cardTuneState;
      int ticketId = 0;
      bool isCardAvail;
      bool hasUserHigherPriorityThanBlockingUser = false;
      lock (tvcard.Tuner.CardReservationsLock)
      {
        isCardAvail = IsCardAvail(tvcard);
        if (!isCardAvail)
        {
          if (tvcard.Tuner.CardTuneState != CardTuneState.TuneCancelled)
          {
            IUser blockingUser = GetBlockingUser(tvcard);
            hasUserHigherPriorityThanBlockingUser = (HasUserHigherPriorityThanBlockingUser(user, blockingUser));
            if (hasUserHigherPriorityThanBlockingUser)
            {
              tvcard.Tuner.CardTuneState = CardTuneState.TuneCancelled;
            }
          }          
        }
      }
      if (!isCardAvail)
      {
        if (hasUserHigherPriorityThanBlockingUser)
        {
          tvcard.Tuner.CancelTune(tvcard.Tuner.ActiveCardTuneReservationTicket.PendingSubchannel);          
          lock (tvcard.Tuner.CardReservationsLock)
          {
            isCardAvail = IsCardAvail(tvcard);
          }
        }
      }

      lock (tvcard.Tuner.CardReservationsLock)
      {
        if (isCardAvail)
        {          
          tvcard.Tuner.CardTuneState = CardTuneState.TunePending;            
          bool isTunedToTransponder = IsTunedToTransponder(tvcard, tuningDetail);

          if (isTunedToTransponder)
          {
            CheckTransponder(tvcard, tuningDetail, layer, user);
          }

          int ownerSubchannel = -1;
          int numberOfUsersOnSameCurrentChannel = 0;
          int numberOfOtherUsersOnSameChannel = 0;
          int numberOfOtherUsersOnCurrentCard = 0;

          bool hasUserHighestPriority = false;
          bool hasUserEqualOrHigherPriority = false;
          bool isCamAlreadyDecodingChannel = false;
          bool conflictingSubchannelFound = false;
          bool isRecordingAnyUser = false;
          bool isAnySubChannelTimeshifting = tvcard.TimeShifter.IsAnySubChannelTimeshifting;
          bool isOwner = tvcard.Users.IsOwner(user);
          var users = new List<IUser>(tvcard.Users.GetUsers());
          var inactiveUsers = new List<IUser>();
          var activeUsers = new List<IUser>();
          var recUsers = new List<IUser>();
          var tsUsers = new List<IUser>();

          var context = tvcard.Card.Context as ITvCardContext;
          if (context != null)
          {
            context.GetUser(ref user);
            hasUserHighestPriority = context.HasUserHighestPriority(user);
            hasUserEqualOrHigherPriority = context.HasUserEqualOrHigherPriority(user);
          }          

          int currentChannelId = tvcard.CurrentDbChannel(ref user);

          for (int i = users.Count - 1; i > -1; i--)
          {
            IUser actualUser = users[i];                           
            CardReservationHelper.AddUserIfRecording(tvcard, ref actualUser, recUsers);
            CardReservationHelper.AddUserIfTimeshifting(tvcard, ref actualUser, tsUsers);

            bool isCurrentUser = user.Name.Equals(actualUser.Name);

            IChannel userChannel = tvcard.CurrentChannel(ref actualUser);
            var userDVBchannel = userChannel as DVBBaseChannel;

            if (!isCurrentUser)
            {
              if (!isRecordingAnyUser)
              {
                isRecordingAnyUser = CardReservationHelper.IsRecordingUser(tvcard, user, ref actualUser);
              }

              if (actualUser.SubChannel == user.SubChannel && user.IdChannel > 0)
              {
                conflictingSubchannelFound = true;
              }
              numberOfOtherUsersOnCurrentCard = CardReservationHelper.GetNumberOfOtherUsersOnCurrentCard(user,
                                                                                                         numberOfOtherUsersOnCurrentCard);

              
              if (userChannel == null)
              {
                inactiveUsers.Add(actualUser);
              }
              else
              {                
                if (userDVBchannel != null)
                {
                  actualUser.IdChannel = layer.GetTuningDetail(userDVBchannel).IdChannel;
                }

                bool isDiffTS = tuningDetail.IsDifferentTransponder(userChannel);

                if (isDiffTS)
                {
                  activeUsers.Add(actualUser);
                }
                else
                {
                  if (!isOwner)
                  {
                    bool isUserOnSameChannel = CardReservationHelper.IsUserOnSameChannel(tuningDetail, layer,
                                                                                         userDVBchannel);
                    if (isUserOnSameChannel)
                    {
                      numberOfOtherUsersOnSameChannel++;
                      //we do not want to hook up on schedulers existing subchannel
                      if (!actualUser.IsAdmin)
                      {
                        ownerSubchannel = actualUser.SubChannel;
                      }
                    }                    
                  }                  
                }
              }
            }

            bool isUserOnSameCurrentChannel = CardReservationHelper.IsUserOnSameCurrentChannel(currentChannelId, actualUser);
            if (isUserOnSameCurrentChannel)
            {
              numberOfUsersOnSameCurrentChannel++;
            }

            if (!isCamAlreadyDecodingChannel)
            {
              isCamAlreadyDecodingChannel = IsCamAlreadyDecodingChannel(tuningDetail, userChannel);
            }
          }

          bool isFreeToAir = CardReservationHelper.IsFreeToAir(tvcard, user);

          cardTuneReservationTicket = new CardTuneReservationTicket
              (                
              user,
              tuningDetail, 
              isTunedToTransponder, 
              numberOfOtherUsersOnSameChannel, 
              isAnySubChannelTimeshifting, 
              inactiveUsers, 
              activeUsers, 
              users, 
              ownerSubchannel, 
              isOwner, 
              tvcard.DataBaseCard.IdCard, 
              tvcard.NumberOfChannelsDecrypting, 
              isFreeToAir, 
              numberOfOtherUsersOnCurrentCard, 
              recUsers, 
              tsUsers,               
              conflictingSubchannelFound,
              numberOfUsersOnSameCurrentChannel,
              isCamAlreadyDecodingChannel,
              hasUserHighestPriority,
              hasUserEqualOrHigherPriority);
          tvcard.Tuner.ActiveCardTuneReservationTicket = cardTuneReservationTicket;
          tvcard.Tuner.ReservationsForTune.Add(cardTuneReservationTicket);          
        }

        cardTuneState = tvcard.Tuner.CardTuneState;        
        if (tvcard.Tuner.ActiveCardTuneReservationTicket != null)
        {
          ticketId = tvcard.Tuner.ActiveCardTuneReservationTicket.Id;  
        }        
      }


      if (cardTuneReservationTicket != null)
      {
        Log.Debug("CardReservationBase.RequestCardTuneReservation: placed reservation with id={0}, tuningdetails={1}", cardTuneReservationTicket.Id, cardTuneReservationTicket.TuningDetail);
      }
      else
      {
        if (ticketId > 0)
        {
          Log.Debug("CardReservationBase.RequestCardTuneReservation: failed reservation tuningdetails={0}, res id blocking={1}, state={2}", tuningDetail, ticketId, cardTuneState);
        }
        else
        {
          Log.Debug("CardReservationBase.RequestCardTuneReservation: failed reservation tuningdetails={0}, res id blocking={1}, state={2}", tuningDetail, "n/a", cardTuneState);          
        }
      }              
      return cardTuneReservationTicket;
    }    
    public TvResult CardTune(ITvCardHandler tvcard, ref IUser user, IChannel channel, Channel dbChannel, ICardTuneReservationTicket ticket)
    {
      TvResult tvResult = TvResult.AllCardsBusy;
      bool ticketFound;
      bool isTuningPending = CardReservationHelper.GetIsTuningPending(tvcard, ticket, out ticketFound);

      try
      {
        if (isTuningPending && ticketFound)
        {
          Log.Debug("CardReservationBase: tvcard={0}, user={1}, dbChannel={2}, ticket={3}, tunestate={4}, stopstate={5}", tvcard.DataBaseCard.IdCard, user.Name, dbChannel.IdChannel, ticket.Id, tvcard.Tuner.CardTuneState, tvcard.Tuner.CardStopState);
          tvResult = tvcard.Tuner.CardTune(ref user, channel, dbChannel);

          if (tvResult == TvResult.Succeeded)
          {
            if (OnStartCardTune != null)
            {
              if (!_tvController.IsTimeShifting(ref user))
              {
                CleanTimeShiftFiles(tvcard.DataBaseCard.TimeShiftFolder,
                                    String.Format("live{0}-{1}.ts", user.CardId, user.SubChannel));
              }

              string timeshiftFileName = String.Format(@"{0}\live{1}-{2}.ts", tvcard.DataBaseCard.TimeShiftFolder,
                                                       user.CardId,
                                                       user.SubChannel);
              tvResult = OnStartCardTune(ref user, ref timeshiftFileName);
            }
          }

          CardReservationHelper.SetCardStateBasedOnTVresult(tvcard, tvResult);
        }
        else // state is not tuning, some other card tune session is busy.
        {
        }
      }
      finally
      {        
        CardReservationHelper.RemoveTuneTicket(tvcard, ticket, ticketFound);
        tvcard.Tuner.CleanUpPendingTune(ticket.PendingSubchannel);
      }
      return tvResult;
    }
    private static ICardStopReservationTicket RequestCardStopReservation(ITvCardHandler tvcard, IUser user)
    {
      ICardStopReservationTicket cardStopReservation = null;

      CardTuneState cardTuneState;
      bool hasMoreStopReservations;

      lock (tvcard.Tuner.CardReservationsLock)
      {
        bool isCardIdle = (tvcard.Tuner.CardTuneState == CardTuneState.Idle);
        bool isCardTuned = (tvcard.Tuner.CardTuneState == CardTuneState.Tuned);
        bool isCardTunePending = (tvcard.Tuner.CardTuneState == CardTuneState.TunePending);
        bool isCardTuneCancelled = (tvcard.Tuner.CardTuneState == CardTuneState.TuneCancelled);

        bool isCardStopIdle = (tvcard.Tuner.CardStopState == CardStopState.Idle);
        bool isCardStopped = (tvcard.Tuner.CardStopState == CardStopState.Stopped);

        bool isCardAvail = (isCardIdle || isCardTuned || isCardTunePending || isCardTuneCancelled) && (isCardStopped || isCardStopIdle);

        if (isCardAvail)
        {          
          tvcard.Tuner.CardStopState = CardStopState.StopPending;
          cardStopReservation = new CardStopReservationTicket();          
          tvcard.Tuner.ReservationsForStop.Add(cardStopReservation);
        }

        cardTuneState = tvcard.Tuner.CardTuneState;
        hasMoreStopReservations = (tvcard.Tuner.ReservationsForStop.Count > 0);

      }

      if (cardStopReservation != null)
      {
        Log.Debug("CardTuner.RequestCardStopReservation: placed reservation with id={0}, user={1}", cardStopReservation.Id, user.Name);
      }
      else
      {
        if (hasMoreStopReservations)
        {
          Log.Debug(
            "CardTuner.RequestCardStopReservation: failed reservation user={0}, cardstate={1}, res id blocking={2}",
            user.Name, cardTuneState, "n/a");
        }
        else
        {
          Log.Debug(
            "CardTuner.RequestCardStopReservation: failed reservation user={0}, cardstate={1}",
            user.Name, cardTuneState);
        }
      }

      return cardStopReservation;
    }
Beispiel #50
0
 /// <summary>
 /// Initializes a new instance of the <see cref="UserManagement"/> class.
 /// </summary>
 /// <param name="cardHandler">The card handler.</param>
 public UserManagement(ITvCardHandler cardHandler)
 {
   _cardHandler = cardHandler;
 }
 protected override bool IsSameTransponder(ITvCardHandler tvcard, IChannel tuningDetail)
 {
   return false;
 }
 public override bool CheckTransponder(IUser user, ITvCardHandler tvcard, IChannel tuningDetail)
 {
   return true;
 }
    //TODO: move these helpers to other static classes

    private void SetupChannelMapping(ITvCardHandler cardHandler1, ChannelMap channelMap, TvBusinessLayer businessLayer, Channel channel)
    {
      Isolate.WhenCalled(() => channelMap.EpgOnly).WillReturn(false);
      Isolate.WhenCalled(() => channelMap.ReferencedCard().DevicePath).WillReturn(cardHandler1.DataBaseCard.DevicePath);

      TvDatabase.Card card = cardHandler1.DataBaseCard;
      Isolate.WhenCalled(() => businessLayer.IsChannelMappedToCard(channel, card, false)).WillReturn(true);      

    }
 public static void CancelCardReservationAndRemoveTicket(ITvCardHandler tvCardHandler, ICollection<ICardTuneReservationTicket> tickets)
 {
   if (tvCardHandler != null && tickets != null)
   {
     int cardId = tvCardHandler.DataBaseCard.IdCard;
     ICardTuneReservationTicket ticket = tickets.FirstOrDefault(t => t.CardId == cardId);
     if (ticket != null)
     {
       tickets.Remove(ticket);
       CancelCardReservation(tvCardHandler, ticket);
     }
   }
 }
 protected abstract bool IsTunedToTransponder(ITvCardHandler tvcard, IChannel tuningDetail);    
 protected override int NumberOfOtherUsersOnCurrentCard(ITvCardHandler card, IUser user)
 {
   return 0;
 }   
Beispiel #57
0
 private void CheckTransponderAllUsers(Channel ch, IEnumerable<IUser> allUsers, ITvCardHandler tvcard,
                                              IChannel tuningDetail)
 {      
   foreach (IUser user in allUsers) 
   {
     //ignore admin users, like scheduler
     if (!user.IsAdmin)
     {
       bool checkTransponder = CheckTransponder(user, tvcard, tuningDetail);
       if (checkTransponder)
       {
         UpdateChannelStateUser(user, ChannelState.tunable, ch.IdChannel);
       }
       else
       {
         UpdateChannelStateUser(user, ChannelState.nottunable, ch.IdChannel);
       } 
     }        
   }
 }
    public TvResult Tune(ITvCardHandler tvcard, ref IUser user, IChannel channel, int idChannel, ICardTuneReservationTicket ticket)
    {
      TvResult tvResult = TvResult.AllCardsBusy;
      bool ticketFound;
      bool isTuningPending = CardReservationHelper.GetIsTuningPending(tvcard, ticket, out ticketFound);

      try
      {
        if (isTuningPending && ticketFound)
        {
          tvResult = tvcard.Tuner.Tune(ref user, channel, idChannel);

          bool succes = (tvResult == TvResult.Succeeded);
          if (succes)
          {
            if (!OnStartTune(user))
            {
              tvResult = TvResult.AllCardsBusy;
            }
          }
          CardReservationHelper.SetCardStateBasedOnTVresult(tvcard, tvResult);
        }
        else // state is not tuning, some other card tune session is busy.
        {
        }
      }
      finally
      {
        CardReservationHelper.RemoveTuneTicket(tvcard, ticket, ticketFound);
        tvcard.Tuner.CleanUpPendingTune(ticket.PendingSubchannel);
      }
      return tvResult;
    }
Beispiel #59
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Recording"/> class.
 /// </summary>
 /// <param name="cardHandler">The card handler.</param>
 public Recorder(ITvCardHandler cardHandler) : base(cardHandler)
 {
   var layer = new TvBusinessLayer();
   _cardHandler = cardHandler;
   _timeshiftingEpgGrabberEnabled = (layer.GetSetting("timeshiftingEpgGrabberEnabled", "no").Value == "yes");
 }
    public static bool Stop(ITvCardHandler tvcard, ref IUser user, ICardStopReservationTicket ticket)
    {
      bool isStopPending;
      bool ticketFound;
      bool result = false;

      lock (tvcard.Tuner.CardReservationsLock)
      {        
        isStopPending = (tvcard.Tuner.CardStopState == CardStopState.StopPending);
        ticketFound = (tvcard.Tuner.ReservationsForStop.Contains(ticket));
        if (isStopPending)
        {
          Log.Debug("CardTuner.Stop: ticket id={0}, found={1}", ticket.Id, ticketFound);
          if (ticketFound)
          {
            tvcard.Tuner.CardStopState = CardStopState.Stopping;            
          }
          else
          {
            Log.Debug("ticket not found!");
          }
        }
      }

      try
      {
        if (isStopPending && ticketFound)
        {
          Log.Info("Stop cardid={0}, ticket={1}, tunestate={2}, stopstate={3}", tvcard.DataBaseCard.IdCard, ticket.Id, tvcard.Tuner.CardTuneState, tvcard.Tuner.CardStopState);

          result = tvcard.TimeShifter.Stop(ref user);

          lock (tvcard.Tuner.CardReservationsLock)
          {
            if (result)
            {              
              tvcard.Tuner.CardStopState = CardStopState.Stopped;              
              ResetCardTuneStateToIdle(tvcard);
            }
            else
            {              
              if (tvcard.Tuner.ReservationsForStop.Count > 1)
              {
                tvcard.Tuner.CardStopState = CardStopState.StopPending;                
              }
              else
              {
                tvcard.Tuner.CardStopState = CardStopState.StopFailed;                
              }
              
            }            
          }
        }
        else // state is not tuning, some other card tune session is busy.
        {
        }
      }
      finally
      {
        RemoveStopTicket(tvcard, ticket, ticketFound);
      }

      return result;
    }