Example #1
0
        private void RegisterBTWatcherTask()
        {
            // Registering a background trigger if it is not already registered. It will start background watcher.
            // First get the existing tasks to see if we already registered for it
            if (taskRegistration == null)
            {
                ApplicationData.Current.LocalSettings.Values[taskName]         = "";           //reset message
                ApplicationData.Current.LocalSettings.Values[BEACONPREFIX_TAG] = beaconPrefix; //reset message

                // At this point we assume we haven't found any existing tasks matching the one we want to register
                // First, configure the task entry point, trigger and name
                BluetoothLEAdvertisementWatcherTrigger trigger = SetupTrigger();

                var builder = new BackgroundTaskBuilder();
                builder.TaskEntryPoint = taskEntryPoint;
                builder.SetTrigger(trigger);
                builder.Name = taskName;

                // Now perform the registration.
                taskRegistration = builder.Register();

                // For this scenario, attach an event handler to display the result processed from the background task
                taskRegistration.Completed += OnBTWatcherTaskCompleted;

                MainPage.Current.UpdateDebugMessage(this, "RegisterBTWatcherTask: " + taskRegistration.Name + " / " + taskRegistration.TaskId);
            }
        }
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public Scenario3_BackgroundWatcher()
        {
            this.InitializeComponent();

            // Create and initialize a new trigger to configure it.
            trigger = new BluetoothLEAdvertisementWatcherTrigger();

            // Configure the advertisement filter to look for the data advertised by the publisher in Scenario 2 or 4.
            // You need to run Scenario 2 on another Windows platform within proximity of this one for Scenario 3 to
            // take effect.

            // Unlike the APIs in Scenario 1 which operate in the foreground. This API allows the developer to register a background
            // task to process advertisement packets in the background. It has more restrictions on valid filter configuration.
            // For example, exactly one single matching filter condition is allowed (no more or less) and the sampling interval

            // For determining the filter restrictions programatically across APIs, use the following properties:
            //      MinSamplingInterval, MaxSamplingInterval, MinOutOfRangeTimeout, MaxOutOfRangeTimeout

            // Part 1A: Configuring the advertisement filter to watch for a particular advertisement payload

            // First, let create a manufacturer data section we wanted to match for. These are the same as the one
            // created in Scenario 2 and 4. Note that in the background only a single filter pattern is allowed per trigger.
            var manufacturerData = new BluetoothLEManufacturerData();

            // Then, set the company ID for the manufacturer data. Here we picked an unused value: 0xFFFE
            manufacturerData.CompanyId = 0xFFFE;

            // Finally set the data payload within the manufacturer-specific section
            // Here, use a 16-bit UUID: 0x1234 -> {0x34, 0x12} (little-endian)
            DataWriter writer = new DataWriter();

            writer.WriteUInt16(0x1234);

            // Make sure that the buffer length can fit within an advertisement payload. Otherwise you will get an exception.
            manufacturerData.Data = writer.DetachBuffer();

            // Add the manufacturer data to the advertisement filter on the trigger:
            trigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

            // Part 1B: Configuring the signal strength filter for proximity scenarios

            // Configure the signal strength filter to only propagate events when in-range
            // Please adjust these values if you cannot receive any advertisement
            // Set the in-range threshold to -70dBm. This means advertisements with RSSI >= -70dBm
            // will start to be considered "in-range".
            trigger.SignalStrengthFilter.InRangeThresholdInDBm = -70;

            // Set the out-of-range threshold to -75dBm (give some buffer). Used in conjunction with OutOfRangeTimeout
            // to determine when an advertisement is no longer considered "in-range"
            trigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = -75;

            // Set the out-of-range timeout to be 2 seconds. Used in conjunction with OutOfRangeThresholdInDBm
            // to determine when an advertisement is no longer considered "in-range"
            trigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);

            // By default, the sampling interval is set to be disabled, or the maximum sampling interval supported.
            // The sampling interval set to MaxSamplingInterval indicates that the event will only trigger once after it comes into range.
            // Here, set the sampling period to 1 second, which is the minimum supported for background.
            trigger.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(1000);
        }
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public Scenario3_BackgroundWatcher()
        {
            this.InitializeComponent();

            // Create and initialize a new trigger to configure it.
            trigger = new BluetoothLEAdvertisementWatcherTrigger();

            // Configure the advertisement filter to look for the data advertised by the publisher in Scenario 2 or 4.
            // You need to run Scenario 2 on another Windows platform within proximity of this one for Scenario 3 to 
            // take effect.

            // Unlike the APIs in Scenario 1 which operate in the foreground. This API allows the developer to register a background
            // task to process advertisement packets in the background. It has more restrictions on valid filter configuration.
            // For example, exactly one single matching filter condition is allowed (no more or less) and the sampling interval

            // For determining the filter restrictions programatically across APIs, use the following properties:
            //      MinSamplingInterval, MaxSamplingInterval, MinOutOfRangeTimeout, MaxOutOfRangeTimeout

            // Part 1A: Configuring the advertisement filter to watch for a particular advertisement payload

            // First, let create a manufacturer data section we wanted to match for. These are the same as the one 
            // created in Scenario 2 and 4. Note that in the background only a single filter pattern is allowed per trigger.
            var manufacturerData = new BluetoothLEManufacturerData();

            // Then, set the company ID for the manufacturer data. Here we picked an unused value: 0xFFFE
            manufacturerData.CompanyId = 0xFFFE;

            // Finally set the data payload within the manufacturer-specific section
            // Here, use a 16-bit UUID: 0x1234 -> {0x34, 0x12} (little-endian)
            DataWriter writer = new DataWriter();
            writer.WriteUInt16(0x1234);

            // Make sure that the buffer length can fit within an advertisement payload. Otherwise you will get an exception.
            manufacturerData.Data = writer.DetachBuffer();

            // Add the manufacturer data to the advertisement filter on the trigger:
            trigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

            // Part 1B: Configuring the signal strength filter for proximity scenarios

            // Configure the signal strength filter to only propagate events when in-range
            // Please adjust these values if you cannot receive any advertisement 
            // Set the in-range threshold to -70dBm. This means advertisements with RSSI >= -70dBm 
            // will start to be considered "in-range".
            trigger.SignalStrengthFilter.InRangeThresholdInDBm = -70;

            // Set the out-of-range threshold to -75dBm (give some buffer). Used in conjunction with OutOfRangeTimeout
            // to determine when an advertisement is no longer considered "in-range"
            trigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = -75;

            // Set the out-of-range timeout to be 2 seconds. Used in conjunction with OutOfRangeThresholdInDBm
            // to determine when an advertisement is no longer considered "in-range"
            trigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);

            // By default, the sampling interval is set to be disabled, or the maximum sampling interval supported.
            // The sampling interval set to MaxSamplingInterval indicates that the event will only trigger once after it comes into range.
            // Here, set the sampling period to 1 second, which is the minimum supported for background.
            trigger.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(1000);
        }
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public Scenario5_AggregatingWatcher()
        {
            InitializeComponent();

            // Create and initialize a new trigger to configure it.
            trigger = new BluetoothLEAdvertisementWatcherTrigger();

            var manufacturerData = new BluetoothLEManufacturerData { CompanyId = 76 };
            trigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

            _tracker = new Tracker();
        }
