Пример #1
0
 private void OnCharacteristicValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
 {
     try
     {
         using (Stream s = args.CharacteristicValue.AsStream())
         {
             using (BinaryReader br = new BinaryReader(s))
             {
                 LineSensorData lsd = CreateLineSensorData(br);
                 DeviceSentDataEvent?.Invoke(this, lsd);
             }
         }
     }
     catch (Exception e)
     {
         this.logger.Error(e, "unexpected exception while receiving data from BLE device");
     }
 }
Пример #2
0
        private async Task <LineSensorReading> getLineSensorData(double currentPosition, int numberOfSamples, CancellationToken token)
        {
            bool            callbackIsCalled = false;
            Semaphore       semaphore        = new Semaphore(0, 1);
            List <ushort[]> sensorValues     = new List <ushort[]>();

            DeviceSentDataEvent callback = (source, data) =>
            {
                callbackIsCalled = true;

                if (token.IsCancellationRequested)
                {
                    try
                    {
                        semaphore.Release();
                    }
                    catch (SemaphoreFullException)
                    {
                        // ignore as callback might get called multiple times after being cancelled
                    }
                }
                else if ((data.CurrentStatus & LineSensorStatus.LSS_OK_FLAG_NEW_DATA_AVAILABLE) == LineSensorStatus.LSS_OK_FLAG_NEW_DATA_AVAILABLE &&
                         (data.CurrentStatus & LineSensorStatus.LSS_ERROR) == 0)
                {
                    lock (sensorValues)
                    {
                        if (sensorValues.Count >= numberOfSamples)
                        {
                            semaphore.Release();
                        }
                        else
                        {
                            sensorValues.Add(data.SensorValues);
                        }
                    }
                }
            };

            this.wirelessLineSensor.DeviceSentDataEvent += callback;

            try
            {
                // make sure we purge all old events before starting to receive new ones

                while (callbackIsCalled)
                {
                    callbackIsCalled = false;
                    await Task.Delay(500).ConfigureAwait(false);
                }

                bool success = false;

                for (int i = 0; i < START_QUERYING_LINE_SENSOR_RETRIES_COUNT && !token.IsCancellationRequested; ++i)
                {
                    if (await this.wirelessLineSensor.StartQueryingLineSensor().ConfigureAwait(false))
                    {
                        success = true;
                        break;
                    }

                    await Task.Delay(100).ConfigureAwait(false);
                }

                if (!success)
                {
                    throw new InvalidOperationException("failed to start querying line sensor, wireless device might have disconnected or powered down");
                }

#if DEBUG
                if (!semaphore.WaitOne())
#else
                if (!semaphore.WaitOne(TIMEOUT_TO_QUERY_LINE_SENSOR_MILLISECONDS))
#endif
                {
                    throw new TimeoutException("querying line sensor timed out");
                }

                for (int i = 0; i < STOP_QUERYING_LINE_SENSOR_RETRIES_COUNT && !token.IsCancellationRequested; ++i)
                {
                    if (await this.wirelessLineSensor.StopQueryingLineSensor().ConfigureAwait(false))
                    {
                        token.ThrowIfCancellationRequested();

                        if (sensorValues.Count < numberOfSamples)
                        {
                            throw new InvalidOperationException($"for some reason we collected {sensorValues.Count} sensor values which is less than {numberOfSamples} sensor values ");
                        }
                        else if (sensorValues.Count > numberOfSamples)
                        {
                            sensorValues = sensorValues.GetRange(0, numberOfSamples);
                        }

                        return(new LineSensorReading {
                            Position = currentPosition, SensorValues = sensorValues
                        });
                    }

                    await Task.Delay(100).ConfigureAwait(false);
                }

                throw new InvalidOperationException("failed to stop querying line sensor, wireless device might have disconnected or powered down");
            }
            finally
            {
                this.wirelessLineSensor.DeviceSentDataEvent -= callback;
            }
        }