private void DataConsumerLoop() { while (true) { try { _cancelSource.Token.ThrowIfCancellationRequested(); Task.Delay(50).Wait(_cancelSource.Token); } catch (OperationCanceledException) { IncomingData?.Clear(); throw; } lock (IncomingQueue) { if (IncomingQueue.Count <= 0) { continue; } while (IncomingQueue.TryDequeue(out var frame)) { IncomingData.AddRange(frame); } } do { try { var raw = IncomingData.OfType <byte>().ToArray(); foreach (var hook in ScriptManager.Instance.RawStreamHooks) { hook?.OnRawDataAvailable(ref raw); } var msg = SPPMessage.DecodeMessage(raw); Log.Verbose($">> Incoming: {msg}"); foreach (var hook in ScriptManager.Instance.MessageHooks) { hook?.OnMessageAvailable(ref msg); } MessageReceived?.Invoke(this, msg); if (msg.TotalPacketSize >= IncomingData.Count) { IncomingData.Clear(); break; } IncomingData.RemoveRange(0, msg.TotalPacketSize); if (ByteArrayUtils.IsBufferZeroedOut(IncomingData)) { /* No more data remaining */ break; } } catch (InvalidPacketException e) { InvalidDataReceived?.Invoke(this, e); break; } } while (IncomingData.Count > 0); } }
private void DataConsumerLoop() { while (true) { try { _cancelSource.Token.ThrowIfCancellationRequested(); Task.Delay(50).Wait(_cancelSource.Token); } catch (OperationCanceledException) { IncomingData?.Clear(); throw; } lock (IncomingQueue) { if (IncomingQueue.Count <= 0) { continue; } while (IncomingQueue.TryDequeue(out var frame)) { IncomingData.AddRange(frame); } } var failCount = 0; do { var msgSize = 0; SPPMessage?msg = null; try { var raw = IncomingData.OfType <byte>().ToArray(); foreach (var hook in ScriptManager.Instance.RawStreamHooks) { hook?.OnRawDataAvailable(ref raw); } msg = SPPMessage.DecodeMessage(raw); msgSize = msg.TotalPacketSize; Log.Verbose($">> Incoming: {msg}"); foreach (var hook in ScriptManager.Instance.MessageHooks) { hook?.OnMessageAvailable(ref msg); } MessageReceived?.Invoke(this, msg); } catch (InvalidPacketException e) { // Attempt to remove broken message, otherwise skip data block var somIndex = 0; for (var i = 1; i < IncomingData.Count; i++) { if ((ActiveModel == Models.Buds && (byte)(IncomingData[i] ?? 0) == (byte)SPPMessage.Constants.SOM) || (ActiveModel != Models.Buds && (byte)(IncomingData[i] ?? 0) == (byte)SPPMessage.Constants.SOMPlus)) { somIndex = i; break; } } msgSize = somIndex; if (failCount > 5) { // Abandon data block InvalidDataReceived?.Invoke(this, e); break; } failCount++; } if (msgSize >= IncomingData.Count) { IncomingData.Clear(); break; } IncomingData.RemoveRange(0, msgSize); if (ByteArrayUtils.IsBufferZeroedOut(IncomingData)) { /* No more data remaining */ break; } } while (IncomingData.Count > 0); } }