Example #5
0
        BluetoothLEAdvertisementWatcherTrigger MakeWatcherTrigger()
        {
            var trigger = new BluetoothLEAdvertisementWatcherTrigger();

            trigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(
                new BluetoothLEManufacturerData()
            {
                CompanyId = TheTask.MSCompanyId
            }
                );
            return(trigger);
        }
Example #6
0
        private void initBluetoothAdvertisementWatcherTrigger()
        {
            this.trigger = new BluetoothLEAdvertisementWatcherTrigger();

            // Background advertisements require 1 advertisement filter. Here we filter by Guid in the Advertisement
            trigger.AdvertisementFilter.Advertisement.ServiceUuids.Add(peripheralDeviceServiceGUID);

            // Only activate the watcher when we're recieving values >= -80
            trigger.SignalStrengthFilter.InRangeThresholdInDBm = -80;

            // Stop watching if the value drops below -90 (user walked away)
            trigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;

            // Wait 5 seconds to make sure the device is really out of range
            trigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);
            trigger.SignalStrengthFilter.SamplingInterval  = TimeSpan.FromMilliseconds(2000);
        }
        /// <summary>
        /// Registers Bluetooth advertisement listener
        /// </summary>
        /// <returns></returns>
        public bool RegisterAdvertisementWatcherBackgroundTask()
        {
            if (BackgroundTaskRegistered(AdvertisementWatcherBackgroundTaskName))
            {
                return(true);
            }
            else
            {
                BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder();

                backgroundTaskBuilder.Name           = AdvertisementWatcherBackgroundTaskName;
                backgroundTaskBuilder.TaskEntryPoint = AdvertisementWatcherBackgroundTaskEntryPoint;

                IBackgroundTrigger trigger = null;

                BluetoothLEAdvertisementWatcherTrigger advertisementWatcherTrigger =
                    new BluetoothLEAdvertisementWatcherTrigger();

                //This filter includes UUIDSpace 7367672374000000ffff0000ffff00xx
                var pattern = BEACONIDToAdvertisementBytePattern(CommonConstants.UUIDSpace1);
                advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern);

                //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;
                advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm    = CommonConstants.SignalStrengthFilterInRangeThresholdInDBm;
                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = CommonConstants.SignalStrengthFilterOutOfRangeThresholdInDBm;
                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeTimeout        = TimeSpan.FromMilliseconds(9000);

                trigger = advertisementWatcherTrigger;

                backgroundTaskBuilder.SetTrigger(trigger);

                try
                {
                    BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register();
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("RegisterAdvertisementWatcherBackgroundTask(): Failed to register: " + ex);
                    return(false);
                }
                return(true);
            }
        }
        /// <summary>
        /// Registers Bluetooth advertisement listener
        /// </summary>
        /// <returns></returns>
        public bool RegisterAdvertisementWatcherBackgroundTask()
        {
            if (BackgroundTaskRegistered(AdvertisementWatcherBackgroundTaskName))
            {
                return true;
            }
            else
            {
                BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder();

                backgroundTaskBuilder.Name = AdvertisementWatcherBackgroundTaskName;
                backgroundTaskBuilder.TaskEntryPoint = AdvertisementWatcherBackgroundTaskEntryPoint;

                IBackgroundTrigger trigger = null;

                BluetoothLEAdvertisementWatcherTrigger advertisementWatcherTrigger =
                    new BluetoothLEAdvertisementWatcherTrigger();

                //This filter includes UUIDSpace 7367672374000000ffff0000ffff00xx
                var pattern = BEACONIDToAdvertisementBytePattern(CommonConstants.UUIDSpace1);
                advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern);

                //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;
                advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = CommonConstants.SignalStrengthFilterInRangeThresholdInDBm;
                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = CommonConstants.SignalStrengthFilterOutOfRangeThresholdInDBm;
                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(9000);

                trigger = advertisementWatcherTrigger;

                backgroundTaskBuilder.SetTrigger(trigger);

                try
                {
                    BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register();
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("RegisterAdvertisementWatcherBackgroundTask(): Failed to register: " + ex);
                    return false;
                }
                return true;
            }
        }
