/// <summary>Transmit request to embedded system.</summary>
        /// <param name="request">The request to send to embedded.</param>
        private static void TransmitRequest(RequestContext request)
        {
            bool requestIsTransmitted = false;

            ServiceInfo serviceInfo;

            // Check if target element is online
            bool elementIsOnline;
            T2GManagerErrorEnum rqstResult = _train2groundManager.IsElementOnline(request.ElementId, out elementIsOnline);

            switch (rqstResult)
            {
            case T2GManagerErrorEnum.eSuccess:
                if (elementIsOnline == true)
                {
                    T2GManagerErrorEnum result = _train2groundManager.GetAvailableServiceData(request.ElementId, (int)eServiceID.eSrvSIF_LiveVideoControlServer, out serviceInfo);
                    switch (result)
                    {
                    case T2GManagerErrorEnum.eSuccess:
                    {
                        string endpoint = "http://" + serviceInfo.ServiceIPAddress + ":" + serviceInfo.ServicePortNumber;
                        try
                        {
                            // Call LiveVideoControl train service
                            using (LiveVideoControlServiceClient trainClient = new LiveVideoControlServiceClient("LiveVideoControlEndpoint", endpoint))
                            {
                                try
                                {
                                    if (request is ProcessStopVideoStreamingCommandRequestContext)
                                    {
                                        RequestProcessor.TransmitStopVideoStreamingCommandRequest(trainClient, request as ProcessStopVideoStreamingCommandRequestContext);
                                    }
                                    else if (request is ProcessStartVideoStreamingCommandRequestContext)
                                    {
                                        RequestProcessor.TransmitStartVideoStreamingCommandRequest(trainClient, request as ProcessStartVideoStreamingCommandRequestContext);
                                    }
                                    else if (request is ProcessSendVideoStreamingStatusRequestContext)
                                    {
                                        RequestProcessor.TransmitSendVideoStreamingStatusRequest(trainClient, request as ProcessSendVideoStreamingStatusRequestContext);
                                    }
                                    else
                                    {
                                        // No other request type supported
                                    }

                                    requestIsTransmitted = true;
                                }
                                catch (Exception ex)
                                {
                                    if (!RequestProcessor.ShouldContinueOnTransmissionError(ex))
                                    {
                                        // Assume transmitted (no reason to retry)
                                        requestIsTransmitted = true;
                                    }
                                }
                                finally
                                {
                                    if (trainClient.State == CommunicationState.Faulted)
                                    {
                                        trainClient.Abort();
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            if (!RequestProcessor.ShouldContinueOnTransmissionError(ex))
                            {
                                // Assume transmitted (no reason to retry)
                                requestIsTransmitted = true;
                            }
                        }
                    }

                    break;

                    case T2GManagerErrorEnum.eT2GServerOffline:
                        RequestProcessor.SendNotificationToGroundApp(request.RequestId, PIS.Ground.GroundCore.AppGround.NotificationIdEnum.LiveVideoControlT2GServerOffline, string.Empty);
                        break;

                    case T2GManagerErrorEnum.eElementNotFound:
                        RequestProcessor.SendNotificationToGroundApp(request.RequestId, PIS.Ground.GroundCore.AppGround.NotificationIdEnum.LiveVideoControlElementNotFound, request.ElementId);
                        break;

                    case T2GManagerErrorEnum.eServiceInfoNotFound:
                        RequestProcessor.SendNotificationToGroundApp(request.RequestId, PIS.Ground.GroundCore.AppGround.NotificationIdEnum.LiveVideoControlServiceNotFound, request.ElementId);
                        break;

                    default:
                        break;
                    }
                }

                break;

            case T2GManagerErrorEnum.eT2GServerOffline:
                RequestProcessor.SendNotificationToGroundApp(request.RequestId, PIS.Ground.GroundCore.AppGround.NotificationIdEnum.LiveVideoControlT2GServerOffline, string.Empty);
                break;

            case T2GManagerErrorEnum.eElementNotFound:
                requestIsTransmitted = true;
                RequestProcessor.SendNotificationToGroundApp(request.RequestId, PIS.Ground.GroundCore.AppGround.NotificationIdEnum.LiveVideoControlElementNotFound, request.ElementId);
                break;

            default:
                break;
            }

            request.TransmissionStatus = requestIsTransmitted;

            if (request.State == RequestState.WaitingRetry && request.TransferAttemptsDone == 1)
            {
                // first attempt failed, send notification
                RequestProcessor.SendNotificationToGroundApp(request.RequestId, PIS.Ground.GroundCore.AppGround.NotificationIdEnum.LiveVideoControlDistributionWaitingToSend, request.ElementId);
            }
        }
        /// <summary>Executes the transmit event action.</summary>
        private static void OnTransmitEvent()
        {
            try
            {
                List <RequestContext> currentRequests = new List <RequestContext>();

                while (true)
                {
                    if (currentRequests.Count == 0)
                    {
                        _transmitEvent.WaitOne();
                    }

                    lock (RequestProcessor._lock)
                    {
                        // Move pending from _newRequests to currentRequests
                        if (_newRequests.Count > 0)
                        {
                            currentRequests.AddRange(RequestProcessor._newRequests);
                            RequestProcessor._newRequests.Clear();
                            currentRequests.RemoveAll(c => c == null);
                        }
                    }

                    for (int i = 0; i < currentRequests.Count; ++i)
                    {
                        RequestContext request = currentRequests[i];

                        switch (request.State)
                        {
                        case RequestState.Created:
                            for (int j = currentRequests.Count - 1; j >= 0; --j)
                            {
                                RequestContext c = currentRequests[j];
                                if (i != j && (c.ElementId == request.ElementId && ((c.RequestId != request.RequestId) || (c.RequestId == Guid.Empty || request.RequestId == Guid.Empty))))
                                {
                                    currentRequests.RemoveAt(j);
                                    if (j < i)
                                    {
                                        --i;
                                    }
                                }
                            }
                            break;

                        case RequestState.ReadyToSend:

                            RequestProcessor.TransmitRequest(request);
                            break;

                        case RequestState.WaitingRetry:
                            break;

                        case RequestState.Expired:
                            lock (RequestProcessor._lock)
                            {
                                RequestProcessor._newRequests.Add(request);
                                RequestProcessor._transmitEvent.Set();
                            }

                            break;

                        case RequestState.Transmitted:
                            request.CompletionStatus = true;
                            break;

                        case RequestState.AllRetriesExhausted:
                            break;

                        case RequestState.Completed:
                            break;
                        }
                    }

                    currentRequests.RemoveAll(c => c.IsStateFinal);
                    Thread.Sleep(100);
                }
            }
            catch (ThreadAbortException)
            {
                // No logic to apply
            }
            catch (System.Exception exception)
            {
                LogManager.WriteLog(TraceType.EXCEPTION, exception.Message, "PIS.Ground.LiveVideoControl.LiveVideoControlService.OnTransmitEvent", exception, EventIdEnum.LiveVideoControl);
            }
        }