public ViscaProtocolProcessor(Action <byte[]> sendData, Action <byte, string, object[]> logAction, int commandTimeOut)
        {
            _sendData       = sendData;
            _logAction      = logAction;
            _commandTimeOut = commandTimeOut;

            Cameras = new CamerasIndexer(getCameraAction);
#if SSHARP
            _sendQueueItemInProgressTimer = new CTimer((o) =>
#else
            _sendQueueItemInProgressTimer = new Timer((o) =>
#endif
            {
                _sendQueueCommandInProgress = null;
                logMessage(1, "Command timeout");
                sendNextQueuedCommand();
            }, null, Timeout.Infinite, Timeout.Infinite);

#if SSHARP
            _responseParseThread = new Thread(parseResponse, null, Thread.eThreadStartOptions.Running);
#else
            _responseParseThread = new Thread(parseResponse);
            _responseParseThread.Start();
#endif
        }
Ejemplo n.º 2
0
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, null))
            {
                return(false);
            }
            if (ReferenceEquals(this, obj))
            {
                return(true);
            }

            ViscaTxPacket second = obj as ViscaTxPacket;

            return(second is object && _hash == second._hash);
        }
        /// <summary>
        /// Sends the next queued command to the device
        /// </summary>
        private void sendNextQueuedCommand()
        {
            if (_sendQueue.Count > 0)
            {
                _sendQueueCommandInProgress = _sendQueue.Dequeue();
                logMessage(1, "Command '{0}' Dequeued. CommandQueue Size: {1}", _sendQueueCommandInProgress.ToString(), _sendQueue.Count);
                // start the timer to expire current command in case of no response
#if SSHARP
                _sendQueueItemInProgressTimer.Reset(_commandTimeOut);
#else
                _sendQueueItemInProgressTimer.Change(_commandTimeOut, Timeout.Infinite);
#endif
                _sendData(_sendQueueCommandInProgress);
            }
        }
        public void EnqueueCommand(ViscaTxPacket command)
        {
            // check for existing command in the Queue
            bool commandIsEnqueued = false;

            foreach (var sendQueueItem in _sendQueue)
            {
                //if (sendQueueItem.Packet == command)
                if (sendQueueItem == command)
                {
                    commandIsEnqueued = true;
                    break;
                }
            }

            if (commandIsEnqueued)
            {
                logMessage(1, "Enqueueing command '{0}' is duplicate, skipping. CommandQueue Size: '{1}'", command.ToString(), _sendQueue.Count);
                logMessage(2, "CommandQueue:");
                foreach (var sendQueueItem in _sendQueue)
                {
                    logMessage(2, "\t'{0}'", sendQueueItem.ToString());
                }
            }
            else
            {
                // If command is ViscaDynamicCommand, clone it to get static version for enquing
                if (command is ViscaDynamicCommand)
                {
                    command = (command as ViscaDynamicCommand).Clone();
                }
                _sendQueue.Enqueue(command);
                logMessage(1, "Enqueued command '{0}'. CommandQueue Size: '{1}'", command.ToString(), _sendQueue.Count);
            }

            if (_sendQueueCommandInProgress == null && (_responseQueue.Count == 0))
            {
                sendNextQueuedCommand();
            }
        }
        private void parseResponse(object obj)