Example #9
0
        private void RegisterTasks()
        {
            if (BackgroundTaskRegistration.AllTasks.Any(x => x.Value.Name == TaskName))
            {
                return;
            }

            var backgroundTaskBuilder = new BackgroundTaskBuilder
            {
                Name           = TaskName,
                TaskEntryPoint = typeof(AdvertisementHandler).FullName
            };

            var trigger = new BluetoothLEAdvertisementWatcherTrigger();

            trigger.AdvertisementFilter.Advertisement.ServiceUuids.Add(flicServiceUuid);
            trigger.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(1000);

            backgroundTaskBuilder.SetTrigger(trigger);
            backgroundTaskBuilder.Register();
        }
Example #10
0
        public bool RegisterAdvertisementWatcherTask()
        {
            foreach (var task in BackgroundTaskRegistration.AllTasks)
            {
                if (task.Value.Name == TaskName)
                {
                    return(false);
                }
            }
            var builder = new BackgroundTaskBuilder
            {
                Name           = TaskName,
                TaskEntryPoint = $"{Namespace}.{TaskName}"
            };
            var trigger = new BluetoothLEAdvertisementWatcherTrigger();

            trigger.AdvertisementFilter.Advertisement.LocalName = "Digit";
            builder.SetTrigger(trigger);
            BackgroundTaskRegistration t = builder.Register();

            return(true);
        }
