public async Task <T> Recieve <T>(int nTimeout) where T : RecieveBaseCommand { T retCommand = null; RecieveBaseCommand cmd = null; Log.Debug("Await response..."); if (!m_recieveQueue.TryDequeue(out cmd)) { Task completedTask = await Task.WhenAny(m_responseWaitHandle.Task, Task.Delay(nTimeout)); if (m_recieveQueue.TryDequeue(out cmd)) { retCommand = cmd as T; if (retCommand == null && cmd != null) { Log.Debug($"Discarding response {retCommand}..."); m_responseWaitHandle = new TaskCompletionSource <RecieveBaseCommand>(); retCommand = await Recieve <T>(nTimeout); } else { Log.Debug($"Returning response {retCommand}..."); m_responseWaitHandle = new TaskCompletionSource <RecieveBaseCommand>(); } } else { Log.Warn("Recieve timed out..."); //Timeout } } else { retCommand = cmd as T; m_responseWaitHandle = new TaskCompletionSource <RecieveBaseCommand>(); } return(retCommand); }
public async Task <IEnumerable <INukiLogEntry> > RequestLogEntries(bool blnMostRecent, UInt16 nStartIndex, UInt16 nCount, UInt16 nSecurityPIN) { List <INukiLogEntry> retEntries = new List <INukiLogEntry>(); int nRetryCount = 0; bool blnSuccessfull = false; while (!blnSuccessfull && nRetryCount++ <= 3) { try { using (var lockHandle = await Locker.Lock()) { if (lockHandle.Successfull && await Challenge()) { var cmdStatus = await m_UGDIO.Send <RecieveBaseCommand>(new SendRequestLogEntriesCommand(this, blnMostRecent, nStartIndex, nCount, nSecurityPIN), 30000); if ( (cmdStatus as RecieveStatusCommand)?.StatusCode == NukiErrorCode.COMPLETE || (cmdStatus as RecieveLogEntryCountCommand)?.Count > 0 || cmdStatus is RecieveLogEntryCommand) { if (cmdStatus is RecieveLogEntryCommand) { retEntries.Add(cmdStatus as RecieveLogEntryCommand); } bool blnTimeout = false, blmComplete = false; for (int i = retEntries.Count; i < nCount && !blnTimeout && !blmComplete; ++i) { RecieveBaseCommand cmd = await m_UGDIO.Recieve <RecieveBaseCommand>(30000); if (cmd == null) { //Timeout... blnTimeout = true; } else if (cmd is RecieveLogEntryCommand) { retEntries.Add(cmd as RecieveLogEntryCommand); } else if (cmd is RecieveStatusCommand) { blmComplete = true; } else { } // } blnSuccessfull = !blnTimeout; } else { } } else { Log.Warn("Challenge failed"); } } } catch (Exception ex) { Update(new NukiCommandException(NukiCommandType.RequestLogEntries, ex)); } } return(retEntries); //return await m_UGDIO.Send<RecieveLogEntryCountCommand>(new SendRequestDataCommand(NukiCommandType.LogEntryCount)); }
private void M_GattCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) { var recieveBuffer = args.CharacteristicValue; Log.Debug("M_GattCharacteristic_ValueChanged"); lock (syncroot) { DataReader reader = null; if (TryGetRecieveBuffer(recieveBuffer, out reader)) { while (reader.UnconsumedBufferLength >= 2) { if (m_cmdInProgress == null) { m_cmdInProgress = ResponseCommandParser.Parse(reader); } if (m_cmdInProgress != null) { m_cmdInProgress.ProcessRecievedData(reader); if (m_cmdInProgress.Complete) { var cmd = m_cmdInProgress; m_cmdInProgress = null; Log.Info($"Recieved Command {cmd}..."); bool blnWarnIfNotHandlet = false; if (cmd is RecieveErrorReportCommand) { Connection.Update(cmd as RecieveErrorReportCommand); } else if (cmd is RecieveNukiStatesCommand) { Connection.Update(cmd as RecieveNukiStatesCommand); } else if (cmd is RecieveChallengeCommand) { Connection.Update(cmd as RecieveChallengeCommand); } else { blnWarnIfNotHandlet = true; } m_recieveQueue.Enqueue(cmd); if (m_responseWaitHandle?.TrySetResult(cmd) == true) { Log.Debug("m_responseWaitHandle set"); } else { if (blnWarnIfNotHandlet) { Log.Warn($"Recieved Command {cmd} is not handlet..."); } } } else { Log.Debug($"Command {m_cmdInProgress.CommandType} not complete (Recieved {m_cmdInProgress.BytesRecieved} from {m_cmdInProgress.BytesTotal})..."); } } else { Log.Warn("Recieved unknown command"); } } } else { } } }
public virtual void Reset() { m_cmdInProgress = null; m_responseWaitHandle = new TaskCompletionSource <RecieveBaseCommand>(); m_recieveQueue = new ConcurrentQueue <RecieveBaseCommand>(); }
public static RecieveBaseCommand Parse(IDataReader reader) { RecieveBaseCommand cmd = null; if (reader.UnconsumedBufferLength >= 2) { NukiCommandType cmdType = (NukiCommandType)reader.ReadUInt16(); switch (cmdType) { case NukiCommandType.AuthorizationID: cmd = new RecieveAuthorizationIDCommand(); break; case NukiCommandType.Challenge: cmd = new RecieveChallengeCommand(); break; case NukiCommandType.ErrorReport: cmd = new RecieveErrorReportCommand(); break; case NukiCommandType.PublicKey: cmd = new RecievePublicKeyCommand(); break; case NukiCommandType.Status: cmd = new RecieveStatusCommand(); break; case NukiCommandType.NukiStates: cmd = new RecieveNukiStatesCommand(); break; case NukiCommandType.Config: cmd = new RecieveConfigCommand(); break; case NukiCommandType.BatteryReport: cmd = new RecieveBatteryReportCommand(); break; case NukiCommandType.LogEntryCount: cmd = new RecieveLogEntryCountCommand(); break; case NukiCommandType.LogEntry: cmd = new RecieveLogEntryCommand(); break; default: Log.Error($"Command {cmdType} is not handelt!"); break; } } else { //not enough data... } return(cmd); }