├── .gitignore
├── BluetoothLEExplorer
├── BluetoothLEExplorer.sln
├── BluetoothLEExplorer
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── Assets
│ │ ├── BadgeLogo.scale-100.png
│ │ ├── BadgeLogo.scale-125.png
│ │ ├── BadgeLogo.scale-150.png
│ │ ├── BadgeLogo.scale-200.png
│ │ ├── BadgeLogo.scale-400.png
│ │ ├── BadgeSource.png
│ │ ├── SplashScreen.scale-200.png
│ │ ├── Square150x150Logo.scale-100.png
│ │ ├── Square150x150Logo.scale-200.png
│ │ ├── Square150x150Logo.scale-400.png
│ │ ├── Square310x310Logo.scale-100.png
│ │ ├── Square310x310Logo.scale-200.png
│ │ ├── Square310x310Logo.scale-400.png
│ │ ├── Square44x44Logo.scale-100.png
│ │ ├── Square44x44Logo.scale-200.png
│ │ ├── Square44x44Logo.scale-400.png
│ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ │ ├── Square71x71Logo.scale-100.png
│ │ ├── Square71x71Logo.scale-200.png
│ │ ├── Square71x71Logo.scale-400.png
│ │ ├── StoreLogo-125.png
│ │ ├── StoreLogo-150.png
│ │ ├── StoreLogo-200.png
│ │ ├── StoreLogo-400.png
│ │ ├── StoreLogo.png
│ │ ├── Wide310x150Logo.scale-100.png
│ │ ├── Wide310x150Logo.scale-200.png
│ │ └── Wide310x150Logo.scale-400.png
│ ├── BluetoothLEExplorer.csproj
│ ├── CustomControls
│ │ ├── GattLocalCharacteristicControl.xaml
│ │ └── GattLocalCharacteristicControl.xaml.cs
│ ├── Help.htm
│ ├── Models
│ │ ├── DisposableObservableCollection.cs
│ │ ├── GattSampleContext.cs
│ │ ├── HidHelper.cs
│ │ ├── ObservableBluetoothLEAdvertisement.cs
│ │ ├── ObservableBluetoothLEAdvertisementFilter.cs
│ │ ├── ObservableBluetoothLEBeacon.cs
│ │ ├── ObservableBluetoothLEDevice.cs
│ │ ├── ObservableGattCharacteristics.cs
│ │ ├── ObservableGattDescriptors.cs
│ │ ├── ObservableGattDeviceService.cs
│ │ ├── ObservableHidClient.cs
│ │ └── VirtualKeyboard.cs
│ ├── Package.appxmanifest
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Default.rd.xml
│ ├── Services
│ │ ├── AdvertisementService
│ │ │ └── AdvertisementDataTypeService.cs
│ │ ├── Converters
│ │ │ └── Converters.cs
│ │ ├── DispatcherService
│ │ │ └── DispatcherService.cs
│ │ ├── GattUuidsService
│ │ │ └── GattUuidsService.cs
│ │ ├── Other
│ │ │ ├── BytePadder.cs
│ │ │ └── GattProtocolErrorParser.cs
│ │ ├── SettingsServices
│ │ │ └── SettingsService.cs
│ │ └── ToastService
│ │ │ └── ToastService.cs
│ ├── Settings.StyleCop
│ ├── Styles
│ │ └── Custom.xaml
│ ├── ViewModels
│ │ ├── AdvertisementBeaconDetailsPageViewModel.cs
│ │ ├── AdvertisementBeaconPageViewModel.cs
│ │ ├── AdvertisementMonitorPageViewModel.cs
│ │ ├── AdvertisementPageViewModel.cs
│ │ ├── CharacteristicPageViewModel.cs
│ │ ├── DeviceServicesPageViewModel.cs
│ │ ├── DiscoverViewModel.cs
│ │ ├── GenericGattCharacteristicViewModel.cs
│ │ ├── GenericGattServiceViewModel.cs
│ │ ├── ServicePageViewModel.cs
│ │ ├── Services
│ │ │ ├── AlertNotificationServicePageViewModel.cs
│ │ │ ├── BatteryServicePageViewModel.cs
│ │ │ ├── BloodPressureServicePageViewModel.cs
│ │ │ ├── CurrentTimeServicePageViewModel.cs
│ │ │ ├── HeartRateServicePageViewModel.cs
│ │ │ └── MicrosoftServicePageViewModel.cs
│ │ ├── SettingsPageViewModel.cs
│ │ ├── ShellViewModel.cs
│ │ ├── VirtualKeyboardPageViewModel.cs
│ │ └── VirtualPeripheralPageViewModel.cs
│ └── Views
│ │ ├── AdvertisementBeaconDetailsPage.xaml
│ │ ├── AdvertisementBeaconDetailsPage.xaml.cs
│ │ ├── AdvertisementBeaconPage.xaml
│ │ ├── AdvertisementBeaconPage.xaml.cs
│ │ ├── AdvertisementMonitorPage.xaml
│ │ ├── AdvertisementMonitorPage.xaml.cs
│ │ ├── AdvertisementPage.xaml
│ │ ├── AdvertisementPage.xaml.cs
│ │ ├── Busy.xaml
│ │ ├── Busy.xaml.cs
│ │ ├── CharacteristicPage.xaml
│ │ ├── CharacteristicPage.xaml.cs
│ │ ├── DeviceServicesPage.xaml
│ │ ├── DeviceServicesPage.xaml.cs
│ │ ├── Discover.xaml
│ │ ├── Discover.xaml.cs
│ │ ├── ServicePage.xaml
│ │ ├── ServicePage.xaml.cs
│ │ ├── Services
│ │ ├── AlertNotificationServicePage.xaml
│ │ ├── AlertNotificationServicePage.xaml.cs
│ │ ├── BatteryServicePage.xaml
│ │ ├── BatteryServicePage.xaml.cs
│ │ ├── BloodPressureServicePage.xaml
│ │ ├── BloodPressureServicePage.xaml.cs
│ │ ├── CurrentTimeServicePage.xaml
│ │ ├── CurrentTimeServicePage.xaml.cs
│ │ ├── HeartRateServicePage.xaml
│ │ ├── HeartRateServicePage.xaml.cs
│ │ ├── MicrosoftServicePage.xaml
│ │ └── MicrosoftServicePage.xaml.cs
│ │ ├── SettingsPage.xaml
│ │ ├── SettingsPage.xaml.cs
│ │ ├── Shell.xaml
│ │ ├── Shell.xaml.cs
│ │ ├── Splash.xaml
│ │ ├── Splash.xaml.cs
│ │ ├── VirtualKeyboardPage.xaml
│ │ ├── VirtualKeyboardPage.xaml.cs
│ │ ├── VirtualPeripheralPage.xaml
│ │ └── VirtualPeripheralPage.xaml.cs
├── BluetoothLEExplorerUnitTests
│ ├── Assets
│ │ ├── LockScreenLogo.scale-200.png
│ │ ├── SplashScreen.scale-200.png
│ │ ├── Square150x150Logo.scale-200.png
│ │ ├── Square44x44Logo.scale-200.png
│ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ │ ├── StoreLogo.png
│ │ └── Wide310x150Logo.scale-200.png
│ ├── BluetoothLEExplorerUnitTests.csproj
│ ├── Package.appxmanifest
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── UnitTestApp.rd.xml
│ ├── UnitTest.cs
│ ├── UnitTestApp.xaml
│ └── UnitTestApp.xaml.cs
├── DesignModel
│ ├── DesignModel.modelproj
│ └── ModelDefinition
│ │ └── DesignModel.uml
└── GattHelper
│ ├── Converters
│ └── GattConvert.cs
│ ├── GattHelper.csproj
│ ├── Properties
│ ├── AssemblyInfo.cs
│ └── GattHelper.rd.xml
│ └── project.json
├── GattServicesLibrary
├── GattServicesLibrary.sln
└── GattServicesLibrary
│ ├── CharacteristicParameterValues
│ └── CharacteristicParameterValueEnums.cs
│ ├── Characteristics
│ ├── AlertNotificationControlPointCharacteristic.cs
│ ├── BatteryLevelCharacteristic.cs
│ ├── BloodPressureFeatureCharacteristic.cs
│ ├── BloodPressureMeasurementCharacteristic.cs
│ ├── CurrentTimeCharacteristic.cs
│ ├── HeartRateMeasurementCharacteristic.cs
│ ├── MicrosoftIndicateCharacteristic.cs
│ ├── MicrosoftNotifyCharacteristic.cs
│ ├── MicrosoftReadCharacteristic.cs
│ ├── MicrosoftReadLongCharacteristic.cs
│ ├── MicrosoftWriteCharacteristic.cs
│ ├── NewAlertCharacteristic.cs
│ └── UnreadAlertStatusCharacteristic.cs
│ ├── GattServicesLibrary.csproj
│ ├── GenericGattCharacteristic.cs
│ ├── GenericGattService.cs
│ ├── Helpers
│ ├── CreateServiceException.cs
│ ├── GattServicesHelper.cs
│ ├── HelperExtensions.cs
│ ├── PresentationFormats.cs
│ └── ValueConverter.cs
│ ├── Properties
│ ├── AssemblyInfo.cs
│ └── GattServicesLibrary.rd.xml
│ ├── Services
│ ├── AlertNotificationService.cs
│ ├── BatteryService.cs
│ ├── BloodPressureService.cs
│ ├── CurrentTimeService.cs
│ ├── HeartRateService.cs
│ └── MicrosoftService.cs
│ └── project.json
├── LICENSE
├── README.md
├── SECURITY.md
└── SortedObservableCollection
├── SortedObservableCollection.sln
├── SortedObservableCollection
├── Properties
│ ├── AssemblyInfo.cs
│ └── SortedObservableCollection.rd.xml
├── SortedObservableCollection.cs
├── SortedObservableCollection.csproj
└── project.json
└── SortedObservableCollectionUnitTests
├── Assets
├── LockScreenLogo.scale-200.png
├── SplashScreen.scale-200.png
├── Square150x150Logo.scale-200.png
├── Square44x44Logo.scale-200.png
├── Square44x44Logo.targetsize-24_altform-unplated.png
├── StoreLogo.png
└── Wide310x150Logo.scale-200.png
├── Package.appxmanifest
├── Properties
├── AssemblyInfo.cs
└── UnitTestApp.rd.xml
├── SortedObservableCollectionUnitTests.cs
├── SortedObservableCollectionUnitTests.csproj
├── UnitTestApp.xaml
├── UnitTestApp.xaml.cs
└── project.json
/BluetoothLEExplorer/BluetoothLEExplorer/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-100.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-125.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-150.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeLogo.scale-400.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeSource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/BadgeSource.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square150x150Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square150x150Logo.scale-100.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square150x150Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square150x150Logo.scale-400.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square310x310Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square310x310Logo.scale-100.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square310x310Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square310x310Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square310x310Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square310x310Logo.scale-400.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.scale-100.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.scale-400.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square71x71Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square71x71Logo.scale-100.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square71x71Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square71x71Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square71x71Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Square71x71Logo.scale-400.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-125.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-150.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo-400.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Wide310x150Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Wide310x150Logo.scale-100.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Wide310x150Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorer/Assets/Wide310x150Logo.scale-400.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/CustomControls/GattLocalCharacteristicControl.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 | Green
14 | Green
15 | Green
16 |
17 |
18 | Red
19 | Red
20 | Red
21 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Help.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Template 10
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Models/DisposableObservableCollection.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Linq;
7 | using System.Collections.ObjectModel;
8 |
9 | namespace BluetoothLEExplorer.Models
10 | {
11 | ///
12 | /// Helper collection class that disposes of items when they are removed
13 | ///
14 | public class DisposableObservableCollection : ObservableCollection, IDisposable where T : IDisposable
15 | {
16 | public void Dispose()
17 | {
18 | this.ToList().ForEach(disposable => disposable.Dispose());
19 | }
20 |
21 | new public void Clear()
22 | {
23 | var temp = this.ToList();
24 | base.Clear();
25 | temp.ForEach(disposable => disposable.Dispose());
26 | }
27 |
28 | new public void ClearItems()
29 | {
30 | var temp = this.ToList();
31 | base.ClearItems();
32 | temp.ForEach(disposable => disposable.Dispose());
33 | }
34 |
35 | new public bool Remove(T item)
36 | {
37 | T temp = item;
38 | bool result = base.Remove(item);
39 | if (result)
40 | {
41 | item.Dispose();
42 | }
43 | return result;
44 | }
45 |
46 | new public void RemoveAt(int index)
47 | {
48 | T temp = this.ElementAt(index);
49 | base.RemoveAt(index);
50 | temp.Dispose();
51 | }
52 |
53 | new public void RemoveItem(int index)
54 | {
55 | T temp = this.ElementAt(index);
56 | base.RemoveItem(index);
57 | temp.Dispose();
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Models/ObservableBluetoothLEAdvertisementFilter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.ComponentModel;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Windows.Devices.Bluetooth;
9 | using Windows.Devices.Bluetooth.Advertisement;
10 | using Windows.Foundation.Metadata;
11 | using Windows.Storage.Streams;
12 | using GattHelper.Converters;
13 | using BluetoothLEExplorer.Services.AdvertisementHelpers;
14 | using Windows.Security.Cryptography;
15 |
16 | namespace BluetoothLEExplorer.Models
17 | {
18 | public class ObservableBluetoothLEAdvertisementFilter : INotifyPropertyChanged
19 | {
20 | public enum DataFormatType
21 | {
22 | NotSet,
23 | Hex,
24 | String,
25 | }
26 |
27 | public string Name
28 | {
29 | get;
30 | private set;
31 | }
32 |
33 | public byte SectionType
34 | {
35 | get;
36 | private set;
37 | }
38 |
39 | public byte SectionOffset
40 | {
41 | get;
42 | set;
43 | }
44 |
45 | public string SectionDataString
46 | {
47 | get;
48 | set;
49 | }
50 |
51 | public bool DataSectionRawFilter
52 | {
53 | get
54 | {
55 | return true;
56 | }
57 | }
58 |
59 | private DataFormatType sectionDataFormat = DataFormatType.Hex;
60 |
61 | public DataFormatType SectionDataFormat
62 | {
63 | get
64 | {
65 | return sectionDataFormat;
66 | }
67 |
68 | set
69 | {
70 | if (value == DataFormatType.NotSet)
71 | {
72 | return;
73 | }
74 |
75 | if (sectionDataFormat != value)
76 | {
77 | sectionDataFormat = value;
78 | OnPropertyChanged(new PropertyChangedEventArgs("SectionDataFormat"));
79 | }
80 | }
81 | }
82 |
83 | public ObservableBluetoothLEAdvertisementFilter(byte sectionType)
84 | {
85 | SectionType = sectionType;
86 | Name = AdvertisementDataTypeHelper.ConvertSectionTypeToString(sectionType);
87 | }
88 |
89 | ///
90 | /// Event to notify when this object has changed
91 | ///
92 | public event PropertyChangedEventHandler PropertyChanged;
93 |
94 | ///
95 | /// Executes when this class changes
96 | ///
97 | ///
98 | private void OnPropertyChanged(PropertyChangedEventArgs e)
99 | {
100 | if (PropertyChanged != null)
101 | {
102 | PropertyChanged(this, e);
103 | }
104 | }
105 |
106 | public BluetoothLEAdvertisementBytePattern GetBytePattern()
107 | {
108 | var pattern = new BluetoothLEAdvertisementBytePattern();
109 | pattern.DataType = SectionType;
110 | pattern.Offset = SectionOffset;
111 | if (SectionDataString != null && SectionDataString.Length > 0)
112 | {
113 | if (sectionDataFormat == DataFormatType.Hex)
114 | {
115 | // pad the value if we've received odd number of bytes
116 | if (SectionDataString.Length % 2 == 1)
117 | {
118 | pattern.Data = GattConvert.ToIBufferFromHexString("0" + SectionDataString);
119 | }
120 | else
121 | {
122 | pattern.Data = GattConvert.ToIBufferFromHexString(SectionDataString);
123 | }
124 | }
125 | else if (sectionDataFormat == DataFormatType.String)
126 | {
127 | pattern.Data = CryptographicBuffer.ConvertStringToBinary(SectionDataString, BinaryStringEncoding.Utf8);
128 | }
129 | }
130 | return pattern;
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Models/ObservableHidClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using Windows.Devices.Bluetooth;
8 | using System.Diagnostics;
9 |
10 | namespace BluetoothLEExplorer.Models
11 | {
12 | public class ObservableGattClient : INotifyPropertyChanged, IEquatable
13 | {
14 | public event PropertyChangedEventHandler PropertyChanged;
15 |
16 | private BluetoothLEDevice m_leDevice;
17 |
18 | private bool m_isConnected;
19 | public bool IsConnected
20 | {
21 | get
22 | {
23 | return m_isConnected;
24 | }
25 | private set
26 | {
27 | m_isConnected = value;
28 | OnPropertyChanged("IsConnected");
29 | }
30 | }
31 |
32 | public string Name
33 | {
34 | get
35 | {
36 | return m_leDevice.Name;
37 | }
38 | }
39 |
40 | public static async Task FromIdAsync(string deviceId)
41 | {
42 | var leDevice = await BluetoothLEDevice.FromIdAsync(deviceId);
43 | return new ObservableGattClient(leDevice);
44 | }
45 |
46 | public ObservableGattClient(BluetoothLEDevice device)
47 | {
48 | m_leDevice = device;
49 | m_leDevice.ConnectionStatusChanged += ConnectionStatusChanged;
50 | IsConnected = (m_leDevice.ConnectionStatus == BluetoothConnectionStatus.Connected);
51 | }
52 |
53 | ~ObservableGattClient()
54 | {
55 | m_leDevice.ConnectionStatusChanged -= ConnectionStatusChanged;
56 | m_leDevice.Dispose();
57 | }
58 |
59 | bool IEquatable.Equals(ObservableGattClient other)
60 | {
61 | if (other == null)
62 | {
63 | return false;
64 | }
65 |
66 | return (m_leDevice.DeviceId == other.m_leDevice.DeviceId);
67 | }
68 |
69 | private void ConnectionStatusChanged(BluetoothLEDevice sender, object args)
70 | {
71 | IsConnected = (sender.ConnectionStatus == BluetoothConnectionStatus.Connected);
72 | }
73 |
74 | private async void OnPropertyChanged(string propertyName)
75 | {
76 | try
77 | {
78 | if (PropertyChanged != null)
79 | {
80 | await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
81 | Windows.UI.Core.CoreDispatcherPriority.Normal,
82 | () =>
83 | {
84 | PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
85 | });
86 | }
87 | }
88 | catch (Exception e)
89 | {
90 | Debug.Fail(String.Format("Failed to update property '{0}' due to {1}", propertyName, e.ToString()));
91 | }
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Bluetooth LE Explorer
7 | Microsoft Corporation
8 | Assets\StoreLogo.png
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Reflection;
6 | using System.Runtime.CompilerServices;
7 | using System.Runtime.InteropServices;
8 |
9 | // General Information about an assembly is controlled through the following
10 | // set of attributes. Change these attribute values to modify the information
11 | // associated with an assembly.
12 | [assembly: AssemblyTitle("BluetoothLEExplorer")]
13 | [assembly: AssemblyDescription("")]
14 | [assembly: AssemblyConfiguration("")]
15 | [assembly: AssemblyCompany("Microsoft")]
16 | [assembly: AssemblyProduct("BluetoothLEExplorer")]
17 | [assembly: AssemblyCopyright("Copyright © 2015")]
18 | [assembly: AssemblyTrademark("")]
19 | [assembly: AssemblyCulture("")]
20 |
21 | // Version information for an assembly consists of the following four values:
22 | //
23 | // Major Version
24 | // Minor Version
25 | // Build Number
26 | // Revision
27 | //
28 | // You can specify all the values or you can default the Build and Revision Numbers
29 | // by using the '*' as shown below:
30 | // [assembly: AssemblyVersion("1.0.*")]
31 | [assembly: AssemblyVersion("1.0.0.0")]
32 | [assembly: AssemblyFileVersion("1.0.0.0")]
33 | [assembly: ComVisible(false)]
34 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Services/AdvertisementService/AdvertisementDataTypeService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using Windows.Devices.Bluetooth;
7 | using Windows.Devices.Bluetooth.Advertisement;
8 |
9 | namespace BluetoothLEExplorer.Services.AdvertisementHelpers
10 | {
11 | enum AdvertisementSectionType : byte
12 | {
13 | Flags = 0x01,
14 | IncompleteService16BitUuids = 0x02,
15 | CompleteService16BitUuids = 0x03,
16 | IncompleteService32BitUuids = 0x04,
17 | CompleteService32BitUuids = 0x05,
18 | IncompleteService128BitUuids = 0x06,
19 | CompleteService128BitUuids = 0x07,
20 | ShortenedLocalName = 0x08,
21 | CompleteLocalName = 0x09,
22 | TxPowerLevel = 0x0A,
23 | ClassOfDevice = 0x0D,
24 | SimplePairingHashC192 = 0x0E,
25 | SimplePairingRandomizerR192 = 0x0F,
26 | SecurityManagerTKValues = 0x10,
27 | SecurityManagerOutOfBandFlags = 0x11,
28 | SlaveConnectionIntervalRange = 0x12,
29 | ServiceSolicitation16BitUuids = 0x14,
30 | ServiceSolicitation32BitUuids = 0x1F,
31 | ServiceSolicitation128BitUuids = 0x15,
32 | ServiceData16BitUuids = 0x16,
33 | ServiceData32BitUuids = 0x20,
34 | ServiceData128BitUuids = 0x21,
35 | PublicTargetAddress = 0x17,
36 | RandomTargetAddress = 0x18,
37 | Appearance = 0x19,
38 | AdvertisingInterval = 0x1A,
39 | LEBluetoothDeviceAddress = 0x1B,
40 | LERole = 0x1C,
41 | SimplePairingHashC256 = 0x1D,
42 | SimplePairingRandomizerR256 = 0x1E,
43 | ThreeDimensionInformationData = 0x3D,
44 | ManufacturerSpecificData = 0xFF,
45 | }
46 |
47 | public static class AdvertisementDataTypeHelper
48 | {
49 | public static string ConvertSectionTypeToString(byte sectionType)
50 | {
51 | AdvertisementSectionType convertedSectionType;
52 | if (Enum.TryParse(sectionType.ToString(), out convertedSectionType))
53 | {
54 | return convertedSectionType.ToString();
55 | }
56 | return sectionType.ToString("X2");
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Services/DispatcherService/DispatcherService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Threading.Tasks;
7 | using Windows.UI.Core;
8 |
9 | namespace BluetoothLEExplorer.Services.DispatcherService
10 | {
11 | ///
12 | /// Helper class used to run functions on the UI thread
13 | ///
14 | public static class DispatcherService
15 | {
16 | ///
17 | /// Helper function to run task on UI thread
18 | ///
19 | /// return value of task
20 | ///
21 | ///
22 | ///
23 | /// UI thread task
24 | public static async Task RunTaskAsync(
25 | this CoreDispatcher dispatcher,
26 | Func> func,
27 | CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
28 | {
29 | var taskCompletionSource = new TaskCompletionSource();
30 |
31 | await dispatcher.RunAsync(
32 | priority,
33 | async () =>
34 | {
35 | try
36 | {
37 | taskCompletionSource.SetResult(await func());
38 | }
39 | catch (Exception ex)
40 | {
41 | taskCompletionSource.SetException(ex);
42 | }
43 | });
44 | return await taskCompletionSource.Task;
45 | }
46 |
47 | //// There is no TaskCompletionSource so we use a bool that we throw away.
48 |
49 | ///
50 | /// Helper function to run task on UI thread
51 | ///
52 | ///
53 | ///
54 | ///
55 | /// UI thread task
56 | public static async Task RunTaskAsync(
57 | this CoreDispatcher dispatcher,
58 | Func func,
59 | CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) =>
60 | await RunTaskAsync(
61 | dispatcher,
62 | async () =>
63 | {
64 | await func();
65 | return false;
66 | },
67 | priority);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Services/Other/BytePadder.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 |
6 | namespace BluetoothLEExplorer.Services.Other
7 | {
8 | ///
9 | /// Helper class used to pad bytes
10 | ///
11 | public static class BytePadder
12 | {
13 | ///
14 | /// Takes an input array of bytes and returns an array with more zeros in the front
15 | ///
16 | ///
17 | ///
18 | /// A byte array with more zeros in front"/>
19 | public static byte[] GetBytes(byte[] input, int length)
20 | {
21 | byte[] ret = new byte[length];
22 |
23 | if (input.Length >= length)
24 | {
25 | return input;
26 | }
27 |
28 | for (int i = 0; i < input.Length; i++)
29 | {
30 | ret[i] = input[i];
31 | }
32 |
33 | return ret;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Services/Other/GattProtocolErrorParser.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
6 |
7 | namespace BluetoothLEExplorer.Services.Other
8 | {
9 | ///
10 | /// Helper function when working with
11 | ///
12 | public static class GattProtocolErrorParser
13 | {
14 | ///
15 | /// Helper to convert an gatt error value into a string
16 | ///
17 | ///
18 | /// String representation of the error
19 | public static string GetErrorString(byte? errorValue)
20 | {
21 | string ret = "Protocol Error";
22 |
23 | if (errorValue.HasValue == false)
24 | {
25 | return ret;
26 | }
27 |
28 | if (errorValue == GattProtocolError.AttributeNotFound)
29 | {
30 | return "Attribute Not Found";
31 | }
32 | else if (errorValue == GattProtocolError.AttributeNotLong)
33 | {
34 | return "Attribute Not Long";
35 | }
36 | else if (errorValue == GattProtocolError.InsufficientAuthentication)
37 | {
38 | return "Insufficient Authentication";
39 | }
40 | else if (errorValue == GattProtocolError.InsufficientAuthorization)
41 | {
42 | return "Insufficient Authorization";
43 | }
44 | else if (errorValue == GattProtocolError.InsufficientEncryption)
45 | {
46 | return "Insufficient Encryption";
47 | }
48 | else if (errorValue == GattProtocolError.InsufficientEncryptionKeySize)
49 | {
50 | return "Insufficient Encryption Key Size";
51 | }
52 | else if (errorValue == GattProtocolError.InsufficientResources)
53 | {
54 | return "Insufficient Resources";
55 | }
56 | else if (errorValue == GattProtocolError.InvalidAttributeValueLength)
57 | {
58 | return "Invalid Attribute Value Length";
59 | }
60 | else if (errorValue == GattProtocolError.InvalidHandle)
61 | {
62 | return "Invalid Handle";
63 | }
64 | else if (errorValue == GattProtocolError.InvalidOffset)
65 | {
66 | return "Invalid Offset";
67 | }
68 | else if (errorValue == GattProtocolError.InvalidPdu)
69 | {
70 | return "Invalid Pdu";
71 | }
72 | else if (errorValue == GattProtocolError.PrepareQueueFull)
73 | {
74 | return "Prepare Queue Full";
75 | }
76 | else if (errorValue == GattProtocolError.ReadNotPermitted)
77 | {
78 | return "Read Not Permitted";
79 | }
80 | else if (errorValue == GattProtocolError.RequestNotSupported)
81 | {
82 | return "Request Not Supported";
83 | }
84 | else if (errorValue == GattProtocolError.UnlikelyError)
85 | {
86 | return "UnlikelyError";
87 | }
88 | else if (errorValue == GattProtocolError.UnsupportedGroupType)
89 | {
90 | return "Unsupported Group Type";
91 | }
92 | else if (errorValue == GattProtocolError.WriteNotPermitted)
93 | {
94 | return "Write Not Permitted";
95 | }
96 |
97 | return ret;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Services/SettingsServices/SettingsService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using Template10.Common;
7 | using Template10.Utils;
8 | using Windows.UI.Xaml;
9 |
10 | namespace BluetoothLEExplorer.Services.SettingsServices
11 | {
12 | ///
13 | /// Settings helper service
14 | ///
15 | public class SettingsService
16 | {
17 | ///
18 | /// Gets the settings service
19 | ///
20 | public static SettingsService Instance { get; } = new SettingsService();
21 |
22 | ///
23 | /// The settings helper
24 | ///
25 | private Template10.Services.SettingsService.ISettingsHelper helper;
26 |
27 | ///
28 | /// Prevents a default instance of the class from being created.
29 | ///
30 | private SettingsService()
31 | {
32 | helper = new Template10.Services.SettingsService.SettingsHelper();
33 | }
34 |
35 | ///
36 | /// Gets or sets a value indicating whether the shell screen should have a back button
37 | ///
38 | public bool UseShellBackButton
39 | {
40 | get
41 | {
42 | return helper.Read(nameof(UseShellBackButton), true);
43 | }
44 |
45 | set
46 | {
47 | helper.Write(nameof(UseShellBackButton), value);
48 | BootStrapper.Current.NavigationService.Dispatcher.Dispatch(() =>
49 | {
50 | BootStrapper.Current.ShowShellBackButton = value;
51 | BootStrapper.Current.UpdateShellBackButton();
52 | BootStrapper.Current.NavigationService.Refresh();
53 | });
54 | }
55 | }
56 |
57 | ///
58 | /// Gets or sets a value indicating whether to use caching.
59 | ///
60 | public bool UseCaching
61 | {
62 | get
63 | {
64 | return helper.Read(nameof(UseCaching), true);
65 | }
66 |
67 | set
68 | {
69 | helper.Write(nameof(UseCaching), value);
70 | }
71 | }
72 |
73 | ///
74 | /// Gets or sets a value indicating whether connections should be closed upon going back to Discovery page.
75 | ///
76 | public bool CloseConnections
77 | {
78 | get
79 | {
80 | return helper.Read(nameof(CloseConnections), true);
81 | }
82 |
83 | set
84 | {
85 | helper.Write(nameof(CloseConnections), value);
86 | }
87 | }
88 |
89 | ///
90 | /// Gets or sets the application theme
91 | ///
92 | public ApplicationTheme AppTheme
93 | {
94 | get
95 | {
96 | var theme = ApplicationTheme.Light;
97 | var value = helper.Read(nameof(AppTheme), theme.ToString());
98 | return Enum.TryParse(value, out theme) ? theme : ApplicationTheme.Dark;
99 | }
100 |
101 | set
102 | {
103 | helper.Write(nameof(AppTheme), value.ToString());
104 | (Window.Current.Content as FrameworkElement).RequestedTheme = value.ToElementTheme();
105 | Views.Shell.HamburgerMenu.RefreshStyles(value);
106 | }
107 | }
108 |
109 | ///
110 | /// Gets or sets a value that I don't know what it does
111 | ///
112 | public TimeSpan CacheMaxDuration
113 | {
114 | get
115 | {
116 | return helper.Read(nameof(CacheMaxDuration), TimeSpan.FromDays(2));
117 | }
118 |
119 | set
120 | {
121 | helper.Write(nameof(CacheMaxDuration), value);
122 | BootStrapper.Current.CacheMaxDuration = value;
123 | }
124 | }
125 |
126 | public ObservableDictionary SettingsDictionary = new ObservableDictionary();
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Services/ToastService/ToastService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Text;
6 | using Windows.Data.Xml.Dom;
7 | using Windows.Foundation.Collections;
8 | using Windows.Foundation.Metadata;
9 | using Windows.UI.Notifications;
10 |
11 | namespace BluetoothLEExplorer.Services.ToastService
12 | {
13 | ///
14 | /// Service to help displaying toast notifications
15 | ///
16 | public static class ToastService
17 | {
18 | ///
19 | /// Pop up a toast
20 | ///
21 | ///
22 | ///
23 | /// A toast notification
24 | public static ToastNotification PopToast(string title, string content)
25 | {
26 | return PopToast(title, content, null, null);
27 | }
28 |
29 | ///
30 | /// Pop up a toast
31 | ///
32 | ///
33 | ///
34 | ///
35 | ///
36 | /// A toast notification
37 | public static ToastNotification PopToast(string title, string content, string tag, string group)
38 | {
39 | string xml = $@"
40 |
41 |
42 |
43 |
44 | ";
45 |
46 | XmlDocument doc = new XmlDocument();
47 |
48 | doc.LoadXml(xml);
49 |
50 | var binding = doc.SelectSingleNode("//binding");
51 |
52 | var el = doc.CreateElement("text");
53 | el.InnerText = title;
54 |
55 | binding.AppendChild(el);
56 |
57 | el = doc.CreateElement("text");
58 |
59 | try
60 | {
61 | el.InnerText = content;
62 | }
63 | catch (System.Runtime.InteropServices.COMException)
64 | {
65 | el.InnerText = "Undisplayable UTF8 character";
66 | }
67 |
68 | binding.AppendChild(el);
69 |
70 | return PopCustomToast(doc, tag, group);
71 | }
72 |
73 | ///
74 | /// Pop up a task
75 | ///
76 | ///
77 | /// A toast notification
78 | public static ToastNotification PopCustomToast(string xml)
79 | {
80 | return PopCustomToast(xml, null, null);
81 | }
82 |
83 | ///
84 | /// Pop up a custom toast
85 | ///
86 | ///
87 | ///
88 | ///
89 | /// A toast notification
90 | public static ToastNotification PopCustomToast(string xml, string tag, string group)
91 | {
92 | XmlDocument doc = new XmlDocument();
93 | doc.LoadXml(xml);
94 |
95 | return PopCustomToast(doc, tag, group);
96 | }
97 |
98 | ///
99 | /// pop up a custom toast
100 | ///
101 | ///
102 | ///
103 | ///
104 | /// A toast notification
105 | [DefaultOverloadAttribute]
106 | public static ToastNotification PopCustomToast(XmlDocument doc, string tag, string group)
107 | {
108 | var toast = new ToastNotification(doc);
109 |
110 | if (tag != null)
111 | {
112 | toast.Tag = tag;
113 | }
114 |
115 | if (group != null)
116 | {
117 | toast.Group = group;
118 | }
119 |
120 | ToastNotificationManager.CreateToastNotifier().Show(toast);
121 |
122 | return toast;
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Settings.StyleCop:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | aspx
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | False
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/AdvertisementBeaconDetailsPageViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using System.Collections.ObjectModel;
5 |
6 | using Template10.Mvvm;
7 | using Template10.Services.NavigationService;
8 |
9 | using Windows.UI.Xaml.Navigation;
10 | using Windows.Devices.Bluetooth.Advertisement;
11 |
12 | using BluetoothLEExplorer.Models;
13 | using BluetoothLEExplorer.Services.AdvertisementHelpers;
14 |
15 |
16 | namespace BluetoothLEExplorer.ViewModels
17 | {
18 | public class AdvertisementBeaconDetailsPageViewModel : ViewModelBase
19 | {
20 | public void GotoSettings() => NavigationService.Navigate(typeof(Views.SettingsPage), 0);
21 |
22 | ///
23 | /// Go to privacy
24 | ///
25 | public void GotoPrivacy() => NavigationService.Navigate(typeof(Views.SettingsPage), 1);
26 |
27 | ///
28 | /// Go to about
29 | ///
30 | public void GotoAbout() => NavigationService.Navigate(typeof(Views.SettingsPage), 2);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/AdvertisementPageViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using BluetoothLEExplorer.Models;
7 | using Template10.Mvvm;
8 | using Template10.Services.NavigationService;
9 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
10 | using Windows.Security.Cryptography;
11 | using Windows.Storage.Streams;
12 | using Windows.UI.Xaml.Navigation;
13 | using Windows.UI.Popups;
14 | using GattHelper.Converters;
15 |
16 | namespace BluetoothLEExplorer.ViewModels
17 | {
18 | public class AdvertisementPageViewModel : ViewModelBase
19 | {
20 | private GattSampleContext context = GattSampleContext.Context;
21 |
22 | ///
23 | /// Source for
24 | ///
25 | private ObservableBluetoothLEAdvertisement advertisement = GattSampleContext.Context.SelectedAdvertisement;
26 |
27 | ///
28 | /// Gets or sets the advertisement that this view model wraps
29 | ///
30 | public ObservableBluetoothLEAdvertisement Advertisement
31 | {
32 | get
33 | {
34 | return advertisement;
35 | }
36 |
37 | set
38 | {
39 | Set(ref advertisement, value, "Advertisement");
40 | }
41 | }
42 |
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/Services/AlertNotificationServicePageViewModel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using BluetoothLEExplorer.Models;
9 | using GattServicesLibrary.Services;
10 | using Template10.Mvvm;
11 | using Template10.Services.NavigationService;
12 | using Windows.UI.Xaml.Navigation;
13 |
14 | namespace BluetoothLEExplorer.ViewModels
15 | {
16 | ///
17 | /// View Model for the view
18 | ///
19 | public class AlertNotificationServicePageViewModel : ViewModelBase
20 | {
21 | ///
22 | /// App context
23 | ///
24 | private GattSampleContext context = GattSampleContext.Context;
25 |
26 | ///
27 | /// Gets or sets the currently selected service view model
28 | ///
29 | public GenericGattServiceViewModel ServiceVM { get; set; } = GattSampleContext.Context.SelectedGattServerService;
30 |
31 | ///
32 | /// Gets or sets the currently selected service
33 | ///
34 | public AlertNotificationService Service { get; set; } = GattSampleContext.Context.SelectedGattServerService.Service as AlertNotificationService;
35 |
36 | ///
37 | /// Gets the New Alert characteristic.
38 | ///
39 | public GenericGattCharacteristicViewModel NewAlert { get; private set; }
40 |
41 | ///
42 | /// Gets the Unread Alert Status characteristic.
43 | ///
44 | public GenericGattCharacteristicViewModel UnreadAlertStatus { get; private set; }
45 |
46 | public GenericGattCharacteristicViewModel AlertNotificationControlPoint { get; private set; }
47 |
48 | ///
49 | /// Initializes a new instance of the class.
50 | ///
51 | public AlertNotificationServicePageViewModel()
52 | {
53 | NewAlert = new GenericGattCharacteristicViewModel(Service.NewAlert);
54 | UnreadAlertStatus = new GenericGattCharacteristicViewModel(Service.UnreadAlertStatus);
55 | AlertNotificationControlPoint = new GenericGattCharacteristicViewModel(Service.AlertNotificationControlPoint);
56 | }
57 |
58 | ///
59 | /// Navigate from page
60 | ///
61 | ///
62 | /// Navigate from task
63 | public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
64 | {
65 | context.SelectedGattServerService = null;
66 | args.Cancel = false;
67 | await Task.CompletedTask;
68 | }
69 |
70 | ///
71 | /// Go to settings
72 | ///
73 | public void GotoSettings() =>
74 | NavigationService.Navigate(typeof(Views.SettingsPage), 0);
75 |
76 | ///
77 | /// Go to privacy
78 | ///
79 | public void GotoPrivacy() =>
80 | NavigationService.Navigate(typeof(Views.SettingsPage), 1);
81 |
82 | ///
83 | /// Go to about
84 | ///
85 | public void GotoAbout() =>
86 | NavigationService.Navigate(typeof(Views.SettingsPage), 2);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/Services/BatteryServicePageViewModel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using BluetoothLEExplorer.Models;
9 | using GattServicesLibrary.Services;
10 | using Template10.Mvvm;
11 | using Template10.Services.NavigationService;
12 | using Windows.UI.Xaml.Navigation;
13 |
14 | namespace BluetoothLEExplorer.ViewModels
15 | {
16 | ///
17 | /// View Model for the view
18 | ///
19 | public class BatteryServicePageViewModel : ViewModelBase
20 | {
21 | ///
22 | /// App context
23 | ///
24 | private GattSampleContext context = GattSampleContext.Context;
25 |
26 | ///
27 | /// Gets or sets the currently selected service view model
28 | ///
29 | public GenericGattServiceViewModel ServiceVM { get; set; } = GattSampleContext.Context.SelectedGattServerService;
30 |
31 | ///
32 | /// Gets or sets the currently selected service
33 | ///
34 | public BatteryService Service { get; set; } = GattSampleContext.Context.SelectedGattServerService.Service as BatteryService;
35 |
36 | ///
37 | /// Gets the battery level
38 | ///
39 | public GenericGattCharacteristicViewModel BatteryLevel { get; private set; }
40 |
41 | ///
42 | /// Initializes a new instance of the class.
43 | ///
44 | public BatteryServicePageViewModel()
45 | {
46 | BatteryLevel = new GenericGattCharacteristicViewModel(Service.BatteryLevel);
47 | }
48 |
49 | ///
50 | /// Navigate from page
51 | ///
52 | ///
53 | /// Navigate from task
54 | public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
55 | {
56 | context.SelectedGattServerService = null;
57 | args.Cancel = false;
58 | await Task.CompletedTask;
59 | }
60 |
61 | ///
62 | /// Go to settings
63 | ///
64 | public void GotoSettings() =>
65 | NavigationService.Navigate(typeof(Views.SettingsPage), 0);
66 |
67 | ///
68 | /// Go to privacy
69 | ///
70 | public void GotoPrivacy() =>
71 | NavigationService.Navigate(typeof(Views.SettingsPage), 1);
72 |
73 | ///
74 | /// Go to about
75 | ///
76 | public void GotoAbout() =>
77 | NavigationService.Navigate(typeof(Views.SettingsPage), 2);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/Services/BloodPressureServicePageViewModel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using BluetoothLEExplorer.Models;
9 | using GattServicesLibrary.Services;
10 | using Template10.Mvvm;
11 | using Template10.Services.NavigationService;
12 | using Windows.UI.Xaml.Navigation;
13 |
14 | namespace BluetoothLEExplorer.ViewModels
15 | {
16 | ///
17 | /// View Model for the view
18 | ///
19 | public class BloodPressureServicePageViewModel : ViewModelBase
20 | {
21 | ///
22 | /// App context
23 | ///
24 | private GattSampleContext context = GattSampleContext.Context;
25 |
26 | ///
27 | /// Gets or sets the currently selected service view model
28 | ///
29 | public GenericGattServiceViewModel ServiceVM { get; set; } = GattSampleContext.Context.SelectedGattServerService;
30 |
31 | ///
32 | /// Gets or sets the currently selected service
33 | ///
34 | public BloodPressureService Service { get; set; } = GattSampleContext.Context.SelectedGattServerService.Service as BloodPressureService;
35 |
36 | ///
37 | /// Gets the blood pressure measurement
38 | ///
39 | public GenericGattCharacteristicViewModel BloodPressureMeasurement { get; private set; }
40 |
41 | ///
42 | /// Gets the blood pressure feature
43 | ///
44 | public GenericGattCharacteristicViewModel BloodPressureFeature { get; private set; }
45 |
46 | ///
47 | /// Initializes a new instance of the class.
48 | ///
49 | public BloodPressureServicePageViewModel()
50 | {
51 | BloodPressureMeasurement = new GenericGattCharacteristicViewModel(Service.BloodPressureMeasurement);
52 | BloodPressureFeature = new GenericGattCharacteristicViewModel(Service.BloodPressureFeature);
53 | }
54 |
55 | ///
56 | /// Navigate from page
57 | ///
58 | ///
59 | /// Navigate from task
60 | public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
61 | {
62 | context.SelectedGattServerService = null;
63 | args.Cancel = false;
64 | await Task.CompletedTask;
65 | }
66 |
67 | ///
68 | /// Go to settings
69 | ///
70 | public void GotoSettings() =>
71 | NavigationService.Navigate(typeof(Views.SettingsPage), 0);
72 |
73 | ///
74 | /// Go to privacy
75 | ///
76 | public void GotoPrivacy() =>
77 | NavigationService.Navigate(typeof(Views.SettingsPage), 1);
78 |
79 | ///
80 | /// Go to about
81 | ///
82 | public void GotoAbout() =>
83 | NavigationService.Navigate(typeof(Views.SettingsPage), 2);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/Services/CurrentTimeServicePageViewModel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using BluetoothLEExplorer.Models;
9 | using GattServicesLibrary.Services;
10 | using Template10.Mvvm;
11 | using Template10.Services.NavigationService;
12 | using Windows.UI.Xaml.Navigation;
13 |
14 | namespace BluetoothLEExplorer.ViewModels
15 | {
16 | ///
17 | /// View Model for the view
18 | ///
19 | public class CurrentTimeServicePageViewModel : ViewModelBase
20 | {
21 | ///
22 | /// App context
23 | ///
24 | private GattSampleContext context = GattSampleContext.Context;
25 |
26 | ///
27 | /// Gets or sets the currently selected service view model
28 | ///
29 | public GenericGattServiceViewModel ServiceVM { get; set; } = GattSampleContext.Context.SelectedGattServerService;
30 |
31 | ///
32 | /// Gets or sets the currently selected service
33 | ///
34 | public CurrentTimeService Service { get; set; } = GattSampleContext.Context.SelectedGattServerService.Service as CurrentTimeService;
35 |
36 | ///
37 | /// Gets the New Alert characteristic.
38 | ///
39 | public GenericGattCharacteristicViewModel CurrentTime { get; private set; }
40 |
41 | ///
42 | /// Gets the Unread Alert Status characteristic.
43 | ///
44 | public GenericGattCharacteristicViewModel UnreadAlertStatus { get; private set; }
45 |
46 | ///
47 | /// Initializes a new instance of the class.
48 | ///
49 | public CurrentTimeServicePageViewModel()
50 | {
51 | CurrentTime = new GenericGattCharacteristicViewModel(Service.CurrentTime);
52 | }
53 |
54 | ///
55 | /// Navigate from page
56 | ///
57 | ///
58 | /// Navigate from task
59 | public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
60 | {
61 | context.SelectedGattServerService = null;
62 | args.Cancel = false;
63 | await Task.CompletedTask;
64 | }
65 |
66 | ///
67 | /// Go to settings
68 | ///
69 | public void GotoSettings() =>
70 | NavigationService.Navigate(typeof(Views.SettingsPage), 0);
71 |
72 | ///
73 | /// Go to privacy
74 | ///
75 | public void GotoPrivacy() =>
76 | NavigationService.Navigate(typeof(Views.SettingsPage), 1);
77 |
78 | ///
79 | /// Go to about
80 | ///
81 | public void GotoAbout() =>
82 | NavigationService.Navigate(typeof(Views.SettingsPage), 2);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/Services/HeartRateServicePageViewModel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using BluetoothLEExplorer.Models;
9 | using GattServicesLibrary.Services;
10 | using Template10.Mvvm;
11 | using Template10.Services.NavigationService;
12 | using Windows.UI.Xaml.Navigation;
13 |
14 | namespace BluetoothLEExplorer.ViewModels
15 | {
16 | ///
17 | /// View Model for the view
18 | ///
19 | public class HeartRateServicePageViewModel : ViewModelBase
20 | {
21 | ///
22 | /// App context
23 | ///
24 | private GattSampleContext context = GattSampleContext.Context;
25 |
26 | ///
27 | /// Gets or sets the currently selected service view model
28 | ///
29 | public GenericGattServiceViewModel ServiceVM { get; set; } = GattSampleContext.Context.SelectedGattServerService;
30 |
31 | ///
32 | /// Gets or sets the currently selected service
33 | ///
34 | public HeartRateService Service { get; set; } = GattSampleContext.Context.SelectedGattServerService.Service as HeartRateService;
35 |
36 | ///
37 | /// Gets the heart rate measurement
38 | ///
39 | public GenericGattCharacteristicViewModel HeartRateMeasurement { get; private set; }
40 |
41 | ///
42 | /// Initializes a new instance of the class.
43 | ///
44 | public HeartRateServicePageViewModel()
45 | {
46 | HeartRateMeasurement = new GenericGattCharacteristicViewModel(Service.HeartRateMeasurement);
47 | }
48 |
49 | ///
50 | /// Navigate from page
51 | ///
52 | ///
53 | /// Navigate from task
54 | public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
55 | {
56 | context.SelectedGattServerService = null;
57 | args.Cancel = false;
58 | await Task.CompletedTask;
59 | }
60 |
61 | ///
62 | /// Go to settings
63 | ///
64 | public void GotoSettings() =>
65 | NavigationService.Navigate(typeof(Views.SettingsPage), 0);
66 |
67 | ///
68 | /// Go to privacy
69 | ///
70 | public void GotoPrivacy() =>
71 | NavigationService.Navigate(typeof(Views.SettingsPage), 1);
72 |
73 | ///
74 | /// Go to about
75 | ///
76 | public void GotoAbout() =>
77 | NavigationService.Navigate(typeof(Views.SettingsPage), 2);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/Services/MicrosoftServicePageViewModel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using BluetoothLEExplorer.Models;
9 | using GattServicesLibrary.Services;
10 | using Template10.Mvvm;
11 | using Template10.Services.NavigationService;
12 | using Windows.UI.Xaml.Navigation;
13 |
14 | namespace BluetoothLEExplorer.ViewModels
15 | {
16 | ///
17 | /// View Model for the view
18 | ///
19 | public class MicrosoftServicePageViewModel : ViewModelBase
20 | {
21 | ///
22 | /// App context
23 | ///
24 | private GattSampleContext context = GattSampleContext.Context;
25 |
26 | ///
27 | /// Gets or sets the selected service view model
28 | ///
29 | public GenericGattServiceViewModel ServiceVM { get; set; } = GattSampleContext.Context.SelectedGattServerService;
30 |
31 | ///
32 | /// Gets or sets the selected service
33 | ///
34 | public MicrosoftService Service { get; set; } = GattSampleContext.Context.SelectedGattServerService.Service as MicrosoftService;
35 |
36 | ///
37 | /// Gets the read Characteristic
38 | ///
39 | public GenericGattCharacteristicViewModel ReadCharacteristic { get; private set; }
40 |
41 | ///
42 | /// Gets write Characteristic
43 | ///
44 | public GenericGattCharacteristicViewModel WriteCharacteristic { get; private set; }
45 |
46 | ///
47 | /// Gets notify Characteristic
48 | ///
49 | public GenericGattCharacteristicViewModel NotifyCharacteristic { get; private set; }
50 |
51 | ///
52 | /// Gets indicate Characteristic
53 | ///
54 | public GenericGattCharacteristicViewModel IndicateCharacteristic { get; private set; }
55 |
56 | ///
57 | /// Gets the read long characteristic
58 | ///
59 | public GenericGattCharacteristicViewModel ReadLongCharacteristic { get; private set; }
60 |
61 | ///
62 | /// Initializes a new instance of the class.
63 | ///
64 | public MicrosoftServicePageViewModel()
65 | {
66 | ReadCharacteristic = new GenericGattCharacteristicViewModel(Service.ReadCharacteristic);
67 | WriteCharacteristic = new GenericGattCharacteristicViewModel(Service.WriteCharacteristic);
68 | NotifyCharacteristic = new GenericGattCharacteristicViewModel(Service.NotifyCharacteristic);
69 | IndicateCharacteristic = new GenericGattCharacteristicViewModel(Service.IndicateCharacteristic);
70 | ReadLongCharacteristic = new GenericGattCharacteristicViewModel(Service.ReadLongCharacteristic);
71 | }
72 |
73 | ///
74 | /// Navigate from page
75 | ///
76 | ///
77 | /// Navigate from task
78 | public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
79 | {
80 | context.SelectedGattServerService = null;
81 | args.Cancel = false;
82 | await Task.CompletedTask;
83 | }
84 |
85 | ///
86 | /// Go to settings
87 | ///
88 | public void GotoSettings() =>
89 | NavigationService.Navigate(typeof(Views.SettingsPage), 0);
90 |
91 | ///
92 | /// Go to privacy
93 | ///
94 | public void GotoPrivacy() =>
95 | NavigationService.Navigate(typeof(Views.SettingsPage), 1);
96 |
97 | ///
98 | /// Go to about
99 | ///
100 | public void GotoAbout() =>
101 | NavigationService.Navigate(typeof(Views.SettingsPage), 2);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/ViewModels/ShellViewModel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using BluetoothLEExplorer.Models;
6 | using Template10.Mvvm;
7 |
8 | namespace BluetoothLEExplorer.ViewModels
9 | {
10 | ///
11 | /// View Model for the shell
12 | ///
13 | public class ShellViewModel : ViewModelBase
14 | {
15 | ///
16 | /// App context
17 | ///
18 | private GattSampleContext context = GattSampleContext.Context;
19 |
20 | ///
21 | /// Gets a value indicating whether this host supports peripheral role
22 | ///
23 | public bool IsPeripheralRoleSupported
24 | {
25 | get
26 | {
27 | return context.IsPeripheralRoleSupported;
28 | }
29 | }
30 |
31 | ///
32 | /// Gets a value indicating whether this host supports central role
33 | ///
34 | public bool IsCentralRoleSupported
35 | {
36 | get
37 | {
38 | return context.IsCentralRoleSupported;
39 | }
40 | }
41 |
42 | ///
43 | /// Initializes a new instance of the class.
44 | ///
45 | public ShellViewModel()
46 | {
47 | if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
48 | {
49 | }
50 |
51 | context.PropertyChanged += Context_PropertyChanged;
52 | }
53 |
54 | ///
55 | /// Property changed
56 | ///
57 | ///
58 | ///
59 | private void Context_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
60 | {
61 | if (e.PropertyName == "IsPeripheralRoleSupported")
62 | {
63 | this.RaisePropertyChanged("IsPeripheralRoleSupported");
64 | }
65 |
66 | if (e.PropertyName == "IsCentralRoleSupported")
67 | {
68 | RaisePropertyChanged("IsCentralRoleSupported");
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/AdvertisementBeaconDetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Collapsed
26 |
27 |
28 | Visible
29 |
30 |
31 |
32 |
33 |
34 | True
35 |
36 |
37 | Visible
38 |
39 |
40 | Collapsed
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/AdvertisementBeaconDetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
17 |
18 | namespace BluetoothLEExplorer.Views
19 | {
20 | ///
21 | /// An empty page that can be used on its own or navigated to within a Frame.
22 | ///
23 | public sealed partial class AdvertisementBeaconDetailsPage : Page
24 | {
25 | public AdvertisementBeaconDetailsPage()
26 | {
27 | this.InitializeComponent();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/AdvertisementBeaconPage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 | using System.Text.RegularExpressions;
7 |
8 | namespace BluetoothLEExplorer.Views
9 | {
10 | //public class ValidationTextBox : TextBox
11 | //{
12 | // public Regex ValidationExpression { get; set; }
13 |
14 | // protected override void OnPreviewTextInput(TextCompositionEventArgs e)
15 | // {
16 |
17 |
18 | // string currentText = this.Text;
19 | // string newText = currentText + e.Text;
20 | // }
21 |
22 | ///
23 | /// An empty page that can be used on its own or navigated to within a Frame.
24 | ///
25 | public sealed partial class AdvertisementBeaconPage : Page
26 | {
27 | ///
28 | /// Initializes a new instance of the class.
29 | ///
30 | public AdvertisementBeaconPage()
31 | {
32 | this.InitializeComponent();
33 | }
34 |
35 | public void PreferredTxPower_BeforeTextChanging(TextBox sender, TextBoxBeforeTextChangingEventArgs e)
36 | {
37 | if (!string.IsNullOrWhiteSpace(e.NewText) && Regex.IsMatch(e.NewText, @"[^0-9\-]+"))
38 | {
39 | e.Cancel = true;
40 | }
41 | }
42 |
43 | public void Payload_BeforeTextChanging(TextBox sender, TextBoxBeforeTextChangingEventArgs e)
44 | {
45 | if (!string.IsNullOrWhiteSpace(e.NewText) &&
46 | !Regex.IsMatch(e.NewText, @"^([0-9a-f]{1,2}[\-]{0,1})*$", RegexOptions.IgnoreCase))
47 | {
48 | e.Cancel = true;
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/AdvertisementMonitorPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.Xaml;
9 | using Windows.UI.Xaml.Controls;
10 | using Windows.UI.Xaml.Controls.Primitives;
11 | using Windows.UI.Xaml.Data;
12 | using Windows.UI.Xaml.Input;
13 | using Windows.UI.Xaml.Media;
14 | using Windows.UI.Xaml.Navigation;
15 |
16 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
17 |
18 | namespace BluetoothLEExplorer.Views
19 | {
20 | ///
21 | /// An empty page that can be used on its own or navigated to within a Frame.
22 | ///
23 | public sealed partial class AdvertisementMonitorPage : Page
24 | {
25 | public AdvertisementMonitorPage()
26 | {
27 | this.InitializeComponent();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/AdvertisementPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using BluetoothLEExplorer.Models;
2 | using Windows.UI.Xaml.Controls;
3 | using Windows.UI.Xaml.Media;
4 | using Windows.UI.Xaml.Navigation;
5 |
6 | namespace BluetoothLEExplorer.Views
7 | {
8 | ///
9 | /// An empty page that can be used on its own or navigated to within a Frame.
10 | ///
11 | public sealed partial class AdvertisementPage : Page
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | public AdvertisementPage()
17 | {
18 | InitializeComponent();
19 | NavigationCacheMode = NavigationCacheMode.Disabled;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Busy.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Busy.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Template10.Common;
6 | using Template10.Controls;
7 | using Windows.UI.Xaml;
8 | using Windows.UI.Xaml.Controls;
9 |
10 | namespace BluetoothLEExplorer.Views
11 | {
12 | ///
13 | /// Busy overlay
14 | ///
15 | public sealed partial class Busy : UserControl
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | public Busy()
21 | {
22 | InitializeComponent();
23 | }
24 |
25 | ///
26 | /// Gets or sets a value of the busy text
27 | ///
28 | public string BusyText
29 | {
30 | get { return (string)GetValue(BusyTextProperty); }
31 | set { SetValue(BusyTextProperty, value); }
32 | }
33 |
34 | ///
35 | /// Busy text property
36 | ///
37 | public static readonly DependencyProperty BusyTextProperty = DependencyProperty.Register(nameof(BusyText), typeof(string), typeof(Busy), new PropertyMetadata("Please wait..."));
38 |
39 | ///
40 | /// Gets or sets a value indicating whether the busy screen should be displayed
41 | ///
42 | public bool IsBusy
43 | {
44 | get { return (bool)GetValue(IsBusyProperty); }
45 | set { SetValue(IsBusyProperty, value); }
46 | }
47 |
48 | ///
49 | /// Dependency object for is busy property
50 | ///
51 | public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register(nameof(IsBusy), typeof(bool), typeof(Busy), new PropertyMetadata(false));
52 |
53 | ///
54 | /// hide and show busy dialog
55 | ///
56 | ///
57 | ///
58 | public static void SetBusy(bool busy, string text = null)
59 | {
60 | WindowWrapper.Current().Dispatcher.Dispatch(() =>
61 | {
62 | var modal = Window.Current.Content as ModalDialog;
63 | var view = modal.ModalContent as Busy;
64 |
65 | if (view == null)
66 | {
67 | modal.ModalContent = view = new Busy();
68 | }
69 |
70 | modal.IsModal = view.IsBusy = busy;
71 | view.BusyText = text;
72 | });
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/CharacteristicPage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using BluetoothLEExplorer.Models;
6 | using Windows.UI.Xaml.Controls;
7 | using Windows.UI.Xaml.Media;
8 | using Windows.UI.Xaml.Navigation;
9 |
10 | namespace BluetoothLEExplorer.Views
11 | {
12 | ///
13 | /// Characteristic Page
14 | ///
15 | public sealed partial class CharacteristicPage : Page
16 | {
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | public CharacteristicPage()
21 | {
22 | InitializeComponent();
23 | NavigationCacheMode = NavigationCacheMode.Disabled;
24 | }
25 |
26 | private void WriteValue_TextChanging(TextBox sender, TextBoxTextChangingEventArgs args)
27 | {
28 | WriteBoxBackgroundCheck();
29 | }
30 |
31 | private void radioButton5_Checked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
32 | {
33 | WriteBoxBackgroundCheck();
34 | }
35 |
36 | private void radioButton5_Unchecked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
37 | {
38 | WriteBoxBackgroundCheck();
39 | }
40 |
41 | private void WriteBoxBackgroundCheck()
42 | {
43 | if (ViewModel.WriteType == ViewModels.CharacteristicPageViewModel.WriteTypes.Hex)
44 | {
45 | int buf;
46 | if (string.IsNullOrWhiteSpace(WriteValue.Text) == false)
47 | {
48 | for(int i = 0; i < WriteValue.Text.Length; i++)
49 | {
50 | if(int.TryParse(WriteValue.Text[i].ToString(), System.Globalization.NumberStyles.AllowHexSpecifier, null, out buf) == false)
51 | {
52 | WriteValue.Background = new SolidColorBrush(Windows.UI.Colors.Red);
53 | return;
54 | }
55 | }
56 | }
57 | }
58 |
59 | WriteValue.Background = new SolidColorBrush(Windows.UI.Colors.White);
60 | }
61 |
62 | private void DescriptorsListView_ItemClick(object sender, ItemClickEventArgs e)
63 | {
64 | ViewModel.SelectedDescriptor = (ObservableGattDescriptors)e.ClickedItem;
65 | }
66 |
67 | ///
68 | /// Detect when a user presses enter and writes the value to the selected GattCharacterisitc.
69 | ///
70 | public void DetectEnter_Keydown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
71 | {
72 | if (e.Key == Windows.System.VirtualKey.Enter)
73 | {
74 | ViewModel.WriteValue();
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/DeviceServicesPage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using BluetoothLEExplorer.Models;
6 | using System;
7 | using Windows.UI;
8 | using Windows.UI.Xaml.Controls;
9 | using Windows.UI.Xaml.Data;
10 | using Windows.UI.Xaml.Media;
11 | using Windows.UI.Xaml.Navigation;
12 |
13 | namespace BluetoothLEExplorer.Views
14 | {
15 | ///
16 | /// Device Service page
17 | ///
18 | public sealed partial class DeviceServicesPage : Page
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public DeviceServicesPage()
24 | {
25 | InitializeComponent();
26 | NavigationCacheMode = NavigationCacheMode.Disabled;
27 | }
28 |
29 | ///
30 | /// Updates the view model with the just selected characteristic
31 | ///
32 | ///
33 | ///
34 | private void CharacteristicsListView_ItemClick(object sender, ItemClickEventArgs e)
35 | {
36 | ViewModel.SelectedCharacteristic = (ObservableGattCharacteristics)e.ClickedItem;
37 | }
38 |
39 | ///
40 | /// Updates the view model with the just selected service
41 | ///
42 | ///
43 | ///
44 | private void ServicesListView_ItemClick(object sender, ItemClickEventArgs e)
45 | {
46 | ViewModel.SelectedService = (ObservableGattDeviceService)e.ClickedItem;
47 | }
48 | }
49 |
50 | public class BackgroundColorConverter : IValueConverter
51 | {
52 | public object Convert(object value, Type targetType, object parameter, string language)
53 | {
54 | if (value is bool && (bool)value == false)
55 | {
56 | return new SolidColorBrush(Colors.Red);
57 | }
58 | else
59 | {
60 | return new SolidColorBrush(Colors.Transparent);
61 | }
62 | }
63 |
64 | public object ConvertBack(object value, Type targetType, object parameter, string language)
65 | {
66 | throw new NotImplementedException();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Discover.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml;
6 | using Windows.UI.Xaml.Controls;
7 | using Windows.UI.Xaml.Controls.Primitives;
8 |
9 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
10 |
11 | namespace BluetoothLEExplorer.Views
12 | {
13 | ///
14 | /// An empty page that can be used on its own or navigated to within a Frame.
15 | ///
16 | public sealed partial class Discover : Page
17 | {
18 | ///
19 | /// Initializes a new instance of the class.
20 | ///
21 | public Discover()
22 | {
23 | this.InitializeComponent();
24 | }
25 |
26 | private void Grid_Holding(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs e)
27 | {
28 | FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/ServicePage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using BluetoothLEExplorer.Models;
6 | using System;
7 | using Windows.UI;
8 | using Windows.UI.Xaml.Controls;
9 | using Windows.UI.Xaml.Data;
10 | using Windows.UI.Xaml.Media;
11 | using Windows.UI.Xaml.Navigation;
12 |
13 | namespace BluetoothLEExplorer.Views
14 | {
15 | ///
16 | /// Device Service page
17 | ///
18 | public sealed partial class ServicePage : Page
19 | {
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | public ServicePage()
24 | {
25 | InitializeComponent();
26 | NavigationCacheMode = NavigationCacheMode.Disabled;
27 | }
28 |
29 | ///
30 | /// Updates the view model with the just selected characteristic
31 | ///
32 | ///
33 | ///
34 | private void CharacteristicsListView_ItemClick(object sender, ItemClickEventArgs e)
35 | {
36 | ViewModel.SelectedCharacteristic = (ObservableGattCharacteristics)e.ClickedItem;
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Services/AlertNotificationServicePage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// An empty page that can be used on its own or navigated to within a Frame.
13 | ///
14 | public sealed partial class AlertNotificationServicePage : Page
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public AlertNotificationServicePage()
20 | {
21 | this.InitializeComponent();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Services/BatteryServicePage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// An empty page that can be used on its own or navigated to within a Frame.
13 | ///
14 | public sealed partial class BatteryServicePage : Page
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public BatteryServicePage()
20 | {
21 | this.InitializeComponent();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Services/BloodPressureServicePage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// An empty page that can be used on its own or navigated to within a Frame.
13 | ///
14 | public sealed partial class BloodPressureServicePage : Page
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public BloodPressureServicePage()
20 | {
21 | this.InitializeComponent();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Services/CurrentTimeServicePage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// An empty page that can be used on its own or navigated to within a Frame.
13 | ///
14 | public sealed partial class CurrentTimeServicePage : Page
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public CurrentTimeServicePage()
20 | {
21 | this.InitializeComponent();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Services/HeartRateServicePage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// An empty page that can be used on its own or navigated to within a Frame.
13 | ///
14 | public sealed partial class HeartRateServicePage : Page
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public HeartRateServicePage()
20 | {
21 | this.InitializeComponent();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Services/MicrosoftServicePage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | namespace BluetoothLEExplorer.Views
8 | {
9 | ///
10 | /// An empty page that can be used on its own or navigated to within a Frame.
11 | ///
12 | public sealed partial class MicrosoftServicePage : Page
13 | {
14 | ///
15 | /// Initializes a new instance of the class.
16 | ///
17 | public MicrosoftServicePage()
18 | {
19 | this.InitializeComponent();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/SettingsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 | using Windows.UI.Xaml.Navigation;
7 |
8 | namespace BluetoothLEExplorer.Views
9 | {
10 | ///
11 | /// Settings page
12 | ///
13 | public sealed partial class SettingsPage : Page
14 | {
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | public SettingsPage()
19 | {
20 | InitializeComponent();
21 | }
22 |
23 | ///
24 | /// Executes when navigating to settings page
25 | ///
26 | ///
27 | protected override void OnNavigatedTo(NavigationEventArgs e)
28 | {
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Shell.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Template10.Controls;
6 | using Template10.Services.NavigationService;
7 | using Windows.UI.Xaml.Controls;
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// Shell page
13 | ///
14 | public sealed partial class Shell : Page
15 | {
16 | ///
17 | /// Gets or sets the shell instance
18 | ///
19 | public static Shell Instance { get; set; }
20 |
21 | ///
22 | /// Hamburger menu instance
23 | ///
24 | public static HamburgerMenu HamburgerMenu => Instance.MyHamburgerMenu;
25 |
26 | ///
27 | /// Initializes a new instance of the class.
28 | ///
29 | public Shell()
30 | {
31 | Instance = this;
32 | InitializeComponent();
33 | }
34 |
35 | ///
36 | /// Initializes a new instance of the class.
37 | ///
38 | ///
39 | public Shell(INavigationService navigationService) : this()
40 | {
41 | SetNavigationService(navigationService);
42 | }
43 |
44 | ///
45 | /// Initializes the navigation service
46 | ///
47 | ///
48 | public void SetNavigationService(INavigationService navigationService)
49 | {
50 | MyHamburgerMenu.NavigationService = navigationService;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Splash.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
29 |
30 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/Splash.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.ApplicationModel.Activation;
6 | using Windows.UI.Xaml;
7 | using Windows.UI.Xaml.Controls;
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// Splash screen
13 | ///
14 | public sealed partial class Splash : UserControl
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | ///
20 | public Splash(SplashScreen splashScreen)
21 | {
22 | InitializeComponent();
23 | Window.Current.SizeChanged += (s, e) => Resize(splashScreen);
24 | Resize(splashScreen);
25 | }
26 |
27 | ///
28 | /// Resizes the splash screen
29 | ///
30 | ///
31 | private void Resize(SplashScreen splashScreen)
32 | {
33 | if (splashScreen.ImageLocation.Top == 0)
34 | {
35 | splashImage.Visibility = Visibility.Collapsed;
36 | return;
37 | }
38 | else
39 | {
40 | rootCanvas.Background = null;
41 | splashImage.Visibility = Visibility.Visible;
42 | }
43 |
44 | splashImage.Height = splashScreen.ImageLocation.Height;
45 | splashImage.Width = splashScreen.ImageLocation.Width;
46 | splashImage.SetValue(Canvas.TopProperty, splashScreen.ImageLocation.Top);
47 | splashImage.SetValue(Canvas.LeftProperty, splashScreen.ImageLocation.Left);
48 | ProgressTransform.TranslateY = splashImage.Height / 2;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/VirtualKeyboardPage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// An empty page that can be used on its own or navigated to within a Frame.
13 | ///
14 | public sealed partial class VirtualKeyboardPage : Page
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public VirtualKeyboardPage()
20 | {
21 | InitializeComponent();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorer/Views/VirtualPeripheralPage.xaml.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using Windows.UI.Xaml.Controls;
6 |
7 | //// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
8 |
9 | namespace BluetoothLEExplorer.Views
10 | {
11 | ///
12 | /// An empty page that can be used on its own or navigated to within a Frame.
13 | ///
14 | public sealed partial class VirtualPeripheralPage : Page
15 | {
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | public VirtualPeripheralPage()
20 | {
21 | this.InitializeComponent();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | BluetoothLEExplorerUnitTests
7 | stfro
8 | Assets\StoreLogo.png
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle("BluetoothLEExplorerUnitTests")]
6 | [assembly: AssemblyDescription("")]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany("")]
9 | [assembly: AssemblyProduct("BluetoothLEExplorerUnitTests")]
10 | [assembly: AssemblyCopyright("Copyright © 2017")]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 | [assembly: AssemblyMetadata("TargetPlatform","UAP")]
14 |
15 | // [assembly: AssemblyVersion("1.0.*")]
16 | [assembly: AssemblyVersion("1.0.0.0")]
17 | [assembly: AssemblyFileVersion("1.0.0.0")]
18 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/Properties/UnitTestApp.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/UnitTestApp.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/BluetoothLEExplorerUnitTests/UnitTestApp.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace BluetoothLEExplorerUnitTests
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | this.InitializeComponent();
32 | this.Suspending += OnSuspending;
33 | }
34 |
35 | ///
36 | /// Invoked when the application is launched normally by the end user. Other entry points
37 | /// will be used such as when the application is launched to open a specific file.
38 | ///
39 | /// Details about the launch request and process.
40 | protected override void OnLaunched(LaunchActivatedEventArgs e)
41 | {
42 |
43 | #if DEBUG
44 | if (System.Diagnostics.Debugger.IsAttached)
45 | {
46 | this.DebugSettings.EnableFrameRateCounter = true;
47 | }
48 | #endif
49 |
50 | Frame rootFrame = Window.Current.Content as Frame;
51 |
52 | // Do not repeat app initialization when the Window already has content,
53 | // just ensure that the window is active
54 | if (rootFrame == null)
55 | {
56 | // Create a Frame to act as the navigation context and navigate to the first page
57 | rootFrame = new Frame();
58 |
59 | rootFrame.NavigationFailed += OnNavigationFailed;
60 |
61 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
62 | {
63 | //TODO: Load state from previously suspended application
64 | }
65 |
66 | // Place the frame in the current Window
67 | Window.Current.Content = rootFrame;
68 | }
69 |
70 | Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
71 |
72 | // Ensure the current window is active
73 | Window.Current.Activate();
74 |
75 | Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments);
76 | }
77 |
78 | ///
79 | /// Invoked when Navigation to a certain page fails
80 | ///
81 | /// The Frame which failed navigation
82 | /// Details about the navigation failure
83 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
84 | {
85 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
86 | }
87 |
88 | ///
89 | /// Invoked when application execution is being suspended. Application state is saved
90 | /// without knowing whether the application will be terminated or resumed with the contents
91 | /// of memory still intact.
92 | ///
93 | /// The source of the suspend request.
94 | /// Details about the suspend request.
95 | private void OnSuspending(object sender, SuspendingEventArgs e)
96 | {
97 | var deferral = e.SuspendingOperation.GetDeferral();
98 | //TODO: Save application state and stop any background activity
99 | deferral.Complete();
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/DesignModel/DesignModel.modelproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | 2.0
8 | {11b48755-a5f4-4640-9c9d-1176ff71f0e8}
9 | 2.0.0.0
10 | DesignModel
11 | DesignModel
12 |
13 |
14 | bin\Debug\
15 |
16 |
17 | bin\Release\
18 |
19 |
20 | 10.0
21 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)
22 |
23 |
24 |
25 |
26 |
27 | Content
28 |
29 |
30 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/DesignModel/ModelDefinition/DesignModel.uml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
12 |
13 |
15 |
18 |
19 |
20 |
21 |
22 |
28 |
29 |
30 |
35 |
40 |
45 |
50 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/GattHelper/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("GattHelper")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GattHelper")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/BluetoothLEExplorer/GattHelper/Properties/GattHelper.rd.xml:
--------------------------------------------------------------------------------
1 |
2 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/BluetoothLEExplorer/GattHelper/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.3.3"
4 | },
5 | "frameworks": {
6 | "uap10.0": {}
7 | },
8 | "runtimes": {
9 | "win10-arm": {},
10 | "win10-arm-aot": {},
11 | "win10-x86": {},
12 | "win10-x86-aot": {},
13 | "win10-x64": {},
14 | "win10-x64-aot": {}
15 | }
16 | }
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GattServicesLibrary", "GattServicesLibrary\GattServicesLibrary.csproj", "{644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|ARM = Debug|ARM
12 | Debug|x64 = Debug|x64
13 | Debug|x86 = Debug|x86
14 | Release|Any CPU = Release|Any CPU
15 | Release|ARM = Release|ARM
16 | Release|x64 = Release|x64
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|ARM.ActiveCfg = Debug|ARM
23 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|ARM.Build.0 = Debug|ARM
24 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|x64.ActiveCfg = Debug|x64
25 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|x64.Build.0 = Debug|x64
26 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|x86.ActiveCfg = Debug|x86
27 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Debug|x86.Build.0 = Debug|x86
28 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|ARM.ActiveCfg = Release|ARM
31 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|ARM.Build.0 = Release|ARM
32 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|x64.ActiveCfg = Release|x64
33 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|x64.Build.0 = Release|x64
34 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|x86.ActiveCfg = Release|x86
35 | {644F40AD-EABB-4570-B9B7-E3F8DDAA80F3}.Release|x86.Build.0 = Release|x86
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | EndGlobal
41 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/AlertNotificationControlPointCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using GattServicesLibrary.Helpers;
11 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
12 | using Windows.Devices.Power;
13 | using Windows.Storage.Streams;
14 | using Windows.System.Threading;
15 | using System.Runtime.InteropServices.WindowsRuntime;
16 |
17 | namespace GattServicesLibrary.Characteristics
18 | {
19 | ///
20 | /// Implementation of the battery profile
21 | ///
22 | public class AlertNotificationControlPointCharacteristic : GenericGattCharacteristic
23 | {
24 | public struct AlertNotificationControlPointCommand
25 | {
26 | public GattServicesLibrary.CharacteristicParameterValues.AlertNotificationControlPointCommandId CommandId;
27 | public GattServicesLibrary.CharacteristicParameterValues.AlertCategoryId CategotyId;
28 | }
29 |
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// The characteristic that this wraps
34 | public AlertNotificationControlPointCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
35 | {
36 | }
37 |
38 | protected override bool WriteRequested(GattSession session, GattWriteRequest request)
39 | {
40 | var service = base.ParentService as GattServicesLibrary.Services.AlertNotificationService;
41 | if (service != null)
42 | {
43 | AlertNotificationControlPointCommand command = new AlertNotificationControlPointCommand();
44 | var byteAccess = request.Value.ToArray();
45 | command.CommandId = (CharacteristicParameterValues.AlertNotificationControlPointCommandId)byteAccess[0];
46 | command.CategotyId = (CharacteristicParameterValues.AlertCategoryId)byteAccess[1];
47 |
48 | service.ProcessCommand(command);
49 |
50 | Value = request.Value;
51 | request.Respond();
52 | return true;
53 | }
54 | return false;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/BatteryLevelCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using GattServicesLibrary.Helpers;
11 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
12 | using Windows.Devices.Power;
13 | using Windows.Storage.Streams;
14 |
15 | namespace GattServicesLibrary.Characteristics
16 | {
17 | ///
18 | /// Implementation of the battery profile
19 | ///
20 | public class BatteryLevelCharacteristic : GenericGattCharacteristic
21 | {
22 | ///
23 | /// Access to the battery of this system
24 | ///
25 | private Battery aggBattery = Battery.AggregateBattery;
26 |
27 | ///
28 | /// Initializes a new instance of the class.
29 | ///
30 | /// The characteristic that this wraps
31 | public BatteryLevelCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
32 | {
33 | aggBattery.ReportUpdated += AggBattery_ReportUpdated;
34 | UpdateBatteryValue();
35 | }
36 |
37 | ///
38 | /// Callback when the battery level changes
39 | ///
40 | ///
41 | ///
42 | private void AggBattery_ReportUpdated(Battery sender, object args)
43 | {
44 | UpdateBatteryValue();
45 | NotifyValue();
46 | }
47 |
48 | ///
49 | /// Method that updates with the current battery level
50 | ///
51 | private void UpdateBatteryValue()
52 | {
53 | // Get report
54 | BatteryReport report = aggBattery.GetReport();
55 | float fullCharge = Convert.ToSingle(report.FullChargeCapacityInMilliwattHours);
56 | float currentCharge = Convert.ToSingle(report.RemainingCapacityInMilliwattHours);
57 |
58 | float val = (fullCharge > 0) ? (currentCharge / fullCharge) * 100.0f : 0.0f;
59 |
60 | Value = GattHelper.Converters.GattConvert.ToIBuffer((byte)Math.Round(val, 0));
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/BloodPressureFeatureCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using GattServicesLibrary.Helpers;
12 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
13 | using Windows.Devices.Power;
14 | using Windows.Storage.Streams;
15 | using GattHelper.Converters;
16 |
17 | namespace GattServicesLibrary.Characteristics
18 | {
19 | ///
20 | /// Microsoft boilerplate characteristic that supports 'Indicate' provided for completeness. This service is almost identical to MicrosoftNotifyCharacteristic.
21 | ///
22 | public class BloodPressureFeatureCharacteristic : GenericGattCharacteristic
23 | {
24 | ///
25 | /// Initializes a new instance of the class.
26 | ///
27 | /// Characteristic this wraps
28 | public BloodPressureFeatureCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
29 | {
30 | // Supports no extra features - required per spec
31 | // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.blood_pressure_feature.xml
32 | Value = GattConvert.ToIBuffer((Int16)0);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/BloodPressureMeasurementCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using GattServicesLibrary.Helpers;
12 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
13 | using Windows.Devices.Power;
14 | using Windows.Storage.Streams;
15 | using System.Threading;
16 | using GattHelper.Converters;
17 |
18 | namespace GattServicesLibrary.Characteristics
19 | {
20 | ///
21 | /// Microsoft boilerplate characteristic that supports 'Indicate' provided for completeness. This service is almost identical to MicrosoftNotifyCharacteristic.
22 | ///
23 | public class BloodPressureMeasurementCharacteristic : GenericGattCharacteristic
24 | {
25 | private Timer bloodPressureTicker = null;
26 | private Int16 Systolic = 120;
27 | private Int16 Diastolic = 80;
28 | private Random rand = new Random();
29 |
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// Characteristic this wraps
34 | public BloodPressureMeasurementCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
35 | {
36 | bloodPressureTicker = new Timer(updateBloodPressure, "", TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
37 | }
38 |
39 | private void updateBloodPressure(Object state)
40 | {
41 | // Create random blood pressure between 100-160 over 60-100
42 | Systolic = (Int16)rand.Next(100, 160);
43 | Diastolic = (Int16)rand.Next(60, 100);
44 |
45 | UInt16 MAP = (UInt16)(((2 * Diastolic) + Systolic) / 3);
46 |
47 | // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.blood_pressure_measurement.xml
48 | byte[] flags = { 0 };
49 | byte[] value = flags.Concat(
50 | BitConverter.GetBytes(Systolic)).Concat(
51 | BitConverter.GetBytes(Diastolic)).Concat(
52 | BitConverter.GetBytes(MAP)).ToArray();
53 |
54 | Value = GattConvert.ToIBuffer(value);
55 | NotifyValue();
56 | }
57 |
58 | ///
59 | /// Override so we can update the value before notifying or indicating the client
60 | ///
61 | public override void NotifyValue()
62 | {
63 | base.NotifyValue();
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/CurrentTimeCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using GattServicesLibrary.Helpers;
11 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
12 | using Windows.Devices.Power;
13 | using Windows.Storage.Streams;
14 | using Windows.System.Threading;
15 |
16 | namespace GattServicesLibrary.Characteristics
17 | {
18 | ///
19 | /// Implementation of the battery profile
20 | ///
21 | public class CurrentTimeCharacteristic : GenericGattCharacteristic
22 | {
23 | private ThreadPoolTimer m_timeUpdate = null;
24 |
25 | ///
26 | /// Initializes a new instance of the class.
27 | ///
28 | /// The characteristic that this wraps
29 | public CurrentTimeCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
30 | {
31 | UpdateCurrentTimeValue();
32 | }
33 |
34 | public override void NotifyValue()
35 | {
36 | UpdateCurrentTimeValue();
37 | base.NotifyValue();
38 | }
39 |
40 | protected override void Characteristic_SubscribedClientsChanged(GattLocalCharacteristic sender, object args)
41 | {
42 | lock (this)
43 | {
44 | if (sender.SubscribedClients.Count == 0)
45 | {
46 | if (m_timeUpdate != null)
47 | {
48 | m_timeUpdate.Cancel();
49 | m_timeUpdate = null;
50 | }
51 | }
52 | else if (m_timeUpdate == null)
53 | {
54 | m_timeUpdate = ThreadPoolTimer.CreatePeriodicTimer(
55 | (source) =>
56 | {
57 | UpdateCurrentTimeValue();
58 | NotifyValue();
59 | },
60 | TimeSpan.FromMinutes(15));
61 | }
62 | }
63 |
64 | base.Characteristic_SubscribedClientsChanged(sender, args);
65 | }
66 |
67 | ///
68 | /// Method that updates with the current battery level
69 | ///
70 | private void UpdateCurrentTimeValue()
71 | {
72 | var writer = new DataWriter();
73 | // Date time according to: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.date_time.xml
74 | DateTime exactDateTime = DateTime.Now;
75 | writer.WriteUInt16((ushort)exactDateTime.Year);
76 | writer.WriteByte((byte)exactDateTime.Month);
77 | writer.WriteByte((byte)exactDateTime.Day);
78 | writer.WriteByte((byte)exactDateTime.Hour);
79 | writer.WriteByte((byte)exactDateTime.Minute);
80 | writer.WriteByte((byte)exactDateTime.Second);
81 | // Day of week according to: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.day_of_week.xml
82 | // Going to leave this "not known" for now - would have to perform a rotate of DayOfWeek property
83 | writer.WriteByte(0x0);
84 |
85 | Value = writer.DetachBuffer();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/HeartRateMeasurementCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using GattServicesLibrary.Helpers;
11 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
12 | using Windows.Devices.Power;
13 | using Windows.Storage.Streams;
14 | using System.Threading;
15 | using GattHelper.Converters;
16 |
17 | namespace GattServicesLibrary.Characteristics
18 | {
19 | ///
20 | /// Microsoft boilerplate characteristic that supports 'Notify' provided for completeness. This service is almost identical to MicrosoftIndicateCharacteristic.
21 | ///
22 | public class HeartRateMeasurementCharacteristic : GenericGattCharacteristic
23 | {
24 | private Timer heartRateTicker = null;
25 | private Int16 currentHeartRate = 70;
26 |
27 | ///
28 | /// Initializes a new instance of the class.
29 | ///
30 | /// Characteristic this wraps
31 | public HeartRateMeasurementCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
32 | {
33 | heartRateTicker = new Timer(UpdateHeartRate, "", TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
34 | }
35 |
36 | private void UpdateHeartRate(Object state)
37 | {
38 | if (currentHeartRate == 110)
39 | {
40 | currentHeartRate = 70;
41 | }
42 | else
43 | {
44 | currentHeartRate++;
45 | }
46 |
47 | SetHeartRate();
48 | }
49 |
50 | private void SetHeartRate()
51 | {
52 | // Heart rate service starts with flags, then the value. I combine them here then set the characterstic value
53 | byte[] flags = { 0x07 };
54 | byte[] heartRate = BitConverter.GetBytes(currentHeartRate);
55 |
56 | byte[] value = flags.Concat(heartRate).ToArray();
57 |
58 | Value = GattConvert.ToIBuffer(value);
59 | NotifyValue();
60 | }
61 |
62 | ///
63 | /// Override so we can update the value before notifying or indicating the client
64 | ///
65 | public override void NotifyValue()
66 | {
67 | base.NotifyValue();
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/MicrosoftIndicateCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using GattServicesLibrary.Helpers;
12 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
13 | using Windows.Devices.Power;
14 | using Windows.Storage.Streams;
15 |
16 | namespace GattServicesLibrary.Characteristics
17 | {
18 | ///
19 | /// Microsoft boilerplate characteristic that supports 'Indicate' provided for completeness. This service is almost identical to MicrosoftNotifyCharacteristic.
20 | ///
21 | public class MicrosoftIndicateCharacteristic : GenericGattCharacteristic
22 | {
23 | ///
24 | /// Random number generator used when updating the value
25 | ///
26 | private Random rand = new Random();
27 |
28 | ///
29 | /// Initializes a new instance of the class.
30 | ///
31 | /// Characteristic this wraps
32 | public MicrosoftIndicateCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
33 | {
34 | UpdateValue();
35 | }
36 |
37 | ///
38 | /// Read request callback to update the value
39 | ///
40 | ///
41 | ///
42 | protected override bool ReadRequested(GattSession session, GattReadRequest request)
43 | {
44 | System.Diagnostics.Debug.WriteLine("Entering MSFTIndicateRequest.Characteristic_ReadRequested");
45 | UpdateValue();
46 | return false;
47 | }
48 |
49 | ///
50 | /// Override so we can update the value before notifying or indicating the client
51 | ///
52 | public override void NotifyValue()
53 | {
54 | UpdateValue();
55 | base.NotifyValue();
56 | }
57 |
58 | ///
59 | /// Updates our value with a random number
60 | ///
61 | private void UpdateValue()
62 | {
63 | int readValue = rand.Next(20, 40);
64 | Value = GattServicesHelper.ConvertValueToBuffer(Convert.ToByte(readValue));
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/MicrosoftNotifyCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using GattServicesLibrary.Helpers;
11 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
12 | using Windows.Devices.Power;
13 | using Windows.Storage.Streams;
14 |
15 | namespace GattServicesLibrary.Characteristics
16 | {
17 | ///
18 | /// Microsoft boilerplate characteristic that supports 'Notify' provided for completeness. This service is almost identical to MicrosoftIndicateCharacteristic.
19 | ///
20 | public class MicrosoftNotifyCharacteristic : GenericGattCharacteristic
21 | {
22 | ///
23 | /// Random number generator used when updating the value
24 | ///
25 | private Random rand = new Random();
26 |
27 | ///
28 | /// Initializes a new instance of the class.
29 | ///
30 | /// Characteristic this wraps
31 | public MicrosoftNotifyCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
32 | {
33 | DataWriter writer = new DataWriter();
34 | writer.WriteString("Hello World!");
35 | Value = writer.DetachBuffer();
36 | }
37 |
38 | ///
39 | /// Override so we can update the value before notifying or indicating the client
40 | ///
41 | public override void NotifyValue()
42 | {
43 | base.NotifyValue();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/MicrosoftReadCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using GattServicesLibrary.Helpers;
12 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
13 | using Windows.Devices.Power;
14 | using Windows.Storage.Streams;
15 |
16 | namespace GattServicesLibrary.Characteristics
17 | {
18 | ///
19 | /// Microsoft boilerplate characteristic that supports 'Read' provided for completeness.
20 | ///
21 | public class MicrosoftReadCharacteristic : GenericGattCharacteristic
22 | {
23 | ///
24 | /// Random number generator used when updating the value
25 | ///
26 | private Random rand = new Random();
27 |
28 | ///
29 | /// Initializes a new instance of the class.
30 | ///
31 | /// Characteristic this wraps
32 | public MicrosoftReadCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
33 | {
34 | UpdateValue();
35 | }
36 |
37 | ///
38 | /// Read request callback to update the value
39 | ///
40 | ///
41 | ///
42 | protected override bool ReadRequested(GattSession session, GattReadRequest request)
43 | {
44 | System.Diagnostics.Debug.WriteLine("Entering MSFTReadRequest.Characteristic_ReadRequested");
45 | UpdateValue();
46 | return false;
47 | }
48 |
49 | ///
50 | /// Override so we can update the value when the value is read
51 | ///
52 | private void UpdateValue()
53 | {
54 | int readValue = rand.Next(1, 20);
55 | Value = GattServicesHelper.ConvertValueToBuffer(Convert.ToByte(readValue));
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/MicrosoftReadLongCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Diagnostics;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using GattServicesLibrary.Helpers;
12 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
13 | using Windows.Devices.Power;
14 | using Windows.Foundation;
15 | using Windows.Storage.Streams;
16 |
17 | namespace GattServicesLibrary.Characteristics
18 | {
19 | ///
20 | /// Microsoft boilerplate characteristic that has a long characteristic value provided for completeness.
21 | ///
22 | public class MicrosoftReadLongCharacteristic : GenericGattCharacteristic
23 | {
24 | #region Local variables
25 | ///
26 | /// Long characteristic payload
27 | ///
28 | private byte[] longCharacteristicData = new byte[800];
29 |
30 | ///
31 | /// Lock around longCharacteristicData
32 | ///
33 | private object dataLock = new object();
34 |
35 | ///
36 | /// Microsoft service long characteristics offset value
37 | ///
38 | private int longCharacteristicReadOffset = 0;
39 | #endregion
40 |
41 | ///
42 | /// Initializes a new instance of the class.
43 | ///
44 | /// Characteristic this wraps
45 | public MicrosoftReadLongCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
46 | {
47 | for (int i = 0; i < longCharacteristicData.Length; i++)
48 | {
49 | longCharacteristicData[i] = (byte)(i % 10);
50 | }
51 | }
52 |
53 | ///
54 | /// Read request callback to update the value
55 | ///
56 | ///
57 | ///
58 | protected override bool ReadRequested(GattSession session, GattReadRequest request)
59 | {
60 | DataWriter writer = new DataWriter();
61 |
62 | int maxPayloadSize = session.MaxPduSize - 1;
63 |
64 | // make sure our source data is bigger than a single read request to make sure a ReadBlobRequest is done
65 | if (longCharacteristicData.Length < maxPayloadSize)
66 | {
67 | // This should not be required as the server should only be processing one request at a time
68 | // but it's better to be safe than sorry
69 | lock (dataLock)
70 | {
71 | longCharacteristicData = new byte[(int)(maxPayloadSize * 2.5)];
72 |
73 | for (int i = 0; i < longCharacteristicData.Length; i++)
74 | {
75 | longCharacteristicData[i] = (byte)(i % 10);
76 | }
77 | }
78 | }
79 |
80 | // finish getting the read request
81 | int offset = (int)request.Offset;
82 |
83 | // calculate the size of the data we send back
84 | int chunk = Math.Min(maxPayloadSize, longCharacteristicData.Length - offset);
85 | Debug.WriteLine($"UpdateValue: payloadSize: {maxPayloadSize}, chunk {chunk}");
86 |
87 | // prep the data we send back
88 | var readValue = String.Empty;
89 | var buffer = new byte[chunk];
90 | buffer.Initialize();
91 |
92 | // copy from source to target
93 | Array.Copy(longCharacteristicData, longCharacteristicReadOffset, buffer, 0, chunk);
94 |
95 | // write to our internal Value which will be used to send back the data
96 | writer.WriteBytes(buffer);
97 |
98 | readValue = buffer.BytesToString();
99 | Debug.WriteLine("MicrosoftReadLongCharacteristic: Read request value: {readValue}");
100 |
101 | // Update our characteristics value.
102 | Value = writer.DetachBuffer();
103 |
104 | // Respond back to the caller.
105 | request.RespondWithValue(Value);
106 | return true;
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/MicrosoftWriteCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
11 | using Windows.Devices.Power;
12 | using Windows.Storage.Streams;
13 |
14 | namespace GattServicesLibrary.Characteristics
15 | {
16 | ///
17 | /// Microsoft boilerplate characteristic that supports 'Write' provided for completeness.
18 | ///
19 | public class MicrosoftWriteCharacteristic : GenericGattCharacteristic
20 | {
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// Characteristic this wraps
25 | public MicrosoftWriteCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
26 | {
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Characteristics/UnreadAlertStatusCharacteristic.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using GattServicesLibrary.Helpers;
11 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
12 | using Windows.Devices.Power;
13 | using Windows.Storage.Streams;
14 | using Windows.System.Threading;
15 | using Windows.UI;
16 | using Windows.UI.Notifications;
17 | using Windows.UI.Notifications.Management;
18 | using GattServicesLibrary.CharacteristicParameterValues;
19 | using Windows.ApplicationModel.Core;
20 | using Windows.UI.Core;
21 | using GattHelper.Converters;
22 | using GattServicesLibrary.Services;
23 |
24 | namespace GattServicesLibrary.Characteristics
25 | {
26 | ///
27 | /// Implementation of the battery profile
28 | ///
29 | public class UnreadAlertStatusCharacteristic : GenericGattCharacteristic
30 | {
31 | private Windows.UI.Notifications.Management.UserNotificationListener notificationListener;
32 | private bool enabled = false;
33 |
34 | ///
35 | /// Initializes a new instance of the class.
36 | ///
37 | /// The characteristic that this wraps
38 | public UnreadAlertStatusCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service)
39 | {
40 | notificationListener = UserNotificationListener.Current;
41 | }
42 |
43 | public void DisableForCategory(AlertCategoryId categoryId)
44 | {
45 | if ((categoryId != AlertCategoryId.SimpleAlert) && (categoryId != AlertCategoryId.All))
46 | {
47 | return;
48 | }
49 |
50 | enabled = false;
51 | }
52 |
53 | public /*async*/ void EnableForCategory(AlertCategoryId categoryId)
54 | {
55 | if ((categoryId != AlertCategoryId.SimpleAlert) && (categoryId != AlertCategoryId.All))
56 | {
57 | return;
58 | }
59 |
60 | enabled = true;
61 | }
62 |
63 | public /*async*/ void NotifyImmediatelyForCategory(AlertCategoryId categoryId)
64 | {
65 | if ((categoryId != AlertCategoryId.SimpleAlert) && (categoryId != AlertCategoryId.All))
66 | {
67 | return;
68 | }
69 |
70 | var service = base.ParentService as AlertNotificationService;
71 |
72 | var value = new byte[] { (byte)AlertCategoryId.SimpleAlert, Convert.ToByte(service.UnreadCount) };
73 | Value = GattConvert.ToIBuffer(value);
74 | base.NotifyValue();
75 | }
76 |
77 | public override void NotifyValue()
78 | {
79 | if (!enabled)
80 | {
81 | return;
82 | }
83 |
84 | NotifyImmediatelyForCategory(AlertCategoryId.SimpleAlert);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Helpers/CreateServiceException.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
7 |
8 | namespace GattServicesLibrary.Helpers
9 | {
10 | ///
11 | /// Class for Create Service Exception
12 | ///
13 | public class CreateServiceException : Exception
14 | {
15 | ///
16 | /// Gets the value indicating the create service exception details
17 | ///
18 | public GattServiceProviderResult CreateServiceExceptionResult { get; }
19 |
20 | ///
21 | /// Initializes a new instance of the class
22 | ///
23 | /// Gatt Service provider result
24 | public CreateServiceException(GattServiceProviderResult createServiceExceptionResult) :
25 | base(string.Format($"Error occured while creating the provider, Error Code:{createServiceExceptionResult.Error}"))
26 | {
27 | CreateServiceExceptionResult = createServiceExceptionResult;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Helpers/GattServicesHelper.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Diagnostics;
7 | using Windows.Devices.Bluetooth;
8 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
9 | using Windows.Storage.Streams;
10 |
11 | namespace GattServicesLibrary.Helpers
12 | {
13 | ///
14 | /// Gatt Service Helper Class containing Utility functions used across the services.
15 | ///
16 | public static class GattServicesHelper
17 | {
18 | ///
19 | /// Get Characteristics from the Characteristics Result
20 | ///
21 | /// Gatt Characteristics Result
22 | /// Gatt characteristics
23 | public static void GetCharacteristicsFromResult(GattLocalCharacteristicResult result, ref GattLocalCharacteristic characteristics)
24 | {
25 | if (result.Error == BluetoothError.Success)
26 | {
27 | characteristics = result.Characteristic;
28 | }
29 | else
30 | {
31 | Debug.WriteLine(result.Error.ToString());
32 | }
33 | }
34 |
35 | ///
36 | /// Converts byte value into Buffer
37 | ///
38 | /// Byte value
39 | /// Data writer buffer
40 | public static IBuffer ConvertValueToBuffer(byte byteValue)
41 | {
42 | //TODO: User GattConvert here
43 | DataWriter writer = new DataWriter();
44 | writer.WriteByte(byteValue);
45 | return writer.DetachBuffer();
46 | }
47 |
48 | ///
49 | /// Converts two byte values into buffer
50 | ///
51 | /// Byte value 1
52 | /// Byte value 2
53 | /// Data writer buffer
54 | public static IBuffer ConvertValueToBuffer(byte byteValue1, byte byteValue2)
55 | {
56 | DataWriter writer = new DataWriter();
57 | writer.WriteByte(byteValue1);
58 | writer.WriteByte(byteValue2);
59 |
60 | return writer.DetachBuffer();
61 | }
62 |
63 | ///
64 | /// Converts date time value to buffer
65 | ///
66 | /// DateTime value
67 | /// Data Writer Buffer
68 | public static IBuffer ConvertValueToBuffer(DateTime time)
69 | {
70 | DataWriter writer = new DataWriter();
71 |
72 | // Date time according to: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.date_time.xml
73 | writer.WriteUInt16((ushort)time.Year);
74 | writer.WriteByte((byte)time.Month);
75 | writer.WriteByte((byte)time.Day);
76 | writer.WriteByte((byte)time.Hour);
77 | writer.WriteByte((byte)time.Minute);
78 | writer.WriteByte((byte)time.Second);
79 |
80 | // Day of week according to: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.day_of_week.xml
81 | // Going to leave this "not known" for now - would have to perform a rotate of DayOfWeek property
82 | writer.WriteByte(0x0);
83 |
84 | return writer.DetachBuffer();
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Helpers/HelperExtensions.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using Windows.UI.Core;
11 |
12 | namespace GattServicesLibrary.Helpers
13 | {
14 | ///
15 | /// Extension class for byte
16 | ///
17 | public static class HelperExtensions
18 | {
19 | ///
20 | /// Converts byte array to string
21 | ///
22 | /// Byte array to covert
23 | /// string equivalent of the byte array
24 | public static string BytesToString(this byte[] array)
25 | {
26 | var result = new StringBuilder();
27 |
28 | for (int i = 0; i < array.Length; i++)
29 | {
30 | result.Append($"{array[i]:X2}");
31 | if (i < array.Length - 1)
32 | {
33 | result.Append(" ");
34 | }
35 | }
36 |
37 | return result.ToString();
38 | }
39 | }
40 |
41 | public static class DispatcherTaskExtensions
42 | {
43 | public static async Task RunTaskAsync(
44 | this CoreDispatcher dispatcher,
45 | Func> func,
46 | CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
47 | {
48 | var taskCompletionSource = new TaskCompletionSource();
49 | await dispatcher.RunAsync(priority, async () =>
50 | {
51 | try
52 | {
53 | taskCompletionSource.SetResult(await func());
54 | }
55 | catch (Exception ex)
56 | {
57 | taskCompletionSource.SetException(ex);
58 | }
59 | });
60 | return await taskCompletionSource.Task;
61 | }
62 |
63 | // There is no TaskCompletionSource so we use a bool that we throw away.
64 | public static async Task RunTaskAsync(this CoreDispatcher dispatcher,
65 | Func func, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) =>
66 | await RunTaskAsync(dispatcher, async () => { await func(); return false; }, priority);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System.Reflection;
6 | using System.Runtime.InteropServices;
7 |
8 | // General Information about an assembly is controlled through the following
9 | // set of attributes. Change these attribute values to modify the information
10 | // associated with an assembly.
11 | [assembly: AssemblyTitle("GattServicesLibrary")]
12 | [assembly: AssemblyDescription("")]
13 | [assembly: AssemblyConfiguration("")]
14 | [assembly: AssemblyCompany("")]
15 | [assembly: AssemblyProduct("GattServicesLibrary")]
16 | [assembly: AssemblyCopyright("Copyright © 2016")]
17 | [assembly: AssemblyTrademark("")]
18 | [assembly: AssemblyCulture("")]
19 |
20 | // Version information for an assembly consists of the following four values:
21 | //
22 | // Major Version
23 | // Minor Version
24 | // Build Number
25 | // Revision
26 | //
27 | // You can specify all the values or you can default the Build and Revision Numbers
28 | // by using the '*' as shown below:
29 | // [assembly: AssemblyVersion("1.0.*")]
30 | [assembly: AssemblyVersion("1.0.0.0")]
31 | [assembly: AssemblyFileVersion("1.0.0.0")]
32 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Properties/GattServicesLibrary.rd.xml:
--------------------------------------------------------------------------------
1 |
2 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Services/BatteryService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.ComponentModel;
7 | using System.Threading.Tasks;
8 | using GattServicesLibrary.Helpers;
9 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
10 | using Windows.Devices.Power;
11 |
12 | namespace GattServicesLibrary.Services
13 | {
14 | ///
15 | /// Class for Battery Services
16 | ///
17 | public class BatteryService : GenericGattService
18 | {
19 | ///
20 | /// Name of the service
21 | ///
22 | public override string Name
23 | {
24 | get
25 | {
26 | return "Battery Service";
27 | }
28 | }
29 |
30 | ///
31 | /// Battery level
32 | ///
33 | private GenericGattCharacteristic batteryLevel;
34 |
35 | ///
36 | /// Gets or sets the battery level
37 | ///
38 | public GenericGattCharacteristic BatteryLevel
39 | {
40 | get
41 | {
42 | return batteryLevel;
43 | }
44 |
45 | set
46 | {
47 | if (batteryLevel != value)
48 | {
49 | batteryLevel = value;
50 | OnPropertyChanged(new PropertyChangedEventArgs("BatteryLevel"));
51 | }
52 | }
53 | }
54 |
55 | ///
56 | /// Asynchronous initialization
57 | ///
58 | /// Initialization Task
59 | public override async Task Init()
60 | {
61 | await CreateServiceProvider(GattServiceUuids.Battery);
62 |
63 | // Preparing the Battery Level characteristics
64 | GattLocalCharacteristicParameters batteryCharacteristicsParameters = PlainReadNotifyParameters;
65 |
66 | // Set the user descriptions
67 | batteryCharacteristicsParameters.UserDescription = "Battery Level percentage remaining";
68 |
69 | // Add presentation format - 16-bit integer, with exponent 0, the unit is percentage, defined per Bluetooth SIG with Microsoft as descriptor
70 | batteryCharacteristicsParameters.PresentationFormats.Add(
71 | GattPresentationFormat.FromParts(
72 | Convert.ToByte(PresentationFormats.FormatTypes.Unsigned8BitInteger),
73 | PresentationFormats.Exponent,
74 | Convert.ToUInt16(PresentationFormats.Units.Percentage),
75 | Convert.ToByte(PresentationFormats.NamespaceId.BluetoothSigAssignedNumber),
76 | PresentationFormats.Description));
77 |
78 | // Create the characteristic for the service
79 | GattLocalCharacteristicResult result =
80 | await ServiceProvider.Service.CreateCharacteristicAsync(
81 | GattCharacteristicUuids.BatteryLevel,
82 | batteryCharacteristicsParameters);
83 |
84 | // Grab the characterist object from the service set it to the BatteryLevel property which is of a specfic Characteristic type
85 | GattLocalCharacteristic baseBatteryLevel = null;
86 | GattServicesHelper.GetCharacteristicsFromResult(result, ref baseBatteryLevel);
87 |
88 | if (baseBatteryLevel != null)
89 | {
90 | BatteryLevel = new Characteristics.BatteryLevelCharacteristic(baseBatteryLevel, this);
91 | }
92 | }
93 | }
94 | }
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Services/CurrentTimeService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Threading.Tasks;
7 | using GattServicesLibrary.Helpers;
8 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
9 | using System.ComponentModel;
10 |
11 | namespace GattServicesLibrary.Services
12 | {
13 | ///
14 | /// Class for Current time service
15 | ///
16 | public class CurrentTimeService : GenericGattService
17 | {
18 | ///
19 | /// Name of the service
20 | ///
21 | public override string Name
22 | {
23 | get
24 | {
25 | return "Current Time Service";
26 | }
27 | }
28 |
29 | ///
30 | /// Current time characteristic
31 | ///
32 | private GenericGattCharacteristic currentTime;
33 |
34 | ///
35 | /// Gets or sets the currentTime
36 | ///
37 | public GenericGattCharacteristic CurrentTime
38 | {
39 | get
40 | {
41 | return currentTime;
42 | }
43 |
44 | set
45 | {
46 | if (currentTime != value)
47 | {
48 | currentTime = value;
49 | OnPropertyChanged(new PropertyChangedEventArgs("CurrentTime"));
50 | }
51 | }
52 | }
53 |
54 | ///
55 | /// Asynchronous initialization
56 | ///
57 | /// Initialization Task
58 | public override async Task Init()
59 | {
60 | await CreateServiceProvider(GattServiceUuids.CurrentTime);
61 |
62 | GattLocalCharacteristicResult result = await ServiceProvider.Service.CreateCharacteristicAsync(
63 | GattCharacteristicUuids.CurrentTime,
64 | PlainReadNotifyParameters);
65 |
66 | GattLocalCharacteristic currentTimeCharacterisitic = null;
67 | GattServicesHelper.GetCharacteristicsFromResult(result, ref currentTimeCharacterisitic);
68 | if (currentTimeCharacterisitic != null)
69 | {
70 | CurrentTime = new Characteristics.CurrentTimeCharacteristic(currentTimeCharacterisitic, this);
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/Services/HeartRateService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | //
4 | //----------------------------------------------------------------------------------------------
5 | using System;
6 | using System.Threading.Tasks;
7 | using GattServicesLibrary.Helpers;
8 | using Windows.Devices.Bluetooth.GenericAttributeProfile;
9 | using System.ComponentModel;
10 |
11 | namespace GattServicesLibrary.Services
12 | {
13 | ///
14 | /// Class for Heart rate service
15 | ///
16 | public class HeartRateService : GenericGattService
17 | {
18 | ///
19 | /// Name of the service
20 | ///
21 | public override string Name
22 | {
23 | get
24 | {
25 | return "Heart Rate Service";
26 | }
27 | }
28 |
29 | ///
30 | /// This characteristic is used to send a heart rate measurement.
31 | ///
32 | private GenericGattCharacteristic heartRateMeasurement;
33 |
34 | ///
35 | /// Gets or Sets the heart rate characteristic
36 | ///
37 | public GenericGattCharacteristic HeartRateMeasurement
38 | {
39 | get
40 | {
41 | return heartRateMeasurement;
42 | }
43 |
44 | set
45 | {
46 | if (heartRateMeasurement != value)
47 | {
48 | heartRateMeasurement = value;
49 | OnPropertyChanged(new PropertyChangedEventArgs("HeartRateMeasurement"));
50 | }
51 | }
52 | }
53 |
54 | ///
55 | /// Starts the Heart rate service
56 | ///
57 | public override async Task Init()
58 | {
59 | await CreateServiceProvider(GattServiceUuids.HeartRate);
60 |
61 | // Preparing the Blood pressure characteristics
62 | var heartRateCharacteristics = PlainNotifyParameters;
63 | heartRateCharacteristics.UserDescription = "Heart Rates in Beats per Minute";
64 | heartRateCharacteristics.PresentationFormats.Add(
65 | GattPresentationFormat.FromParts(
66 | Convert.ToByte(PresentationFormats.FormatTypes.Unsigned16BitInteger),
67 | PresentationFormats.Exponent,
68 | Convert.ToUInt16(PresentationFormats.Units.PeriodBeatsPerMinute),
69 | Convert.ToByte(PresentationFormats.NamespaceId.BluetoothSigAssignedNumber),
70 | PresentationFormats.Description));
71 |
72 | // Create the heart rate characteristic for the service
73 | GattLocalCharacteristicResult result =
74 | await ServiceProvider.Service.CreateCharacteristicAsync(
75 | GattCharacteristicUuids.HeartRateMeasurement,
76 | PlainNotifyParameters);
77 |
78 | // Grab the characterist object from the service set it to the HeartRate property which is of a specfic Characteristic type
79 | GattLocalCharacteristic baseHeartRateMeasurement = null;
80 | GattServicesHelper.GetCharacteristicsFromResult(result, ref baseHeartRateMeasurement);
81 |
82 | if (baseHeartRateMeasurement != null)
83 | {
84 | HeartRateMeasurement = new Characteristics.HeartRateMeasurementCharacteristic(baseHeartRateMeasurement, this);
85 | }
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/GattServicesLibrary/GattServicesLibrary/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.3.3"
4 | },
5 | "frameworks": {
6 | "uap10.0": {}
7 | },
8 | "runtimes": {
9 | "win10-arm": {},
10 | "win10-arm-aot": {},
11 | "win10-x86": {},
12 | "win10-x86-aot": {},
13 | "win10-x64": {},
14 | "win10-x64-aot": {}
15 | }
16 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Bluetooth LE Explorer
4 | Copyright (c) Microsoft Corporation. All rights reserved.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.microsoft.com.
6 |
7 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14 |
15 | Note: **[Bluetooth Explorer](https://www.ellisys.com/products/bex400)** by Ellisys is a separate unaffiliated product.
16 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollection.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26430.13
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SortedObservableCollection", "SortedObservableCollection\SortedObservableCollection.csproj", "{BE79FC52-6041-4913-B0D4-66C100944904}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SortedObservableCollectionUnitTests", "SortedObservableCollectionUnitTests\SortedObservableCollectionUnitTests.csproj", "{BEB995DE-D866-41CD-B0A8-64CC637C4A9F}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|ARM = Debug|ARM
14 | Debug|x64 = Debug|x64
15 | Debug|x86 = Debug|x86
16 | Release|Any CPU = Release|Any CPU
17 | Release|ARM = Release|ARM
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|ARM.ActiveCfg = Debug|ARM
25 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|ARM.Build.0 = Debug|ARM
26 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|x64.ActiveCfg = Debug|x64
27 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|x64.Build.0 = Debug|x64
28 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|x86.ActiveCfg = Debug|x86
29 | {BE79FC52-6041-4913-B0D4-66C100944904}.Debug|x86.Build.0 = Debug|x86
30 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|ARM.ActiveCfg = Release|ARM
33 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|ARM.Build.0 = Release|ARM
34 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|x64.ActiveCfg = Release|x64
35 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|x64.Build.0 = Release|x64
36 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|x86.ActiveCfg = Release|x86
37 | {BE79FC52-6041-4913-B0D4-66C100944904}.Release|x86.Build.0 = Release|x86
38 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|Any CPU.ActiveCfg = Debug|x86
39 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|ARM.ActiveCfg = Debug|ARM
40 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|ARM.Build.0 = Debug|ARM
41 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|ARM.Deploy.0 = Debug|ARM
42 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|x64.ActiveCfg = Debug|x64
43 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|x64.Build.0 = Debug|x64
44 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|x64.Deploy.0 = Debug|x64
45 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|x86.ActiveCfg = Debug|x86
46 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|x86.Build.0 = Debug|x86
47 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Debug|x86.Deploy.0 = Debug|x86
48 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|Any CPU.ActiveCfg = Release|x86
49 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|ARM.ActiveCfg = Release|ARM
50 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|ARM.Build.0 = Release|ARM
51 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|ARM.Deploy.0 = Release|ARM
52 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|x64.ActiveCfg = Release|x64
53 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|x64.Build.0 = Release|x64
54 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|x64.Deploy.0 = Release|x64
55 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|x86.ActiveCfg = Release|x86
56 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|x86.Build.0 = Release|x86
57 | {BEB995DE-D866-41CD-B0A8-64CC637C4A9F}.Release|x86.Deploy.0 = Release|x86
58 | EndGlobalSection
59 | GlobalSection(SolutionProperties) = preSolution
60 | HideSolutionNode = FALSE
61 | EndGlobalSection
62 | EndGlobal
63 |
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollection/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SortedObservableCollection")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("SortedObservableCollection")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollection/Properties/SortedObservableCollection.rd.xml:
--------------------------------------------------------------------------------
1 |
2 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollection/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.3.3"
4 | },
5 | "frameworks": {
6 | "uap10.0": {}
7 | },
8 | "runtimes": {
9 | "win10-arm": {},
10 | "win10-arm-aot": {},
11 | "win10-x86": {},
12 | "win10-x86-aot": {},
13 | "win10-x64": {},
14 | "win10-x64-aot": {}
15 | }
16 | }
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/BluetoothLEExplorer/494ccc99d7e615498af71ecb71ba8945083adb35/SortedObservableCollection/SortedObservableCollectionUnitTests/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
13 |
14 |
15 | SortedObservableCollectionUnitTests
16 | stfro
17 | Assets\StoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle("SortedObservableCollectionUnitTests")]
6 | [assembly: AssemblyDescription("")]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany("")]
9 | [assembly: AssemblyProduct("SortedObservableCollectionUnitTests")]
10 | [assembly: AssemblyCopyright("Copyright © 2017")]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 | [assembly: AssemblyMetadata("TargetPlatform","UAP")]
14 |
15 | // [assembly: AssemblyVersion("1.0.*")]
16 | [assembly: AssemblyVersion("1.0.0.0")]
17 | [assembly: AssemblyFileVersion("1.0.0.0")]
18 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/Properties/UnitTestApp.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/UnitTestApp.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/UnitTestApp.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 |
18 | namespace SortedObservableCollectionUnitTests
19 | {
20 | ///
21 | /// Provides application-specific behavior to supplement the default Application class.
22 | ///
23 | sealed partial class App : Application
24 | {
25 | ///
26 | /// Initializes the singleton application object. This is the first line of authored code
27 | /// executed, and as such is the logical equivalent of main() or WinMain().
28 | ///
29 | public App()
30 | {
31 | this.InitializeComponent();
32 | this.Suspending += OnSuspending;
33 | }
34 |
35 | ///
36 | /// Invoked when the application is launched normally by the end user. Other entry points
37 | /// will be used such as when the application is launched to open a specific file.
38 | ///
39 | /// Details about the launch request and process.
40 | protected override void OnLaunched(LaunchActivatedEventArgs e)
41 | {
42 |
43 | #if DEBUG
44 | if (System.Diagnostics.Debugger.IsAttached)
45 | {
46 | this.DebugSettings.EnableFrameRateCounter = true;
47 | }
48 | #endif
49 |
50 | Frame rootFrame = Window.Current.Content as Frame;
51 |
52 | // Do not repeat app initialization when the Window already has content,
53 | // just ensure that the window is active
54 | if (rootFrame == null)
55 | {
56 | // Create a Frame to act as the navigation context and navigate to the first page
57 | rootFrame = new Frame();
58 |
59 | rootFrame.NavigationFailed += OnNavigationFailed;
60 |
61 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
62 | {
63 | }
64 |
65 | // Place the frame in the current Window
66 | Window.Current.Content = rootFrame;
67 | }
68 |
69 | Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
70 |
71 | // Ensure the current window is active
72 | Window.Current.Activate();
73 |
74 | Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments);
75 | }
76 |
77 | ///
78 | /// Invoked when Navigation to a certain page fails
79 | ///
80 | /// The Frame which failed navigation
81 | /// Details about the navigation failure
82 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
83 | {
84 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
85 | }
86 |
87 | ///
88 | /// Invoked when application execution is being suspended. Application state is saved
89 | /// without knowing whether the application will be terminated or resumed with the contents
90 | /// of memory still intact.
91 | ///
92 | /// The source of the suspend request.
93 | /// Details about the suspend request.
94 | private void OnSuspending(object sender, SuspendingEventArgs e)
95 | {
96 | var deferral = e.SuspendingOperation.GetDeferral();
97 | deferral.Complete();
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/SortedObservableCollection/SortedObservableCollectionUnitTests/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.2.3",
4 | "MSTest.TestAdapter": "1.1.11",
5 | "MSTest.TestFramework": "1.1.11"
6 | },
7 | "frameworks": {
8 | "uap10.0": {}
9 | },
10 | "runtimes": {
11 | "win10-arm": {},
12 | "win10-arm-aot": {},
13 | "win10-x86": {},
14 | "win10-x86-aot": {},
15 | "win10-x64": {},
16 | "win10-x64-aot": {}
17 | }
18 | }
--------------------------------------------------------------------------------