Example #11
0
        private BluetoothLEAdvertisementWatcherTrigger SetupTrigger()
        {
            // The watcher trigger used to configure the background task registration
            BluetoothLEAdvertisementWatcherTrigger trigger;

            // Create and initialize a new trigger to configure it.
            trigger = new BluetoothLEAdvertisementWatcherTrigger();

            // We need to add some payload to the advertisement. A publisher without any payload
            // or with invalid ones cannot be started. We only need to configure the payload once
            // for any publisher.

            // Add a manufacturer-specific section:
            // First, create a manufacturer data section
            var manufacturerData = new BluetoothLEManufacturerData();

            // Then, set the company ID for the manufacturer data. Here we picked an unused value: 0xFFFE
            manufacturerData.CompanyId = companyId;

            // Add the manufacturer data to the advertisement publisher:
            trigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

            trigger.SignalStrengthFilter.InRangeThresholdInDBm    = App.curScenario.BTFilterInRange;  // -50; // -60;
            trigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = App.curScenario.BTFilterOutRange; // -100;
            double timeout = App.curScenario.BTSamplingIntervalms * 2.5;

            if (timeout < App.configManager.BTMinOutRangeTimeoutms)
            {
                timeout = App.configManager.BTMinOutRangeTimeoutms;
            }
            trigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(timeout);
            trigger.SignalStrengthFilter.SamplingInterval  = TimeSpan.FromMilliseconds(App.curScenario.BTSamplingIntervalms);

            // Display the information about the published payload
            Debug.WriteLine(string.Format("Watch BLE payload information: CompanyId=0x{0}", manufacturerData.CompanyId.ToString("X")));

            return(trigger);
        }
