예제 #1
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);
                    }
                }

                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);
            }
        }
예제 #2
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);
            }
        }