private void Start_AppBarButton_Click(object sender, RoutedEventArgs e) { if (_periodicTimer != null) { _periodicTimer.Cancel(); _periodicTimer = null; } // we use temporal copy of beaocnlist for testing purposes tmpCollection = new ObservableCollection <Beacon>(); foreach (Beacon beacon in BeaconCollection) { // store the listening cycle, so we can show it in the results beacon.ListeningCycle = AppSettings.Lifecycle; tmpCollection.Add(BeaconFactory.DublicateBeacon(beacon)); } //reset counter _listeningCycleCounter = 0; //and start the timer _periodicTimer = ThreadPoolTimer.CreatePeriodicTimer(new TimerElapsedHandler(PeriodicTimerCallback), TimeSpan.FromMilliseconds(AppSettings.Lifecycle)); //show the test overlay ProgressView.Visibility = Visibility.Visible; }
private void CalculateDistance(int rawSignalStrengthInDBm, int measuredPower) { if (rawSignalStrengthInDBm != 0 && measuredPower != 0) { Distance = BeaconFactory.CalculateDistanceFromRssi(rawSignalStrengthInDBm, measuredPower); } }
/// <summary> /// Constructs Beacon instances from the trigger data and adds recognized beacons to the _beacons list. /// </summary> private List <Beacon> TriggerDetailsToBeacons(BluetoothLEAdvertisementWatcherTriggerDetails triggerDetails) { List <Beacon> beacons = new List <Beacon>(); if (triggerDetails != null) { foreach (var bleAdvertisementReceivedEventArgs in triggerDetails.Advertisements) { Beacon beacon = BeaconFactory.BeaconFromBluetoothLeAdvertisementReceivedEventArgs(bleAdvertisementReceivedEventArgs); beacons.Add(beacon); } } return(beacons); }
public async void BeaconEngine_Discovered(BluetoothLEAdvertisementReceivedEventArgs args) { //System.Diagnostics.Debug.WriteLine("Found Beacon : " + args.BluetoothAddress); //the test is progressing, so we do minimun amount of work here //and simply mark the beacon we got as seen during this test cycle if (_periodicTimer != null) { foreach (Beacon beacon in tmpCollection) { if (beacon.BluetoothAddress == args.BluetoothAddress) { if (_listeningCycleCounter < beacon.DiscoveryTestData.Length) { beacon.DiscoveryTestData[_listeningCycleCounter] = true; return; } } } //if it was some beacon we do not have in our list, then we simply ignore it return; } //beaconlist is only updated while we are not doing test await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Beacon beacon = BeaconFactory.BeaconFromBluetoothLEAdvertisementReceivedEventArgs(args); if (beacon == null) { return; } bool existingBeaconUpdated = false; foreach (Beacon existingBeacon in BeaconCollection) { if (existingBeacon.Update(beacon)) { existingBeaconUpdated = true; beacon.Dispose(); } } if (!existingBeaconUpdated) { BeaconCollection.Add(beacon); } }); }
/// <summary> /// Triggered when the watcher receives an advertisement. /// If the advertisement came from a beacon, a Beacon instance is created based on the /// received data. A new beacon is added to the list and an existing one is only updated. /// </summary> private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { Logger.Debug("Scanner: Advertisement received " + args.Timestamp.ToString("HH:mm:ss.fff")); Beacon beacon = BeaconFactory.BeaconFromBluetoothLeAdvertisementReceivedEventArgs(args); if (beacon != null) { if (_enterDistanceThreshold != null && beacon.Distance > _enterDistanceThreshold.Value) { return; } if (!FilterBeaconByUuid(beacon)) { return; } NotifyBeaconEvent(beacon); } }
/// <summary> /// Starts the watcher and hooks its events to callbacks. /// </summary> /// <param name="manufacturerId">The manufacturer ID.</param> /// <param name="beaconCode">The beacon code.</param> /// <param name="beaconExitTimeoutInMiliseconds">Time in miliseconds after beacon will be trated as lost.</param> /// <param name="rssiEnterThreshold">Optional rssi threshold which will trigger beacon discover event. Value must be between -128 and 127.</param> /// <param name="enterDistanceThreshold">Optional minimal distance in meters that will trigger beacon discover event.</param> public void StartWatcher(ushort manufacturerId, ushort beaconCode, ulong beaconExitTimeoutInMiliseconds, short?rssiEnterThreshold = null, ulong?enterDistanceThreshold = null) { _beaconExitTimeout = beaconExitTimeoutInMiliseconds; _enterDistanceThreshold = enterDistanceThreshold; _beaconExitTimeout = 30000; if (_beaconExitTimeout < 1000) { _beaconExitTimeout = 1000; } if (Status != ScannerStatus.Started) { if (_bluetoothLeAdvertisementWatcher == null) { _bluetoothLeManufacturerData = BeaconFactory.BeaconManufacturerData(manufacturerId, beaconCode); _bluetoothLeAdvertisementWatcher = new BluetoothLEAdvertisementWatcher(); if (rssiEnterThreshold != null && rssiEnterThreshold.Value >= -128 && rssiEnterThreshold.Value <= 127) { _bluetoothLeAdvertisementWatcher.SignalStrengthFilter = new BluetoothSignalStrengthFilter() { InRangeThresholdInDBm = rssiEnterThreshold.Value }; } _bluetoothLeAdvertisementWatcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(_bluetoothLeManufacturerData); _bluetoothLeAdvertisementWatcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(0); _bluetoothLeAdvertisementWatcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(_beaconExitTimeout); _bluetoothLeAdvertisementWatcher.ScanningMode = BluetoothLEScanningMode.Active; } _bluetoothLeAdvertisementWatcher.Received += OnAdvertisementReceived; _bluetoothLeAdvertisementWatcher.Stopped += OnWatcherStopped; ServiceManager.LayoutManager?.VerifyLayoutAsync(); _bluetoothLeAdvertisementWatcher.Start(); Status = ScannerStatus.Started; Logger.Debug("Scanner.StartWatcher(): Watcher started"); } }
/// <summary> /// Starts advertizing based on the set values (beacon ID 1, ID 2 and ID 3). /// Note that this method does not validate the values and will throw exception, if the /// values are invalid. /// </summary> public void Start() { if (!IsStarted) { _beacon = new Beacon(); _beacon.Id1 = BeaconId1; _beacon.ManufacturerId = ManufacturerId; _beacon.Code = BeaconCode; _beacon.Id2 = BeaconId2; _beacon.Id3 = BeaconId3; _beacon.MeasuredPower = DefaultMeasuredPower; _advertisementPublisher = new BluetoothLEAdvertisementPublisher(); BluetoothLEAdvertisementDataSection dataSection = BeaconFactory.BeaconToSecondDataSection(_beacon); Logger.Debug("Advertiser.Start(): " + BeaconFactory.DataSectionToRawString(dataSection)); _advertisementPublisher.Advertisement.DataSections.Add(dataSection); _advertisementPublisher.Start(); IsStarted = true; } }
/// <summary> /// Registers the BLE advertisement watcher background task. /// </summary> /// <param name="configuration">Configuration for the new registration.</param> /// <returns>The registration result.</returns> private async Task <BackgroundTaskRegistrationResult> RegisterAdvertisementWatcherBackgroundTaskAsync(SdkConfiguration configuration) { BackgroundTaskRegistrationResult result = new BackgroundTaskRegistrationResult() { Success = false, Exception = null }; if (BackgroundTaskRegistered(AdvertisementClass)) { // Already registered Logger.Debug("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Already registered"); result.Success = true; } else { BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder(); backgroundTaskBuilder.Name = AdvertisementClass + Guid.NewGuid(); backgroundTaskBuilder.TaskEntryPoint = configuration.BackgroundAdvertisementClassName; BluetoothLEAdvertisementWatcherTrigger advertisementWatcherTrigger = new BluetoothLEAdvertisementWatcherTrigger(); // This filter includes all Sensorberg beacons var pattern = BeaconFactory.UuidToAdvertisementBytePattern(configuration.BackgroundBeaconUuidSpace, configuration.ManufacturerId, configuration.BeaconCode); advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern); ILayoutManager layoutManager = ServiceManager.LayoutManager; AppSettings = await ServiceManager.SettingsManager.GetSettings(); // Using MaxSamplingInterval as SamplingInterval ensures that we get an event only // when entering or exiting from the range of the beacon advertisementWatcherTrigger.SignalStrengthFilter.SamplingInterval = advertisementWatcherTrigger.MaxSamplingInterval; if (AppSettings.RssiEnterThreshold != null && AppSettings.RssiEnterThreshold.Value >= -128 && AppSettings.RssiEnterThreshold.Value <= 127) { advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = AppSettings.RssiEnterThreshold; } else { advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = Constants.DefaultBackgroundScannerEnterThreshold; } advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = SignalStrengthFilterOutOfRangeThresholdInDBm; advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(AppSettings.BeaconExitTimeout); IBackgroundTrigger trigger = advertisementWatcherTrigger; backgroundTaskBuilder.SetTrigger(trigger); try { BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register(); backgroundTaskRegistration.Completed += OnAdvertisementWatcherBackgroundTaskCompleted; backgroundTaskRegistration.Progress += OnAdvertisementWatcherBackgroundTaskProgress; result.Success = true; } catch (Exception ex) { result.Exception = ex; Logger.Error("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Failed to register: ", ex); if (ex.Message.Contains("0x800710DF)")) { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await new MessageDialog("Activate Bluetooth for the app").ShowAsync()); } } if (result.Success) { // Check if there was a pending filter update if (SdkData.BackgroundFilterUpdateRequired) { string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout); if (!string.IsNullOrEmpty(upToDateHash) && SdkData.LayoutBeaconId1Hash.Equals(upToDateHash)) { // Background filter updated successfully SdkData.BackgroundFilterUpdateRequired = false; BackgroundFiltersUpdated?.Invoke(this, null); } } else if (string.IsNullOrEmpty(SdkData.LayoutBeaconId1Hash)) { // This is the first time the background task is registered with valid layout => // set the hash string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout); if (!string.IsNullOrEmpty(upToDateHash)) { SdkData.LayoutBeaconId1Hash = upToDateHash; } } } } //Load last events from background await LoadBackgroundActions(); return(result); }