├── LICENSE ├── README.md ├── cs ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── LargeTile.scale-100.png │ ├── LargeTile.scale-200.png │ ├── LargeTile.scale-400.png │ ├── SmallTile-sdk.altform-lightunplated_targetsize-16.png │ ├── SmallTile-sdk.altform-lightunplated_targetsize-256.png │ ├── SmallTile-sdk.altform-lightunplated_targetsize-48.png │ ├── SmallTile-sdk.altform-unplated_targetsize-16.png │ ├── SmallTile-sdk.altform-unplated_targetsize-256.png │ ├── SmallTile-sdk.altform-unplated_targetsize-48.png │ ├── SmallTile-sdk.scale-100.png │ ├── SmallTile-sdk.scale-200.png │ ├── SmallTile-sdk.scale-400.png │ ├── SmallTile-sdk.targetsize-16.png │ ├── SmallTile-sdk.targetsize-256.png │ ├── SmallTile-sdk.targetsize-48.png │ ├── SmallTile.scale-100.png │ ├── SmallTile.scale-200.png │ ├── SmallTile.scale-400.png │ ├── Splash-sdk.scale-100.png │ ├── Splash-sdk.scale-200.png │ ├── Splash-sdk.scale-400.png │ ├── StoreLogo-sdk.scale-100.png │ ├── StoreLogo-sdk.scale-200.png │ ├── StoreLogo-sdk.scale-400.png │ ├── WideTile.scale-100.png │ ├── WideTile.scale-200.png │ ├── WideTile.scale-400.png │ ├── applause.mp3 │ ├── ble_hackme.png │ ├── nrf_connect_advertisement_data_format_display.png │ ├── nrf_connect_advertisement_details.png │ ├── nrf_connect_advertisement_flags.png │ ├── nrf_connect_battery_level.png │ ├── nrf_connect_filter_rssi.png │ ├── nrf_connect_generic_access_characteristics.png │ ├── nrf_connect_heart_rate_notification.png │ ├── nrf_connect_ibeacon_advertisement.png │ ├── nrf_connect_ibeacon_advertisement_as_ble41.png │ ├── nrf_connect_ibeacon_raw_explained.png │ ├── nrf_connect_import_macro.png │ ├── nrf_connect_macro_add_delay.png │ ├── nrf_connect_macro_available.png │ ├── nrf_connect_macro_delay_set_ms.png │ ├── nrf_connect_macro_export_to_xml.png │ ├── nrf_connect_macro_functionality.png │ ├── nrf_connect_macro_functionality_small.png │ ├── nrf_connect_macro_menu.png │ ├── nrf_connect_macro_pass_brute.png │ ├── nrf_connect_macro_repeat.png │ ├── nrf_connect_macro_save.png │ ├── nrf_connect_macro_send_pass_single.png │ ├── nrf_connect_macro_start_recording.png │ ├── nrf_connect_microsoft_advertisement.png │ ├── nrf_connect_notify_arrow.png │ ├── nrf_connect_quicklock_history_service.png │ ├── nrf_connect_raw_advertisement_desc.png │ ├── nrf_connect_read_arrow.png │ ├── nrf_connect_scan_desc.png │ ├── nrf_connect_text_descriptor.png │ ├── nrf_connect_write_01.png │ ├── nrf_connect_write_arrow.png │ ├── nrf_connect_write_hello_command.png │ ├── nrf_connect_write_text_option.png │ ├── nrf_connect_write_value_form.png │ ├── quicklock_date_format_decompiled.png │ ├── quicklock_sniff.jpg │ ├── rick.wmv │ ├── smartlockpicking.png │ ├── squareTile-sdk.scale-100.png │ ├── squareTile-sdk.scale-200.png │ ├── squareTile-sdk.scale-400.png │ ├── trophy.jpg │ ├── wireshark_apply_as_column.png │ ├── wireshark_apply_filter_write_request.png │ ├── wireshark_btatt_filter.png │ ├── wireshark_btatt_filter_small.png │ ├── wireshark_btatt_filter_smaller.png │ ├── wireshark_filter_write_request.png │ ├── wireshark_intro.png │ ├── wireshark_new_column_value.png │ └── wireshark_quicklock_authentication.png ├── BLE.cs ├── BLEServices │ ├── BatteryLevelCharacteristic.cs │ ├── BatteryService.cs │ ├── CurrentTimeCharacteristic.cs │ ├── CurrentTimeService.cs │ ├── GenericGattCharacteristic.cs │ ├── GenericGattService.cs │ ├── HeartRateMeasurementCharacteristic.cs │ ├── HeartRateService.cs │ ├── Helpers.cs │ ├── LightBulbColorCharacteristic.cs │ ├── LightBulbService.cs │ ├── LightBulbSwitchCharacteristic.cs │ ├── LightBulbTTSCharacteristic.cs │ ├── QuickLockAuthCharacteristic.cs │ ├── QuickLockAuthStatusCharacteristic.cs │ ├── QuickLockCommandCharacteristic.cs │ ├── QuickLockHistoryControlCharacteristic.cs │ ├── QuickLockHistoryDataCharacteristic.cs │ ├── QuickLockHistoryService.cs │ ├── QuickLockMainService.cs │ ├── QuickLockOpenTimeCharacteristic.cs │ ├── QuickLockUnlockStatusCharacteristic.cs │ ├── QuickLockUsernameCharacteristic.cs │ └── iBeacon.cs ├── BLE_Hackme.csproj ├── BLE_Hackme.sln ├── Constants.cs ├── MainPage.xaml ├── MainPage.xaml.cs ├── Package.appxmanifest ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── Scenarios │ ├── Scenario_01_Compatibility.xaml │ ├── Scenario_01_Compatibility.xaml.cs │ ├── Scenario_02_Intro.xaml │ ├── Scenario_02_Intro.xaml.cs │ ├── Scenario_03_Advertisements.xaml │ ├── Scenario_03_Advertisements.xaml.cs │ ├── Scenario_04_Beacons.xaml │ ├── Scenario_04_Beacons.xaml.cs │ ├── Scenario_05_ManufacturerAdvertisements.xaml │ ├── Scenario_05_ManufacturerAdvertisements.xaml.cs │ ├── Scenario_06_Connections.xaml │ ├── Scenario_06_Connections.xaml.cs │ ├── Scenario_07_Read.xaml │ ├── Scenario_07_Read.xaml.cs │ ├── Scenario_08_Notifications.xaml │ ├── Scenario_08_Notifications.xaml.cs │ ├── Scenario_09_Descriptors.xaml │ ├── Scenario_09_Descriptors.xaml.cs │ ├── Scenario_10_Write.xaml │ ├── Scenario_10_Write.xaml.cs │ ├── Scenario_11_WriteCommand.xaml │ ├── Scenario_11_WriteCommand.xaml.cs │ ├── Scenario_12_Macros.xaml │ ├── Scenario_12_Macros.xaml.cs │ ├── Scenario_13_RGB.xaml │ ├── Scenario_13_RGB.xaml.cs │ ├── Scenario_14_PasswordBrute.xaml │ ├── Scenario_14_PasswordBrute.xaml.cs │ ├── Scenario_15_QuickLockReplay.xaml │ ├── Scenario_15_QuickLockReplay.xaml.cs │ ├── Scenario_16_QuickLockLogs.xaml │ ├── Scenario_16_QuickLockLogs.xaml.cs │ ├── Scenario_Summary.xaml │ └── Scenario_Summary.xaml.cs ├── ScenariosConfiguration.cs ├── Styles │ └── Styles.xaml └── UserControls │ ├── LightBulbUserControl.xaml │ ├── LightBulbUserControl.xaml.cs │ ├── ScenarioSubHeaderHints.xaml │ ├── ScenarioSubHeaderHints.xaml.cs │ ├── ScenarioSubHeaderIntro.xaml │ ├── ScenarioSubHeaderIntro.xaml.cs │ ├── ScenarioSubHeaderSimulatedDevice.xaml │ ├── ScenarioSubHeaderSimulatedDevice.xaml.cs │ ├── ScenarioSubHeaderSubmit.xaml │ ├── ScenarioSubHeaderSubmit.xaml.cs │ ├── ScenarioSubHeaderTask.xaml │ ├── ScenarioSubHeaderTask.xaml.cs │ ├── SmartLockUserControl.xaml │ └── SmartLockUserControl.xaml.cs └── logo.png /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Slawomir Jasek slawomir.jasek@smartlockpicking.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![BLE_HackMe](https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/main/logo.png) 3 | 4 | 5 | # Bluetooth Low Energy hardware-less HackMe 6 | 7 | The project aims to introduce the BLE protocol and its security basics. 8 | A standard Windows 10 computer with Bluetooth interface will simulate various BLE devices - on the radio layer working exactly as real ones. 9 | In a series of tasks with increasing level of complexity, allows to get familiar with BLE advertisements, beacons, connections, take control over talking BLE smart bulb, reverse-engineer the communication, brute force passwords, and even hack real smart lock. 10 | 11 | 12 | ## System requirements 13 | 14 | * Windows 10 Anniversary Edition 15 | * Bluetooth adapter - should work with most adapters built in standard laptops, not necessarily with external dongle 16 | 17 | The tasks are designed to be solved using free Android mobile application, connecting to the simulated devices via BLE (iOS has limited low level BLE features). 18 | 19 | It is also possible to use other BLE tools, for example running on Linux or Mac, however details are not covered in the HackMe instructions. 20 | 21 | 22 | ## Installation 23 | 24 | Binary version is available in Microsoft Store: 25 | 26 | [https://www.microsoft.com/store/apps/9N7PNVS9J1B7](https://www.microsoft.com/store/apps/9N7PNVS9J1B7) 27 | 28 | ## Building from source 29 | 30 | ### Build in Visual Studio 31 | 32 | For building from source, Microsoft Visual Studio is required (free, Community edition will work). 33 | 34 | 1. Start Microsoft Visual Studio and select **File** \> **Open** \> **Project/Solution**. 35 | 2. Double-click the Visual Studio Solution (.sln) file. 36 | 3. Press Ctrl+Shift+B, or select **Build** \> **Build Solution**. 37 | 38 | ### Run the debug session 39 | 40 | To debug the application and then run it, press F5 or select Debug > Start Debugging. To run without debugging, press Ctrl+F5 or selectDebug > Start Without Debugging. 41 | 42 | Some debug information available in the "Output" section in Visual Studio. 43 | 44 | 45 | ## FAQ, more information 46 | 47 | Frequently Asked Questions, list of incompatible hardware: [https://github.com/smartlockpicking/BLE_HackMe/wiki/FAQ](https://github.com/smartlockpicking/BLE_HackMe/wiki/FAQ) 48 | 49 | More information: [www.smartlockpicking.com/ble_hackme](www.smartlockpicking.com/ble_hackme) 50 | 51 | 52 | ## License 53 | 54 | This application was developed by Slawomir Jasek slawomir.jasek@smartlockpicking.com. 55 | 56 | It is free software licensed under the MIT License. 57 | 58 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 59 | 60 | 61 | The code is partially based on Microsoft [Bluetooth LE Explorer](https://github.com/microsoft/BluetoothLEExplorer) and [Bluetooth LE Sample](https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/BluetoothLE). 62 | -------------------------------------------------------------------------------- /cs/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /cs/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.ApplicationModel.Activation; 3 | using Windows.UI.Xaml; 4 | using Windows.UI.Xaml.Controls; 5 | using Windows.UI.Xaml.Navigation; 6 | 7 | namespace BLE_Hackme 8 | { 9 | sealed partial class App : Application 10 | { 11 | /// 12 | /// Initializes the singleton application object. This is the first line of authored code 13 | /// executed, and as such is the logical equivalent of main() or WinMain(). 14 | /// 15 | public App() 16 | { 17 | this.InitializeComponent(); 18 | this.Construct(); 19 | } 20 | 21 | /// 22 | /// Invoked when the application is launched normally by the end user. Other entry points 23 | /// will be used such as when the application is launched to open a specific file. 24 | /// 25 | /// Details about the launch request and process. 26 | protected override void OnLaunched(LaunchActivatedEventArgs e) 27 | { 28 | 29 | #if DEBUG 30 | if (System.Diagnostics.Debugger.IsAttached) 31 | { 32 | this.DebugSettings.EnableFrameRateCounter = false; 33 | } 34 | #endif 35 | 36 | Frame rootFrame = Window.Current.Content as Frame; 37 | 38 | // Do not repeat app initialization when the Window already has content, 39 | // just ensure that the window is active 40 | if (rootFrame == null) 41 | { 42 | // Create a Frame to act as the navigation context and navigate to the first page 43 | rootFrame = new Frame(); 44 | // Set the default language 45 | rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; 46 | 47 | rootFrame.NavigationFailed += OnNavigationFailed; 48 | 49 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 50 | { 51 | //TODO: Load state from previously suspended application 52 | } 53 | 54 | // Place the frame in the current Window 55 | Window.Current.Content = rootFrame; 56 | } 57 | 58 | if (rootFrame.Content == null) 59 | { 60 | // When the navigation stack isn't restored navigate to the first page, 61 | // configuring the new page by passing required information as a navigation 62 | // parameter 63 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 64 | } 65 | 66 | // Ensure the current window is active 67 | Window.Current.Activate(); 68 | 69 | // in case LaunchActivatedEventArgs is needed 70 | LaunchCompleted(e); 71 | } 72 | 73 | private Frame CreateRootFrame() 74 | { 75 | Frame rootFrame = Window.Current.Content as Frame; 76 | 77 | // Do not repeat app initialization when the Window already has content, 78 | // just ensure that the window is active 79 | if (rootFrame == null) 80 | { 81 | // Create a Frame to act as the navigation context and navigate to the first page 82 | rootFrame = new Frame(); 83 | 84 | // Set the default language 85 | rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; 86 | rootFrame.NavigationFailed += OnNavigationFailed; 87 | 88 | // Place the frame in the current Window 89 | Window.Current.Content = rootFrame; 90 | } 91 | 92 | return rootFrame; 93 | } 94 | 95 | /// 96 | /// Invoked when Navigation to a certain page fails 97 | /// 98 | /// The Frame which failed navigation 99 | /// Details about the navigation failure 100 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 101 | { 102 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 103 | } 104 | 105 | // Add any application contructor code in here. 106 | partial void Construct(); 107 | 108 | // Add any OnLaunched customization here. 109 | partial void LaunchCompleted(LaunchActivatedEventArgs e); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /cs/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /cs/Assets/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/LargeTile.scale-200.png -------------------------------------------------------------------------------- /cs/Assets/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/LargeTile.scale-400.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.altform-lightunplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.altform-lightunplated_targetsize-16.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.altform-lightunplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.altform-lightunplated_targetsize-256.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.altform-lightunplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.altform-lightunplated_targetsize-48.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.scale-100.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.scale-200.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.scale-400.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.targetsize-16.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.targetsize-256.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile-sdk.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile-sdk.targetsize-48.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile.scale-200.png -------------------------------------------------------------------------------- /cs/Assets/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/SmallTile.scale-400.png -------------------------------------------------------------------------------- /cs/Assets/Splash-sdk.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/Splash-sdk.scale-100.png -------------------------------------------------------------------------------- /cs/Assets/Splash-sdk.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/Splash-sdk.scale-200.png -------------------------------------------------------------------------------- /cs/Assets/Splash-sdk.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/Splash-sdk.scale-400.png -------------------------------------------------------------------------------- /cs/Assets/StoreLogo-sdk.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/StoreLogo-sdk.scale-100.png -------------------------------------------------------------------------------- /cs/Assets/StoreLogo-sdk.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/StoreLogo-sdk.scale-200.png -------------------------------------------------------------------------------- /cs/Assets/StoreLogo-sdk.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/StoreLogo-sdk.scale-400.png -------------------------------------------------------------------------------- /cs/Assets/WideTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/WideTile.scale-100.png -------------------------------------------------------------------------------- /cs/Assets/WideTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/WideTile.scale-200.png -------------------------------------------------------------------------------- /cs/Assets/WideTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/WideTile.scale-400.png -------------------------------------------------------------------------------- /cs/Assets/applause.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/applause.mp3 -------------------------------------------------------------------------------- /cs/Assets/ble_hackme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/ble_hackme.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_advertisement_data_format_display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_advertisement_data_format_display.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_advertisement_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_advertisement_details.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_advertisement_flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_advertisement_flags.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_battery_level.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_battery_level.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_filter_rssi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_filter_rssi.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_generic_access_characteristics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_generic_access_characteristics.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_heart_rate_notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_heart_rate_notification.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_ibeacon_advertisement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_ibeacon_advertisement.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_ibeacon_advertisement_as_ble41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_ibeacon_advertisement_as_ble41.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_ibeacon_raw_explained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_ibeacon_raw_explained.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_import_macro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_import_macro.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_add_delay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_add_delay.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_available.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_available.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_delay_set_ms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_delay_set_ms.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_export_to_xml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_export_to_xml.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_functionality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_functionality.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_functionality_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_functionality_small.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_menu.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_pass_brute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_pass_brute.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_repeat.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_save.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_send_pass_single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_send_pass_single.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_macro_start_recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_macro_start_recording.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_microsoft_advertisement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_microsoft_advertisement.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_notify_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_notify_arrow.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_quicklock_history_service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_quicklock_history_service.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_raw_advertisement_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_raw_advertisement_desc.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_read_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_read_arrow.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_scan_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_scan_desc.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_text_descriptor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_text_descriptor.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_write_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_write_01.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_write_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_write_arrow.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_write_hello_command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_write_hello_command.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_write_text_option.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_write_text_option.png -------------------------------------------------------------------------------- /cs/Assets/nrf_connect_write_value_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/nrf_connect_write_value_form.png -------------------------------------------------------------------------------- /cs/Assets/quicklock_date_format_decompiled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/quicklock_date_format_decompiled.png -------------------------------------------------------------------------------- /cs/Assets/quicklock_sniff.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/quicklock_sniff.jpg -------------------------------------------------------------------------------- /cs/Assets/rick.wmv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/rick.wmv -------------------------------------------------------------------------------- /cs/Assets/smartlockpicking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/smartlockpicking.png -------------------------------------------------------------------------------- /cs/Assets/squareTile-sdk.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/squareTile-sdk.scale-100.png -------------------------------------------------------------------------------- /cs/Assets/squareTile-sdk.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/squareTile-sdk.scale-200.png -------------------------------------------------------------------------------- /cs/Assets/squareTile-sdk.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/squareTile-sdk.scale-400.png -------------------------------------------------------------------------------- /cs/Assets/trophy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/trophy.jpg -------------------------------------------------------------------------------- /cs/Assets/wireshark_apply_as_column.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_apply_as_column.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_apply_filter_write_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_apply_filter_write_request.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_btatt_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_btatt_filter.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_btatt_filter_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_btatt_filter_small.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_btatt_filter_smaller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_btatt_filter_smaller.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_filter_write_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_filter_write_request.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_intro.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_new_column_value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_new_column_value.png -------------------------------------------------------------------------------- /cs/Assets/wireshark_quicklock_authentication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smartlockpicking/BLE_HackMe/8e47cbcd2addd5b135202585150f9e44f5540a67/cs/Assets/wireshark_quicklock_authentication.png -------------------------------------------------------------------------------- /cs/BLEServices/BatteryLevelCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | 8 | 9 | namespace BLE_Hackme.BLEServices 10 | { 11 | /// 12 | /// Implementation of the battery profile 13 | /// 14 | public class BatteryLevelCharacteristic : GenericGattCharacteristic 15 | { 16 | 17 | public int batteryLevelIndication; 18 | 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | /// The characteristic that this wraps 23 | public BatteryLevelCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 24 | { 25 | // generate random value 1-100% 26 | Random rnd = new Random(); 27 | batteryLevelIndication = rnd.Next(1, 100); 28 | Value = BLEServices.Helpers.ToIBuffer(batteryLevelIndication); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /cs/BLEServices/BatteryService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.ComponentModel; 8 | 9 | namespace BLE_Hackme.BLEServices 10 | { 11 | /// 12 | /// Class for Battery Services 13 | /// 14 | public class BatteryService : GenericGattService 15 | { 16 | /// 17 | /// Name of the service 18 | /// 19 | public override string Name 20 | { 21 | get 22 | { 23 | return "Battery Service"; 24 | } 25 | } 26 | 27 | /// 28 | /// Battery level 29 | /// 30 | private BatteryLevelCharacteristic batteryLevel; 31 | 32 | /// 33 | /// Gets or sets the battery level 34 | /// 35 | public BatteryLevelCharacteristic BatteryLevel 36 | { 37 | get 38 | { 39 | return batteryLevel; 40 | } 41 | 42 | set 43 | { 44 | if (batteryLevel != value) 45 | { 46 | batteryLevel = value; 47 | OnPropertyChanged(new PropertyChangedEventArgs("BatteryLevel")); 48 | } 49 | } 50 | } 51 | 52 | /// 53 | /// Asynchronous initialization 54 | /// 55 | /// Initialization Task 56 | public override async Task Init() 57 | { 58 | await CreateServiceProvider(GattServiceUuids.Battery); 59 | 60 | // Preparing the Battery Level characteristics 61 | GattLocalCharacteristicParameters batteryCharacteristicsParameters = PlainReadParameters; 62 | 63 | // Set the user descriptions 64 | // batteryCharacteristicsParameters.UserDescription = "Battery Level percentage remaining"; 65 | 66 | // Create the characteristic for the service 67 | GattLocalCharacteristicResult result = 68 | await ServiceProvider.Service.CreateCharacteristicAsync( 69 | GattCharacteristicUuids.BatteryLevel, 70 | batteryCharacteristicsParameters); 71 | 72 | // Grab the characterist object from the service set it to the BatteryLevel property which is of a specfic Characteristic type 73 | GattLocalCharacteristic baseBatteryLevel = null; 74 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseBatteryLevel); 75 | 76 | if (baseBatteryLevel != null) 77 | { 78 | BatteryLevel = new BLEServices.BatteryLevelCharacteristic(baseBatteryLevel, this); 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /cs/BLEServices/CurrentTimeCharacteristic.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 9 | using Windows.Devices.Power; 10 | using Windows.Security.Authentication.Identity.Provider; 11 | using Windows.Storage.Streams; 12 | using Windows.System.Threading; 13 | 14 | namespace BLE_Hackme.BLEServices 15 | { 16 | public class CurrentTimeCharacteristic : GenericGattCharacteristic 17 | { 18 | private ThreadPoolTimer m_timeUpdate = null; 19 | 20 | public CurrentTimeCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 21 | { 22 | UpdateCurrentTimeValue(); 23 | } 24 | 25 | public override void NotifyValue() 26 | { 27 | UpdateCurrentTimeValue(); 28 | base.NotifyValue(); 29 | } 30 | 31 | protected override bool ReadRequested(GattSession session, GattReadRequest request) 32 | { 33 | UpdateCurrentTimeValue(); 34 | request.RespondWithValue(Value); 35 | return true; 36 | } 37 | 38 | 39 | protected override void Characteristic_SubscribedClientsChanged(GattLocalCharacteristic sender, object args) 40 | { 41 | lock (this) 42 | { 43 | if (sender.SubscribedClients.Count == 0) 44 | { 45 | if (m_timeUpdate != null) 46 | { 47 | m_timeUpdate.Cancel(); 48 | m_timeUpdate = null; 49 | } 50 | } 51 | else if (m_timeUpdate == null) 52 | { 53 | m_timeUpdate = ThreadPoolTimer.CreatePeriodicTimer( 54 | (source) => 55 | { 56 | UpdateCurrentTimeValue(); 57 | NotifyValue(); 58 | }, 59 | // update time via notification every minute 60 | TimeSpan.FromMinutes(1)); 61 | } 62 | } 63 | 64 | base.Characteristic_SubscribedClientsChanged(sender, args); 65 | } 66 | 67 | private void UpdateCurrentTimeValue() 68 | { 69 | // Quicklock stores data as seconds counted from 2000-01-01 00:00:00 70 | DateTime currentDateTime = DateTime.Now; 71 | DateTime quickLockEpochStart = new DateTime(2000,1,1); 72 | 73 | var currentSeconds = (int)(currentDateTime - quickLockEpochStart).TotalSeconds; 74 | 75 | Debug.WriteLine($"Current time for quicklock (seconds counted from 2000-01-01): {currentSeconds}"); 76 | 77 | Value = Helpers.ToIBuffer(currentSeconds); 78 | } 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /cs/BLEServices/CurrentTimeService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 4 | using System.ComponentModel; 5 | 6 | namespace BLE_Hackme.BLEServices 7 | { 8 | /// 9 | /// Class for Current time service 10 | /// 11 | public class CurrentTimeService : GenericGattService 12 | { 13 | /// 14 | /// Name of the service 15 | /// 16 | public override string Name 17 | { 18 | get 19 | { 20 | return "Current Time Service (Quicklock)"; 21 | } 22 | } 23 | 24 | /// 25 | /// Current time characteristic 26 | /// 27 | private GenericGattCharacteristic currentTime; 28 | 29 | /// 30 | /// Gets or sets the currentTime 31 | /// 32 | public GenericGattCharacteristic CurrentTime 33 | { 34 | get 35 | { 36 | return currentTime; 37 | } 38 | 39 | set 40 | { 41 | if (currentTime != value) 42 | { 43 | currentTime = value; 44 | OnPropertyChanged(new PropertyChangedEventArgs("CurrentTime")); 45 | } 46 | } 47 | } 48 | 49 | /// 50 | /// Asynchronous initialization 51 | /// 52 | /// Initialization Task 53 | public override async Task Init() 54 | { 55 | await CreateServiceProvider(GattServiceUuids.CurrentTime); 56 | 57 | GattLocalCharacteristicParameters currentTimeCharacteristicsParameters = PlainReadNotifyParameters; 58 | // Set the user descriptions 59 | currentTimeCharacteristicsParameters.UserDescription = "Current Time!"; 60 | 61 | 62 | GattLocalCharacteristicResult result = await ServiceProvider.Service.CreateCharacteristicAsync( 63 | GattCharacteristicUuids.CurrentTime, 64 | PlainReadNotifyParameters); 65 | 66 | GattLocalCharacteristic currentTimeCharacterisitic = null; 67 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref currentTimeCharacterisitic); 68 | if (currentTimeCharacterisitic != null) 69 | { 70 | CurrentTime = new BLEServices.CurrentTimeCharacteristic(currentTimeCharacterisitic, this); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /cs/BLEServices/HeartRateMeasurementCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 8 | using Windows.Devices.Power; 9 | using Windows.Storage.Streams; 10 | using System.Threading; 11 | 12 | 13 | namespace BLE_Hackme.BLEServices 14 | { 15 | public class HeartRateMeasurementCharacteristic : GenericGattCharacteristic 16 | { 17 | private Timer heartRateTicker = null; 18 | public Int16 currentHeartRate = 70; 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// Characteristic this wraps 24 | public HeartRateMeasurementCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 25 | { 26 | heartRateTicker = new Timer(UpdateHeartRate, "", TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); 27 | } 28 | 29 | private void UpdateHeartRate(Object state) 30 | { 31 | if (currentHeartRate == 150) 32 | { 33 | currentHeartRate = 70; 34 | } 35 | else 36 | { 37 | currentHeartRate++; 38 | } 39 | 40 | SetHeartRate(); 41 | } 42 | 43 | private void SetHeartRate() 44 | { 45 | // Heart rate service starts with flags, then the value. I combine them here then set the characterstic value 46 | byte[] flags = { 0x07 }; 47 | byte[] heartRate = BitConverter.GetBytes(currentHeartRate); 48 | 49 | byte[] value = flags.Concat(heartRate).ToArray(); 50 | 51 | Value = BLEServices.Helpers.ToIBuffer(value); 52 | NotifyValue(); 53 | } 54 | 55 | /// 56 | /// Override so we can update the value before notifying or indicating the client 57 | /// 58 | public override void NotifyValue() 59 | { 60 | base.NotifyValue(); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /cs/BLEServices/HeartRateService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 8 | 9 | namespace BLE_Hackme.BLEServices 10 | { 11 | public class HeartRateService : GenericGattService 12 | { 13 | /// 14 | /// Name of the service 15 | /// 16 | public override string Name 17 | { 18 | get 19 | { 20 | return "Heart Rate Service"; 21 | } 22 | } 23 | 24 | /// 25 | /// This characteristic is used to send a heart rate measurement. 26 | /// 27 | private HeartRateMeasurementCharacteristic heartRateMeasurement; 28 | 29 | public String randomForDescriptor { get; private set; } 30 | 31 | /// 32 | /// Gets or Sets the heart rate characteristic 33 | /// 34 | public HeartRateMeasurementCharacteristic HeartRateMeasurement 35 | { 36 | get 37 | { 38 | return heartRateMeasurement; 39 | } 40 | 41 | set 42 | { 43 | if (heartRateMeasurement != value) 44 | { 45 | heartRateMeasurement = value; 46 | OnPropertyChanged(new PropertyChangedEventArgs("HeartRateMeasurement")); 47 | } 48 | } 49 | } 50 | 51 | /// 52 | /// Starts the Heart rate service 53 | /// 54 | public override async Task Init() 55 | { 56 | await CreateServiceProvider(GattServiceUuids.HeartRate); 57 | 58 | // Preparing the heart rate characteristics 59 | var heartRateCharacteristicsParameters = PlainReadNotifyParameters; 60 | 61 | //random 4 digits added to manufacturer specific advertisement text 62 | Random rnd = new Random(); 63 | randomForDescriptor = Convert.ToString(rnd.Next(1000, 9999)); 64 | 65 | heartRateCharacteristicsParameters.UserDescription = $"{Constants.heartRateDescriptorText}{randomForDescriptor}"; 66 | 67 | // Create the heart rate characteristic for the service 68 | GattLocalCharacteristicResult result = 69 | await ServiceProvider.Service.CreateCharacteristicAsync( 70 | GattCharacteristicUuids.HeartRateMeasurement, 71 | heartRateCharacteristicsParameters); 72 | 73 | // Grab the characteristic object from the service set it to the HeartRate property which is of a specfic Characteristic type 74 | GattLocalCharacteristic baseHeartRateMeasurement = null; 75 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseHeartRateMeasurement); 76 | 77 | if (baseHeartRateMeasurement != null) 78 | { 79 | HeartRateMeasurement = new BLEServices.HeartRateMeasurementCharacteristic(baseHeartRateMeasurement, this); 80 | } 81 | } 82 | 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /cs/BLEServices/LightBulbColorCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.Diagnostics; 8 | using System.ComponentModel; 9 | using Windows.Security.Cryptography; 10 | 11 | namespace BLE_Hackme.BLEServices 12 | { 13 | public class LightBulbColorCharacteristic : GenericGattCharacteristic 14 | { 15 | public byte[] pin = { 0, 0, 0 }; 16 | public byte[] argb = { 0, 0, 0, 0 }; 17 | public byte specialEffectsScenario = 0; 18 | 19 | public LightBulbColorCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 20 | { 21 | // argb 22 | Value = BLEServices.Helpers.ToIBuffer(argb); 23 | 24 | //generate random PIN 25 | Random rnd = new Random(); 26 | pin[0] = (byte)rnd.Next(0, 10); 27 | pin[1] = (byte)rnd.Next(0, 10); 28 | pin[2] = (byte)rnd.Next(0, 10); 29 | } 30 | 31 | protected override bool WriteRequested(GattSession session, GattWriteRequest request) 32 | { 33 | byte[] receivedWrite; 34 | CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); 35 | var receivedWriteHexString = Helpers.ToHexString(request.Value); 36 | 37 | if ((request.Value.Length != 6) || (receivedWrite[5] != 0xFF)) 38 | { 39 | Debug.WriteLine($"Light Bulb color Write requested, INVALID INPUT: {receivedWriteHexString} ({request.Value.Length})"); 40 | //send notification to user 41 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); 42 | 43 | //do not update Value, return 44 | return true; 45 | } 46 | 47 | // ARGB request 48 | if (receivedWrite[0] == 0xAA) 49 | { 50 | ProcessARGB(receivedWrite); 51 | } 52 | 53 | // password protected request 54 | else if (receivedWrite[0] == 0xBE) 55 | { 56 | ProcessPassProtected(receivedWrite); 57 | } 58 | 59 | //send to scenario 60 | return true; 61 | } 62 | 63 | private bool ProcessARGB(byte[] req) 64 | { 65 | // Set the characteristic Value - strip beginning 0xAA and ending 0xFF, leave 4 bytes ARGB 66 | argb = req.Skip(1).Take(4).ToArray(); 67 | Value = Helpers.ToIBuffer(argb); 68 | return true; 69 | } 70 | 71 | private bool ProcessPassProtected(byte[] req) 72 | { 73 | //check PIN 74 | if ((req[1] != pin[0]) || (req[2] != pin[1]) || (req[3] != pin[2])) 75 | { 76 | Debug.WriteLine($"Light Bulb protected INVALID PIN: {req[1]}{req[2]}{req[3]}, expected {pin[0]}{pin[1]}{pin[2]}"); 77 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidPin")); 78 | return false; 79 | } 80 | 81 | //do not store in the Value, only in the local var 82 | specialEffectsScenario = req[4]; 83 | //notify scenario 84 | OnPropertyChanged(new PropertyChangedEventArgs("SpecialValue")); 85 | return true; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /cs/BLEServices/LightBulbService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.ComponentModel; 8 | 9 | 10 | namespace BLE_Hackme.BLEServices 11 | { 12 | /// 13 | /// Class for Light Bulb Services 14 | /// 15 | public class LightBulbService : GenericGattService 16 | { 17 | /// 18 | /// Name of the service 19 | /// 20 | public override string Name 21 | { 22 | get 23 | { 24 | return "Light Bulb Service"; 25 | } 26 | } 27 | 28 | /// 29 | /// Light bulb 30 | /// 31 | private LightBulbSwitchCharacteristic lightBulbSwitch; 32 | private LightBulbTTSCharacteristic lightBulbTTS; 33 | private LightBulbColorCharacteristic lightBulbColor; 34 | 35 | /// 36 | /// Gets or sets the light bulb state 37 | /// 38 | public LightBulbSwitchCharacteristic LightBulbSwitch 39 | { 40 | get 41 | { 42 | return lightBulbSwitch; 43 | } 44 | 45 | set 46 | { 47 | if (lightBulbSwitch != value) 48 | { 49 | lightBulbSwitch = value; 50 | OnPropertyChanged(new PropertyChangedEventArgs("LightBulbSwitch")); 51 | } 52 | } 53 | } 54 | public LightBulbTTSCharacteristic LightBulbTTS 55 | { 56 | get 57 | { 58 | return lightBulbTTS; 59 | } 60 | 61 | set 62 | { 63 | if (lightBulbTTS != value) 64 | { 65 | lightBulbTTS = value; 66 | OnPropertyChanged(new PropertyChangedEventArgs("LightBulbTTS")); 67 | } 68 | } 69 | } 70 | 71 | /// 72 | /// Gets or sets the lightbulb color 73 | /// 74 | public LightBulbColorCharacteristic LightBulbColor 75 | { 76 | get 77 | { 78 | return lightBulbColor; 79 | } 80 | 81 | set 82 | { 83 | if (lightBulbColor != value) 84 | { 85 | lightBulbColor = value; 86 | OnPropertyChanged(new PropertyChangedEventArgs("LightBulbColor")); 87 | } 88 | } 89 | } 90 | 91 | 92 | /// 93 | /// Asynchronous initialization 94 | /// 95 | /// Initialization Task 96 | public override async Task Init() 97 | { 98 | await CreateServiceProvider(Constants.LightBulbServiceUuid); 99 | 100 | //Light Bulb Switch characteristic 101 | GattLocalCharacteristicParameters lightBulbSwitchCharacteristicsParameters = PlainReadWriteParameters; 102 | // Set the user descriptions 103 | lightBulbSwitchCharacteristicsParameters.UserDescription = "Light bulb on/off"; 104 | // Create the characteristic for the service 105 | GattLocalCharacteristicResult result = 106 | await ServiceProvider.Service.CreateCharacteristicAsync( 107 | Constants.LightBulbSwitchCharacteristicUuid, 108 | lightBulbSwitchCharacteristicsParameters); 109 | 110 | // Grab the characterist object from the service set it to the property which is of a specfic Characteristic type 111 | GattLocalCharacteristic baseLightBulbSwitch = null; 112 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseLightBulbSwitch); 113 | 114 | if (baseLightBulbSwitch != null) 115 | { 116 | LightBulbSwitch = new BLEServices.LightBulbSwitchCharacteristic(baseLightBulbSwitch, this); 117 | } 118 | 119 | 120 | 121 | //Light Bulb Text To Speech characteristic 122 | GattLocalCharacteristicParameters lightBulbTTSCharacteristicsParameters = PlainWriteOrWriteWithoutResponseParameters; 123 | // Set the user descriptions 124 | lightBulbTTSCharacteristicsParameters.UserDescription = "Light bulb text to speech"; 125 | // Create the characteristic for the service 126 | result = 127 | await ServiceProvider.Service.CreateCharacteristicAsync( 128 | Constants.LightBulbTTSCharacteristicUuid, 129 | lightBulbTTSCharacteristicsParameters); 130 | 131 | // Grab the characterist object from the service set it to the property which is of a specfic Characteristic type 132 | GattLocalCharacteristic baseLightBulbTTS = null; 133 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseLightBulbTTS); 134 | 135 | if (baseLightBulbTTS != null) 136 | { 137 | LightBulbTTS = new BLEServices.LightBulbTTSCharacteristic(baseLightBulbTTS, this); 138 | } 139 | 140 | 141 | 142 | 143 | //Light Bulb Color characteristic 144 | GattLocalCharacteristicParameters lightBulbColorCharacteristicsParameters = PlainWriteOrWriteWithoutResponseParameters; 145 | // Set the user descriptions 146 | lightBulbColorCharacteristicsParameters.UserDescription = "Light bulb color/dim"; 147 | // Create the characteristic for the service 148 | result = 149 | await ServiceProvider.Service.CreateCharacteristicAsync( 150 | Constants.LightBulbColorCharacteristicUuid, 151 | lightBulbColorCharacteristicsParameters); 152 | 153 | // Grab the characterist object from the service set it to the property which is of a specfic Characteristic type 154 | GattLocalCharacteristic baseLightBulbColor = null; 155 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseLightBulbColor); 156 | 157 | if (baseLightBulbColor != null) 158 | { 159 | LightBulbColor = new BLEServices.LightBulbColorCharacteristic(baseLightBulbColor, this); 160 | } 161 | 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /cs/BLEServices/LightBulbSwitchCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.Diagnostics; 8 | using System.ComponentModel; 9 | 10 | 11 | namespace BLE_Hackme.BLEServices 12 | { 13 | /// 14 | /// Implementation of the light bulb switch 15 | /// 16 | public class LightBulbSwitchCharacteristic : GenericGattCharacteristic 17 | { 18 | 19 | private DateTime previousTime, currentTime; 20 | private TimeSpan span; 21 | private int switchCounter; 22 | 23 | 24 | public LightBulbSwitchCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 25 | { 26 | Value = BLEServices.Helpers.ToIBuffer((byte)0); 27 | switchCounter = 0; 28 | 29 | } 30 | 31 | protected override bool WriteRequested(GattSession session, GattWriteRequest request) 32 | { 33 | 34 | var receivedWrite = Helpers.ToHexString(request.Value); 35 | 36 | // invalid input, discard 37 | if ( !receivedWrite.Equals("00") && !receivedWrite.Equals("01") ) 38 | { 39 | Debug.WriteLine($"Light Bulb cmd WriteRequested: INVALID INPUT: {receivedWrite} ({request.Value.Length})"); 40 | //send notification to user 41 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); 42 | //do not update Value, return 43 | return true; 44 | } 45 | 46 | //check for macros blink challenge 47 | currentTime = DateTime.Now; 48 | span = currentTime.Subtract(previousTime); 49 | Debug.WriteLine($"Time span from previoius write: {span.TotalMilliseconds} ms"); 50 | previousTime = currentTime; 51 | // previus write less than 0.5s ago 52 | if (span.TotalMilliseconds < 500) 53 | { 54 | Debug.WriteLine("Time span less than 0.5s!"); 55 | //check if previous value != current (light bulb swith) 56 | if (Value != request.Value) 57 | { 58 | switchCounter++; 59 | Debug.WriteLine($"Value switch - OK {switchCounter}"); 60 | } else 61 | { 62 | switchCounter = 0; 63 | } 64 | } 65 | 66 | if (switchCounter > 10) 67 | { 68 | OnPropertyChanged(new PropertyChangedEventArgs("BlinkPassed")); 69 | } 70 | 71 | // Set the characteristic Value 72 | Value = request.Value; 73 | 74 | return true; 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /cs/BLEServices/LightBulbTTSCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.Diagnostics; 8 | using Windows.Security.Cryptography; 9 | using Windows.Devices.SerialCommunication; 10 | using System.ComponentModel; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | 15 | public class LightBulbTTSCharacteristic : GenericGattCharacteristic 16 | { 17 | 18 | public LightBulbTTSCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 19 | { 20 | Value = BLEServices.Helpers.ToIBuffer(0); 21 | } 22 | 23 | protected override bool WriteRequested(GattSession session, GattWriteRequest request) 24 | { 25 | //check if this is write command not write request 26 | if (request.Option == GattWriteOption.WriteWithResponse) 27 | { 28 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); 29 | Debug.WriteLine("Write request"); 30 | } 31 | else 32 | { 33 | Debug.WriteLine("Write command"); 34 | Value = request.Value; 35 | } 36 | return true; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockAuthCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 8 | using System.Diagnostics; 9 | using System.Runtime.InteropServices.WindowsRuntime; 10 | using Windows.Security.Cryptography; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | public class QuickLockAuthCharacteristic : GenericGattCharacteristic 15 | { 16 | // matching sample pcap dump 17 | public byte[] password = { 0x66, 0x61, 0x26, 0x66 }; 18 | 19 | public QuickLockAuthCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 20 | { 21 | Value = BLEServices.Helpers.ToIBuffer((byte)0); 22 | } 23 | 24 | protected override bool WriteRequested(GattSession session, GattWriteRequest request) 25 | { 26 | byte[] receivedWrite; 27 | CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); 28 | var receivedWriteHexString = Helpers.ToHexString(request.Value); 29 | 30 | QuickLockMainService parent = (QuickLockMainService)this.ParentService; 31 | 32 | //expected: 0066612666 (pcap), or 006661266600000000 (also correct) 33 | if ( (request.Value.Length != 5) && (request.Value.Length != 9)) 34 | { 35 | Debug.WriteLine($"Smart lock auth WriteRequested, but invalid format: {receivedWriteHexString} ({request.Value.Length})"); 36 | //do not update Value, return 37 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); 38 | return true; 39 | } 40 | 41 | //check just the first byte and password, ignore rest if provided 42 | if ((receivedWrite[0] != 0x00) || (receivedWrite[1] != password[0]) || (receivedWrite[2] != password[1]) || (receivedWrite[3] != password[2]) || (receivedWrite[4] != password[3])) 43 | { 44 | Debug.WriteLine($"Smart lock auth WriteRequested: INVALID PASSWORD: {receivedWriteHexString} ({request.Value.Length})"); 45 | //do not update Value, return 46 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidPin")); 47 | return true; 48 | } 49 | 50 | parent.UpdateAuthenticationState(true); 51 | OnPropertyChanged(new PropertyChangedEventArgs("AuthenticationState")); 52 | 53 | return true; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockAuthStatusCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 8 | using System.Diagnostics; 9 | using System.Runtime.InteropServices.WindowsRuntime; 10 | using Windows.Security.Cryptography; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | public class QuickLockAuthStatusCharacteristic : GenericGattCharacteristic 15 | { 16 | public QuickLockAuthStatusCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 17 | { 18 | 19 | Value = BLEServices.Helpers.ToIBuffer((byte)0); 20 | } 21 | 22 | // the value is updated from the QuickLockAuthCharacteristic 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockCommandCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.Diagnostics; 8 | using System.Runtime.InteropServices.WindowsRuntime; 9 | using Windows.Security.Cryptography; 10 | using System.ComponentModel; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | public class QuickLockCommandCharacteristic : GenericGattCharacteristic 15 | { 16 | public QuickLockCommandCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 17 | { 18 | Value = BLEServices.Helpers.ToIBuffer((byte)0); 19 | } 20 | 21 | protected override bool WriteRequested(GattSession session, GattWriteRequest request) 22 | { 23 | byte[] receivedWrite; 24 | CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); 25 | var receivedWriteHexString = Helpers.ToHexString(request.Value); 26 | 27 | QuickLockMainService parent = (QuickLockMainService)this.ParentService; 28 | 29 | if (!parent.isAuthenticated) 30 | { 31 | Debug.WriteLine($"Quicklock cmd WriteRequested, but not authenticated {receivedWriteHexString} ({request.Value.Length})"); 32 | //do not update Value, return 33 | OnPropertyChanged(new PropertyChangedEventArgs("Unauthenticated")); 34 | return true; 35 | } 36 | 37 | if ((request.Value.Length != 1) || ( (receivedWrite[0] != 0x00) && (receivedWrite[0] !=0x01)) ) 38 | { 39 | Debug.WriteLine($"Quicklock cmd WriteRequested, but invalid format {receivedWriteHexString} ({request.Value.Length})"); 40 | //do not update Value, return 41 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); 42 | return true; 43 | } 44 | 45 | Debug.WriteLine($"Quicklock cmd received: {receivedWriteHexString} ({request.Value.Length})"); 46 | 47 | if (receivedWrite[0] == 00) // lock 48 | { 49 | Debug.WriteLine($"Locking!"); 50 | parent.UpdateUnlockState(false); 51 | } 52 | else if (receivedWrite[0] == 01) // unlock 53 | { 54 | Debug.WriteLine($"Unlocking!"); 55 | parent.UpdateUnlockState(true); 56 | } 57 | 58 | OnPropertyChanged(new PropertyChangedEventArgs("LockState")); 59 | 60 | return true; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockHistoryControlCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.Diagnostics; 8 | using System.Runtime.InteropServices.WindowsRuntime; 9 | using Windows.Security.Cryptography; 10 | using System.ComponentModel; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | public class QuickLockHistoryControlCharacteristic : GenericGattCharacteristic 15 | { 16 | public QuickLockHistoryControlCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 17 | { 18 | Value = Helpers.ToIBuffer((byte)1); 19 | } 20 | 21 | // if received "01", send logs via notification from HistoryData characteristic 22 | protected override bool WriteRequested(GattSession session, GattWriteRequest request) 23 | { 24 | byte[] receivedWrite; 25 | CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); 26 | var receivedWriteHexString = Helpers.ToHexString(request.Value); 27 | 28 | QuickLockHistoryService parent = (QuickLockHistoryService)this.ParentService; 29 | 30 | if ((request.Value.Length != 1) || (receivedWrite[0] != 0x01)) 31 | { 32 | Debug.WriteLine($"Quicklock history cmd WriteRequested, but invalid format: {receivedWriteHexString} ({request.Value.Length})"); 33 | //do not update Value, return 34 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); 35 | return true; 36 | } 37 | 38 | Debug.WriteLine($"Quicklock history cmd received, sending out logs"); 39 | 40 | // OnPropertyChanged(new PropertyChangedEventArgs("Logs")); 41 | 42 | // set the status characteristic and send notification 43 | parent.QuickLockHistoryData.SendLogs(); 44 | 45 | return true; 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockHistoryDataCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.Diagnostics; 8 | using System.Runtime.InteropServices.WindowsRuntime; 9 | using Windows.Security.Cryptography; 10 | using System.ComponentModel; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | public class QuickLockHistoryDataCharacteristic : GenericGattCharacteristic 15 | { 16 | 17 | private static String LOG_END_DELIMITER = "E0E0E0E0E0E0E0E0000000000000000000000000"; 18 | 19 | // for now just a few static log history values 20 | private static String[] SAMPLE_LOGS = 21 | { 22 | // user "smartlockpick" 2020-11-06 10:56:38 23 | "0d736d6172746c6f636b7069636b0066e8372700", 24 | // user "smartlockpick" 2020-11-06 13:40:00 25 | "0d736d6172746c6f636b7069636b00b00e382700", 26 | // user "hackmeuser" 2020-11-07 13:30 27 | "0a6861636b6d657573657200000000fc5d392700", 28 | }; 29 | 30 | public QuickLockHistoryDataCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 31 | { 32 | Value = Helpers.HexStringToIBuffer(LOG_END_DELIMITER); 33 | } 34 | 35 | public async void SendLogs() 36 | { 37 | // send all the SAMPLE_LOGS 38 | foreach (String log in SAMPLE_LOGS) 39 | { 40 | Debug.WriteLine($"Sending log notification: {log}"); 41 | Value = BLEServices.Helpers.HexStringToIBuffer(log); 42 | // short delay to imitate real device, and also allow to notice in nRF that the value is changing 43 | await Task.Delay(200); 44 | base.NotifyValue(); 45 | } 46 | 47 | Debug.WriteLine($"Sending log notification end delimiter: {LOG_END_DELIMITER}"); 48 | Value = BLEServices.Helpers.HexStringToIBuffer(LOG_END_DELIMITER); 49 | base.NotifyValue(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockHistoryService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.ComponentModel; 8 | 9 | namespace BLE_Hackme.BLEServices 10 | { 11 | public class QuickLockHistoryService : GenericGattService 12 | { 13 | 14 | // 0 - uninitialized, 1 - init, waiting for auth, 2 - authenticated 15 | public byte currentState = 0; 16 | // 0 - locked, 1 - unlocked 17 | public byte locked = 0; 18 | 19 | /// 20 | /// Name of the service 21 | /// 22 | public override string Name 23 | { 24 | get 25 | { 26 | return "Quick Lock History Service"; 27 | } 28 | } 29 | 30 | private QuickLockHistoryControlCharacteristic quickLockHistoryControl; 31 | private QuickLockHistoryDataCharacteristic quickLockHistoryData; 32 | private QuickLockUsernameCharacteristic quickLockUsername; 33 | 34 | /// 35 | /// Getters / setters 36 | /// 37 | 38 | public QuickLockHistoryControlCharacteristic QuickLockHistoryControl 39 | { 40 | get 41 | { 42 | return quickLockHistoryControl; 43 | } 44 | set 45 | { 46 | if (quickLockHistoryControl != value) 47 | { 48 | quickLockHistoryControl = value; 49 | OnPropertyChanged(new PropertyChangedEventArgs("QuickLockHistoryControl")); 50 | } 51 | } 52 | } 53 | 54 | public QuickLockHistoryDataCharacteristic QuickLockHistoryData 55 | { 56 | get 57 | { 58 | return quickLockHistoryData; 59 | } 60 | set 61 | { 62 | if (quickLockHistoryData != value) 63 | { 64 | quickLockHistoryData = value; 65 | OnPropertyChanged(new PropertyChangedEventArgs("QuickLockHistory")); 66 | } 67 | } 68 | } 69 | 70 | public QuickLockUsernameCharacteristic QuickLockUsername 71 | { 72 | get 73 | { 74 | return quickLockUsername; 75 | } 76 | set 77 | { 78 | if (quickLockUsername != value) 79 | { 80 | quickLockUsername = value; 81 | OnPropertyChanged(new PropertyChangedEventArgs("QuickLockUsername")); 82 | } 83 | } 84 | } 85 | 86 | 87 | /// 88 | /// Asynchronous initialization 89 | /// 90 | /// Initialization Task 91 | public override async Task Init() 92 | { 93 | await CreateServiceProvider(Constants.QuickLockHistoryServiceUuid); 94 | 95 | 96 | // history control 97 | 98 | GattLocalCharacteristicParameters quickLockHistoryControlCharacteristicsParameters = PlainReadWriteParameters; 99 | // Set the user descriptions 100 | quickLockHistoryControlCharacteristicsParameters.UserDescription = "control!"; 101 | 102 | // Create the characteristic for the service 103 | GattLocalCharacteristicResult result = 104 | await ServiceProvider.Service.CreateCharacteristicAsync( 105 | Constants.QuickLockHistoryControlCharacteristicUuid, 106 | quickLockHistoryControlCharacteristicsParameters); 107 | 108 | // Grab the characteristic object from the service set it to the property which is of a specfic Characteristic type 109 | GattLocalCharacteristic baseQuickLockHistoryControl = null; 110 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseQuickLockHistoryControl); 111 | 112 | if (baseQuickLockHistoryControl != null) 113 | { 114 | QuickLockHistoryControl = new BLEServices.QuickLockHistoryControlCharacteristic(baseQuickLockHistoryControl, this); 115 | } 116 | 117 | 118 | // history data 119 | 120 | GattLocalCharacteristicParameters quickLockHistoryDataCharacteristicsParameters = PlainReadNotifyParameters; 121 | // Set the user descriptions 122 | quickLockHistoryDataCharacteristicsParameters.UserDescription = "history!"; 123 | 124 | // Create the characteristic for the service 125 | result = 126 | await ServiceProvider.Service.CreateCharacteristicAsync( 127 | Constants.QuickLockHistoryDataCharacteristicUuid, 128 | quickLockHistoryDataCharacteristicsParameters); 129 | 130 | // Grab the characteristic object from the service set it to the property which is of a specfic Characteristic type 131 | GattLocalCharacteristic baseQuickLockHistoryData = null; 132 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseQuickLockHistoryData); 133 | 134 | if (baseQuickLockHistoryData != null) 135 | { 136 | QuickLockHistoryData = new BLEServices.QuickLockHistoryDataCharacteristic(baseQuickLockHistoryData, this); 137 | } 138 | 139 | 140 | // "imei" (username) 141 | 142 | // Preparing the characteristics 143 | GattLocalCharacteristicParameters quickLockUsernameCharacteristicsParameters = PlainReadWriteParameters; 144 | // Set the user descriptions 145 | quickLockUsernameCharacteristicsParameters.UserDescription = "phone id!"; 146 | 147 | // Create the characteristic for the service 148 | result = 149 | await ServiceProvider.Service.CreateCharacteristicAsync( 150 | Constants.QuickLockUsernameCharacteristicUuid, 151 | quickLockUsernameCharacteristicsParameters); 152 | 153 | // Grab the characterist object from the service set it to the property which is of a specfic Characteristic type 154 | GattLocalCharacteristic baseQuickLockUsername = null; 155 | BLEServices.Helpers.GetCharacteristicsFromResult(result, ref baseQuickLockUsername); 156 | 157 | if (baseQuickLockUsername != null) 158 | { 159 | QuickLockUsername = new BLEServices.QuickLockUsernameCharacteristic(baseQuickLockUsername, this); 160 | } 161 | 162 | } 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockOpenTimeCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 8 | using System.Diagnostics; 9 | using System.Runtime.InteropServices.WindowsRuntime; 10 | using Windows.Security.Cryptography; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | // this characteristic stores number of seconds the lock stays unlocked (before auto-lock again) 15 | public class QuickLockOpenTimeCharacteristic : GenericGattCharacteristic 16 | { 17 | public QuickLockOpenTimeCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 18 | { 19 | // for now just static 5 seconds, setting the value not yet implemented in HackMe 20 | Value = BLEServices.Helpers.ToIBuffer((byte)5); 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockUnlockStatusCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 8 | using System.Diagnostics; 9 | using System.Runtime.InteropServices.WindowsRuntime; 10 | using Windows.Security.Cryptography; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | public class QuickLockUnlockStatusCharacteristic : GenericGattCharacteristic 15 | { 16 | public QuickLockUnlockStatusCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 17 | { 18 | 19 | Value = BLEServices.Helpers.ToIBuffer((byte)0); 20 | } 21 | 22 | // the value is actually updated from the QuickLockCommandCharacteristic 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /cs/BLEServices/QuickLockUsernameCharacteristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 7 | using System.Diagnostics; 8 | using System.Runtime.InteropServices.WindowsRuntime; 9 | using Windows.Security.Cryptography; 10 | using System.ComponentModel; 11 | 12 | namespace BLE_Hackme.BLEServices 13 | { 14 | public class QuickLockUsernameCharacteristic : GenericGattCharacteristic 15 | { 16 | 17 | public QuickLockUsernameCharacteristic(GattLocalCharacteristic characteristic, GenericGattService service) : base(characteristic, service) 18 | { 19 | // "smartlockpick" user 20 | Value = Helpers.HexStringToIBuffer("0d736d6172746c6f636b7069636b00"); 21 | } 22 | 23 | protected override bool WriteRequested(GattSession session, GattWriteRequest request) 24 | { 25 | byte[] receivedWrite; 26 | CryptographicBuffer.CopyToByteArray(request.Value, out receivedWrite); 27 | var receivedWriteHexString = Helpers.ToHexString(request.Value); 28 | 29 | // valid format: one byte of length, followed by ascii hex username, and padded with 00 up to 15 bytes 30 | // for now just check the length and accept 15 chars only 31 | if ( (request.Value.Length != 15) ) 32 | { 33 | Debug.WriteLine($"Quicklock username WriteRequested, wrong length: {receivedWriteHexString} ({request.Value.Length})"); 34 | //do not update Value, return 35 | OnPropertyChanged(new PropertyChangedEventArgs("InvalidRequest")); 36 | return true; 37 | } 38 | 39 | // Set the characteristic Value to the value received 40 | Value = request.Value; 41 | return true; 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /cs/BLEServices/iBeacon.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Storage.Streams; 7 | 8 | namespace BLE_Hackme.BLEServices 9 | { 10 | class iBeacon 11 | { 12 | public Guid Uuid { get; private set; } 13 | public ushort Major { get; private set; } 14 | public ushort Minor { get; private set; } 15 | public byte RSSI { get; private set; } 16 | 17 | public iBeacon(Guid uuid, ushort major, ushort minor, byte rssi) 18 | { 19 | Uuid = uuid; 20 | Major = major; 21 | Minor = minor; 22 | RSSI = rssi; 23 | } 24 | 25 | public IBuffer getBuffer() 26 | { 27 | var writer = new DataWriter(); 28 | 29 | writer.WriteByte(0x02); // type: 0x02 = iBeacon 30 | writer.WriteByte(0x15); // length 21 bytes 31 | 32 | writer.WriteBytes(Uuid.ToByteArray()); 33 | writer.WriteUInt16(Major); 34 | writer.WriteUInt16(Minor); 35 | writer.WriteByte(RSSI); 36 | 37 | return writer.DetachBuffer(); 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /cs/BLE_Hackme.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30523.141 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLE_Hackme", "BLE_Hackme.csproj", "{445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}" 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 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|Any CPU.ActiveCfg = Debug|x86 21 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|Any CPU.Build.0 = Debug|x86 22 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|Any CPU.Deploy.0 = Debug|x86 23 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|ARM.ActiveCfg = Debug|ARM 24 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|ARM.Build.0 = Debug|ARM 25 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|ARM.Deploy.0 = Debug|ARM 26 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|x64.ActiveCfg = Debug|x64 27 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|x64.Build.0 = Debug|x64 28 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|x64.Deploy.0 = Debug|x64 29 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|x86.ActiveCfg = Debug|x86 30 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|x86.Build.0 = Debug|x86 31 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Debug|x86.Deploy.0 = Debug|x86 32 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|Any CPU.ActiveCfg = Release|x86 33 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|Any CPU.Build.0 = Release|x86 34 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|Any CPU.Deploy.0 = Release|x86 35 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|ARM.ActiveCfg = Release|ARM 36 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|ARM.Build.0 = Release|ARM 37 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|ARM.Deploy.0 = Release|ARM 38 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|x64.ActiveCfg = Release|x64 39 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|x64.Build.0 = Release|x64 40 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|x64.Deploy.0 = Release|x64 41 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|x86.ActiveCfg = Release|x86 42 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|x86.Build.0 = Release|x86 43 | {445C51F0-1B60-5DF7-8798-DC8C1F7D0C90}.Release|x86.Deploy.0 = Release|x86 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {8F332316-09D2-4B99-B63F-86A5C07FE034} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /cs/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.Devices.Bluetooth.GenericAttributeProfile; 3 | 4 | namespace BLE_Hackme 5 | { 6 | public class Constants 7 | { 8 | public static readonly Guid iBeaconUuid = Guid.Parse("6834636b-6d33-6942-3334-63306e553144"); 9 | 10 | public static readonly String manufacturerSpecificAdvertisementText = "Please don't hack me "; 11 | 12 | public static readonly String heartRateDescriptorText = "Beats per minute "; 13 | 14 | public static readonly Guid LightBulbServiceUuid = Guid.Parse("6834636b-6d33-4c31-3668-744275314221"); 15 | 16 | public static readonly Guid LightBulbSwitchCharacteristicUuid = Guid.Parse("6834636b-6d33-4c31-3668-744275314201"); 17 | public static readonly Guid LightBulbTTSCharacteristicUuid = Guid.Parse("6834636b-6d33-4c31-3668-744275314202"); 18 | public static readonly Guid LightBulbColorCharacteristicUuid = Guid.Parse("6834636b-6d33-4c31-3668-744275314203"); 19 | public static readonly Guid LightBulbProtectedCharacteristicUuid = Guid.Parse("6834636b-6d33-4c31-3668-744275314204"); 20 | 21 | //quicklock 22 | public static readonly Guid QuickLockHistoryServiceUuid = Guid.Parse("0000fff0-0000-1000-8000-00805f9b34fb"); 23 | public static readonly Guid QuickLockHistoryControlCharacteristicUuid = Guid.Parse("0000fff1-0000-1000-8000-00805f9b34fb"); 24 | public static readonly Guid QuickLockHistoryDataCharacteristicUuid = Guid.Parse("0000fff2-0000-1000-8000-00805f9b34fb"); 25 | public static readonly Guid QuickLockUsernameCharacteristicUuid = Guid.Parse("0000fff3-0000-1000-8000-00805f9b34fb"); 26 | 27 | public static readonly Guid QuickLockMainServiceUuid = Guid.Parse("0000ffd0-0000-1000-8000-00805f9b34fb"); 28 | public static readonly Guid QuickLockAuthCharacteristicUuid = Guid.Parse("0000ffd6-0000-1000-8000-00805f9b34fb"); 29 | public static readonly Guid QuickLockAuthStatusCharacteristicUuid = Guid.Parse("0000ffd7-0000-1000-8000-00805f9b34fb"); 30 | public static readonly Guid QuickLockOpenTimeCharacteristicUuid = Guid.Parse("0000ffd8-0000-1000-8000-00805f9b34fb"); 31 | public static readonly Guid QuickLockCommandCharacteristicUuid = Guid.Parse("0000ffd9-0000-1000-8000-00805f9b34fb"); 32 | public static readonly Guid QuickLockUnlockStatusCharacteristicUuid = Guid.Parse("0000ffda-0000-1000-8000-00805f9b34fb"); 33 | 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /cs/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 54 |