private void ProcessCommand(CommandDefinition.CommandFormat command) { if (ProcessCommandEvent != null) try { ProcessCommandEvent(command); } catch { /*nobody to report to*/ } if (command.CommandAck.AckRequired == BooleanValue.True) SendAck(command); }
private CommandDefinition.CommandFormat? CommandSendProcess(CommandDefinition.CommandFormat? reply) { if (!reply.HasValue) reply = null; else if (reply.Value.CommandAck.Command == CommandEnum.AdaptiveModeSpeed) { AdaptiveSpeed = BitConverter.ToSingle(reply.Value.Payload, 0); AdaptiveSpeedMode = (OperatingMode)reply.Value.Action.SubAction; SpeedMessageEvent.Set(); reply = null; } else if (reply.Value.CommandAck.Command == CommandEnum.SignOfLife) { uint sequence = BitConverter.ToUInt32(reply.Value.Payload, 0); SignOfLifeSequence = sequence; // If a board reset is detected, notify any subscribers. APCSReset = /*reset?*/ SignOfLifeSequence > (uint)int.MaxValue; if (/*reset?*/ APCSReset) if (/*not shutting down?*/ !_monitorEnd.WaitOne(0)) if (/*subscribers?*/ APCSResetEvent != null) try { APCSResetEvent(this, EventArgs.Empty); } catch { } reply = null; } return reply; }
private CommandDefinition.CommandFormat? /*reply, if any*/ CommandSend(CommandDefinition.CommandFormat command, bool replyIsExpected = true) { CommandDefinition.CommandFormat? reply = null; try { int ReadBufferLength = 10 * Marshal.SizeOf(typeof(CommandDefinition.CommandFormat)); lock (_commandSendLock) if (/*run?*/ !_monitorEnd.WaitOne(CommandMargin)) if (/*OK?*/ (_connection != null) && _connection.Connected && (_connection.GetStream() != null)) { byte[] buffer = command.Serialize(); _connection.GetStream().Write(buffer, 0, buffer.Length); _connection.GetStream().Flush(); CommandMarginReset(); if (/*reply expected?*/ replyIsExpected) if (/*run?*/ !_monitorEnd.WaitOne(0)) { // Acquire the reply. buffer = new byte[ReadBufferLength]; reply = null; for (int retry = 0; /*OK?*/ retry < CommandSendReads; reply = null, retry++) if (!_connection.GetStream().DataAvailable) if (/*run?*/ !_monitorEnd.WaitOne((retry + 1) * Utilities.TimeTENTH)) continue; else break; else { // Read blocks/waits up through // TcpClient.GetStream().ReadTimeout; if the // client is disposed, the read faults. if (/*read OK?*/ _connection.GetStream().Read(buffer, 0, buffer.Length) >= 1) { reply = CommandSendProcess(command.Deserialize(buffer)); if (/*OK?*/ reply != null) if (/*OK?*/ reply.HasValue) if (/*OK?*/ reply.Value.CommandAck.Command == command.CommandAck.Command) if (/*OK?*/ reply.Value.Action.Action == ActionEnum.Response) { if (/*run?*/ !_monitorEnd.WaitOne(0)) if (/*subscriber(s)?*/ ApcsUpdate != null) try { ApcsUpdate(reply.Value.CommandAck.Command, reply.Value.Action.Action, reply.Value.Action.SubAction, reply.Value.Payload); } catch { } break; } } else break; } try { // Empty the "pipe." buffer = new byte[ReadBufferLength]; Debug.Assert(_connection.GetStream().ReadTimeout == Utilities.TimeTENTH); Debug.Assert(_connection.GetStream().CanRead); while (/*run?*/ !_monitorEnd.WaitOne(0) && /*not empty?*/ _connection.GetStream().DataAvailable) // Read blocks/waits up through // TcpClient.GetStream().ReadTimeout; if the // client is disposed, the read faults. if (/*data?*/ _connection.GetStream().Read(buffer, 0, buffer.Length) >= 1) CommandSendProcess(command.Deserialize(buffer)); } catch { } } } } catch { ConnectionDispose(); if (/*run?*/ !_monitorEnd.WaitOne(0)) throw; } return reply; }
private string CommandReplyValidate(CommandDefinition.CommandFormat? reply, CommandEnum expectedCommand, byte expectedSubAction) { string result = CommandReplyValidate(reply, expectedCommand); if (/*OK?*/ string.IsNullOrWhiteSpace(result)) if (/*fail?*/ reply.Value.CommandAck.IsAck != BooleanValue.True) result = ".Value.CommandAck.IsAck(" + reply.Value.CommandAck.IsAck.ToString() + ") != BooleanValue.True"; else if (/*fail?*/ reply.Value.Action.SubAction != expectedSubAction) result = ".Value.Action.SubAction(" + reply.Value.Action.SubAction.ToString() + ") != " + expectedSubAction.ToString(); return result; }
private string CommandReplyValidate(CommandDefinition.CommandFormat? reply, CommandEnum expectedCommand) { string result = /*OK*/ string.Empty; if (/*fail?*/ reply == null) result = "null reply"; else if (/*fail?*/ !reply.HasValue) result = "reply has no value (!.HasValue)"; else if (/*fail?*/ reply.Value.CommandAck.Command != expectedCommand) result = ".Value.CommandAck.Command(" + reply.Value.CommandAck.Command.ToString() + ") != " + expectedCommand.ToString(); else if (/*fail?*/ reply.Value.Action.Action != ActionEnum.Response) result = ".Value.Action.Action(" + reply.Value.Action.Action.ToString() + ") != " + ActionEnum.Response.ToString(); return result; }
private void ReplySendBase(CommandDefinition.CommandFormat reply) { try { lock (_sessionSocket) { byte[] buffer = reply.Serialize(); if (_sessionSocket.Send(buffer) < 1) throw new Exception(); } } catch { SessionClose( /*_sessionSocket == null*/ ); /*make ServerAgent reconnect*/ throw; } }
private bool ReplySend(CommandDefinition.CommandFormat reply) { try { ReplySendBase(reply); } catch { return false; } return true; }
private void SendAck(CommandDefinition.CommandFormat command) { CommandDefinition.CommandFormat /*can't name it command*/ cmd = new CommandDefinition.CommandFormat(); cmd.CommandAck.Command = command.CommandAck.Command; cmd.CommandAck.IsAck = BooleanValue.True; cmd.Action.Action = ActionEnum.Response; cmd.Action.SubAction = command.Action.SubAction; cmd.Payload = command.Payload; ReplySend(cmd); }
private bool ConfirmSetActionResponse(CommandDefinition.CommandFormat? response, CommandEnum command, byte subAction) { return (response != null && response.Value.CommandAck.Command == command && response.Value.Action.Action == ActionEnum.Response && response.Value.CommandAck.IsAck == BooleanValue.True && response.Value.Action.SubAction == subAction); }
private CommandDefinition.CommandFormat? SendCommand(CommandDefinition.CommandFormat command, bool expectingReply) { CommandDefinition.CommandFormat? response = null; try { if (Connected) { byte[] cmd = command.Serialize(); _responseEvent.Reset(); _networkStream.Write(cmd, 0, cmd.Length); for (int i = 0; i < _sendCommandRetrys; i++) { if (_responseEvent.WaitOne(_apcsCommandTimeout)) { if (_commandResponse.CommandAck.Command == command.CommandAck.Command && _commandResponse.Action.Action == ActionEnum.Response) { response = _commandResponse; _responseEvent.Reset(); break; } } } } #if false else throw new Exception("SendCommand called while not connected to APCS."); #endif } catch (Exception ex) { if (/*not terminated?*/ !_cancelEvent.WaitOne(0)) { Debug.Assert(Lgr != null); Lgr.LogError(ex); } } return response; }
private CommandDefinition.CommandFormat? CommandSendProcess(CommandDefinition.CommandFormat? reply) { #if !DEBUG // Any kind of (even marginally valid) reply from the APCS is a suitable sign of life // indicator: reset the APCS's sign of life timer by recreating it. WatchDogCreate(); #endif // Process the reply. if (!reply.HasValue) reply = null; else if (reply.Value.CommandAck.Command == CommandEnum.AdaptiveModeSpeed) { AdaptiveSpeed = BitConverter.ToSingle(reply.Value.Payload, 0); AdaptiveSpeedMode = (OperatingMode)reply.Value.Action.SubAction; SpeedMessageEvent.Set(); reply = null; } else if (reply.Value.CommandAck.Command == CommandEnum.SignOfLife) { uint sequence = BitConverter.ToUInt32(reply.Value.Payload, 0); SignOfLifeSequence = sequence; // If a board reset is detected, notify any subscribers. APCSReset = /*reset?*/ SignOfLifeSequence > (uint)int.MaxValue; if (/*reset?*/ APCSReset) if (/*not shutting down?*/ !_monitorEnd.WaitOne(0)) if (/*subscribers?*/ APCSResetEvent != null) try { APCSResetEvent(this, EventArgs.Empty); } catch { } reply = null; } return reply; }
static void hostAccess_ProcessCommandEvent(CommandDefinition.CommandFormat command) { if (command.CommandAck.Command == CommandEnum.ScanMode) { if (command.Action.Action == ActionEnum.Set) { currentEnergyMode = (ScanEnergyMode)command.Action.SubAction; PWMOutputConfig pwmConfig = (PWMOutputConfig)pc.GetPWMRunStatus(); if (pwmConfig == PWMOutputConfig.OutputEnabled) pc.PWMOutputDisable(); if (currentEnergyMode == ScanEnergyMode.Dual) { Reset.Write(true); Preset.Write(true); } else if (currentEnergyMode == ScanEnergyMode.High) { Reset.Write(true); Preset.Write(false); } else { Reset.Write(false); Preset.Write(true); } if (pwmConfig == PWMOutputConfig.OutputEnabled) pc.PWMOutputEnable(); } hostAccess.SendScanModeResponse(currentEnergyMode); } else if (command.CommandAck.Command == CommandEnum.StaticPulseFreq) { OperatingMode mode = (OperatingMode)command.Action.SubAction; int freq = BitConverter.ToInt32(command.Payload, 0); ; if (command.Action.Action == ActionEnum.Set) { if (mode == OperatingMode.NonAdaptiveMobile) StaticPulseFreq[0] = freq; else if (mode == OperatingMode.NonAdpativePortal) StaticPulseFreq[1] = freq; if (currentOperatingMode == mode) { currentStaticPulseFreq = freq; pc.UpdatePWMFrequency(freq); } hostAccess.SendStaticPulseFreqResponse(mode, freq); } else if (command.Action.Action == ActionEnum.Get) { if (mode == OperatingMode.NonAdaptiveMobile) freq = StaticPulseFreq[0]; else if (mode == OperatingMode.NonAdpativePortal) freq = StaticPulseFreq[1]; hostAccess.SendStaticPulseFreqResponse(mode, freq); } } else if (command.CommandAck.Command == CommandEnum.PulseWidth) { if (command.Action.Action == ActionEnum.Set) { if (currentPulseWidth != (PulseWidth)command.Action.SubAction) { currentPulseWidth = (PulseWidth)command.Action.SubAction; pc.UpdatePWMPulseWidth(PulseWidthsDutyCycle[(int)currentPulseWidth - 1]); } } hostAccess.SendPulseWidthResponse(currentPulseWidth); } else if (command.CommandAck.Command == CommandEnum.ConfigPulseWidth) { if (command.Action.Action == ActionEnum.Set) { int index = command.Action.SubAction - 1; PulseWidthsDutyCycle[index] = BitConverter.ToSingle(command.Payload, 0); if (currentPulseWidth == (PulseWidth)command.Action.SubAction) pc.UpdatePWMPulseWidth(PulseWidthsDutyCycle[index]); } PulseWidth width = (PulseWidth)command.Action.SubAction; hostAccess.SendPulseWidthConfigResponse(width, PulseWidthsDutyCycle[(byte)width - 1]); } else if (command.CommandAck.Command == CommandEnum.OperatingMode) { short minFreq, maxFreq; if (command.Action.Action == ActionEnum.Set) { minFreq = (short)BitConverter.ToInt16(command.Payload, 0); maxFreq = (short)BitConverter.ToInt16(command.Payload, 2); currentOperatingMode = (OperatingMode)command.Action.SubAction; if ((currentOperatingMode == OperatingMode.NonAdaptiveMobile) || (currentOperatingMode == OperatingMode.NonAdpativePortal)) { if (currentOperatingMode == OperatingMode.NonAdaptiveMobile) currentStaticPulseFreq = StaticPulseFreq[0]; else currentStaticPulseFreq = StaticPulseFreq[1]; pc.SetOperatingMode(currentOperatingMode); pc.UpdatePWMFrequency(currentStaticPulseFreq); pc.UpdatePWMPulseWidth(PulseWidthsDutyCycle[(int)currentPulseWidth - 1]); pc.PWMOutputEnable(); } else if ((currentOperatingMode == OperatingMode.AdaptiveMobile) || (currentOperatingMode == OperatingMode.AdaptivePortal)) { pc.SetFrequencyRange(currentOperatingMode, minFreq, maxFreq); pc.SetOperatingMode(currentOperatingMode); pc.PWMOutputEnable(); } hostAccess.SendOperatingModeResponse(currentOperatingMode, minFreq, maxFreq); } else if (command.Action.Action == ActionEnum.Get) { pc.GetFrequencyRange(currentOperatingMode, out minFreq, out maxFreq); hostAccess.SendOperatingModeResponse(currentOperatingMode, minFreq, maxFreq); } } else if (command.CommandAck.Command == CommandEnum.AdaptiveModeToTrigRatio) { float ratio; OperatingMode mode = (OperatingMode)command.Action.SubAction; if (command.Action.Action == ActionEnum.Set) { ratio = BitConverter.ToSingle(command.Payload, 0); pc.SetInputToOutputRatio(mode, ratio); hostAccess.SendAdaptiveModeToTrigRatioResponse(mode, ratio); } else if (command.Action.Action == ActionEnum.Get) { pc.GetInputToOutputRatio(mode, out ratio); hostAccess.SendAdaptiveModeToTrigRatioResponse(mode, ratio); } } else if (command.CommandAck.Command == CommandEnum.AdaptiveSpeedFeedbackConfig) { if (command.Action.Action == ActionEnum.Set) { adaptiveSpeedMsgFreq = BitConverter.ToSingle(command.Payload, 0); speedMsgMode = (AdaptiveSpeedFeedbackConfig)command.Action.SubAction; if ((speedMsgMode == AdaptiveSpeedFeedbackConfig.EnabledWithFreq) && (adaptiveSpeedMsgFreq > 0.0f)) { int period = (int)(1000.0f / adaptiveSpeedMsgFreq); adaptiveSpeedMsgTimer.Change(period, period); } else adaptiveSpeedMsgTimer.Change(Timeout.Infinite, Timeout.Infinite); } hostAccess.SendAdaptiveSpeedFeedbackConfigResponse(speedMsgMode, adaptiveSpeedMsgFreq); } else if (command.CommandAck.Command == CommandEnum.PWMOutput) { if (command.Action.Action == ActionEnum.Set) { if ((PWMOutputConfig)command.Action.SubAction == PWMOutputConfig.OutputEnabled) pc.PWMOutputEnable(); else pc.PWMOutputDisable(); hostAccess.SendPWMOutputStatus((PWMOutputConfig)command.Action.SubAction); } else if (command.Action.Action == ActionEnum.Get) { hostAccess.SendPWMOutputStatus((PWMOutputConfig)pc.GetPWMRunStatus()); } } else if (command.CommandAck.Command == CommandEnum.ResetBoard) ResetBoard(); }