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 }
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 }