Example #12
0
        /// <summary>
        /// Registers the Bluetooth LE watcher background task, assuming Bluetooth is available.
        /// </summary>
        private async Task EnableWatcherAsync()
        {
            if (_taskRegistration != null)
            {
                return;
            }
            _trigger = new BluetoothLEAdvertisementWatcherTrigger();

            // Add manufacturer data.
            var manufacturerData = new BluetoothLEManufacturerData();

            manufacturerData.CompanyId = 0xFFFE;
            DataWriter writer = new DataWriter();

            writer.WriteUInt16(0x1234);
            manufacturerData.Data = writer.DetachBuffer();
            _trigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

            // Add signal strength filters and sampling interval.
            _trigger.SignalStrengthFilter.InRangeThresholdInDBm    = -65;
            _trigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = -70;
            _trigger.SignalStrengthFilter.OutOfRangeTimeout        = TimeSpan.FromSeconds(2);
            _trigger.SignalStrengthFilter.SamplingInterval         = TimeSpan.FromSeconds(1);

            // Create the task.
            BackgroundAccessStatus backgroundAccessStatus =
                await BackgroundExecutionManager.RequestAccessAsync();

            var builder = new BackgroundTaskBuilder()
            {
                Name           = _taskName,
                TaskEntryPoint = "BackgroundTasks.AdvertisementWatcherTask"
            };

            builder.SetTrigger(_trigger);
            builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
            _taskRegistration = builder.Register();
        }
        /// <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);
        }
        /// <summary>
        /// Registers the Bluetooth LE watcher background task, assuming Bluetooth is available.
        /// </summary>
        private async Task EnableWatcherAsync()
        {
            if (_taskRegistration != null)
            {
                return;
            }
            _trigger = new BluetoothLEAdvertisementWatcherTrigger();

            // Add manufacturer data.
            var manufacturerData = new BluetoothLEManufacturerData();
            manufacturerData.CompanyId = 0xFFFE;
            DataWriter writer = new DataWriter();
            writer.WriteUInt16(0x1234);
            manufacturerData.Data = writer.DetachBuffer();
            _trigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

            // Add signal strength filters and sampling interval.
            _trigger.SignalStrengthFilter.InRangeThresholdInDBm = -65;
            _trigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = -70;
            _trigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromSeconds(2);
            _trigger.SignalStrengthFilter.SamplingInterval = TimeSpan.FromSeconds(1);

            // Create the task.
            BackgroundAccessStatus backgroundAccessStatus = 
                await BackgroundExecutionManager.RequestAccessAsync();
            var builder = new BackgroundTaskBuilder()
            {
                Name = _taskName,
                TaskEntryPoint = "BackgroundTasks.AdvertisementWatcherTask"
            };
            builder.SetTrigger(_trigger);
            builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
            _taskRegistration = builder.Register();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (taskAdvertisementWatcher != null)
            {
                taskAdvertisementWatcher.Completed -= OnBackgroundTaskCompleted;
                taskAdvertisementWatcher.Unregister(true);
                taskAdvertisementWatcher = null;
                btnRegisterUnregister.Content = "Register Background Task";
            }
            else
            {
                //Register the new task
                // Applications registering for background trigger must request for permission.
                BackgroundExecutionManager.RequestAccessAsync().AsTask().ContinueWith(async (r) =>
                {
                    if (r.IsFaulted || r.IsCanceled)
                        return;
                    if ((r.Result == BackgroundAccessStatus.Denied) || (r.Result == BackgroundAccessStatus.Unspecified))
                    {
                        await new MessageDialog("Not able to run in background. Application must given permission to be added to lock screen.").ShowAsync();
                        Application.Current.Exit();
                    }

                    // Create and initialize a new trigger to configure it.
                    trigger = new BluetoothLEAdvertisementWatcherTrigger();
                    // Add the manufacturer data to the advertisement filter on the trigger:
                    trigger.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(new iBeaconData());
                    // By default, the sampling interval is set to be disabled, or the maximum sampling interval supported.
                    // The sampling interval set to MaxSamplingInterval indicates that the event will only trigger once after it comes into range.
                    // Here, set the sampling period to 1 second, which is the minimum supported for background.
                    trigger.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(1000);

                    // At this point we assume we haven't found any existing tasks matching the one we want to register
                    // First, configure the task entry point, trigger and name
                    var builder = new BackgroundTaskBuilder();
                    builder.TaskEntryPoint = taskEntryPoint;
                    builder.SetTrigger(trigger);
                    builder.Name = taskName;

                    // Now perform the registration. The registration can throw an exception if the current 
                    // hardware does not support background advertisement offloading
                    try
                    {
                        taskAdvertisementWatcher = builder.Register();
                        Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
                         {
                             // For this scenario, attach an event handler to display the result processed from the background task
                             taskAdvertisementWatcher.Completed += OnBackgroundTaskCompleted;
                             btnRegisterUnregister.Content = "Unregister Background Task";
                         });
                        
                    }
                    catch (Exception ex)
                    {
                        taskAdvertisementWatcher = null;
                        switch ((uint)ex.HResult)
                        {
                            case (0x80070032): // ERROR_NOT_SUPPORTED
                                Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
                                {
                                    await new MessageDialog("The hardware does not support background advertisement offload.").ShowAsync();
                                    Application.Current.Exit();
                                });
                                break;
                            default:
                                throw ex;
                        }
                    }

                });

                
            }
        }
        /// <summary>
        /// Registers the BLE advertisement watcher background task.
        /// </summary>
        /// <param name="manufacturerId">The manufacturer ID of beacons to watch.</param>
        /// <param name="beaconCode">The beacon code of beacons to watch.</param>
        /// <returns>The registration result.</returns>
        private async Task<BackgroundTaskRegistrationResult> RegisterAdvertisementWatcherBackgroundTaskAsync(
            UInt16 manufacturerId, UInt16 beaconCode)
        {
            BackgroundTaskRegistrationResult result = new BackgroundTaskRegistrationResult()
            {
                success = false,
                exception = null
            };

            if (BackgroundTaskRegistered(_advertisementWatcherBackgroundTaskName))
            {
                // Already registered
                System.Diagnostics.Debug.WriteLine("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Already registered");
                result.success = true;
            }
            else
            {
                BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder();

                backgroundTaskBuilder.Name = _advertisementWatcherBackgroundTaskName;
                backgroundTaskBuilder.TaskEntryPoint = AdvertisementWatcherBackgroundTaskEntryPoint;

                IBackgroundTrigger trigger = null;

                BluetoothLEAdvertisementWatcherTrigger advertisementWatcherTrigger =
                    new BluetoothLEAdvertisementWatcherTrigger();

                //BluetoothLEManufacturerData manufacturerData = BeaconFactory.DefaultBeaconManufacturerData();
                //advertisementWatcherTrigger.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

                // This filter includes all Sensorberg beacons 
                var pattern = BeaconFactory.UUIDToAdvertisementBytePattern(Constants.SensorbergUuidSpace, manufacturerId, beaconCode);
                advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern);

                LayoutManager layoutManager = LayoutManager.Instance;

#if FILTER_SUPPORTS_MORE_UUIDS
                // Only UUIDs that are registered to the app will be added into filter                      
                if (await layoutManager.VerifyLayoutAsync(false)
                    && layoutManager.Layout.ContainsOtherThanSensorbergBeaconId1s())
                {
                    int counter = 0;

                    foreach (string beaconId1 in LayoutManager.Instance.Layout.AccountBeaconId1s)
                    {
                        if (beaconId1.Length == Constants.BeaconId1LengthWithoutDashes && counter < MaxBeaconId1FilterCount)
                        {
                            if (!beaconId1.StartsWith(Constants.SensorbergUuidSpace, StringComparison.CurrentCultureIgnoreCase))
                            {
                                pattern = BeaconFactory.UUIDToAdvertisementBytePattern(beaconId1);
                                advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern);
                                counter++;
                            }
                        }
                    }
                }