#endif
        {
            while (true)
            {
                try
                {
                    ViscaRxPacket rxPacket = _responseQueue.Dequeue();
                    if (rxPacket == null)
                    {
                        logMessage(2, "Exception in parseResponse thread, deque byte array is null");
                        break;
                    }

                    //if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
                    logMessage(2, "Response '{0}' Dequeued. ResponseQueue Size: {1}",
                               rxPacket.ToString(),
                               //String.Concat(message.Select(b => string.Format(@"[{0:X2}]", (int)b)).ToArray()),
                               _responseQueue.Count);

                    if (rxPacket.IsNetworkChange)
                    {
                        // TODO: rxPacket.IsNetworkChange not sure what shall we doo
                        continue;
                    }
                    else if (rxPacket.IsClearBroadcast)
                    {
                        // TODO: rxPacket.IsClearBroadcast not sure what shall we doo
                        continue;
                    }


                    if (_sendQueueCommandInProgress == null)
                    {
                        /// response is not associated with any particular command
                        logMessage(2, "Collision, response for command not in progress");
                    }
                    else
                    {
#if SSHARP
                        _sendQueueItemInProgressTimer.Stop();
#else
                        _sendQueueItemInProgressTimer.Change(Timeout.Infinite, Timeout.Infinite);
#endif
                        if (rxPacket.IsAck)
                        {
                            _socketInProgress = rxPacket.Socket;
                            logMessage(1, "Command '{0}' accepted on socket '{1}'", _sendQueueCommandInProgress.ToString(), _socketInProgress.Value);
                            continue;
                        } // rxPacket.IsAck
                        else if (rxPacket.IsCompletionCommand)
                        {
                            if (!_sendQueueCommandInProgress.IsCommand)
                            {
                                logMessage(2, "Collision, completion message is not for Command type message");
                            }
                            ViscaCommand command = _sendQueueCommandInProgress as ViscaCommand;
                            if (command != null && command.CompletionAction != null)
                            {
                                command.CompletionAction();
                            }
                        } // rxPacket.IsCompletionCommand
                        else if (rxPacket.IsCompletionInquiry)
                        {
                            // we have pending clearance command in progress, use it's processing hook
                            var query = _sendQueueCommandInProgress as ViscaInquiry;
                            if (query != null)
                            {
                                query.Process(rxPacket);
                            }
                            else
                            {
                                logMessage(2, "Collision, expecting ViscaInquiry type as command in progress");
                            }
                        } // rxPacket.IsCompletionInquiry
                        else if (rxPacket.IsError)
                        {
                            // Error message
                            switch (rxPacket.Error)
                            {
                            case ViscaError.Length:
                                // Message Length Error
                                logMessage(2, "Error from device: Message Length Error");
                                break;

                            case ViscaError.Syntax:
                                // Syntax Error
                                logMessage(2, "Error from device: Syntax Error");
                                break;

                            case ViscaError.Full:
                                // Command Buffer Full
                                logMessage(2, "Error from device: Command Buffer Full");
                                break;

                            case ViscaError.Canceled:
                                // Command Cancelled
                                logMessage(2, "Error from device: Command Cancelled");
                                break;

                            case ViscaError.NoSocket:
                                // No Socket
                                logMessage(2, "Error from device: No Socket");
                                break;

                            case ViscaError.NotExecutable:
                                // Command not executable
                                logMessage(2, "Error from device: Command not executable");
                                break;
                            }
#if SSHARP
                            if (_sendQueueCommandInProgress.ErrorAction != null)
                            {
                                _sendQueueCommandInProgress.ErrorAction(rxPacket.Error);
                            }
#else
                            _sendQueueCommandInProgress.ErrorAction?.Invoke(rxPacket.Error);
#endif
                        } // rxPacket.IsError
                        else
                        {
                            logMessage(1, "Error: unknown packet type");
                        }

                        logMessage(2, "Completing command in progress: '{0}'", _sendQueueCommandInProgress.ToString());
                        _sendQueueCommandInProgress = null;
                        _socketInProgress           = null;
                    }
                }
#if SSHARP
#else
                catch (OperationCanceledException)
                {
                    logMessage(2, "Visca Response Queue shutdown");
                    break;
                }
#endif
                catch (Exception e)
                {
                    logMessage(2, "Exception in parseResponse thread: '{0}'\n{1}", e.Message, e.StackTrace);
                }

                if ((_sendQueue.Count > 0) && (_responseQueue.Count == 0))
                {
                    sendNextQueuedCommand();
                }
            } // while(true)
#if SSHARP
            return(null);
#else
            return;
#endif
        }