#endif

                // 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;
                advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = SignalStrengthFilterInRangeThresholdInDBm;
                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = SignalStrengthFilterOutOfRangeThresholdInDBm;
                advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(Constants.BeaconExitDelayInMilliseconds);
                
                trigger = advertisementWatcherTrigger;

                backgroundTaskBuilder.SetTrigger(trigger);

                try
                {
                    BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register();
                    backgroundTaskRegistration.Completed += new BackgroundTaskCompletedEventHandler(OnAdvertisementWatcherBackgroundTaskCompleted);
                    result.success = true;
                }
                catch (Exception ex)
                {
                    result.exception = ex;
                    System.Diagnostics.Debug.WriteLine("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Failed to register: " + ex);
                }

                if (result.success)
                {
                    SDKData sdkData = SDKData.Instance;

                    // 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;

                            if (BackgroundFiltersUpdated != null)
                            {
                                BackgroundFiltersUpdated(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;
                        }
                    }
                }
            }

            return result;
        }
        /// <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;
        }
Example #18
0
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (taskAdvertisementWatcher != null)
            {
                taskAdvertisementWatcher.Completed -= OnBackgroundTaskCompleted;
                taskAdvertisementWatcher.Unregister(true);
                taskAdvertisementWatcher      = null;
                btnRegisterUnregister.Content = "Register Background Task";
            }
            else
            {
                //Register the new task
                // Applications registering for background trigger must request for permission.
                BackgroundExecutionManager.RequestAccessAsync().AsTask().ContinueWith(async(r) =>
                {
                    if (r.IsFaulted || r.IsCanceled)
                    {
                        return;
                    }
                    if ((r.Result == BackgroundAccessStatus.Denied) || (r.Result == BackgroundAccessStatus.Unspecified))
                    {
                        await new MessageDialog("Not able to run in background. Application must given permission to be added to lock screen.").ShowAsync();
                        Application.Current.Exit();
                    }

                    // Create and initialize a new trigger to configure it.
                    trigger = new BluetoothLEAdvertisementWatcherTrigger();
                    // Add the manufacturer data to the advertisement filter on the trigger:
                    trigger.AdvertisementFilter.Advertisement.iBeaconSetAdvertisement(new iBeaconData());
                    // By default, the sampling interval is set to be disabled, or the maximum sampling interval supported.
                    // The sampling interval set to MaxSamplingInterval indicates that the event will only trigger once after it comes into range.
                    // Here, set the sampling period to 1 second, which is the minimum supported for background.
                    trigger.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(1000);

                    // At this point we assume we haven't found any existing tasks matching the one we want to register
                    // First, configure the task entry point, trigger and name
                    var builder            = new BackgroundTaskBuilder();
                    builder.TaskEntryPoint = taskEntryPoint;
                    builder.SetTrigger(trigger);
                    builder.Name = taskName;

                    // Now perform the registration. The registration can throw an exception if the current
                    // hardware does not support background advertisement offloading
                    try
                    {
                        taskAdvertisementWatcher = builder.Register();
                        Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() =>
                        {
                            // For this scenario, attach an event handler to display the result processed from the background task
                            taskAdvertisementWatcher.Completed += OnBackgroundTaskCompleted;
                            btnRegisterUnregister.Content       = "Unregister Background Task";
                        });
                    }
                    catch (Exception ex)
                    {
                        taskAdvertisementWatcher = null;
                        switch ((uint)ex.HResult)
                        {
                        case (0x80070032):     // ERROR_NOT_SUPPORTED
                            Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() =>
                            {
                                await new MessageDialog("The hardware does not support background advertisement offload.").ShowAsync();
                                Application.Current.Exit();
                            });
                            break;

                        default:
                            throw ex;
                        }
                    }
                });
            }
        }