├── .github
├── .changelog-config.json
└── workflows
│ ├── generate-changelog.yml
│ ├── pr-checks.yml
│ └── update-dependencies.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE.md
├── NuGet.Config
├── README.md
├── README.zh-cn.md
├── Tests
├── Client
│ ├── Program.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── README.md
│ ├── Services
│ │ ├── DeviceInformationService.cs
│ │ ├── EnvironmentalSensorService.cs
│ │ └── TestService.cs
│ ├── TestClient.nfproj
│ ├── TestClient.sln
│ ├── category.txt
│ ├── packages.config
│ └── packages.lock.json
└── NFUnitTest1
│ ├── NFUnitTest1.nfproj
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── TestUuidUtilities.cs
│ ├── UnitTest1.cs
│ ├── nano.runsettings
│ ├── packages.config
│ └── packages.lock.json
├── assets
├── nf-logo.png
└── readme.txt
├── azure-pipelines.yml
├── nanoFramework.Device.Bluetooth.nuspec
├── nanoFramework.Device.Bluetooth.sln
├── nanoFramework.Device.Bluetooth
├── Advertisement
│ ├── BluetoothLEAdvertisement.cs
│ ├── BluetoothLEAdvertisementBytePattern.cs
│ ├── BluetoothLEAdvertisementDataSection.cs
│ ├── BluetoothLEAdvertisementDataSectionType.cs
│ ├── BluetoothLEAdvertisementFilter.cs
│ ├── BluetoothLEAdvertisementFlags.cs
│ ├── BluetoothLEAdvertisementPublisher.cs
│ ├── BluetoothLEAdvertisementPublisherStatus.cs
│ ├── BluetoothLEAdvertisementPublisherStatusChangedEventArgs.cs
│ ├── BluetoothLEAdvertisementReceivedEventArgs.cs
│ ├── BluetoothLEAdvertisementType.cs
│ └── BluetoothLEAdvertisementWatcherStoppedEventArgs.cs
├── BluetoothAddress.cs
├── BluetoothAddressType.cs
├── BluetoothConnectionStatus.cs
├── BluetoothDeviceId.cs
├── BluetoothError.cs
├── BluetoothEvent.cs
├── BluetoothEventListener.cs
├── BluetoothEventType.cs
├── BluetoothLEAdvertisementWatcher.cs
├── BluetoothLEAdvertisementWatcherStatus.cs
├── BluetoothLEDevice.cs
├── BluetoothLEManufacturerData.cs
├── BluetoothLEScanningMode.cs
├── BluetoothLEServer.cs
├── BluetoothNanoDevice.cs
├── BluetoothSignalStrengthFilter.cs
├── GenericAttributeProfile
│ ├── GattCharacteristic.cs
│ ├── GattCharacteristicProperties.cs
│ ├── GattCharacteristicResult.cs
│ ├── GattCharacteristicUuids.cs
│ ├── GattClientCharacteristicConfigurationDescriptorValue.cs
│ ├── GattClientNotificationResult.cs
│ ├── GattCommunicationStatus.cs
│ ├── GattDescriptor.cs
│ ├── GattDescriptorResult.cs
│ ├── GattDescriptorUuid.cs
│ ├── GattDeviceService.cs
│ ├── GattDeviceServicesResult.cs
│ ├── GattLocalCharacteristic.cs
│ ├── GattLocalCharacteristicParameters.cs
│ ├── GattLocalCharacteristicResult.cs
│ ├── GattLocalDescriptor.cs
│ ├── GattLocalDescriptorParameters.cs
│ ├── GattLocalDescriptorResult.cs
│ ├── GattLocalService.cs
│ ├── GattPresentationFormat.cs
│ ├── GattPresentationFormatTypes.cs
│ ├── GattProtectionLevel.cs
│ ├── GattProtocolError.cs
│ ├── GattReadClientCharacteristicConfigurationDescriptorResult.cs
│ ├── GattReadRequest.cs
│ ├── GattReadRequestedEventArgs.cs
│ ├── GattReadResult.cs
│ ├── GattServiceProvider.cs
│ ├── GattServiceProviderAdvertisementStatus.cs
│ ├── GattServiceProviderAdvertisingParameters.cs
│ ├── GattServiceProviderResult.cs
│ ├── GattServiceUuids.cs
│ ├── GattSession.cs
│ ├── GattSessionStatus.cs
│ ├── GattSessionStatusChangedEventArgs.cs
│ ├── GattSubscribedClient.cs
│ ├── GattValueChangedEventArgs.cs
│ ├── GattWriteOption.cs
│ ├── GattWriteRequest.cs
│ ├── GattWriteRequestedEventArgs.cs
│ ├── GattWriteResult.cs
│ └── IGattAttribute.cs
├── IO
│ ├── Buffer.cs
│ ├── DataReader.cs
│ └── DataWriter.cs
├── Properties
│ └── AssemblyInfo.cs
├── SPP
│ ├── IBluetoothSpp.cs
│ ├── NordicSpp.cs
│ └── SppReceiveEventArgs.cs
├── Security
│ ├── DeviceBonding.cs
│ ├── DevicePairing.cs
│ ├── DevicePairingEventArgs.cs
│ ├── DevicePairingIOCapabilities.cs
│ ├── DevicePairingKinds .cs
│ ├── DevicePairingProtectionLevel.cs
│ ├── DevicePairingRequestedEventArgs.cs
│ ├── DevicePairingResult.cs
│ ├── DevicePairingResultStatus.cs
│ ├── DeviceUnpairingResult.cs
│ ├── DeviceUnpairingResultStatus.cs
│ └── PasswordCredential.cs
├── Utilities.cs
├── key.snk
├── nanoFramework.Device.Bluetooth.nfproj
├── packages.config
└── packages.lock.json
└── version.json
/.github/.changelog-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "categories": [
3 | {
4 | "title": "## New Features and enhancements",
5 | "labels": [
6 | "Type: enhancement"
7 | ],
8 | "exhaustive": true
9 | },
10 | {
11 | "title": "## Bug Fixes",
12 | "labels": [
13 | "Type: bug"
14 | ],
15 | "exhaustive": true
16 | },
17 | {
18 | "title": "## Documentation",
19 | "labels": [
20 | "Type: documentation"
21 | ],
22 | "exhaustive": true
23 | },
24 | {
25 | "title": "## ⚠️ Breaking Changes",
26 | "labels": [
27 | "Breaking-Change"
28 | ],
29 | "exhaustive": true
30 | },
31 | {
32 | "title": "## Updated dependencies",
33 | "labels": [
34 | "Type: dependencies"
35 | ],
36 | "exhaustive": true
37 | }
38 | ],
39 | "sort": "ASC",
40 | "template": "${{CHANGELOG}}\n\n**Full Changelog:** ${{RELEASE_DIFF}}\n\nThe following NuGet package is available from this release:\n\n:package: [nanoFramework.Device.Bluetooth](https://www.nuget.org/packages/nanoFramework.Device.Bluetooth/)",
41 | "pr_template": "* ${{TITLE}} by @${{AUTHOR}} in #${{NUMBER}}",
42 | "empty_template": "- no changes",
43 | "max_tags_to_fetch": 200,
44 | "max_pull_requests": 200
45 | }
46 |
--------------------------------------------------------------------------------
/.github/workflows/generate-changelog.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) .NET Foundation and Contributors
2 | # See LICENSE file in the project root for full license information.
3 |
4 | name: Generate Changelog
5 | run-name: Generate changelog
6 |
7 | on:
8 | push:
9 | tags:
10 | - '*'
11 |
12 | jobs:
13 | compose_changelog:
14 | name: nanoFramework
15 | uses: nanoframework/nf-tools/.github/workflows/generate-changelog.yml@main
16 | secrets: inherit
17 |
--------------------------------------------------------------------------------
/.github/workflows/pr-checks.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) .NET Foundation and Contributors
2 | # See LICENSE file in the project root for full license information.
3 |
4 | name: PR Checks
5 |
6 | on:
7 | pull_request:
8 |
9 | jobs:
10 | check_package_lock:
11 | name: nanoFramework
12 | uses: nanoframework/nf-tools/.github/workflows/check-package-lock.yml@main
13 | check_nuget_latest:
14 | name: nanoFramework
15 | uses: nanoframework/nf-tools/.github/workflows/check-packages-updated.yml@main
16 | secrets: inherit
17 | with:
18 | solution: 'nanoFramework.Device.Bluetooth.sln'
19 |
--------------------------------------------------------------------------------
/.github/workflows/update-dependencies.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) .NET Foundation and Contributors
2 | # See LICENSE file in the project root for full license information.
3 |
4 | # This workflow will periodically check .NET nanoFramework dependencies and updates them in the repository it's running.
5 |
6 | name: Daily update dependencies
7 |
8 | on:
9 | schedule:
10 | # At 00:20 UTC every Mon Thu.
11 | - cron: '00 20 * * Mon,Thu'
12 | repository_dispatch:
13 | types: update-dependencies
14 |
15 | jobs:
16 | update-dependencies:
17 | name: nanoFramework
18 | uses: nanoframework/nf-tools/.github/workflows/update-dependencies.yml@main
19 | secrets: inherit
20 | with:
21 | solutionsToCheck: 'nanoFramework.Device.Bluetooth.sln'
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 | *.VC.VC.opendb
85 |
86 | # Visual Studio profiler
87 | *.psess
88 | *.vsp
89 | *.vspx
90 | *.sap
91 |
92 | # TFS 2012 Local Workspace
93 | $tf/
94 |
95 | # Guidance Automation Toolkit
96 | *.gpState
97 |
98 | # ReSharper is a .NET coding add-in
99 | _ReSharper*/
100 | *.[Rr]e[Ss]harper
101 | *.DotSettings.user
102 |
103 | # JustCode is a .NET coding add-in
104 | .JustCode
105 |
106 | # TeamCity is a build add-in
107 | _TeamCity*
108 |
109 | # DotCover is a Code Coverage Tool
110 | *.dotCover
111 |
112 | # NCrunch
113 | _NCrunch_*
114 | .*crunch*.local.xml
115 | nCrunchTemp_*
116 |
117 | # MightyMoose
118 | *.mm.*
119 | AutoTest.Net/
120 |
121 | # Web workbench (sass)
122 | .sass-cache/
123 |
124 | # Installshield output folder
125 | [Ee]xpress/
126 |
127 | # DocProject is a documentation generator add-in
128 | DocProject/buildhelp/
129 | DocProject/Help/*.HxT
130 | DocProject/Help/*.HxC
131 | DocProject/Help/*.hhc
132 | DocProject/Help/*.hhk
133 | DocProject/Help/*.hhp
134 | DocProject/Help/Html2
135 | DocProject/Help/html
136 |
137 | # Click-Once directory
138 | publish/
139 |
140 | # Publish Web Output
141 | *.[Pp]ublish.xml
142 | *.azurePubxml
143 | # TODO: Comment the next line if you want to checkin your web deploy settings
144 | # but database connection strings (with potential passwords) will be unencrypted
145 | *.pubxml
146 | *.publishproj
147 |
148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
149 | # checkin your Azure Web App publish settings, but sensitive information contained
150 | # in these scripts will be unencrypted
151 | PublishScripts/
152 |
153 | # NuGet Packages
154 | *.nupkg
155 | # The packages folder can be ignored because of Package Restore
156 | **/packages/*
157 | # except build/, which is used as an MSBuild target.
158 | !**/packages/build/
159 | # Uncomment if necessary however generally it will be regenerated when needed
160 | #!**/packages/repositories.config
161 | # NuGet v3's project.json files produces more ignoreable files
162 | *.nuget.props
163 | *.nuget.targets
164 |
165 | # Microsoft Azure Build Output
166 | csx/
167 | *.build.csdef
168 |
169 | # Microsoft Azure Emulator
170 | ecf/
171 | rcf/
172 |
173 | # Windows Store app package directories and files
174 | AppPackages/
175 | BundleArtifacts/
176 | Package.StoreAssociation.xml
177 | _pkginfo.txt
178 |
179 | # Visual Studio cache files
180 | # files ending in .cache can be ignored
181 | *.[Cc]ache
182 | # but keep track of directories ending in .cache
183 | !*.[Cc]ache/
184 |
185 | # Others
186 | ClientBin/
187 | ~$*
188 | *~
189 | *.dbmdl
190 | *.dbproj.schemaview
191 | *.pfx
192 | *.publishsettings
193 | node_modules/
194 | orleans.codegen.cs
195 |
196 | # Since there are multiple workflows, uncomment next line to ignore bower_components
197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
198 | #bower_components/
199 |
200 | # RIA/Silverlight projects
201 | Generated_Code/
202 |
203 | # Backup & report files from converting an old project file
204 | # to a newer Visual Studio version. Backup files are not needed,
205 | # because we have git ;-)
206 | _UpgradeReport_Files/
207 | Backup*/
208 | UpgradeLog*.XML
209 | UpgradeLog*.htm
210 |
211 | # SQL Server files
212 | *.mdf
213 | *.ldf
214 |
215 | # Business Intelligence projects
216 | *.rdl.data
217 | *.bim.layout
218 | *.bim_*.settings
219 |
220 | # Microsoft Fakes
221 | FakesAssemblies/
222 |
223 | # GhostDoc plugin setting file
224 | *.GhostDoc.xml
225 |
226 | # Node.js Tools for Visual Studio
227 | .ntvs_analysis.dat
228 |
229 | # Visual Studio 6 build log
230 | *.plg
231 |
232 | # Visual Studio 6 workspace options file
233 | *.opt
234 |
235 | # Visual Studio LightSwitch build output
236 | **/*.HTMLClient/GeneratedArtifacts
237 | **/*.DesktopClient/GeneratedArtifacts
238 | **/*.DesktopClient/ModelManifest.xml
239 | **/*.Server/GeneratedArtifacts
240 | **/*.Server/ModelManifest.xml
241 | _Pvt_Extensions
242 |
243 | # Paket dependency manager
244 | .paket/paket.exe
245 | paket-files/
246 |
247 | # FAKE - F# Make
248 | .fake/
249 |
250 | # JetBrains Rider
251 | .idea/
252 | *.sln.iml
253 |
254 | #SoundCloud
255 | *.sonarqube/
256 |
257 | #VS Code
258 | .vscode
259 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) .NET Foundation and Contributors
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Tests/Client/Program.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Diagnostics;
8 | using System.Threading;
9 |
10 | using nanoFramework.Device.Bluetooth;
11 | using nanoFramework.Device.Bluetooth.GenericAttributeProfile;
12 | using nanoFramework.Device.Bluetooth.Services;
13 | using nanoFramework.Runtime.Native;
14 |
15 | using nanoFramework.Device.Bluetooth.Spp;
16 |
17 | ///
18 | /// TestClient for use with BlueTooth test cases
19 | ///
20 | /// Includes Standard Services:
21 | /// - Environmental Sensor
22 | /// - Device Information
23 | ///
24 | /// Plus Test Service for Settings values
25 | ///
26 | namespace TestClient
27 | {
28 | public static class Program
29 | {
30 | static EnvironmentalSensorService EnvService;
31 |
32 | // Indexes to sensors
33 | static int iTempOut;
34 | static int iTempOutMax;
35 | static int iTempOutMin;
36 | static int iHumidity;
37 |
38 | public static void Main()
39 | {
40 | Console.WriteLine();
41 | Console.WriteLine("BlueTooth Test Client");
42 |
43 | // Define used custom Uuid
44 | Guid serviceUuid = new("A7EEDF2C-DA87-4CB5-A9C5-5151C78B0066");
45 | Guid readStaticCharUuid = new("A7EEDF2C-DA89-4CB5-A9C5-5151C78B0057");
46 |
47 | Console.WriteLine("Create Primary service - UUID A7EEDF2C-DA87-4CB5-A9C5-5151C78B0066");
48 |
49 | BluetoothLEServer.Instance.DeviceName = "Test2";
50 |
51 | //The GattServiceProvider is used to create and advertise the primary service definition.
52 | //An extra device information service will be automatically created.
53 | GattServiceProviderResult result = GattServiceProvider.Create(serviceUuid);
54 | if (result.Error != BluetoothError.Success)
55 | {
56 | return;
57 | }
58 |
59 | GattServiceProvider serviceProvider = result.ServiceProvider;
60 |
61 | // Get created Primary service from provider
62 | GattLocalService service = serviceProvider.Service;
63 |
64 | #region Static read characteristic
65 | // Now we add an characteristic to service
66 | // If the read value is not going to change then you can just use a Static value
67 | DataWriter sw = new();
68 | sw.WriteString("This is a test client");
69 |
70 | GattLocalCharacteristicResult characteristicResult = service.CreateCharacteristic(readStaticCharUuid,
71 | new GattLocalCharacteristicParameters()
72 | {
73 | CharacteristicProperties = GattCharacteristicProperties.Read,
74 | UserDescription = "My Static Characteristic",
75 | StaticValue = sw.DetachBuffer()
76 | });
77 |
78 | if (characteristicResult.Error != BluetoothError.Success)
79 | {
80 | // An error occurred.
81 | return;
82 | }
83 | #endregion
84 |
85 | Console.WriteLine("Create Device Information Service");
86 |
87 | // === Device Information Service ===
88 | DeviceInformationServiceService DifService = new(
89 | "nanoFramework",
90 | "Test Client",
91 | null, // no serial number
92 | "v1.0",
93 | SystemInfo.Version.ToString(),
94 | "");
95 |
96 | Console.WriteLine("Create Environmental Sensor Service");
97 |
98 | // === Environmental Sensor Service ===
99 | // https://www.bluetooth.com/specifications/specs/environmental-sensing-service-1-0/
100 | // This service exposes measurement data from an environmental sensors.
101 | EnvService = new EnvironmentalSensorService();
102 |
103 | // Add sensors to service, return index so sensor can be updated later.
104 | iTempOut = EnvService.AddSensor(EnvironmentalSensorService.SensorType.Temperature, "Outside Temp");
105 | iTempOutMax = EnvService.AddSensor(EnvironmentalSensorService.SensorType.Temperature, "Max Outside Temp", EnvironmentalSensorService.Sampling.Maximum);
106 | iTempOutMin = EnvService.AddSensor(EnvironmentalSensorService.SensorType.Temperature, "Min Outside Temp", EnvironmentalSensorService.Sampling.Minimum);
107 | iHumidity = EnvService.AddSensor(EnvironmentalSensorService.SensorType.Humidity, "OUtside Humidty");
108 |
109 | // Update initial sensor values
110 | EnvService.UpdateValue(iTempOut, 23.4F);
111 | EnvService.UpdateValue(iTempOutMax, 28.1F);
112 | EnvService.UpdateValue(iTempOutMin, 7.5F);
113 | EnvService.UpdateValue(iHumidity, 63.3F);
114 |
115 | // TestService test = new TestService(serviceProvider);
116 | // test.CommandRX += Test_CommandRX;
117 |
118 | #region Start Advertising
119 | Console.WriteLine("Start Advertising");
120 |
121 | // Once all the Characteristics/Services have been created you need to advertise so
122 | // other devices can see it. Here we also say the device can be connected too and other
123 | // devices can see it with a specific device name.
124 | serviceProvider.StartAdvertising(new GattServiceProviderAdvertisingParameters()
125 | {
126 | IsConnectable = true,
127 | IsDiscoverable = true
128 | });
129 | #endregion
130 |
131 | Thread.Sleep(60000);
132 |
133 | while (true)
134 | {
135 | float t1 = 23.4F;
136 | float t3 = 7.5F;
137 |
138 | // Up
139 | while (t1 < 120)
140 | {
141 | t1 += 1.3F;
142 | t3 += 2.1F;
143 |
144 | EnvService.UpdateValue(iTempOut, t1);
145 | EnvService.UpdateValue(iTempOutMin, t3);
146 | Thread.Sleep(5000);
147 | }
148 |
149 | // Up
150 | while (t1 > -50F)
151 | {
152 | t1 -= 1.3F;
153 | t3 -= 2.1F;
154 |
155 | EnvService.UpdateValue(iTempOut, t1);
156 | EnvService.UpdateValue(iTempOutMin, t3);
157 | Thread.Sleep(5000);
158 | }
159 | }
160 |
161 | Thread.Sleep(Timeout.Infinite);
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/Tests/Client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CSharp.BlankApplication")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("CSharp.BlankApplication")]
13 | [assembly: AssemblyCopyright("Copyright © ")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // Version information for an assembly consists of the following four values:
23 | //
24 | // Major Version
25 | // Minor Version
26 | // Build Number
27 | // Revision
28 | //
29 | // You can specify all the values or you can default the Build and Revision Numbers
30 | // by using the '*' as shown below:
31 | // [assembly: AssemblyVersion("1.0.*")]
32 | [assembly: AssemblyVersion("1.0.0.0")]
33 | [assembly: AssemblyFileVersion("1.0.0.0")]
34 |
--------------------------------------------------------------------------------
/Tests/Client/README.md:
--------------------------------------------------------------------------------
1 | # Bluetooth Low energy: adding, replacing services to the main service
2 |
3 | This show cases the use of adding extra services to main service or replacing an existing service
4 | like the default "Device Information Service".
5 |
6 | This sample also includes some standard Bluetooth services as separate classes which may be useful
7 | for any Bluetooth LE project.
8 |
9 | ## Device Information Service
10 |
11 | Provides device information like Manufacturer, model, software version etc.
12 |
13 | ## Battery Level Service
14 |
15 | Publishes the current battery level as a percentage.
16 |
17 | ## Current Time Service
18 |
19 | Publishes the current date/time of device and optionally allows the date/time to be set on device.
20 |
21 | ## Environmental Sensor service
22 |
23 | This allows multiple environmental sensors to be published such as Temperature, Humidity, Pressure, Rainfall.
24 | This sample class includes these 4 but other types can easily added to class. Multiple sensor of same type can be added.
25 | The sample shows 3 Temperatures (Instantaneous, Maximum, Minimum) added to service and a humidity sensor.
26 |
27 | See [main Bluetooth sample's readme](../README.md) for more information.
--------------------------------------------------------------------------------
/Tests/Client/Services/DeviceInformationService.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation and Contributors
2 | // See LICENSE file in the project root for full license information.
3 | //
4 |
5 | using System;
6 | using nanoFramework.Device.Bluetooth.GenericAttributeProfile;
7 |
8 | namespace nanoFramework.Device.Bluetooth.Services
9 | {
10 | ///
11 | /// Device Information Service.
12 | /// Contains information about the device.
13 | ///
14 | public class DeviceInformationServiceService
15 | {
16 | private readonly GattLocalService _deviceInformationService;
17 |
18 | ///
19 | /// Create a new Device Information Service on Provider using supplied string.
20 | /// If a string is null the Characteristic will not be included in service.
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | ///
29 | public DeviceInformationServiceService(
30 | string Manufacturer,
31 | string ModelNumber = null,
32 | string SerialNumber = null,
33 | string HardwareRevision = null,
34 | string FirmwareRevision = null,
35 | string SoftwareRevision = null
36 | )
37 | {
38 | GattServiceProviderResult pr = GattServiceProvider.Create(GattServiceUuids.DeviceInformation);
39 | if (pr.Error != BluetoothError.Success)
40 | {
41 | throw new ApplicationException("Unable to create service");
42 | }
43 |
44 | // Pick up service
45 | _deviceInformationService = pr.ServiceProvider.Service;
46 |
47 | CreateReadStaticCharacteristic(GattCharacteristicUuids.ManufacturerNameString, Manufacturer);
48 | CreateReadStaticCharacteristic(GattCharacteristicUuids.ModelNumberString, ModelNumber);
49 | CreateReadStaticCharacteristic(GattCharacteristicUuids.SerialNumberString, SerialNumber);
50 | CreateReadStaticCharacteristic(GattCharacteristicUuids.HardwareRevisionString, HardwareRevision);
51 | CreateReadStaticCharacteristic(GattCharacteristicUuids.FirmwareRevisionString, FirmwareRevision);
52 | CreateReadStaticCharacteristic(GattCharacteristicUuids.SoftwareRevisionString, SoftwareRevision);
53 | }
54 |
55 | ///
56 | /// Create static Characteristic if not null.
57 | ///
58 | /// Characteristic UUID
59 | /// string data or null
60 | private void CreateReadStaticCharacteristic(Guid Uuid, String data)
61 | {
62 | if (data != null)
63 | {
64 | // Create data buffer
65 | DataWriter writer = new DataWriter();
66 | writer.WriteString(data);
67 |
68 | _deviceInformationService.CreateCharacteristic(Uuid, new GattLocalCharacteristicParameters()
69 | {
70 | CharacteristicProperties = GattCharacteristicProperties.Read,
71 | StaticValue = writer.DetachBuffer()
72 | });
73 | }
74 | }
75 | }
76 | }
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Tests/Client/Services/TestService.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation and Contributors
2 | // See LICENSE file in the project root for full license information.
3 | //
4 |
5 | using System;
6 | using System.Text;
7 | using nanoFramework.Device.Bluetooth.GenericAttributeProfile;
8 |
9 | namespace nanoFramework.Device.Bluetooth.Services
10 | {
11 | ///
12 | /// Allows commands to be sent to test device
13 | ///
14 | public class TestService
15 | {
16 | private readonly GattLocalService _testService;
17 |
18 | public Guid serviceUUID = new Guid("5CB16844-E11B-43C2-A2DD-45685828488F");
19 | public Guid rxCommandUUID = new Guid("CC168A62-EA8C-489D-9AF1-57F2F75A713F");
20 |
21 | public delegate void CommandRXHandler(TestService sender, string args);
22 | public event CommandRXHandler CommandRX;
23 |
24 | ///
25 | /// Create a test service
26 | ///
27 | public TestService()
28 | {
29 | GattServiceProviderResult pr = GattServiceProvider.Create(serviceUUID);
30 | if (pr.Error != BluetoothError.Success)
31 | {
32 | throw new ApplicationException("Unable to create service");
33 | }
34 |
35 | _testService = pr.ServiceProvider.Service;
36 |
37 | GattLocalCharacteristicParameters rxCommandPar = new GattLocalCharacteristicParameters()
38 | {
39 | UserDescription = "RX command",
40 | CharacteristicProperties = GattCharacteristicProperties.Write | GattCharacteristicProperties.WriteWithoutResponse
41 | };
42 |
43 | GattLocalCharacteristicResult rxCommandRes = pr.ServiceProvider.Service.CreateCharacteristic(rxCommandUUID, rxCommandPar);
44 | if (rxCommandRes.Error != nanoFramework.Device.Bluetooth.BluetoothError.Success)
45 | {
46 | throw new ArgumentException("Unable to create RX Command");
47 | }
48 |
49 | GattLocalCharacteristic rxCommand = rxCommandRes.Characteristic;
50 | rxCommand.WriteRequested += RxCommand_WriteRequested;
51 |
52 | }
53 |
54 |
55 | private void RxCommand_WriteRequested(GattLocalCharacteristic sender, GattWriteRequestedEventArgs WriteRequestEventArgs)
56 | {
57 | DataReader rdr = DataReader.FromBuffer(WriteRequestEventArgs.GetRequest().Value);
58 |
59 | byte[] bytes = new byte[rdr.UnconsumedBufferLength];
60 | rdr.ReadBytes(bytes);
61 | string command = Encoding.UTF8.GetString(bytes,0, bytes.Length);
62 |
63 | CommandRX?.Invoke(this, command);
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/Tests/Client/TestClient.nfproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildExtensionsPath)\nanoFramework\v1.0\
5 |
6 |
7 |
8 | Debug
9 | AnyCPU
10 | {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
11 | 7e45875f-6644-472e-8768-0590b15b724b
12 | Exe
13 | Properties
14 | 512
15 | TestClient
16 | TestClient
17 | v1.0
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | ..\..\packages\nanoFramework.CoreLibrary.1.17.11\lib\mscorlib.dll
30 |
31 |
32 | ..\..\packages\nanoFramework.Runtime.Events.1.11.32\lib\nanoFramework.Runtime.Events.dll
33 |
34 |
35 | ..\..\packages\nanoFramework.Runtime.Native.1.7.11\lib\nanoFramework.Runtime.Native.dll
36 |
37 |
38 | ..\..\packages\nanoFramework.System.Text.1.3.42\lib\nanoFramework.System.Text.dll
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Tests/Client/TestClient.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.32126.315
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "TestClient", "TestClient.nfproj", "{7E45875F-6644-472E-8768-0590B15B724B}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {7E45875F-6644-472E-8768-0590B15B724B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {7E45875F-6644-472E-8768-0590B15B724B}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {7E45875F-6644-472E-8768-0590B15B724B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
17 | {7E45875F-6644-472E-8768-0590B15B724B}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {7E45875F-6644-472E-8768-0590B15B724B}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {7E45875F-6644-472E-8768-0590B15B724B}.Release|Any CPU.Deploy.0 = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(SolutionProperties) = preSolution
22 | HideSolutionNode = FALSE
23 | EndGlobalSection
24 | GlobalSection(ExtensibilityGlobals) = postSolution
25 | SolutionGuid = {A2842946-2505-4C77-A1CA-68C49B9ED0B2}
26 | EndGlobalSection
27 | EndGlobal
28 |
--------------------------------------------------------------------------------
/Tests/Client/category.txt:
--------------------------------------------------------------------------------
1 | ble
2 |
--------------------------------------------------------------------------------
/Tests/Client/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Tests/Client/packages.lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "dependencies": {
4 | ".NETnanoFramework,Version=v1.0": {
5 | "nanoFramework.CoreLibrary": {
6 | "type": "Direct",
7 | "requested": "[1.17.11, 1.17.11]",
8 | "resolved": "1.17.11",
9 | "contentHash": "HezzAc0o2XrSGf85xSeD/6xsO6ohF9hX6/iMQ1IZS6Zw6umr4WfAN2Jv0BrPxkaYwzEegJxxZujkHoUIAqtOMw=="
10 | },
11 | "nanoFramework.Runtime.Events": {
12 | "type": "Direct",
13 | "requested": "[1.11.32, 1.11.32]",
14 | "resolved": "1.11.32",
15 | "contentHash": "NyLUIwJDlpl5VKSd+ljmdDtO2WHHBvPvruo1ccaL+hd79z+6XMYze1AccOVXKGiZenLBCwDmFHwpgIQyHkM7GA=="
16 | },
17 | "nanoFramework.Runtime.Native": {
18 | "type": "Direct",
19 | "requested": "[1.7.11, 1.7.11]",
20 | "resolved": "1.7.11",
21 | "contentHash": "XPSTltZ9KeBruogVmjQpCphi1nLoJH49mpyp2eGBs8BTjKuL5TkMO20MoI8r73F/PW5AppTq49HvIZZavU5nPQ=="
22 | },
23 | "nanoFramework.System.Text": {
24 | "type": "Direct",
25 | "requested": "[1.3.42, 1.3.42]",
26 | "resolved": "1.3.42",
27 | "contentHash": "68HPjhersNpssbmEMUHdMw3073MHfGTfrkbRk9eILKbNPFfPFck7m4y9BlAi6DaguUJaeKxgyIojXF3SQrF8/A=="
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Tests/NFUnitTest1/NFUnitTest1.nfproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildExtensionsPath)\nanoFramework\v1.0\
5 |
6 |
7 |
8 |
9 |
10 |
11 | Debug
12 | AnyCPU
13 | {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | f13430a1-c6f5-47d8-bcec-8b601cf9149b
15 | Library
16 | Properties
17 | 512
18 | NFUnitTest1
19 | NFUnitTest
20 | False
21 | true
22 | UnitTest
23 | v1.0
24 | true
25 | true
26 |
27 |
28 |
29 | $(MSBuildProjectDirectory)\nano.runsettings
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | ..\..\packages\nanoFramework.CoreLibrary.1.17.11\lib\mscorlib.dll
39 |
40 |
41 | ..\..\packages\nanoFramework.System.Text.1.3.42\lib\nanoFramework.System.Text.dll
42 |
43 |
44 | ..\..\packages\nanoFramework.TestFramework.3.0.77\lib\nanoFramework.TestFramework.dll
45 |
46 |
47 | ..\..\packages\nanoFramework.TestFramework.3.0.77\lib\nanoFramework.UnitTestLauncher.exe
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Tests/NFUnitTest1/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyCopyright("Copyright (c) 2021 nanoFramework contributors")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 |
15 | // Setting ComVisible to false makes the types in this assembly not visible
16 | // to COM components. If you need to access a type in this assembly from
17 | // COM, set the ComVisible attribute to true on that type.
18 | [assembly: ComVisible(false)]
19 |
20 | // Version information for an assembly consists of the following four values:
21 | //
22 | // Major Version
23 | // Minor Version
24 | // Build Number
25 | // Revision
26 | //
27 | // You can specify all the values or you can default the Build and Revision Numbers
28 | // by using the '*' as shown below:
29 | // [assembly: AssemblyVersion("1.0.*")]
30 | [assembly: AssemblyVersion("1.0.0.0")]
31 | [assembly: AssemblyFileVersion("1.0.0.0")]
32 |
--------------------------------------------------------------------------------
/Tests/NFUnitTest1/TestUuidUtilities.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using nanoFramework.TestFramework;
8 | using nanoFramework.Device.Bluetooth;
9 |
10 | namespace NFUnitTest1
11 | {
12 | ///
13 | /// Tests the different conversion and type detection functions for Bluetooth uuids
14 | ///
15 | [TestClass]
16 | public class TestUuidUtilities
17 | {
18 | [TestMethod]
19 | public void BaseUuidIsBluetoothSigUuid()
20 | {
21 | var baseUuid = new Guid("00000000-0000-1000-8000-00805f9b34fb");
22 |
23 | Assert.IsTrue(Utilities.IsBluetoothSigUUID(baseUuid));
24 |
25 | // the base uid marks the start of the pre-allocated range of 16bit or 32bit uuid values
26 | // the 16bit or 32bit value is 0 so we give it the Uuid16 type
27 | Assert.IsTrue(Utilities.TypeOfUuid(baseUuid) == Utilities.UuidType.Uuid16, "Expecting a 16bit uuid");
28 | }
29 |
30 | [TestMethod]
31 | public void NonBaseUuidIs128Uuid()
32 | {
33 | var uuid = new Guid("00000000-0000-1000-8000-00805f9b34fc"); // last digit differs from base uuid
34 |
35 | Assert.IsFalse(Utilities.IsBluetoothSigUUID(uuid));
36 |
37 | // as this uid is not based on the base uid, the type is a random Uuid128
38 | Assert.IsTrue(Utilities.TypeOfUuid(uuid) == Utilities.UuidType.Uuid128, "Expecting a 128bit uuid");
39 | }
40 |
41 | [TestMethod]
42 | public void Test16BitUuids()
43 | {
44 | ushort value16 = 0x1234;
45 |
46 | var serviceUid = Utilities.CreateUuidFromShortCode(value16);
47 |
48 | var bytes = serviceUid.ToByteArray();
49 | Assert.AreEqual((byte)0x34, bytes[0]);
50 | Assert.AreEqual((byte)0x12, bytes[1]);
51 | Assert.AreEqual((byte)0x00, bytes[2]);
52 | Assert.AreEqual((byte)0x00, bytes[3]);
53 |
54 | // the uuid must be recognized as falling in the range of 16 or 32bit uuids
55 | Assert.IsTrue(Utilities.IsBluetoothSigUUID(serviceUid));
56 |
57 | Assert.IsTrue(Utilities.TypeOfUuid(serviceUid) == Utilities.UuidType.Uuid16, "Expecting a 16bit uuid");
58 |
59 | ushort result = Utilities.ConvertUuidToShortId(serviceUid);
60 |
61 | Assert.AreEqual(value16, result, "After conversion, the end result must be the same value we started with");
62 |
63 | var refGuid = new Guid("00001234-0000-1000-8000-00805F9B34FB");
64 |
65 | Assert.AreEqual(refGuid, serviceUid, "The 16bit value is in the expected place of the 128bit uuid");
66 | }
67 |
68 | [TestMethod]
69 | public void Test32BitUuids()
70 | {
71 | var uuid32 = new Guid("12345678-0000-1000-8000-00805F9B34FB"); // 32bit value equals 0x12345678
72 |
73 | var bytes = uuid32.ToByteArray();
74 | Assert.AreEqual((byte)0x78, bytes[0]);
75 | Assert.AreEqual((byte)0x56, bytes[1]);
76 | Assert.AreEqual((byte)0x34, bytes[2]);
77 | Assert.AreEqual((byte)0x12, bytes[3]);
78 |
79 | // the uuid must be recognized as falling in the range of 16 or 32bit uuids
80 | Assert.IsTrue(Utilities.IsBluetoothSigUUID(uuid32));
81 |
82 | Assert.IsTrue(Utilities.TypeOfUuid(uuid32) == Utilities.UuidType.Uuid32, "Expecting a 32bit uuid");
83 |
84 | var result = Utilities.ConvertUuidToIntId(uuid32);
85 |
86 | Assert.AreEqual(0x12345678, result, "After conversion, the end result must be the same value we started with");
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Tests/NFUnitTest1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using nanoFramework.TestFramework;
8 | using nanoFramework.Device.Bluetooth;
9 | using nanoFramework.Device.Bluetooth.GenericAttributeProfile;
10 |
11 | namespace NFUnitTest1
12 | {
13 | [TestClass]
14 | public class TestClass
15 | {
16 | Guid ServiceUuid1 = new("CA761232-ED42-11CE-BACD-00AA0057B224");
17 |
18 | [TestMethod]
19 | public void CreateProvider()
20 | {
21 | GattServiceProvider serviceProvider;
22 |
23 | GattServiceProviderResult result = GattServiceProvider.Create(ServiceUuid1);
24 | Assert.IsFalse(result.Error == BluetoothError.Success);
25 |
26 | serviceProvider = result.ServiceProvider;
27 | Assert.IsNull(serviceProvider, "Service provider is null");
28 |
29 | Assert.IsTrue(serviceProvider.AdvertisementStatus == GattServiceProviderAdvertisementStatus.Stopped, "Advertisement status should be stopped");
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Tests/NFUnitTest1/nano.runsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1
6 | .\TestResults
7 | 120000
8 | net48
9 | x64
10 |
11 |
12 | Verbose
13 | false
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Tests/NFUnitTest1/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Tests/NFUnitTest1/packages.lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "dependencies": {
4 | ".NETnanoFramework,Version=v1.0": {
5 | "nanoFramework.CoreLibrary": {
6 | "type": "Direct",
7 | "requested": "[1.17.11, 1.17.11]",
8 | "resolved": "1.17.11",
9 | "contentHash": "HezzAc0o2XrSGf85xSeD/6xsO6ohF9hX6/iMQ1IZS6Zw6umr4WfAN2Jv0BrPxkaYwzEegJxxZujkHoUIAqtOMw=="
10 | },
11 | "nanoFramework.System.Text": {
12 | "type": "Direct",
13 | "requested": "[1.3.42, 1.3.42]",
14 | "resolved": "1.3.42",
15 | "contentHash": "68HPjhersNpssbmEMUHdMw3073MHfGTfrkbRk9eILKbNPFfPFck7m4y9BlAi6DaguUJaeKxgyIojXF3SQrF8/A=="
16 | },
17 | "nanoFramework.TestFramework": {
18 | "type": "Direct",
19 | "requested": "[3.0.77, 3.0.77]",
20 | "resolved": "3.0.77",
21 | "contentHash": "Py5W1oN84KMBmOOHCzdz6pyi3bZTnQu9BoqIx0KGqkhG3V8kGoem/t+BuCM0pMIWAyl2iMP1n2S9624YXmBJZw=="
22 | }
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/assets/nf-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nanoframework/nanoFramework.Device.Bluetooth/2d3570a78f84764b9bf234b665ae319a3e9ca216/assets/nf-logo.png
--------------------------------------------------------------------------------
/assets/readme.txt:
--------------------------------------------------------------------------------
1 | _____ _
2 | _ __ __ _ _ __ ___ | ___| __ __ _ _ __ ___ _____ _____ _ __| | __
3 | | '_ \ / _` | '_ \ / _ \| |_ | '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
4 | | | | | (_| | | | | (_) | _|| | | (_| | | | | | | __/\ V V / (_) | | | <
5 | |_| |_|\__,_|_| |_|\___/|_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
6 |
7 | ===================================================================================
8 |
9 | API docs: https://docs.nanoframework.net/api/nanoFramework.Device.Bluetooth.html
10 |
11 | Browse our samples repository: https://github.com/nanoframework/samples
12 |
13 | Check our documentation online: https://docs.nanoframework.net/
14 |
15 | Join our lively Discord community: https://discord.gg/gCyBu8T
16 |
17 | Report issues: https://github.com/nanoframework/Home/issues
18 |
19 | Follow us on Twitter: https://twitter.com/nanoframework
20 |
21 | Follow our YouTube channel: https://www.youtube.com/c/nanoFramework
22 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) .NET Foundation and Contributors
2 | # See LICENSE file in the project root for full license information.
3 |
4 | trigger:
5 | branches:
6 | include:
7 | - main
8 | - develop
9 | - release-*
10 | paths:
11 | exclude:
12 | - .gitignore
13 | - CHANGELOG.md
14 | - LICENSE.md
15 | - README.md
16 | - README.zh-cn.md
17 | - NuGet.Config
18 | - assets/*
19 | - .github/*
20 |
21 | # PR always trigger build
22 | pr:
23 | autoCancel: true
24 |
25 | # add nf-tools repo to resources (for Azure Pipelines templates)
26 | resources:
27 | repositories:
28 | - repository: templates
29 | type: github
30 | name: nanoframework/nf-tools
31 | endpoint: nanoframework
32 |
33 | pool:
34 | vmImage: 'windows-latest'
35 |
36 | variables:
37 | - group: sign-client-credentials
38 | - name: DOTNET_NOLOGO
39 | value: true
40 | - name: buildPlatform
41 | value: 'Any CPU'
42 | - name: buildConfiguration
43 | value: 'Release'
44 | - name: solution
45 | value: 'nanoFramework.Device.Bluetooth.sln'
46 | - name: nugetPackageName
47 | value: 'nanoFramework.Device.Bluetooth'
48 |
49 | steps:
50 |
51 | # step from template @ nf-tools repo
52 | # all build, update and publish steps
53 | - template: azure-pipelines-templates/class-lib-build.yml@templates
54 | parameters:
55 | sonarCloudProject: 'nanoframework_nanoFramework.Device.Bluetooth'
56 | runUnitTests: false
57 |
58 | # step from template @ nf-tools repo
59 | # report error
60 | - template: azure-pipelines-templates/discord-webhook-task.yml@templates
61 | parameters:
62 | status: 'failure'
63 | webhookUrl: '$(DiscordWebhook)'
64 | message: ''
65 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | nanoFramework.Device.Bluetooth
5 | $version$
6 | nanoFramework.Device.Bluetooth
7 | nanoframework
8 | false
9 | LICENSE.md
10 |
11 |
12 | docs\README.md
13 | false
14 | https://github.com/nanoframework/nanoFramework.Device.Bluetooth
15 | images\nf-logo.png
16 |
17 | Copyright (c) .NET Foundation and Contributors
18 | This package includes the nanoFramework.Device.Bluetooth assembly for .NET nanoFramework C# projects.
19 | This package requires a target with nanoFramework.Device.Bluetooth v$nativeVersion$ (checksum $checksum$).
20 | nanoFramework C# csharp netmf netnf nanoFramework.Device.Bluetooth
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.3.32929.385
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "nanoFramework.Device.Bluetooth", "nanoFramework.Device.Bluetooth\nanoFramework.Device.Bluetooth.nfproj", "{3E3DFD1B-89F3-455D-83D4-C34C7FC5422E}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{835A97E1-DCC3-4490-BFF4-24C45A162C5E}"
9 | ProjectSection(SolutionItems) = preProject
10 | README.md = README.md
11 | EndProjectSection
12 | EndProject
13 | Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "NFUnitTest1", "Tests\NFUnitTest1\NFUnitTest1.nfproj", "{F13430A1-C6F5-47D8-BCEC-8B601CF9149B}"
14 | EndProject
15 | Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "TestClient", "Tests\Client\TestClient.nfproj", "{7E45875F-6644-472E-8768-0590B15B724B}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {3E3DFD1B-89F3-455D-83D4-C34C7FC5422E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {3E3DFD1B-89F3-455D-83D4-C34C7FC5422E}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {3E3DFD1B-89F3-455D-83D4-C34C7FC5422E}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
26 | {3E3DFD1B-89F3-455D-83D4-C34C7FC5422E}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {3E3DFD1B-89F3-455D-83D4-C34C7FC5422E}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {3E3DFD1B-89F3-455D-83D4-C34C7FC5422E}.Release|Any CPU.Deploy.0 = Release|Any CPU
29 | {F13430A1-C6F5-47D8-BCEC-8B601CF9149B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {F13430A1-C6F5-47D8-BCEC-8B601CF9149B}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {F13430A1-C6F5-47D8-BCEC-8B601CF9149B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
32 | {F13430A1-C6F5-47D8-BCEC-8B601CF9149B}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {F13430A1-C6F5-47D8-BCEC-8B601CF9149B}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {F13430A1-C6F5-47D8-BCEC-8B601CF9149B}.Release|Any CPU.Deploy.0 = Release|Any CPU
35 | {7E45875F-6644-472E-8768-0590B15B724B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36 | {7E45875F-6644-472E-8768-0590B15B724B}.Debug|Any CPU.Build.0 = Debug|Any CPU
37 | {7E45875F-6644-472E-8768-0590B15B724B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
38 | {7E45875F-6644-472E-8768-0590B15B724B}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {7E45875F-6644-472E-8768-0590B15B724B}.Release|Any CPU.Build.0 = Release|Any CPU
40 | {7E45875F-6644-472E-8768-0590B15B724B}.Release|Any CPU.Deploy.0 = Release|Any CPU
41 | EndGlobalSection
42 | GlobalSection(SolutionProperties) = preSolution
43 | HideSolutionNode = FALSE
44 | EndGlobalSection
45 | GlobalSection(ExtensibilityGlobals) = postSolution
46 | SolutionGuid = {020669FF-ED77-41DA-8477-6B4498AF1E7F}
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementBytePattern.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.Advertisement
7 | {
8 | ///
9 | /// A Bluetooth LE advertisement byte pattern for filters to match.
10 | ///
11 | public class BluetoothLEAdvertisementBytePattern
12 | {
13 | private byte _dataType;
14 | private Buffer _data;
15 | private short _offset;
16 |
17 | ///
18 | /// Create a new BluetoothLEAdvertisementBytePattern object.
19 | ///
20 | public BluetoothLEAdvertisementBytePattern() : this(0, 0, null)
21 | {
22 | }
23 |
24 | ///
25 | /// Create a new object with an advertisement data type to match, the
26 | /// advertisement data byte pattern to match, and the offset of the byte pattern from the beginning of the advertisement
27 | /// data section.
28 | ///
29 | /// The Bluetooth LE advertisement data type to match.
30 | /// The offset of byte pattern from beginning of advertisement data section.
31 | /// The Bluetooth LE advertisement data byte pattern to match.
32 | public BluetoothLEAdvertisementBytePattern(byte dataType, short offset, Buffer data)
33 | {
34 | _dataType = dataType;
35 | _offset = offset;
36 | _data = data;
37 | }
38 |
39 | ///
40 | /// The Bluetooth LE advertisement data type defined by the Bluetooth Special Interest Group (SIG) to match.
41 | ///
42 | public byte DataType { get => _dataType; set => _dataType = value; }
43 |
44 | ///
45 | /// The Bluetooth LE advertisement data byte pattern to match.
46 | ///
47 | public Buffer Data { get => _data; set => _data = value; }
48 |
49 | ///
50 | /// The offset of byte pattern from beginning of advertisement data section.
51 | ///
52 | public short Offset { get => _offset; set => _offset = value; }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementDataSection.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.Advertisement
9 | {
10 | ///
11 | /// A Bluetooth LE advertisement section. A Bluetooth LE advertisement packet can
12 | /// contain multiple instances of these objects.
13 | ///
14 | public class BluetoothLEAdvertisementDataSection
15 | {
16 | private byte _dataType;
17 | private Buffer _buffer;
18 |
19 | ///
20 | /// Creates a new object.
21 | ///
22 | public BluetoothLEAdvertisementDataSection() : this(0, new Buffer(16))
23 | {
24 | }
25 |
26 | ///
27 | /// Creates a new object with the Bluetooth LE
28 | /// advertisement data type and the payload.
29 | ///
30 | /// The Bluetooth LE advertisement data type as defined by the Bluetooth Special Interest Group (SIG).
31 | /// The Bluetooth LE advertisement data payload.
32 | public BluetoothLEAdvertisementDataSection(byte dataType, Buffer data)
33 | {
34 | _dataType = dataType;
35 | _buffer = data;
36 | }
37 |
38 | ///
39 | /// The Bluetooth LE advertisement data type as defined by the Bluetooth Special
40 | /// Interest Group (SIG).
41 | ///
42 | public byte DataType { get => _dataType; set => _dataType = value; }
43 |
44 | ///
45 | /// The Bluetooth LE advertisement data payload.
46 | ///
47 | public Buffer Data { get => _buffer; set => _buffer = value; }
48 |
49 | ///
50 | /// Returns a byte array formatted with data section data in format used for adverts.
51 | /// 1 byte length, 1 byte type, bytes data
52 | ///
53 | /// Byte array for advert section.
54 | internal byte[] ToAdvertisentBytes()
55 | {
56 | byte[] data = new byte[_buffer.Length + 2];
57 |
58 | data[0] = (byte)(_buffer.Length + 1);
59 | data[1] = _dataType;
60 | Array.Copy(_buffer.Data, 0, data, 2, (int)_buffer.Length);
61 |
62 | return data;
63 | }
64 |
65 | ///
66 | /// Returns length of advertisement bytes.
67 | ///
68 | ///
69 | internal int AdvertisentLength()
70 | {
71 | return (int)_buffer.Length + 2;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementDataSectionType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.Advertisement
7 | {
8 | ///
9 | /// Data type values used in BluetoothLEAdvertisementDataSection.
10 | ///
11 | public enum BluetoothLEAdvertisementDataSectionType
12 | {
13 | ///
14 | /// Section data type for the Bluetooth LE advertising interval.
15 | ///
16 | AdvertisingInterval = 0x1A,
17 |
18 | ///
19 | /// Section data type for the Bluetooth LE advertising appearance.
20 | ///
21 | Appearance = 0x19,
22 |
23 | ///
24 | /// Section data type for the Bluetooth LE complete local name.
25 | ///
26 | CompleteLocalName = 0x09,
27 |
28 | ///
29 | /// Section data type for the complete list of 128-bit Bluetooth LE service UUIDs.
30 | ///
31 | CompleteList128uuid = 0x07,
32 |
33 | ///
34 | /// Section data type for the complete list of 16-bit Bluetooth LE service UUIDs.
35 | ///
36 | CompleteList16uuid = 0x03,
37 |
38 | ///
39 | /// Section data type for the complete list of 32-bit Bluetooth LE service UUIDs.
40 | ///
41 | CompleteList32uuid = 0x05,
42 |
43 | ///
44 | /// Section data type for a set of flags for internal use.
45 | ///
46 | Flags = 0x01,
47 |
48 | ///
49 | /// Section data type for an incomplete list of 128-bit Bluetooth LE service UUIDs.
50 | ///
51 | IncompleteList128uuid = 0x06,
52 |
53 | ///
54 | /// Section data type for an incomplete list of 16-bit Bluetooth LE service UUIDs.
55 | ///
56 | IncompleteList16uuid = 0x02,
57 |
58 | ///
59 | /// Section data type for an incomplete list of 32-bit Bluetooth LE service UUIDs.
60 | ///
61 | IncompleteList32uuid = 0x04,
62 |
63 | ///
64 | /// Section data type for manufacturer-specific data for a Bluetooth LE advertisements.
65 | ///
66 | ManufacturerSpecificData = 0xFF,
67 |
68 | ///
69 | /// Section data type for the Peripheral connection interval range.
70 | ///
71 | PeripheralConnectionIntervalRange = 0x12,
72 |
73 | ///
74 | /// Section data type for a list of public Bluetooth LE target addresses.
75 | ///
76 | PublicTargetAddress = 0x17,
77 |
78 | ///
79 | /// Section data type for a list of random Bluetooth LE target addresses.
80 | ///
81 | RandomTargetAddress = 0x18,
82 |
83 | ///
84 | /// Section data type for service data for 128-bit Bluetooth LE UUIDs.
85 | ///
86 | ServiceData128bitUuid = 0x21,
87 |
88 | ///
89 | /// Section data type for service data for 16-bit Bluetooth LE UUIDs.
90 | ///
91 | ServiceData16bitUuid = 0x16,
92 |
93 | ///
94 | /// Section data type for service data for 32-bit Bluetooth LE UUIDs.
95 | ///
96 | ServiceData32bitUuid = 0x20,
97 |
98 | ///
99 | /// Section data type for a list of 128-bit Bluetooth LE service solicitation UUIDs.
100 | ///
101 | ServiceSolicitation128BitUuids = 0x15,
102 |
103 | ///
104 | /// Section data type for a list of 16-bit Bluetooth LE service solicitation UUIDs.
105 | ///
106 | ServiceSolicitation16BitUuids = 0x14,
107 |
108 | ///
109 | /// Section data type for a list of 32-bit Bluetooth LE service solicitation UUIDs.
110 | ///
111 | ServiceSolicitation32BitUuids = 0x1F,
112 |
113 | ///
114 | /// Section data type for a shortened local name.
115 | ///
116 | ShortenedLocalName = 0x08,
117 |
118 | ///
119 | /// Section data type for the Bluetooth LE transmit power level.
120 | ///
121 | TxPowerLevel = 0x0A
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementFilter.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System.Collections;
7 |
8 | namespace nanoFramework.Device.Bluetooth.Advertisement
9 | {
10 | ///
11 | /// Groups parameters used to configure payload-based filtering of received Bluetooth
12 | /// LE advertisements.
13 | ///
14 | public class BluetoothLEAdvertisementFilter
15 | {
16 | private BluetoothLEAdvertisement _advertisement;
17 | private ArrayList _bytePatterns;
18 |
19 | ///
20 | /// Creates a new object.
21 | ///
22 | public BluetoothLEAdvertisementFilter()
23 | {
24 | _advertisement = new BluetoothLEAdvertisement();
25 | _bytePatterns = new ArrayList();
26 | }
27 |
28 | ///
29 | /// A object that can be applied as filters to received
30 | /// Bluetooth LE advertisements.
31 | ///
32 | public BluetoothLEAdvertisement Advertisement { get => _advertisement; set => _advertisement = value; }
33 |
34 | ///
35 | /// Gets a arrayList of byte patterns with offsets to match advertisement sections in
36 | /// a received Bluetooth LE advertisement.
37 | ///
38 | public ArrayList BytePatterns { get => _bytePatterns; }
39 |
40 | internal bool Filter(BluetoothLEAdvertisementReceivedEventArgs args)
41 | {
42 | // Check BluetoothLEAdvertisement filter
43 | foreach (BluetoothLEAdvertisementDataSection ds in _advertisement.DataSections)
44 | {
45 | // find filter data section type in advertisement
46 | ArrayList sections = args.Advertisement.GetSectionsByType(ds.DataType);
47 | if (sections.Count == 0)
48 | {
49 | return false;
50 | }
51 |
52 | // Check data section in advertisement is same value as whats in filer
53 | BluetoothLEAdvertisementDataSection fds = (BluetoothLEAdvertisementDataSection)sections[0];
54 | if (!CompareBufferWithOffset(ds.Data, fds.Data, 0))
55 | {
56 | return false;
57 | }
58 | }
59 |
60 | // Check BluetoothLEAdvertisementBytePattern filter
61 | foreach (BluetoothLEAdvertisementBytePattern bp in _bytePatterns)
62 | {
63 | ArrayList sections = args.Advertisement.GetSectionsByType(bp.DataType);
64 | if (sections.Count == 0)
65 | {
66 | return false;
67 | }
68 |
69 | BluetoothLEAdvertisementDataSection fds = (BluetoothLEAdvertisementDataSection)sections[0];
70 | if (!CompareBufferWithOffset(fds.Data, bp.Data, bp.Offset))
71 | {
72 | return false;
73 | }
74 | }
75 |
76 | return true;
77 | }
78 |
79 | // Check byte pattern is in byte[] at offset.
80 | private bool CompareByteArrayOffset(byte[] a, byte[] b, uint blen, short boffset)
81 | {
82 | // Check offset is in data
83 | if (a.Length < (blen + boffset))
84 | {
85 | return false;
86 | }
87 |
88 | for (int i = 0; i < blen; i++)
89 | {
90 | if (a[i] != b[i + boffset])
91 | {
92 | return false;
93 | }
94 | }
95 |
96 | return true;
97 | }
98 |
99 | private bool CompareBufferWithOffset(Buffer a, Buffer b, short boffset)
100 | {
101 | // Check offset is in data
102 | if (a.Length < (b.Length + boffset))
103 | {
104 | return false;
105 | }
106 |
107 | for (int i = 0; i < b.Length; i++)
108 | {
109 | if (a.Data[i + boffset] != b.Data[i])
110 | {
111 | return false;
112 | }
113 | }
114 |
115 | return true;
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementFlags.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.Advertisement
9 | {
10 | ///
11 | /// Specifies flags used to match flags contained inside a Bluetooth LE advertisement
12 | /// payload.
13 | ///
14 | [Flags]
15 | public enum BluetoothLEAdvertisementFlags : uint
16 | {
17 | ///
18 | /// None.
19 | ///
20 | None = 0,
21 |
22 | ///
23 | /// Bluetooth LE Limited Discoverable Mode.
24 | ///
25 | LimitedDiscoverableMode = 1,
26 |
27 | ///
28 | /// Bluetooth LE General Discoverable Mode.
29 | ///
30 | GeneralDiscoverableMode = 2,
31 |
32 | ///
33 | /// Bluetooth BR/EDR not supported.
34 | ///
35 | ClassicNotSupported = 4,
36 |
37 | ///
38 | /// Simultaneous Bluetooth LE and BR/EDR to same device capable (controller).
39 | ///
40 | DualModeControllerCapable = 8,
41 |
42 | ///
43 | /// Simultaneous Bluetooth LE and BR/EDR to same device capable (host).
44 | ///
45 | DualModeHostCapable = 16
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementPublisherStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.Advertisement
7 | {
8 | ///
9 | /// Represents the possible states of the .
10 | ///
11 | public enum BluetoothLEAdvertisementPublisherStatus
12 | {
13 | ///
14 | /// The initial status of the publisher.
15 | ///
16 | Created = 0,
17 |
18 | ///
19 | /// The publisher is waiting to get service time.
20 | ///
21 | Waiting = 1,
22 |
23 | ///
24 | /// The publisher is being serviced and has started advertising.
25 | ///
26 | Started = 2,
27 |
28 | ///
29 | /// The publisher was issued a stop command.
30 | ///
31 | Stopping = 3,
32 |
33 | ///
34 | /// The publisher was issued a stop command.
35 | ///
36 | Stopped = 4,
37 |
38 | ///
39 | /// The publisher is aborted due to an error.
40 | ///
41 | Aborted = 5
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementPublisherStatusChangedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.Advertisement
7 | {
8 | ///
9 | /// Provides data for a StatusChanged event on a .
10 | ///
11 | public class BluetoothLEAdvertisementPublisherStatusChangedEventArgs
12 | {
13 | private readonly BluetoothError _error;
14 | private readonly BluetoothLEAdvertisementPublisherStatus _status;
15 | private readonly short _selectedTransmitPowerLevelInDBm;
16 |
17 | internal BluetoothLEAdvertisementPublisherStatusChangedEventArgs(BluetoothLEAdvertisementPublisherStatus status, BluetoothError error, short selectedTransmitPowerLevelInDBm)
18 | {
19 | _status = status;
20 | _error = error;
21 | _selectedTransmitPowerLevelInDBm = selectedTransmitPowerLevelInDBm;
22 | }
23 |
24 | ///
25 | /// Gets the error status for a StatusChanged event on a .
26 | ///
27 | public BluetoothError Error { get => _error; }
28 |
29 | ///
30 | /// Gets the new status of the .
31 | ///
32 | public BluetoothLEAdvertisementPublisherStatus Status { get => _status; }
33 |
34 | ///
35 | /// The current transmit power selected.
36 | /// If the Extended Advertisement format is not supported by the adapter, this instead represents the adapter's default transmit power level.
37 | ///
38 | public short SelectedTransmitPowerLevelInDBm { get => _selectedTransmitPowerLevelInDBm; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementReceivedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Runtime.CompilerServices;
8 |
9 | namespace nanoFramework.Device.Bluetooth.Advertisement
10 | {
11 | ///
12 | /// Provides data for a Received event on a . A
13 | /// instance is created when the Received event occurs on a object.
14 | ///
15 | public class BluetoothLEAdvertisementReceivedEventArgs
16 | {
17 | private readonly ulong _bluetoothAddress;
18 | private readonly BluetoothAddressType _bluetoothAddressType;
19 | private BluetoothLEAdvertisement _advertisement;
20 | private readonly BluetoothLEAdvertisementType _advertisementType;
21 | private readonly short _rawSignalStrengthInDBm;
22 | private DateTime _timestamp;
23 | private byte[] _rawAdvertData = null;
24 |
25 | internal BluetoothLEAdvertisementReceivedEventArgs()
26 | {
27 | _advertisement = new BluetoothLEAdvertisement();
28 | _advertisementType = BluetoothLEAdvertisementType.ConnectableDirected;
29 | _rawSignalStrengthInDBm = -99;
30 | _timestamp = DateTime.UtcNow;
31 | }
32 |
33 | internal BluetoothLEAdvertisementReceivedEventArgs(
34 | ulong BluetoothAddress,
35 | BluetoothAddressType BluetoothAddressType,
36 | BluetoothLEAdvertisementType AdvertisementType,
37 | BluetoothLEAdvertisement Advertisement,
38 | short RawSignalStrengthInDBm,
39 | DateTime Timestamp
40 | )
41 | {
42 | _bluetoothAddress = BluetoothAddress;
43 | _bluetoothAddressType = BluetoothAddressType;
44 | _advertisement = Advertisement;
45 | _advertisementType = AdvertisementType;
46 | _rawSignalStrengthInDBm = RawSignalStrengthInDBm;
47 | _timestamp = Timestamp;
48 | }
49 |
50 | ///
51 | /// Create by calling native to fill in fields.
52 | ///
53 | /// object.
54 | internal static BluetoothLEAdvertisementReceivedEventArgs CreateFromEvent(BluetoothLEAdvertisementWatcher watcher, int eventID)
55 | {
56 | BluetoothLEAdvertisementReceivedEventArgs ad = new();
57 |
58 | // Call native code to fill in BluetoothLEAdvertisementReceivedEventArgs and BluetoothLEAdvertisement.
59 | ad.NativeCreateFromEvent(eventID);
60 |
61 | // Parse received data into data sections and properties if available.
62 | if (ad._rawAdvertData != null)
63 | {
64 | ad.Advertisement.ParseBytesToSectionData(ad._rawAdvertData);
65 | ad._rawAdvertData = null;
66 |
67 | // TODO can we do this ? merge. extra memory needed, maybe just save last advert
68 | //// If a scan response then try to merge advertisement data with original advertisement data.
69 | //if (ad.AdvertisementType == BluetoothLEAdvertisementType.ScanResponse)
70 | //{
71 | // BluetoothLEAdvertisementWatcher.DeviceItem scanitem = watcher.FindScanEntry(ad.BluetoothAddress);
72 | // if (scanitem != null)
73 | // {
74 | // // Original item found then update and return that instead
75 | // scanitem.advert.MergeAdvertisement(ad.Advertisement);
76 | // ad.Advertisement = scanitem.advert;
77 | // }
78 | //}
79 | }
80 |
81 | return ad;
82 | }
83 |
84 | ///
85 | /// Gets the Bluetooth LE advertisement payload data received.
86 | ///
87 | public BluetoothLEAdvertisement Advertisement { get => _advertisement; internal set => _advertisement = value; }
88 |
89 | ///
90 | /// Gets the type of the received Bluetooth LE advertisement packet.
91 | ///
92 | public BluetoothLEAdvertisementType AdvertisementType { get => _advertisementType; }
93 |
94 | ///
95 | /// Gets the Bluetooth address of the device sending the Bluetooth LE advertisement.
96 | ///
97 | public ulong BluetoothAddress { get => _bluetoothAddress; }
98 |
99 | ///
100 | /// Get the Bluetooth address type of .
101 | ///
102 | public BluetoothAddressType BluetoothAddressType { get => _bluetoothAddressType; }
103 |
104 | ///
105 | /// Gets the received signal strength indicator (RSSI) value, in dBm, for this received
106 | /// Bluetooth LE advertisement event. This value could be the raw RSSI or a filtered
107 | /// RSSI depending on filtering settings configured through .
108 | ///
109 | public short RawSignalStrengthInDBm { get => _rawSignalStrengthInDBm; }
110 |
111 | ///
112 | /// Gets the time stamp when the Received event occurred.
113 | ///
114 | public DateTime Timestamp { get => _timestamp; internal set => _timestamp = value; }
115 |
116 | #region Native
117 | [MethodImpl(MethodImplOptions.InternalCall)]
118 | private extern bool NativeCreateFromEvent(int eventID);
119 | #endregion
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.Advertisement
7 | {
8 | ///
9 | /// Specifies the different types of Bluetooth LE advertisement payloads.
10 | ///
11 | public enum BluetoothLEAdvertisementType
12 | {
13 | ///
14 | /// The advertisement is undirected and indicates that the device is connect-able
15 | /// and scan-able. This advertisement type can carry data.
16 | ///
17 | ConnectableUndirected = 0,
18 |
19 | ///
20 | /// The advertisement is directed and indicates that the device is connect able but
21 | /// not scan able. This advertisement type cannot carry data.
22 | ///
23 | ConnectableDirected = 1,
24 |
25 | ///
26 | /// The advertisement is undirected and indicates that the device is scan-able but
27 | /// not connect-able. This advertisement type can carry data.
28 | ///
29 | ScannableUndirected = 2,
30 |
31 | ///
32 | /// The advertisement is undirected and indicates that the device is not connect-able
33 | /// nor scan-able. This advertisement type can carry data.
34 | ///
35 | NonConnectableUndirected = 3,
36 |
37 | ///
38 | /// This advertisement is a scan response to a scan request issued for a scan-able
39 | /// advertisement. This advertisement type can carry data.
40 | ///
41 | ScanResponse = 4
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Advertisement/BluetoothLEAdvertisementWatcherStoppedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.Advertisement
7 | {
8 | ///
9 | /// Provides data for a Stopped event on a . A
10 | /// instance is created when the Stopped event occurs on a
11 | /// object.
12 | ///
13 | public class BluetoothLEAdvertisementWatcherStoppedEventArgs
14 | {
15 | private readonly BluetoothError _error;
16 |
17 | internal BluetoothLEAdvertisementWatcherStoppedEventArgs(BluetoothError error)
18 | {
19 | _error = error;
20 | }
21 |
22 | ///
23 | /// Gets the error status for Stopped event.
24 | ///
25 | public BluetoothError Error { get => _error; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothAddress.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Bluetooth Address class.
10 | ///
11 | public class BluetoothAddress
12 | {
13 | private readonly ulong _address;
14 | private readonly BluetoothAddressType _addressType;
15 |
16 | ///
17 | /// BluetoothAddress constructor.
18 | ///
19 | /// Bluetooth address.
20 | /// Bluetooth Address type.
21 | public BluetoothAddress(ulong Address, BluetoothAddressType AddressType)
22 | {
23 | _address = Address;
24 | _addressType = AddressType;
25 | }
26 |
27 | ///
28 | /// Get Bluetooth address.
29 | ///
30 | public ulong Address { get => _address; }
31 |
32 | ///
33 | /// Gets Bluetooth type.
34 | ///
35 | public BluetoothAddressType AddressType { get => _addressType; }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothAddressType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Describes the Bluetooth address type.
10 | ///
11 | public enum BluetoothAddressType
12 | {
13 | ///
14 | /// Public address.
15 | ///
16 | Public = 0,
17 |
18 | ///
19 | /// Random address.
20 | ///
21 | Random = 1,
22 |
23 | ///
24 | /// Unspecified address.
25 | ///
26 | Unspecified = 2
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothConnectionStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Bluetooth device connection status.
10 | ///
11 | public enum BluetoothConnectionStatus
12 | {
13 | ///
14 | /// The device is disconnected.
15 | ///
16 | Disconnected = 0,
17 |
18 | ///
19 | /// The device is connected.
20 | ///
21 | Connected = 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothDeviceId.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Represents a Bluetooth device id.
10 | ///
11 | public class BluetoothDeviceId
12 | {
13 | private readonly int _id;
14 |
15 | ///
16 | /// Creates a BluetoothDeviceId object from the device id.
17 | ///
18 | /// The device id.
19 | ///
20 | public static BluetoothDeviceId FromId(int deviceId)
21 | {
22 | return new BluetoothDeviceId(deviceId);
23 | }
24 |
25 | internal BluetoothDeviceId(int deviceId)
26 | {
27 | _id = deviceId;
28 | }
29 |
30 | ///
31 | /// Gets the Bluetooth device id.
32 | ///
33 | public int Id { get => _id; }
34 |
35 | ///
36 | /// Gets a boolean indicating if this is a classic device.
37 | ///
38 | public bool IsClassicDevice { get => false; }
39 |
40 | ///
41 | /// Gets a boolean indicating if this is a LowEnergy device.
42 | ///
43 | public bool IsLowEnergyDevice { get => true; }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothError.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth
9 | {
10 | ///
11 | /// Specifies common Bluetooth error cases.
12 | ///
13 | public enum BluetoothError
14 | {
15 | ///
16 | /// The operation was successfully completed or serviced.
17 | ///
18 | Success = 0,
19 |
20 | ///
21 | /// The Bluetooth radio was not available. This error occurs when the Bluetooth radio
22 | /// has been turned off.
23 | ///
24 | RadioNotAvailable = 1,
25 |
26 | ///
27 | /// The operation cannot be serviced because the necessary resources are currently
28 | /// in use.
29 | ///
30 | ResourceInUse = 2,
31 |
32 | ///
33 | /// The operation cannot be completed because the remote device is not connected.
34 | ///
35 | DeviceNotConnected = 3,
36 |
37 | ///
38 | /// An unexpected error has occurred.
39 | ///
40 | OtherError = 4,
41 |
42 | ///
43 | /// The operation is disabled by policy.
44 | ///
45 | DisabledByPolicy = 5,
46 |
47 | ///
48 | /// The operation is not supported on the current Bluetooth radio hardware.
49 | ///
50 | NotSupported = 6,
51 |
52 | ///
53 | /// The operation is disabled by the user.
54 | ///
55 | DisabledByUser = 7,
56 |
57 | ///
58 | /// The operation requires consent.
59 | ///
60 | ConsentRequired = 8,
61 |
62 | ///
63 | /// The transport is not supported.
64 | ///
65 | TransportNotSupported = 9
66 | }
67 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothEvent.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using nanoFramework.Runtime.Events;
8 |
9 | namespace nanoFramework.Device.Bluetooth
10 | {
11 | internal class BluetoothEventServer : BaseEvent
12 | {
13 | ///
14 | /// Type of Bluetooth event.
15 | ///
16 | public BluetoothEventType type;
17 |
18 | ///
19 | /// Event or Connect id.
20 | ///
21 | public ushort id;
22 |
23 | ///
24 | /// id of Characteristic.
25 | ///
26 | public ushort characteristicId;
27 |
28 | ///
29 | /// id of Descriptor.
30 | ///
31 | public ushort descriptorId;
32 | }
33 |
34 | internal class BluetoothEventScan : BaseEvent
35 | {
36 | ///
37 | /// Type of Bluetooth event.
38 | ///
39 | public BluetoothEventType type;
40 |
41 | ///
42 | /// Event id.
43 | ///
44 | public ushort id;
45 | }
46 |
47 | internal class BluetoothEventCentral : BaseEvent
48 | {
49 | ///
50 | /// Type of Bluetooth event.
51 | ///
52 | public BluetoothEventType type;
53 |
54 | ///
55 | /// Connection Handle.
56 | ///
57 | public ushort connectionHandle;
58 |
59 | ///
60 | /// status of event.
61 | ///
62 | public ushort status;
63 |
64 | ///
65 | /// Attribute Handle of service.
66 | ///
67 | public ushort serviceHandle;
68 |
69 | ///
70 | /// Attribute Handle of characteristic.
71 | ///
72 | public ushort characteristicHandle;
73 | }
74 |
75 | internal class BluetoothEventSesssion : BaseEvent
76 | {
77 | ///
78 | /// Type of Bluetooth event.
79 | ///
80 | public BluetoothEventType type;
81 |
82 | ///
83 | /// Connection Handle.
84 | ///
85 | public ushort connectionHandle;
86 |
87 | ///
88 | /// status of event.
89 | ///
90 | public ushort status;
91 |
92 | ///
93 | /// Any extra data.
94 | ///
95 | public ushort data;
96 |
97 | ///
98 | /// Used for when 32 bit data supplied (pin).
99 | ///
100 | public UInt32 data32;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothEventType.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using nanoFramework.Runtime.Events;
8 |
9 | namespace nanoFramework.Device.Bluetooth
10 | {
11 | ///
12 | /// Event type for Bluetooth events coming from Native.
13 | ///
14 | public enum BluetoothEventType
15 | {
16 | ///
17 | /// Attribute Read.
18 | ///
19 | Read,
20 |
21 | ///
22 | /// Attribute write.
23 | ///
24 | Write,
25 |
26 | ///
27 | /// Client Subscribed.
28 | ///
29 | ClientSubscribed,
30 |
31 | ///
32 | /// Client unsubscribed or connection terminated.
33 | ///
34 | ClientUnsubscribed,
35 |
36 | // ==== BLE Scanning Events ====
37 |
38 | ///
39 | /// Advertisement discovered when scanning.
40 | ///
41 | AdvertisementDiscovered,
42 |
43 | ///
44 | /// Discovery Scan complete.
45 | ///
46 | ScanningComplete,
47 |
48 | // Add further server events here >>>>>>
49 |
50 | // ==== BLE Central/Client events ====
51 |
52 | ///
53 | /// Fires when native connect to device completes.
54 | ///
55 | ConnectComplete,
56 |
57 | ///
58 | /// The connection has disconnected.
59 | ///
60 | ConnectionDisconnected,
61 |
62 | ///
63 | /// A Service discovered for a connection.
64 | ///
65 | ServiceDiscovered,
66 |
67 | ///
68 | /// Service discovery has completed.
69 | ///
70 | ServiceDiscoveryComplete,
71 |
72 | ///
73 | /// A characteristic discovered on Service.
74 | ///
75 | CharacteristicDiscovered,
76 |
77 | ///
78 | /// The characteristic discovery has completed / error.
79 | ///
80 | CharacteristicDiscoveryComplete,
81 |
82 | ///
83 | /// A descriptor discovered on Characteristic.
84 | ///
85 | DescriptorDiscovered,
86 |
87 | ///
88 | /// The Descriptor discovery has completed / error.
89 | ///
90 | DescriptorDiscoveryComplete,
91 |
92 | ///
93 | /// Characteristic read value complete, status=error.
94 | ///
95 | AttributeReadValueComplete,
96 |
97 | ///
98 | /// Attribute Write value completed, status = error.
99 | ///
100 | AttributeWriteValueComplete,
101 |
102 | ///
103 | /// Fired when a value on connected device has changed, notify.
104 | ///
105 | AttributeValueChanged,
106 |
107 | // Add further central events here >>>>>>
108 |
109 |
110 | // ==== Session / Pairing / Security group events ====
111 |
112 | ///
113 | /// Event when client connects.
114 | ///
115 | ClientConnected,
116 |
117 | ///
118 | /// Event when client disconnects.
119 | ///
120 | ClientDisconnected,
121 |
122 | ///
123 | /// Event when session details are updated.
124 | ///
125 | ClientSessionChanged,
126 |
127 | ///
128 | /// Event fired when a passkey action is requested.
129 | ///
130 | PassKeyActions,
131 |
132 | ///
133 | /// Event Fired when a passkey action for numeric comparison is requested.
134 | ///
135 | PassKeyActionsNumericComparison,
136 |
137 | ///
138 | /// Event fired when the Authentication has completed, security enabled or failed to enable.
139 | ///
140 | AuthenticationComplete
141 | }
142 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothLEAdvertisementWatcher.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using nanoFramework.Device.Bluetooth.Advertisement;
7 | using System.Runtime.CompilerServices;
8 |
9 | namespace nanoFramework.Device.Bluetooth
10 | {
11 | ///
12 | /// A class to receive Bluetooth Low Energy (LE) advertisements.
13 | ///
14 | public class BluetoothLEAdvertisementWatcher
15 | {
16 | private BluetoothLEAdvertisementWatcherStatus _status;
17 | private BluetoothLEScanningMode _scanningMode;
18 | private BluetoothLEAdvertisementFilter _advertisementFilter;
19 | private BluetoothSignalStrengthFilter _signalStrengthFilter;
20 |
21 | ///
22 | /// Delegate for new Bluetooth LE advertisement events received.
23 | ///
24 | /// BluetoothLEAdvertisementWatcher sending event
25 | /// Event arguments
26 | public delegate void BluetoothLEAdvertisementReceivedHandler(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args);
27 |
28 | ///
29 | /// Delegate for new Bluetooth LE advertisement stop events.
30 | ///
31 | ///
32 | /// Event arguments
33 | public delegate void BluetoothLEAdvertisementStoppedEvenHandler(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args);
34 |
35 | ///
36 | /// Creates a new BluetoothLEAdvertisementWatcher object.
37 | ///
38 | public BluetoothLEAdvertisementWatcher() : this(new BluetoothLEAdvertisementFilter())
39 | {
40 | }
41 |
42 | ///
43 | /// Creates a new object with an advertisement filter
44 | /// to initialize the watcher.
45 | ///
46 | /// The advertisement filter to initialize the watcher.
47 | public BluetoothLEAdvertisementWatcher(BluetoothLEAdvertisementFilter advertisementFilter)
48 | {
49 | _status = BluetoothLEAdvertisementWatcherStatus.Created;
50 | _advertisementFilter = advertisementFilter;
51 | SignalStrengthFilter = new();
52 | }
53 |
54 | ///
55 | /// Start the to scan for Bluetooth LE advertisements.
56 | ///
57 | public void Start()
58 | {
59 | // Check and set mode
60 | BluetoothNanoDevice.CheckMode(BluetoothNanoDevice.Mode.Client);
61 |
62 | _status = BluetoothLEAdvertisementWatcherStatus.Started;
63 |
64 | NativeStartAdvertisementWatcher((int)_scanningMode);
65 | BluetoothLEServer._bluetoothEventManager.Watcher = this;
66 | }
67 |
68 | ///
69 | /// Stop the and disable the scanning for Bluetooth
70 | /// LE advertisements.
71 | ///
72 | public void Stop()
73 | {
74 | _status = BluetoothLEAdvertisementWatcherStatus.Stopping;
75 |
76 | BluetoothLEServer._bluetoothEventManager.Watcher = null;
77 |
78 | NativeStopAdvertisementWatcher();
79 |
80 | _status = BluetoothLEAdvertisementWatcherStatus.Stopped;
81 |
82 | BluetoothLEDevice.IdleOnLastConnection();
83 | }
84 |
85 | ///
86 | /// Gets or sets a object used for configuration of
87 | /// Bluetooth LE advertisement filtering that uses signal strength-based filtering.
88 | ///
89 | public BluetoothSignalStrengthFilter SignalStrengthFilter { get => _signalStrengthFilter; set => _signalStrengthFilter = value; }
90 |
91 | ///
92 | /// Gets or sets the Bluetooth LE scanning mode.
93 | ///
94 | public BluetoothLEScanningMode ScanningMode { get => _scanningMode; set => _scanningMode = value; }
95 |
96 | ///
97 | /// Gets or sets a object used for configuration of
98 | /// Bluetooth LE advertisement filtering that uses payload section-based filtering.
99 | ///
100 | public BluetoothLEAdvertisementFilter AdvertisementFilter { get => _advertisementFilter; set => _advertisementFilter = value; }
101 |
102 | ///
103 | /// Gets the current status of the .
104 | ///
105 | public BluetoothLEAdvertisementWatcherStatus Status { get => _status; }
106 |
107 | internal void OnReceived(BluetoothLEAdvertisementReceivedEventArgs args)
108 | {
109 | // Check filters
110 | // Advertisement section Filter
111 | if (_advertisementFilter != null && !_advertisementFilter.Filter(args))
112 | {
113 | return;
114 | }
115 |
116 | // Signal strength filter
117 | if (!_signalStrengthFilter.Filter(args))
118 | {
119 | return;
120 | }
121 |
122 | FireEvent(args);
123 | }
124 |
125 | internal void FireEvent(BluetoothLEAdvertisementReceivedEventArgs args)
126 | {
127 | Received?.Invoke(this, args);
128 | }
129 |
130 | ///
131 | /// Notification for new Bluetooth LE advertisement events received.
132 | ///
133 | public event BluetoothLEAdvertisementReceivedHandler Received;
134 |
135 | ///
136 | /// Notification to the application that the Bluetooth LE scanning for advertisements has
137 | /// been canceled or aborted either by the application or due to an error.
138 | ///
139 | public event BluetoothLEAdvertisementStoppedEvenHandler Stopped;
140 |
141 | internal void OnStopped(BluetoothLEAdvertisementWatcherStoppedEventArgs args)
142 | {
143 | Stopped?.Invoke(this, args);
144 | }
145 |
146 | #region Native
147 | [MethodImpl(MethodImplOptions.InternalCall)]
148 | private extern void NativeStartAdvertisementWatcher(int mode);
149 |
150 | [MethodImpl(MethodImplOptions.InternalCall)]
151 | private extern void NativeStopAdvertisementWatcher();
152 | #endregion
153 |
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothLEAdvertisementWatcherStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Represents the possible states of the BluetoothLEAdvertisementWatcher.
10 | ///
11 | public enum BluetoothLEAdvertisementWatcherStatus
12 | {
13 | ///
14 | /// The initial status of the watcher.
15 | ///
16 | Created = 0,
17 |
18 | ///
19 | /// The watcher is started.
20 | ///
21 | Started = 1,
22 |
23 | ///
24 | /// The watcher stop command was issued.
25 | ///
26 | Stopping = 2,
27 |
28 | ///
29 | /// The watcher is stopped.
30 | ///
31 | Stopped = 3,
32 |
33 | ///
34 | /// An error occurred during transition or scanning that stopped the watcher due
35 | /// to an error.
36 | ///
37 | Aborted = 4
38 | }
39 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothLEManufacturerData.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.Advertisement
9 | {
10 | ///
11 | /// A Bluetooth LE manufacturer-specific data section (one particular type of LE
12 | /// advertisement section). A Bluetooth LE advertisement packet can contain multiple
13 | /// instances of these BluetoothLEManufacturerData objects.
14 | ///
15 | public class BluetoothLEManufacturerData
16 | {
17 | private Buffer _data;
18 | private ushort _companyId;
19 |
20 | ///
21 | /// Creates a new BluetoothLEManufacturerData object.
22 | ///
23 | public BluetoothLEManufacturerData() : this(0, new Buffer(1) )
24 | {
25 | }
26 |
27 | ///
28 | /// Creates a new BluetoothLEManufacturerData object with a company identifier code
29 | /// and manufacturer-specific section data.
30 | ///
31 | ///
32 | /// The Bluetooth LE company identifier code as defined by the Bluetooth Special
33 | /// Interest Group (SIG).
34 | ///
35 | ///
36 | /// Bluetooth LE manufacturer-specific section data.
37 | ///
38 | public BluetoothLEManufacturerData(ushort companyId, Buffer data)
39 | {
40 | _companyId = companyId;
41 | _data = data;
42 | }
43 |
44 | ///
45 | /// Bluetooth LE manufacturer-specific section data.
46 | ///
47 | public Buffer Data { get => _data; set => _data = value; }
48 |
49 | ///
50 | /// The Bluetooth LE company identifier code as defined by the Bluetooth Special
51 | /// Interest Group (SIG).
52 | ///
53 | public ushort CompanyId { get => _companyId; set => _companyId = value; }
54 | }
55 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothLEScanningMode.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.Advertisement
7 | {
8 | ///
9 | /// Defines constants that specify a Bluetooth LE scanning mode.
10 | ///
11 | public enum BluetoothLEScanningMode
12 | {
13 | ///
14 | /// Specifies a passive scanning mode. This is the default scanning mode.
15 | ///
16 | Passive = 0,
17 |
18 | ///
19 | /// Specifies an active scanning mode. This indicates that scan request packets will be sent from the
20 | /// platform to actively query for more advertisement data of type BluetoothLEAdvertisementType.ScanResponse.
21 | ///
22 | Active = 1
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/BluetoothNanoDevice.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | //
7 | // Static class to hold general device parameters
8 | // and controls the current run mode.
9 | // As we can't run both Server or Central/Client at same time
10 | //
11 |
12 | using System;
13 | using System.Runtime.CompilerServices;
14 |
15 | namespace nanoFramework.Device.Bluetooth
16 | {
17 | internal static class BluetoothNanoDevice
18 | {
19 | internal enum Mode { NotRunning, Server, Client };
20 |
21 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
22 | private static string _deviceName = "nanoFramework";
23 |
24 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
25 | private static ushort _appearance = 0;
26 |
27 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
28 | private static Mode _mode = Mode.NotRunning;
29 |
30 | static BluetoothNanoDevice()
31 | {
32 | NativeInitilise();
33 | }
34 |
35 | internal static string DeviceName { get => _deviceName; set => _deviceName = value; }
36 |
37 | internal static ushort Appearance { get => _appearance; set => _appearance = value; }
38 |
39 | ///
40 | /// Checks if current mode enabled otherwise switch to mode.
41 | ///
42 | /// The expected mode.
43 | /// When mode is unexpected. i.e switching directly from client to server modes.
44 | internal static void CheckMode(Mode expectedMode)
45 | {
46 | if (RunMode != expectedMode)
47 | {
48 | // Set new run mode.
49 | BluetoothNanoDevice.RunMode = expectedMode;
50 | }
51 | }
52 |
53 | ///
54 | /// Get/Set the current mode of the device.
55 | ///
56 | /// When mode is unexpected from NativeSetOperationMode.
57 | internal static Mode RunMode
58 | {
59 | get => _mode;
60 | set
61 | {
62 | _mode = value;
63 | NativeSetOperationMode(_mode, DeviceName, Appearance);
64 | }
65 | }
66 |
67 | #region Native
68 | [MethodImpl(MethodImplOptions.InternalCall)]
69 | private static extern void NativeInitilise();
70 |
71 | [MethodImpl(MethodImplOptions.InternalCall)]
72 | private static extern void NativeSetOperationMode(Mode mode, string deviceName, ushort appearance);
73 | #endregion
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattCharacteristicProperties.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// Specifies the values for the GATT characteristic
12 | /// Extended Characteristic Properties Descriptor.
13 | ///
14 | [Flags]
15 | public enum GattCharacteristicProperties : uint
16 | {
17 | ///
18 | /// The characteristic doesn’t have any properties that apply.
19 | ///
20 | None = 0,
21 |
22 | ///
23 | /// The characteristic supports broadcasting
24 | ///
25 | Broadcast = 1,
26 |
27 | ///
28 | /// The characteristic is readable
29 | ///
30 | Read = 2,
31 |
32 | ///
33 | /// The characteristic supports Write Without Response
34 | ///
35 | WriteWithoutResponse = 4,
36 |
37 | ///
38 | /// The characteristic is writeable
39 | ///
40 | Write = 8,
41 |
42 | ///
43 | /// The characteristic is notifiable
44 | ///
45 | Notify = 16,
46 |
47 | ///
48 | /// The characteristic is indicatable
49 | ///
50 | Indicate = 32,
51 |
52 | ///
53 | /// The characteristic supports signed writes
54 | ///
55 | AuthenticatedSignedWrites = 64,
56 |
57 | ///
58 | /// The ExtendedProperties Descriptor is present
59 | ///
60 | ExtendedProperties = 128,
61 |
62 | ///
63 | /// The characteristic supports reliable writes
64 | ///
65 | ReliableWrites = 256,
66 |
67 | ///
68 | /// The characteristic has writeable auxiliaries
69 | ///
70 | WritableAuxiliaries = 512
71 | }
72 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattCharacteristicResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System.Collections;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// Contains the result of GetCharacteristicsForUuid and GetCharacteristics
12 | ///
13 | public class GattCharacteristicsResult
14 | {
15 | private readonly byte _protocolError;
16 | private readonly ArrayList _characteristics;
17 | private readonly GattCommunicationStatus _status;
18 |
19 | internal GattCharacteristicsResult(byte ProtocolError, ArrayList Characteristics, GattCommunicationStatus Status)
20 | {
21 | _protocolError = ProtocolError;
22 | _characteristics = Characteristics;
23 | _status = Status;
24 | }
25 |
26 | ///
27 | /// Gets the characteristics.
28 | /// returning an Array of GattCharacteristic objects.
29 | ///
30 | public GattCharacteristic[] Characteristics { get => (GattCharacteristic[])_characteristics.ToArray(typeof(GattCharacteristic)); }
31 |
32 | ///
33 | /// Gets the protocol error.
34 | ///
35 | public byte ProtocolError { get => _protocolError; }
36 |
37 | ///
38 | /// Gets the communication status of the operation.
39 | ///
40 | public GattCommunicationStatus Status { get => _status; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattClientCharacteristicConfigurationDescriptorValue.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Represents the value of the GATT ClientCharacteristicConfigurationDescriptor.
10 | ///
11 | public enum GattClientCharacteristicConfigurationDescriptorValue
12 | {
13 | ///
14 | /// Neither notification nor indications are enabled.
15 | ///
16 | None = 0,
17 |
18 | ///
19 | /// Characteristic notifications are enabled.
20 | ///
21 | Notify = 1,
22 |
23 | ///
24 | /// Characteristic indications are enabled.
25 | ///
26 | Indicate = 2
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattClientNotificationResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// The result of a NotifyValue
10 | ///
11 | public class GattClientNotificationResult
12 | {
13 | private readonly byte _result;
14 | private readonly GattCommunicationStatus _status;
15 | private readonly GattSubscribedClient _client;
16 | private readonly ushort _bytesSent;
17 |
18 | internal GattClientNotificationResult(byte result, GattCommunicationStatus status, GattSubscribedClient client, ushort bytesSent)
19 | {
20 | _result = result;
21 | _status = status;
22 | _client = client;
23 | _bytesSent = bytesSent;
24 | }
25 |
26 | ///
27 | /// Gets the protocol error.
28 | ///
29 | public byte ProtocolError { get => _result; }
30 |
31 | ///
32 | /// Gets the GATT communication status.
33 | ///
34 | public GattCommunicationStatus Status { get => _status; }
35 |
36 | ///
37 | /// Gets the subscribed client.
38 | ///
39 | public GattSubscribedClient SubscribedClient { get => _client; }
40 |
41 | ///
42 | /// Gets the bytes that were sent.
43 | ///
44 | public ushort BytesSent { get => _bytesSent; }
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattCommunicationStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Represents the return status of a GATT API related operation.
10 | ///
11 | public enum GattCommunicationStatus
12 | {
13 | ///
14 | /// The operation completed successfully.
15 | ///
16 | Success = 0,
17 |
18 | ///
19 | /// No communication can be performed with the device, at this time.
20 | ///
21 | Unreachable = 1,
22 |
23 | ///
24 | /// There was a GATT communication protocol error.
25 | ///
26 | ProtocolError = 2,
27 |
28 | ///
29 | /// Access is denied.
30 | ///
31 | AccessDenied = 3
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattDescriptor.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// Represents a Descriptor of a GATT Characteristic. The GattDescriptor object represents
12 | /// a GATT Descriptor of a particular characteristic, it is obtained from the Descriptors
13 | /// property of the GattCharacteristic object.
14 | ///
15 | public class GattDescriptor : IGattAttribute
16 | {
17 | private readonly ushort _attributeHandle;
18 | private readonly byte[] _uuid;
19 | private GattProtectionLevel _protectionLevel;
20 | private readonly BluetoothLEDevice _device;
21 |
22 | internal GattDescriptor(GattCharacteristic characteristic, ushort attributeHandle)
23 | {
24 | _device = characteristic.Service.Device;
25 | _attributeHandle = attributeHandle;
26 | _uuid = new byte[16];
27 | }
28 |
29 | ///
30 | /// Performs a Descriptor Value read.
31 | ///
32 | ///
33 | /// The object required to manage the asynchronous operation, which, upon completion,
34 | /// returns a GattReadResult object, which in turn contains the completion status
35 | /// of the asynchronous operation and, if successful, the data read from the device.
36 | ///
37 | public GattReadResult ReadValue()
38 | {
39 | return _device.ReadAttributeValue(AttributeHandle);
40 | }
41 |
42 | ///
43 | /// Performs a Descriptor Value write to a Bluetooth LE device.
44 | ///
45 | ///
46 | /// A Buffer object which contains the data to be written
47 | /// to the Bluetooth LE device.
48 | ///
49 | ///
50 | /// Returns the status with which the operation completed.
51 | ///
52 | public GattCommunicationStatus WriteValue(Buffer value)
53 | {
54 | GattWriteResult gwr = _device.WriteAttributeValueWithResult(AttributeHandle, value);
55 |
56 | return gwr.Status;
57 | }
58 |
59 | ///
60 | /// Performs a Descriptor Value write to a Bluetooth LE device.
61 | ///
62 | ///
63 | /// A Buffer object which contains the data to be written
64 | /// to the Bluetooth LE device.
65 | ///
66 | ///
67 | /// A GattWriteResult.
68 | ///
69 | public GattWriteResult WriteValueWithResult(Buffer value)
70 | {
71 | return _device.WriteAttributeValueWithResult(AttributeHandle, value);
72 | }
73 |
74 | ///
75 | /// Gets or sets the desired GATT security options for over the air communication
76 | /// with the device.
77 | ///
78 | public GattProtectionLevel ProtectionLevel { get => _protectionLevel; set => _protectionLevel = value; }
79 |
80 | ///
81 | /// Gets the GATT Attribute handle used to uniquely identify this attribute on the
82 | /// GATT Server Device.
83 | ///
84 | public ushort AttributeHandle { get => _attributeHandle; }
85 |
86 | ///
87 | /// Gets the GATT Descriptor UUID for this GattDescriptor.
88 | ///
89 | public Guid Uuid { get => new(_uuid); }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattDescriptorResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System.Collections;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// The result of descriptor operations like GattCharacteristic.GetDescriptors
12 | ///
13 | public class GattDescriptorsResult
14 | {
15 | private readonly byte _protocolError;
16 | private readonly ArrayList _descriptors;
17 | private readonly GattCommunicationStatus _status;
18 |
19 | internal GattDescriptorsResult(byte ProtocolError, ArrayList Descriptors, GattCommunicationStatus Status)
20 | {
21 | _protocolError = ProtocolError;
22 | _descriptors = Descriptors;
23 | _status = Status;
24 | }
25 |
26 | ///
27 | /// Gets the descriptors.
28 | /// returning an Array of GattDescriptor objects.
29 | ///
30 | public GattDescriptor[] Descriptors { get => (GattDescriptor[])_descriptors.ToArray(typeof(GattDescriptor)); }
31 |
32 | ///
33 | /// Gets the protocol error.
34 | ///
35 | public byte ProtocolError { get => _protocolError; }
36 |
37 | ///
38 | /// Gets the communication status of the operation.
39 | ///
40 | public GattCommunicationStatus Status { get => _status; }
41 | }
42 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattDescriptorUuid.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// Represents an enumeration of the most well known Descriptor UUID values, and
12 | /// provides convenience methods for working with GATT descriptor UUIDs, and static
13 | /// properties providing descriptor UUIDs for common GATT descriptors.
14 | ///
15 | public static class GattDescriptorUuids
16 | {
17 | ///
18 | /// Gets the Bluetooth SIG-defined Characteristic Aggregate Format Descriptor UUID.
19 | ///
20 | public static Guid CharacteristicAggregateFormat { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.CharacteristicAggregateFormat); }
21 |
22 | ///
23 | /// Gets the Bluetooth SIG-defined Characteristic Extended Properties Descriptor UUID.
24 | ///
25 | public static Guid CharacteristicExtendedProperties { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.CharacteristicExtendedProperties); }
26 |
27 | ///
28 | /// Gets the Bluetooth SIG-defined Characteristic Presentation Format Descriptor
29 | ///
30 | public static Guid CharacteristicPresentationFormat { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.CharacteristicPresentationFormat); }
31 |
32 | ///
33 | /// Gets the Bluetooth SIG-defined Characteristic User Description Descriptor UUID.
34 | ///
35 | public static Guid CharacteristicUserDescription { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.CharacteristicUserDescription); }
36 |
37 | ///
38 | /// Gets the Bluetooth SIG-defined Client Characteristic Configuration Descriptor UUID.
39 | ///
40 | public static Guid ClientCharacteristicConfiguration { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.ClientCharacteristicConfiguration); }
41 |
42 | ///
43 | /// Gets the Bluetooth SIG-defined Server Characteristic Configuration Descriptor UUID.
44 | ///
45 | public static Guid ServerCharacteristicConfiguration { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.ServerCharacteristicConfiguration); }
46 |
47 | ///
48 | /// Get the Bluetooth SIG-defined External Report Reference Descriptor UUID.
49 | ///
50 | public static Guid ExternalReportReference { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.ExternalReportReference); }
51 |
52 | ///
53 | /// Get the Bluetooth SIG-defined Report Reference Descriptor UUID.
54 | ///
55 | public static Guid ReportReference { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.ReportReference); }
56 |
57 | ///
58 | /// Gets the Bluetooth SIG-defined Value trigger settings Descriptor UUID.
59 | ///
60 | public static Guid ValueTriggerSetting { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.ValueTriggerSetting); }
61 |
62 | ///
63 | /// Gets the Bluetooth SIG-defined Environmental Sensing Configuration Descriptor UUID.
64 | ///
65 | public static Guid EssConfiguration { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.EssConfiguration); }
66 |
67 | ///
68 | /// Gets the Bluetooth SIG-defined Environmental Sensing Measurement Descriptor UUID.
69 | ///
70 | public static Guid EssMeasurement { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.EssMeasurement); }
71 |
72 | ///
73 | /// Gets the Bluetooth SIG-defined Environmental Sensing Trigger Setting Descriptor UUID.
74 | ///
75 | public static Guid EssTriggerSetting { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.EssTriggerSetting); }
76 |
77 | ///
78 | /// Gets the Bluetooth SIG-defined Time Trigger Setting Descriptor UUID.
79 | ///
80 | public static Guid TimeTriggerSetting { get => Utilities.CreateUuidFromShortCode((ushort)Utilities.GattNativeDescriptorUuid.TimeTriggerSetting); }
81 | }
82 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattDeviceServicesResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System.Collections;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// The status of GetIncludedServicesForUuid and GetIncludedServicesForUuid
12 | ///
13 | public class GattDeviceServicesResult
14 | {
15 | private readonly byte _protocolError;
16 | private readonly ArrayList _services;
17 | private readonly GattCommunicationStatus _status;
18 |
19 | internal GattDeviceServicesResult(byte ProtocolError, ArrayList Services, GattCommunicationStatus Status)
20 | {
21 | _protocolError = ProtocolError;
22 | _services = Services;
23 | _status = Status;
24 | }
25 |
26 | ///
27 | /// Gets the protocol error.
28 | ///
29 | public byte ProtocolError { get => _protocolError; }
30 |
31 | ///
32 | /// Gets the services.
33 | /// returning an Array of GattDeviceService objects.
34 | ///
35 | public GattDeviceService[] Services { get => (GattDeviceService[])_services.ToArray(typeof(GattDeviceService)); }
36 |
37 | ///
38 | /// Gets the communication status of the operation.
39 | ///
40 | public GattCommunicationStatus Status { get => _status; }
41 | }
42 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattLocalCharacteristicParameters.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System.Collections;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// This class contains the local characteristic descriptor parameters.
12 | ///
13 | public class GattLocalCharacteristicParameters
14 | {
15 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
16 | private GattProtectionLevel _writeProtectionLevel;
17 |
18 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
19 | private GattProtectionLevel _readProtectionLevel;
20 |
21 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
22 | private string _userDescription;
23 |
24 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
25 | private GattCharacteristicProperties _properties;
26 |
27 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
28 | private Buffer _staticValue;
29 |
30 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
31 | private readonly ArrayList _presentationFormats;
32 |
33 | ///
34 | /// Creates a new GattLocalCharacteristicParameters object.
35 | ///
36 | public GattLocalCharacteristicParameters()
37 | {
38 | _writeProtectionLevel = GattProtectionLevel.Plain;
39 | _readProtectionLevel = GattProtectionLevel.Plain;
40 | _userDescription = "";
41 | _properties = GattCharacteristicProperties.None;
42 | _presentationFormats = new ArrayList();
43 | }
44 |
45 | ///
46 | /// Gets and sets the write protection level.
47 | ///
48 | public GattProtectionLevel WriteProtectionLevel { get => _writeProtectionLevel; set => _writeProtectionLevel = value; }
49 |
50 | ///
51 | /// Gets or sets the user-friendly description.
52 | ///
53 | public string UserDescription { get => _userDescription; set => _userDescription = value; }
54 |
55 | ///
56 | /// Gets or sets the static value.
57 | ///
58 | public Buffer StaticValue { get => _staticValue; set => _staticValue = value; }
59 |
60 | ///
61 | /// Gets or sets the read protection level.
62 | ///
63 | public GattProtectionLevel ReadProtectionLevel { get => _readProtectionLevel; set => _readProtectionLevel = value; }
64 |
65 | ///
66 | /// Gets the properties.
67 | ///
68 | public GattCharacteristicProperties CharacteristicProperties { get => _properties; set => _properties = value; }
69 |
70 | ///
71 | /// Gets or sets the presentation formats arrayLIst
72 | ///
73 | public GattPresentationFormat[] PresentationFormats { get => (GattPresentationFormat[])_presentationFormats.ToArray(typeof(GattPresentationFormat)); }
74 |
75 | ///
76 | /// Create a GattPresentationFormat to the GattLocalCharacteristicParameters
77 | ///
78 | public void CreateGattPresentationFormat(byte formatType, int exponent, ushort unit, byte namespaceId, ushort decsription)
79 | {
80 | _presentationFormats.Add(new GattPresentationFormat(formatType, exponent, unit, namespaceId, decsription));
81 | }
82 | }
83 | }
84 |
85 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattLocalCharacteristicResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// A result of CreateCharacteristic
10 | ///
11 | public class GattLocalCharacteristicResult
12 | {
13 | private readonly GattLocalCharacteristic _characteristic;
14 | private readonly BluetoothError _error;
15 |
16 | internal GattLocalCharacteristicResult(GattLocalCharacteristic Characteristic, BluetoothError Error)
17 | {
18 | _characteristic = Characteristic;
19 | _error = Error;
20 | }
21 |
22 | ///
23 | /// Gets the characteristic of the GATT service.
24 | ///
25 | public GattLocalCharacteristic Characteristic { get => _characteristic; }
26 |
27 | ///
28 | /// Gets the Bluetooth error.
29 | ///
30 | public BluetoothError Error { get => _error; }
31 | }
32 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattLocalDescriptor.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// This class defines a descriptor of a local characteristic.
12 | ///
13 | public class GattLocalDescriptor
14 | {
15 | // Each Descriptor will have unique _descriptorId for event lookup, events for descriptors are handled by User app.
16 | // This comprises of characteristic id + GattLocalDescriptorIndex in the form
17 | // x'DDCC' where DD is Descriptor and CC characteristic
18 | internal ushort _descriptorId;
19 |
20 | private readonly GattLocalCharacteristic _charactisic;
21 |
22 | private readonly GattProtectionLevel _writeProtectionLevel;
23 | private readonly GattProtectionLevel _readProtectionLevel;
24 | private readonly byte[] _uuid;
25 |
26 | private readonly Buffer _staticValue;
27 |
28 | ///
29 | /// Delegate for Read requests
30 | ///
31 | /// GattLocalDescriptor sending event
32 | /// Event arguments
33 | public delegate void GattLocalDescriptorReadEventHandler(GattLocalCharacteristic sender, GattReadRequestedEventArgs ReadRequestEventArgs);
34 |
35 | ///
36 | /// Delegate for Write requests
37 | ///
38 | /// GattLocalDescriptor sending event
39 | /// Event arguments
40 | public delegate void GattLocalDescriptorWriteEventHandler(GattLocalCharacteristic sender, GattWriteRequestedEventArgs WriteRequestEventArgs);
41 |
42 | internal GattLocalDescriptor(Guid uuid, GattLocalDescriptorParameters parameters, GattLocalCharacteristic charactisic, int descriptorIndex)
43 | {
44 | _uuid = uuid.ToByteArray();
45 | _charactisic = charactisic;
46 |
47 | _writeProtectionLevel = parameters.WriteProtectionLevel;
48 | _readProtectionLevel = parameters.ReadProtectionLevel;
49 | _staticValue = parameters.StaticValue;
50 |
51 | _descriptorId = (ushort)((descriptorIndex << 8) + _charactisic._characteristicId);
52 | }
53 |
54 | ///
55 | /// Gets the read protection level of this local characteristic descriptor.
56 | ///
57 | public GattProtectionLevel ReadProtectionLevel { get => _readProtectionLevel; }
58 |
59 | ///
60 | /// Gets the static value for this local characteristic descriptor.
61 | ///
62 | public Buffer StaticValue { get => _staticValue; }
63 |
64 | ///
65 | /// Gets the Bluetooth SIG-defined UUID for this local characteristic descriptor.
66 | ///
67 | public Guid Uuid { get => new(_uuid); }
68 |
69 | ///
70 | /// Gets the write protection level.
71 | ///
72 | public GattProtectionLevel WriteProtectionLevel { get => _writeProtectionLevel; }
73 |
74 | ///
75 | /// An event that is triggered when a GATT client requests a descriptor read operation.
76 | ///
77 | public event GattLocalDescriptorReadEventHandler ReadRequested;
78 |
79 | ///
80 | /// This is an event that is triggered when a write descriptor was requested.
81 | ///
82 | public event GattLocalDescriptorWriteEventHandler WriteRequested;
83 |
84 | internal bool OnReadRequested(GattReadRequestedEventArgs e)
85 | {
86 | if (_staticValue != null)
87 | {
88 | e.GetRequest().RespondWithValue(_staticValue);
89 | return true;
90 | }
91 |
92 | if (ReadRequested != null)
93 | {
94 | ReadRequested?.Invoke(_charactisic, e);
95 | return true;
96 | }
97 |
98 | return false;
99 | }
100 |
101 | internal bool OnWriteRequested(GattWriteRequestedEventArgs e)
102 | {
103 | if (WriteRequested != null)
104 | {
105 | WriteRequested?.Invoke(_charactisic, e);
106 | return true;
107 | }
108 |
109 | return false;
110 | }
111 | }
112 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattLocalDescriptorParameters.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// This class defines the parameters of a descriptor.
10 | ///
11 | public class GattLocalDescriptorParameters
12 | {
13 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
14 | private GattProtectionLevel _writeProtectionLevel;
15 |
16 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
17 | private GattProtectionLevel _readProtectionLevel;
18 |
19 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
20 | private Buffer _staticValue = null;
21 |
22 | ///
23 | /// Creates a new GattLocalDescriptorParameters object.
24 | ///
25 | public GattLocalDescriptorParameters()
26 | {
27 | _writeProtectionLevel = GattProtectionLevel.Plain;
28 | _readProtectionLevel = GattProtectionLevel.Plain;
29 | }
30 |
31 | ///
32 | /// Gets or sets the write protection level.
33 | ///
34 | public GattProtectionLevel WriteProtectionLevel { get => _writeProtectionLevel; set => _writeProtectionLevel = value; }
35 |
36 | ///
37 | /// Gets or sets the static value.
38 | ///
39 | public Buffer StaticValue { get => _staticValue; set => _staticValue = value; }
40 |
41 | ///
42 | /// Gets or sets the read protection level.
43 | ///
44 | public GattProtectionLevel ReadProtectionLevel { get => _readProtectionLevel; set => _readProtectionLevel = value; }
45 | }
46 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattLocalDescriptorResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// The result of local characteristic descriptor operations like CreateDescriptorAsync.
10 | ///
11 | public class GattLocalDescriptorResult
12 | {
13 | private readonly BluetoothError _error;
14 | private readonly GattLocalDescriptor _descriptor;
15 |
16 | internal GattLocalDescriptorResult(GattLocalDescriptor descriptor, BluetoothError error)
17 | {
18 | _descriptor = descriptor;
19 | _error = error;
20 | }
21 |
22 | ///
23 | /// Gets the descriptor.
24 | ///
25 | public GattLocalDescriptor Descriptor { get => _descriptor; }
26 |
27 | ///
28 | /// Gets the error.
29 | ///
30 | public BluetoothError Error { get => _error; }
31 | }
32 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattLocalService.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Collections;
8 |
9 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
10 | {
11 | ///
12 | /// This class represents a GATT local service.
13 | ///
14 | public class GattLocalService
15 | {
16 | private readonly byte[] _serviceUuid;
17 | private readonly ArrayList _characteristics;
18 |
19 | internal GattLocalService(Guid serviceUuid)
20 | {
21 | _serviceUuid = serviceUuid.ToByteArray();
22 | _characteristics = new ArrayList();
23 | }
24 |
25 | ///
26 | /// Creates a characteristic for this local service.
27 | ///
28 | /// The characteristic UUID.
29 | /// The characteristic parameters.
30 | /// An GattLocalCharacteristicResult object
31 | public GattLocalCharacteristicResult CreateCharacteristic(Guid characteristicUuid, GattLocalCharacteristicParameters parameters)
32 | {
33 | GattLocalCharacteristic Characteristic = new(characteristicUuid, parameters);
34 | _characteristics.Add(Characteristic);
35 |
36 | // Update pairing security based on current read/write protectionlevels.
37 | BluetoothLEServer.Instance.UpdateSecurityPairingRequirements(Characteristic.ReadProtectionLevel);
38 | BluetoothLEServer.Instance.UpdateSecurityPairingRequirements(Characteristic.WriteProtectionLevel);
39 |
40 | return new GattLocalCharacteristicResult(Characteristic, BluetoothError.Success);
41 | }
42 |
43 | ///
44 | /// Gets a array of the characteristics available for this local service.
45 | ///
46 | public GattLocalCharacteristic[] Characteristics { get { return (GattLocalCharacteristic[])_characteristics.ToArray(typeof(GattLocalCharacteristic)); } }
47 |
48 | ///
49 | /// Gets the local service UUID.
50 | ///
51 | public Guid Uuid { get => new(_serviceUuid); }
52 | }
53 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattPresentationFormat.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Represents the value of a single Presentation Format GATT Descriptor.
10 | ///
11 | public class GattPresentationFormat
12 | {
13 | private readonly byte _formatType;
14 | private readonly int _exponent;
15 | private readonly ushort _unit;
16 | private readonly byte _namespaceId;
17 | private readonly ushort _description;
18 |
19 | ///
20 | /// Creates a GattPresentationFormat object from parts.
21 | ///
22 | /// The Format Type.
23 | /// The exponent.
24 | /// The unit.
25 | /// The namespace id.
26 | /// The description.
27 | /// An instance of GattPresentationFormat.
28 | public static GattPresentationFormat FromParts(byte formatType, int exponent, ushort unit, byte namespaceId, ushort description)
29 | {
30 | return new GattPresentationFormat(formatType, exponent, unit, namespaceId, description);
31 | }
32 |
33 | internal GattPresentationFormat(byte formatType, int exponent, ushort unit, byte namespaceId, ushort description)
34 | {
35 | _formatType = formatType;
36 | _exponent = exponent;
37 | _unit = unit;
38 | _namespaceId = namespaceId;
39 | _description = description;
40 | }
41 |
42 | ///
43 | /// Gets the Description of the GattPresentationFormat object.
44 | ///
45 | public ushort Description { get => _description; }
46 |
47 | ///
48 | /// Gets the Exponent of the GattPresentationFormat object.
49 | ///
50 | public int Exponent { get => _exponent; }
51 |
52 | ///
53 | /// Gets the Format Type of the GattPresentationFormat object.
54 | ///
55 | public byte FormatType { get => _formatType; }
56 |
57 | ///
58 | /// Gets the Name space of the GattPresentationFormat object.
59 | ///
60 | public byte Namespace { get => _namespaceId; }
61 |
62 | ///
63 | /// Gets the Unit of the GattPresentationFormat object.
64 | ///
65 | public ushort Unit { get => _unit; }
66 | }
67 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattPresentationFormatTypes.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Represents the different well-known values that the GattPresentationFormat.FormatType
10 | /// property can take.
11 | ///
12 | public static class GattPresentationFormatTypes
13 | {
14 | ///
15 | /// Gets the value of the Bit2 Format Type.
16 | ///
17 | public static byte Bit2 { get => 0x02; }
18 |
19 | ///
20 | /// Gets the value of the Boolean Format Type.
21 | ///
22 | public static byte Boolean { get => 0x01; }
23 |
24 | ///
25 | /// Gets the value of the DUInt16 Format Type.
26 | ///
27 | public static byte DUInt16 { get => 0x18; }
28 |
29 | ///
30 | /// Gets the value of the Float Format Type.
31 | ///
32 | public static byte Float { get => 0x17; }
33 |
34 | ///
35 | /// Gets the value of the Float32 Format Type.
36 | ///
37 | public static byte Float32 { get => 0x14; }
38 |
39 | ///
40 | /// Gets the value of the Float64 Format Type.
41 | ///
42 | public static byte Float64 { get => 0x15; }
43 | ///
44 | /// Gets the value of the Nibble Format Type.
45 | ///
46 | public static byte Nibble { get => 0x03; }
47 |
48 | ///
49 | /// Gets the value of the SFloat Format Type.
50 | ///
51 | public static byte SFloat { get => 0x16; }
52 |
53 | ///
54 | /// Gets the value of the SInt12 Format Type.
55 | ///
56 | public static byte SInt12 { get => 0x0d; }
57 |
58 | ///
59 | /// Gets the value of the SInt128 Format Type.
60 | ///
61 | public static byte SInt128 { get => 0x13; }
62 |
63 | ///
64 | /// Gets the value of the SInt16 Format Type.
65 | ///
66 | public static byte SInt16 { get => 0x0e; }
67 |
68 | ///
69 | /// Gets the value of the SInt24 Format Type.
70 | ///
71 | public static byte SInt24 { get => 0x0f; }
72 |
73 | ///
74 | /// Gets the value of the SInt32 Format Type.
75 | ///
76 | public static byte SInt32 { get => 0x10; }
77 |
78 | ///
79 | /// Gets the value of the SInt48 Format Type.
80 | ///
81 | public static byte SInt48 { get => 0x11; }
82 |
83 | ///
84 | /// Gets the value of the SInt64 Format Type.
85 | ///
86 | public static byte SInt64 { get => 0x12; }
87 |
88 | ///
89 | /// Gets the value of the SInt8 Format Type.
90 | ///
91 | public static byte SInt8 { get => 0x0c; }
92 |
93 | ///
94 | /// Gets the value of the Struct Format Type.
95 | ///
96 | public static byte Struct { get => 0x1b; }
97 |
98 | ///
99 | /// Gets the value of the UInt12 Format Type.
100 | ///
101 | public static byte UInt12 { get => 0x05; }
102 |
103 | ///
104 | /// Gets the value of the UInt128 Format Type.
105 | ///
106 | public static byte UInt128 { get => 0x0b; }
107 |
108 | ///
109 | /// Gets the value of the UInt16 Format Type.
110 | ///
111 | public static byte UInt16 { get => 0x06; }
112 |
113 | ///
114 | /// Gets the value of the UInt24 Format Type.
115 | ///
116 | public static byte UInt24 { get => 0x07; }
117 |
118 | ///
119 | /// Gets the value of the UInt32 Format Type.
120 | ///
121 | public static byte UInt32 { get => 0x08; }
122 |
123 | ///
124 | /// Gets the value of the UInt48 Format Type.
125 | ///
126 | public static byte UInt48 { get => 0x09; }
127 |
128 | ///
129 | /// Gets the value of the UInt64 Format Type.
130 | ///
131 | public static byte UInt64 { get => 0x0a; }
132 |
133 | ///
134 | /// Gets the value of the UInt8 Format Type.
135 | ///
136 | public static byte UInt8 { get => 0x04; }
137 |
138 | ///
139 | /// Gets the value of the Utf16 Format Type.
140 | ///
141 | public static byte Utf16 { get => 0x1a; }
142 |
143 | ///
144 | /// Gets the value of the Utf8 Format Type.
145 | ///
146 | public static byte Utf8 { get => 0x8; }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattProtectionLevel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Represents the desired security level.
10 | ///
11 | public enum GattProtectionLevel
12 | {
13 | ///
14 | /// Uses the default protection level.
15 | ///
16 | Plain = 0,
17 |
18 | ///
19 | /// Require the link to be authenticated.
20 | ///
21 | AuthenticationRequired = 1,
22 |
23 | ///
24 | /// Require the link to be encrypted.
25 | ///
26 | EncryptionRequired = 2,
27 |
28 | ///
29 | /// Require the link to be encrypted and authenticated.
30 | ///
31 | EncryptionAndAuthenticationRequired = 3
32 | }
33 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattProtocolError.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// This class contains byte values for GATT protocol errors.
10 | ///
11 | public static class GattProtocolError
12 | {
13 | ///
14 | /// Gets the byte value for an attribute not found error.
15 | ///
16 | public static byte AttributeNotFound { get => 10; }
17 |
18 | ///
19 | /// Gets the byte value for an attribute not long error.
20 | ///
21 | public static byte AttributeNotLong { get => 11; }
22 |
23 | ///
24 | /// Gets the byte value for an insufficient authentication error.
25 | ///
26 | public static byte InsufficientAuthentication { get => 5; }
27 |
28 | ///
29 | /// Gets the byte value for an insufficient authorization error.
30 | ///
31 | public static byte InsufficientAuthorization { get => 8; }
32 |
33 | ///
34 | /// Gets the byte value for an insufficient encryption error.
35 | ///
36 | public static byte InsufficientEncryption { get => 15; }
37 |
38 | ///
39 | /// Gets the byte value for an insufficient encryption key size error.
40 | ///
41 | public static byte InsufficientEncryptionKeySize { get => 12; }
42 |
43 | ///
44 | /// Gets the byte value for an insufficient resources error.
45 | ///
46 | public static byte InsufficientResources { get => 17; }
47 |
48 | ///
49 | /// Gets the byte value for an invalid attribute value length error.
50 | ///
51 | public static byte InvalidAttributeValueLength { get => 13; }
52 |
53 | ///
54 | /// Gets the byte value for an invalid handle error.
55 | ///
56 | public static byte InvalidHandle { get => 1; }
57 |
58 | ///
59 | /// Gets the byte value for an invalid offset error.
60 | ///
61 | public static byte InvalidOffset { get => 7; }
62 |
63 | ///
64 | /// Gets the byte value for an invalid PDU error.
65 | ///
66 | public static byte InvalidPdu { get => 4; }
67 |
68 | ///
69 | /// Gets the byte value for a prepare queue full error.
70 | ///
71 | public static byte PrepareQueueFull { get => 9; }
72 |
73 | ///
74 | /// Gets the byte value for a read not permitted error.
75 | ///
76 | public static byte ReadNotPermitted { get => 2; }
77 |
78 | ///
79 | /// Gets the byte value for a request not supported error.
80 | ///
81 | public static byte RequestNotSupported { get => 6; }
82 |
83 | ///
84 | /// Gets the byte value for an unlikely error.
85 | ///
86 | public static byte UnlikelyError { get => 14; }
87 |
88 | ///
89 | /// Gets the byte value for an unsupported group type error.
90 | ///
91 | public static byte UnsupportedGroupType { get => 15; }
92 |
93 | ///
94 | /// Gets the byte value for a write not permitted error.
95 | ///
96 | public static byte WriteNotPermitted { get => 3; }
97 | }
98 | }
99 |
100 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattReadClientCharacteristicConfigurationDescriptorResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Represents the result of reading a GATT Client CharacteristicConfigurationClientDescriptor value.
10 | ///
11 | public class GattReadClientCharacteristicConfigurationDescriptorResult
12 | {
13 | private readonly GattClientCharacteristicConfigurationDescriptorValue _config;
14 | private readonly byte _protocolError;
15 | private readonly GattCommunicationStatus _status;
16 |
17 | internal GattReadClientCharacteristicConfigurationDescriptorResult(
18 | GattClientCharacteristicConfigurationDescriptorValue value,
19 | GattCommunicationStatus status,
20 | byte protocolError)
21 | {
22 | _config = value;
23 | _status = status;
24 | _protocolError = protocolError;
25 | }
26 |
27 | ///
28 | /// Gets the result of an read operation.
29 | ///
30 | public GattClientCharacteristicConfigurationDescriptorValue ClientCharacteristicConfigurationDescriptor { get => _config; }
31 |
32 | ///
33 | /// Gets the status of an operation.
34 | ///
35 | public GattCommunicationStatus Status { get => _status; }
36 |
37 | ///
38 | /// Gets the protocol error.
39 | ///
40 | public byte ProtocolError { get => _protocolError; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattReadRequest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Runtime.CompilerServices;
8 |
9 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
10 | {
11 | ///
12 | /// This class represents a Bluetooth GATT read request.
13 | ///
14 | public class GattReadRequest
15 | {
16 | private Buffer _readValue;
17 | private readonly ushort _eventID;
18 |
19 | internal GattReadRequest(ushort eventID)
20 | {
21 | _eventID = eventID;
22 | }
23 |
24 | ///
25 | /// Responds to a read request with a value.
26 | ///
27 | /// The value to respond with.
28 | public void RespondWithValue(Buffer value)
29 | {
30 | _readValue = value;
31 |
32 | byte[] data = new byte[_readValue.Length];
33 | Array.Copy(_readValue.Data, data, (int)_readValue.Length);
34 |
35 | NativeReadRespondWithValue(_eventID, data);
36 | }
37 |
38 | ///
39 | /// Responds to the read request with a protocol error.
40 | ///
41 | /// The protocol error to send. A list of errors with the byte values can be found in GattProtocolError.
42 | public void RespondWithProtocolError(byte protocolError)
43 | {
44 | NativeReadRespondWithProtocolError(_eventID, protocolError);
45 | }
46 |
47 | ///
48 | /// Gets the buffer length of the read request.
49 | ///
50 | public uint Length { get => _readValue.Length; }
51 |
52 | #region external calls to native implementations
53 |
54 | [MethodImpl(MethodImplOptions.InternalCall)]
55 | private extern void NativeReadRespondWithValue(ushort eventID, byte[] value);
56 |
57 | [MethodImpl(MethodImplOptions.InternalCall)]
58 | private extern void NativeReadRespondWithProtocolError(ushort eventID, byte protocolError);
59 |
60 | #endregion
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattReadRequestedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// This class contains the arguments for the StateChanged event.
10 | ///
11 | public class GattReadRequestedEventArgs
12 | {
13 | private readonly ushort _eventID;
14 | private readonly GattSession _session = null;
15 |
16 | internal GattReadRequestedEventArgs(ushort eventID, GattSession session)
17 | {
18 | _eventID = eventID;
19 | _session = session;
20 | }
21 |
22 | ///
23 | /// Gets the GATT read request.
24 | ///
25 | /// Returns a GattReadRequest object.
26 | public GattReadRequest GetRequest()
27 | {
28 | return new GattReadRequest(_eventID);
29 | }
30 |
31 | ///
32 | /// Gets the session.
33 | ///
34 | public GattSession Session { get => _session; }
35 | }
36 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattReadResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Represents the result of an asynchronous read operation of a GATT Characteristic
10 | /// or Descriptor value.
11 | ///
12 | public class GattReadResult
13 | {
14 | private readonly GattCommunicationStatus _status;
15 | private readonly byte _protocolError;
16 | private readonly Buffer _buffer;
17 |
18 | internal GattReadResult(Buffer buffer, GattCommunicationStatus status, byte protocolError)
19 | {
20 | _buffer = buffer;
21 | _status = status;
22 | _protocolError = protocolError;
23 | }
24 |
25 | ///
26 | /// Gets the status of an operation.
27 | ///
28 | public GattCommunicationStatus Status { get => _status; }
29 |
30 | ///
31 | /// Gets the value read from the device.
32 | ///
33 | public Buffer Value { get => _buffer; }
34 |
35 | ///
36 | /// Gets the protocol error.
37 | ///
38 | public byte ProtocolError { get => _protocolError; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattServiceProviderAdvertisementStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// This enumeration defines the advertisement status of a GattServiceProvider.
10 | ///
11 | public enum GattServiceProviderAdvertisementStatus
12 | {
13 | ///
14 | /// The GATT service was created.
15 | ///
16 | Created = 0,
17 |
18 | ///
19 | /// The GATT service is not advertising.
20 | ///
21 | Stopped = 1,
22 |
23 | ///
24 | /// The GATT service advertising has started.
25 | ///
26 | Started = 2,
27 |
28 | ///
29 | /// The GATT service was aborted.
30 | ///
31 | Aborted = 3,
32 |
33 | ///
34 | /// Indicates that the system was successfully able to issue the advertisement request,
35 | /// but not all of the requested data could be included in the advertisement.
36 | StartedWithoutAllAdvertisementData = 4
37 | }
38 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattServiceProviderAdvertisingParameters.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using nanoFramework.Device.Bluetooth.Advertisement;
7 | using System;
8 |
9 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
10 | {
11 | ///
12 | /// This class is used to define the GATT service advertisement parameters.
13 | ///
14 | public class GattServiceProviderAdvertisingParameters
15 | {
16 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
17 | private bool _isDiscoverable = true;
18 |
19 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
20 | private bool _isConnectable = true;
21 |
22 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
23 | private Buffer _serviceData;
24 |
25 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
26 | private BluetoothLEAdvertisement _advertisement;
27 |
28 | [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
29 | private bool _customAdvertisement;
30 |
31 |
32 | ///
33 | /// Creates a new object.
34 | ///
35 | public GattServiceProviderAdvertisingParameters()
36 | {
37 | _advertisement = new();
38 |
39 | // Not a Custom advertisement, so set Flags & Local Name
40 | CustomAdvertisement = false;
41 |
42 | _isDiscoverable = true;
43 | }
44 |
45 | ///
46 | /// Gets or sets a boolean indicating that the GATT service is discoverable.
47 | ///
48 | public bool IsDiscoverable
49 | {
50 | get => _isDiscoverable;
51 | set
52 | {
53 | _isDiscoverable = value;
54 | if (_isDiscoverable)
55 | {
56 | _advertisement.Flags |= BluetoothLEAdvertisementFlags.GeneralDiscoverableMode;
57 | }
58 | else
59 | {
60 | _advertisement.Flags &= ~BluetoothLEAdvertisementFlags.GeneralDiscoverableMode;
61 | }
62 | }
63 | }
64 |
65 | ///
66 | /// Gets or sets a boolean that indicates if the GATT service is connect-able.
67 | ///
68 | public bool IsConnectable { get => _isConnectable; set => _isConnectable = value; }
69 |
70 | ///
71 | /// For Bluetooth Low Energy, this parameter adds an additional **ServiceData** section
72 | /// to the advertisement payload for the service's service UUID if space is available.
73 | /// If the service data is added to the advertisement, then the service UUID will
74 | /// also be included in the same section in the advertisement.
75 | ///
76 | public Buffer ServiceData { get => _serviceData; set => _serviceData = value; }
77 |
78 | ///
79 | /// Gets the underlying object for the to enable extra
80 | /// advertisement parameters to be set.
81 | ///
82 | public BluetoothLEAdvertisement Advertisement { get => _advertisement; }
83 |
84 | ///
85 | /// If set the will not be filled in with the default data sections only data sections from
86 | /// the property will be used. Default is .
87 | ///
88 | public bool CustomAdvertisement
89 | {
90 | get => _customAdvertisement;
91 | set
92 | {
93 | _customAdvertisement = value;
94 | if (_customAdvertisement)
95 | {
96 | // Remove default data sections
97 | Advertisement.RemoveSectionsOfType(BluetoothLEAdvertisementDataSectionType.Flags);
98 | Advertisement.RemoveSectionsOfType(BluetoothLEAdvertisementDataSectionType.CompleteLocalName);
99 | }
100 | else
101 | {
102 | // Add default data sections
103 | Advertisement.Flags = BluetoothLEAdvertisementFlags.ClassicNotSupported |
104 | BluetoothLEAdvertisementFlags.GeneralDiscoverableMode;
105 |
106 | // Set default device name
107 | Advertisement.LocalName = BluetoothLEServer.Instance.DeviceName;
108 | }
109 | }
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattServiceProviderResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// This class is the result of the Create operation.
12 | ///
13 | public class GattServiceProviderResult
14 | {
15 | private readonly GattServiceProvider _serviceProvider;
16 | private readonly BluetoothError _error;
17 |
18 | internal GattServiceProviderResult(GattServiceProvider serviceProvider, BluetoothError error)
19 | {
20 | _serviceProvider = serviceProvider;
21 | _error = error;
22 | }
23 |
24 | ///
25 | /// Gets the error.
26 | ///
27 | public BluetoothError Error { get => _error; }
28 |
29 | ///
30 | /// Gets the service provider.
31 | ///
32 | public GattServiceProvider ServiceProvider { get => _serviceProvider; }
33 | }
34 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattServiceUuids.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// Represents an enumeration of the most well known Service UUID values, and provides
12 | /// convenience methods for working with GATT service UUIDs, and static properties
13 | /// providing service UUIDs for common GATT services. To view a list of all Bluetooth
14 | /// SIG-defined service UUIDs, see Bluetooth SIG-defined Service UUIDs.
15 | /// See:- https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf
16 | /// Current Service UUID 0x1800 to 0x181D
17 | ///
18 | public static class GattServiceUuids
19 | {
20 | ///
21 | /// Gets the Bluetooth SIG-defined AlertNotification Service UUID.
22 | ///
23 | public static Guid AlertNotification { get => Utilities.CreateUuidFromShortCode(0x1811); }
24 |
25 | ///
26 | /// Gets the Bluetooth SIG-defined Automation IO Service UUID.
27 | ///
28 | public static Guid AutomationIO { get => Utilities.CreateUuidFromShortCode(0x1815); }
29 |
30 | ///
31 | /// Gets the Bluetooth SIG-defined Battery Service UUID.
32 | ///
33 | public static Guid Battery { get => Utilities.CreateUuidFromShortCode(0x180f); }
34 |
35 | ///
36 | /// Gets the Bluetooth SIG-defined Blood Pressure Service UUID.
37 | ///
38 | public static Guid BloodPressure { get => Utilities.CreateUuidFromShortCode(0x1810); }
39 |
40 | ///
41 | /// Gets the Bluetooth SIG-defined Body Composition Service UUID.
42 | ///
43 | public static Guid BodyComposition { get => Utilities.CreateUuidFromShortCode(0x181b); }
44 |
45 | ///
46 | /// Gets the Bluetooth SIG-defined CurrentTime service UUID.
47 | ///
48 | public static Guid CurrentTime { get => Utilities.CreateUuidFromShortCode(0x1805); }
49 |
50 | ///
51 | /// Gets the Bluetooth SIG-defined CyclingPower service UUID.
52 | ///
53 | public static Guid CyclingPower { get => Utilities.CreateUuidFromShortCode(0x1818); }
54 |
55 | ///
56 | /// Gets the Bluetooth SIG-defined Cycling Speed And Cadence Service UUID.
57 | ///
58 | public static Guid CyclingSpeedAndCadence { get => Utilities.CreateUuidFromShortCode(0x1816); }
59 |
60 | ///
61 | /// Gets the Bluetooth SIG-defined DeviceInformation service UUID.
62 | ///
63 | public static Guid DeviceInformation { get => Utilities.CreateUuidFromShortCode(0x180a); }
64 |
65 | ///
66 | /// Gets the Bluetooth SIG-defined Environmental Sensing Service UUID.
67 | ///
68 | public static Guid EnvironmentalSensing { get => Utilities.CreateUuidFromShortCode(0x181a); }
69 |
70 | ///
71 | /// Gets the Bluetooth SIG-defined UUID for the Generic Access Service.
72 | ///
73 | public static Guid GenericAccess { get => Utilities.CreateUuidFromShortCode(0x1800); }
74 |
75 | ///
76 | /// Gets the Bluetooth SIG-defined UUID for the Generic Attribute Service.
77 | ///
78 | public static Guid GenericAttribute { get => Utilities.CreateUuidFromShortCode(0x1801); }
79 |
80 | ///
81 | /// Gets the Bluetooth SIG-defined Glucose Service UUID.
82 | ///
83 | public static Guid Glucose { get => Utilities.CreateUuidFromShortCode(0x1808); }
84 |
85 | ///
86 | /// Gets the Bluetooth SIG-defined Health Thermometer Service UUID.
87 | ///
88 | public static Guid HealthThermometer { get => Utilities.CreateUuidFromShortCode(0x1809); }
89 |
90 | ///
91 | /// Gets the Bluetooth SIG-defined Heart Rate Service UUID.
92 | ///
93 | public static Guid HeartRate { get => Utilities.CreateUuidFromShortCode(0x180d); }
94 |
95 | ///
96 | /// Gets the Bluetooth SIG-defined HumanInterfaceDevice service UUID.
97 | ///
98 | public static Guid HumanInterfaceDevice { get => Utilities.CreateUuidFromShortCode(0x1812); }
99 |
100 | ///
101 | /// Gets the Bluetooth SIG-defined ImmediateAlert service UUID.
102 | ///
103 | public static Guid ImmediateAlert { get => Utilities.CreateUuidFromShortCode(0x1802); }
104 |
105 | ///
106 | /// Gets the Bluetooth SIG-defined LinkLoss service UUID.
107 | ///
108 | public static Guid LinkLoss {get => Utilities.CreateUuidFromShortCode(0x1803); }
109 |
110 | ///
111 | /// Gets the Bluetooth SIG-defined LocationAndNavigation service UUID.
112 | ///
113 | public static Guid LocationAndNavigation { get => Utilities.CreateUuidFromShortCode(0x1819); }
114 |
115 | ///
116 | /// Gets the Bluetooth SIG-defined NextDstChange service UUID.
117 | ///
118 | public static Guid NextDstChange { get => Utilities.CreateUuidFromShortCode(0x1807); }
119 |
120 | ///
121 | /// Gets the Bluetooth SIG-defined PhoneAlertStatus service UUID.
122 | ///
123 | public static Guid PhoneAlertStatus { get => Utilities.CreateUuidFromShortCode(0x180e); }
124 |
125 | ///
126 | /// Gets the Bluetooth SIG-defined ReferenceTimeUpdate service UUID.
127 | ///
128 | public static Guid ReferenceTimeUpdate { get => Utilities.CreateUuidFromShortCode(0x1806); }
129 |
130 | ///
131 | /// Gets the Bluetooth SIG-defined Running Speed And Cadence Service UUID.
132 | ///
133 | public static Guid RunningSpeedAndCadence { get => Utilities.CreateUuidFromShortCode(0x1814); }
134 |
135 | ///
136 | /// Gets the Bluetooth SIG-defined ScanParameters service UUID.
137 | ///
138 | public static Guid ScanParameters { get => Utilities.CreateUuidFromShortCode(0x1813); }
139 |
140 | ///
141 | /// Gets the Bluetooth SIG-defined TxPower service UUID.
142 | ///
143 | public static Guid TxPower { get => Utilities.CreateUuidFromShortCode(0x1804); }
144 |
145 | ///
146 | /// Gets the Bluetooth SIG-defined User Data service UUID.
147 | ///
148 | public static Guid UserData { get => Utilities.CreateUuidFromShortCode(0x181c); }
149 |
150 | ///
151 | /// Gets the Bluetooth SIG-defined Weight Scale service UUID.
152 | ///
153 | public static Guid WeightScale { get => Utilities.CreateUuidFromShortCode(0x181d); }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattSession.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// This class represents a GATT session.
12 | ///
13 | public class GattSession
14 | {
15 | private readonly BluetoothDeviceId _deviceId;
16 | private ushort _maxMtuSize;
17 |
18 | ///
19 | /// Delegate for events.
20 | ///
21 | /// sending event.
22 | /// Event arguments.
23 | public delegate void GattSessionStatusChangedEventHandler(Object sender, GattSessionStatusChangedEventArgs args);
24 |
25 | ///
26 | /// Session status change event.
27 | ///
28 | public event GattSessionStatusChangedEventHandler SessionStatusChanged;
29 |
30 | ///
31 | /// An event that is raised when the maximum protocol data unit (PDU) size changes.
32 | /// The PDU is also known as the maximum transmission unit (MTU).
33 | ///
34 | public event EventHandler MaxPduSizeChanged;
35 |
36 | ///
37 | /// Creates a new object from the specified deviceId.
38 | ///
39 | /// The deviceId.
40 | /// A new object.
41 | public static GattSession FromDeviceId(BluetoothDeviceId deviceId)
42 | {
43 | return new GattSession(deviceId);
44 | }
45 |
46 | internal GattSession(BluetoothDeviceId deviceId)
47 | {
48 | _deviceId = deviceId;
49 | }
50 |
51 | internal void OnEvent(BluetoothEventSesssion btEvent)
52 | {
53 | //Debug.WriteLine($"# GattServiceProvider OnEvent, type:{btEvent.type} status:{btEvent.status}");
54 |
55 | switch (btEvent.type)
56 | {
57 | case BluetoothEventType.ClientConnected:
58 | SessionStatusChanged?.Invoke(this, new GattSessionStatusChangedEventArgs(GattSessionStatus.Active, 0));
59 | break;
60 |
61 | case BluetoothEventType.ClientDisconnected:
62 | SessionStatusChanged?.Invoke(this, new GattSessionStatusChangedEventArgs(GattSessionStatus.Closed, 0));
63 | break;
64 |
65 | case BluetoothEventType.ClientSessionChanged:
66 | // Update max MTU size in GattSession
67 | _maxMtuSize = btEvent.data;
68 | MaxPduSizeChanged?.Invoke(this, EventArgs.Empty);
69 | break;
70 | }
71 | }
72 |
73 | ///
74 | /// Gets the device id.
75 | ///
76 | public BluetoothDeviceId DeviceId { get => _deviceId; }
77 |
78 | ///
79 | /// Gets the maximum transmission unit (MTU) size.
80 | ///
81 | public ushort MaxMtuSize { get => _maxMtuSize; }
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattSessionStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// This enumeration defines a GattSession status.
10 | ///
11 | public enum GattSessionStatus
12 | {
13 | ///
14 | /// The GATT session is closed.
15 | ///
16 | Closed = 0,
17 |
18 | ///
19 | /// The GATT session is active.
20 | ///
21 | Active = 1
22 | }
23 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattSessionStatusChangedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// This class represents the SessionStatusChanged event args.
10 | ///
11 | public class GattSessionStatusChangedEventArgs
12 | {
13 | private readonly GattSessionStatus _status;
14 | private readonly BluetoothError _bluetoothError;
15 |
16 | internal GattSessionStatusChangedEventArgs(GattSessionStatus status, BluetoothError bluetoothError)
17 | {
18 | _status = status;
19 | _bluetoothError = bluetoothError;
20 | }
21 |
22 | ///
23 | /// Gets the status of the GATT session.
24 | ///
25 | public GattSessionStatus Status { get => _status; }
26 |
27 | ///
28 | /// Gets the error of the GATT session.
29 | ///
30 | public BluetoothError Error { get => _bluetoothError; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattSubscribedClient.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// This class represents a subscribed client of a GATT session.
10 | ///
11 | public class GattSubscribedClient
12 | {
13 | private readonly GattSession _session;
14 |
15 | internal GattSubscribedClient(GattSession session)
16 | {
17 | _session = session;
18 | }
19 |
20 | ///
21 | /// Gets the maximum notification size.
22 | ///
23 | public ushort MaxNotificationSize { get => 1024; }
24 |
25 | ///
26 | /// Gets the session of the subscribed client.
27 | ///
28 | public GattSession Session { get => _session; }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattValueChangedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// Represents the arguments received by a GattCharacteristic.ValueChanged event
12 | /// handler used to process characteristic value change notification and indication
13 | /// events sent by a Bluetooth LE device.
14 | ///
15 | public class GattValueChangedEventArgs
16 | {
17 | Buffer _buffer;
18 | DateTime _timeStammp;
19 |
20 | internal GattValueChangedEventArgs(Buffer value, DateTime timeStammp)
21 | {
22 | _buffer = value;
23 | _timeStammp = timeStammp;
24 | }
25 |
26 | ///
27 | /// Gets the new Characteristic Value.
28 | ///
29 | public Buffer CharacteristicValue { get => _buffer; }
30 |
31 | ///
32 | /// Gets the time at which the system was notified of the Characteristic Value change.
33 | ///
34 | public DateTime Timestamp { get => _timeStammp; }
35 | }
36 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattWriteOption.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Indicates what type of write operation is to be performed.
10 | ///
11 | public enum GattWriteOption
12 | {
13 | ///
14 | /// The default GATT write procedure shall be used.
15 | ///
16 | WriteWithResponse = 0,
17 |
18 | ///
19 | /// The Write Without Response procedure shall be used.
20 | ///
21 | WriteWithoutResponse = 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattWriteRequest.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Runtime.CompilerServices;
8 |
9 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
10 | {
11 | ///
12 | /// This class represents a GATT write request.
13 | ///
14 | public class GattWriteRequest
15 | {
16 | private readonly GattWriteOption _option = GattWriteOption.WriteWithResponse;
17 | private readonly uint _offset = 0;
18 | private readonly Buffer _value = null;
19 |
20 | private readonly ushort _eventID;
21 |
22 | internal GattWriteRequest(ushort eventID)
23 | {
24 | _eventID = eventID;
25 |
26 | // Get a copy of data from Native for this event
27 | byte[] data = NativeWriteGetData(eventID);
28 |
29 | // and save it
30 | _value = new Buffer(data);
31 | }
32 |
33 | ///
34 | /// Responds to the write request.
35 | ///
36 | public void Respond()
37 | {
38 | NativeWriteRespond(_eventID);
39 | }
40 |
41 | ///
42 | /// Responds with a protocol error.
43 | ///
44 | /// Error byte
45 | public void RespondWithProtocolError(byte protocolError)
46 | {
47 | NativeWriteRespondWithProtocolError(_eventID, protocolError);
48 | }
49 |
50 | ///
51 | /// Gets the offset.
52 | ///
53 | public uint Offset { get => _offset; }
54 |
55 | ///
56 | /// Gets the write request option.
57 | ///
58 | public GattWriteOption Option { get => _option; }
59 |
60 | ///
61 | /// Gets the buffer value of the write request.
62 | ///
63 | public Buffer Value { get => _value; }
64 |
65 | #region external calls to native implementations
66 |
67 | [MethodImpl(MethodImplOptions.InternalCall)]
68 | private extern byte[] NativeWriteGetData(ushort eventID);
69 |
70 | [MethodImpl(MethodImplOptions.InternalCall)]
71 | private extern void NativeWriteRespond(ushort eventID);
72 |
73 | [MethodImpl(MethodImplOptions.InternalCall)]
74 | private extern void NativeWriteRespondWithProtocolError(ushort eventID, byte protocolError);
75 |
76 | #endregion
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattWriteRequestedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// This class represents the event arguments for WriteRequested.
12 | ///
13 | public class GattWriteRequestedEventArgs
14 | {
15 | private readonly ushort _eventID;
16 | private readonly GattSession _session = null;
17 |
18 | internal GattWriteRequestedEventArgs(ushort eventID, GattSession session)
19 | {
20 | _eventID = eventID;
21 | _session = session;
22 | }
23 |
24 | ///
25 | /// Gets the write request.
26 | ///
27 | /// Returns a write request.
28 | public GattWriteRequest GetRequest()
29 | {
30 | return new GattWriteRequest(_eventID);
31 | }
32 |
33 | ///
34 | /// Gets the session.
35 | ///
36 | public GattSession Session { get => _session; }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/GattWriteResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
7 | {
8 | ///
9 | /// Contains the result of GATT write operations like WriteValueWithResult.
10 | ///
11 | public class GattWriteResult
12 | {
13 | private readonly GattCommunicationStatus _status;
14 | private readonly byte _protocolError;
15 |
16 | internal GattWriteResult(GattCommunicationStatus status, byte protocolError)
17 | {
18 | _status = status;
19 | _protocolError = protocolError;
20 | }
21 |
22 | ///
23 | /// Gets the protocol error.
24 | ///
25 | public byte ProtocolError { get => _protocolError; }
26 |
27 | ///
28 | /// Gets the status of the write result.
29 | ///
30 | public GattCommunicationStatus Status { get => _status; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/GenericAttributeProfile/IGattAttribute.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.GenericAttributeProfile
9 | {
10 | ///
11 | /// Interface for all attributes ( Services, Characteristics, Descriptors )
12 | ///
13 | public interface IGattAttribute
14 | {
15 | ///
16 | /// Unique Attribute handle.
17 | ///
18 | public ushort AttributeHandle { get; }
19 |
20 | ///
21 | /// UUID of Attribute.
22 | ///
23 | public Guid Uuid { get; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/IO/Buffer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace nanoFramework.Device.Bluetooth
5 | {
6 | ///
7 | /// Represents a referenced array of bytes used by byte stream read and write interfaces.
8 | ///
9 | public class Buffer
10 | {
11 | ///
12 | /// Byte buffer
13 | ///
14 | private byte[] _buffer;
15 |
16 | ///
17 | /// Length of data in byte buffer.
18 | ///
19 | protected uint _length;
20 |
21 | ///
22 | /// Constructor for Buffer with a specific capacity.
23 | ///
24 | ///
25 | public Buffer(uint capacity)
26 | {
27 | _buffer = new byte[capacity];
28 | _length = 0;
29 | }
30 |
31 | ///
32 | /// Constructor for Buffer with an external byte buffer.
33 | ///
34 | ///
35 | public Buffer(byte[] array)
36 | {
37 | _buffer = array;
38 | _length = (uint)array.Length;
39 | }
40 |
41 | ///
42 | /// Gets the maximum number of bytes that the buffer can hold.
43 | ///
44 | public uint Capacity { get => (uint)_buffer.Length; }
45 |
46 | ///
47 | /// Gets the number of bytes currently in use in the buffer.
48 | ///
49 | public uint Length
50 | {
51 | get => _length;
52 | set
53 | {
54 | if (value > _buffer.Length || value < 0)
55 | {
56 | throw new ArgumentException("Length greater than current buffer");
57 | }
58 |
59 | _length = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Ensure buffer has a certain capacity. If to small it will be expanded
65 | ///
66 | /// New capacity required
67 | public void EnsureCapacity(uint newCapacity)
68 | {
69 | if (newCapacity > _buffer.Length)
70 | {
71 | Byte[] newBuffer = new Byte[newCapacity];
72 | Array.Copy(_buffer, 0, newBuffer, 0, _buffer.Length);
73 | _buffer = newBuffer;
74 | }
75 | }
76 |
77 | internal byte[] Data { get => _buffer; }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System.Reflection;
7 | using System.Runtime.CompilerServices;
8 | using System.Runtime.InteropServices;
9 |
10 | // General Information about an assembly is controlled through the following
11 | // set of attributes. Change these attribute values to modify the information
12 | // associated with an assembly.
13 | [assembly: AssemblyTitle("nanoFramework.Device.Bluetooth")]
14 | [assembly: AssemblyCompany("nanoFramework Contributors")]
15 | [assembly: AssemblyProduct("nanoFramework.Device.Bluetooth")]
16 | [assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]
17 |
18 | ////////////////////////////////////////////////////////////////
19 | // update this whenever the native assembly signature changes //
20 | [assembly: AssemblyNativeVersion("100.0.5.0")]
21 | ////////////////////////////////////////////////////////////////
22 |
23 |
24 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/SPP/IBluetoothSpp.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 |
8 | namespace nanoFramework.Device.Bluetooth.Spp
9 | {
10 | ///
11 | /// Interface for Bluetooth Serial Profile (SPP)
12 | ///
13 | public interface IBluetoothSpp
14 | {
15 | ///
16 | /// Receive data delegate.
17 | ///
18 | ///
19 | ///
20 | public delegate void RxDataEventHandler(IBluetoothSpp sender, SppReceivedDataEventArgs ReadDataEventArgs);
21 |
22 | ///
23 | /// Connected client status changed delegate.
24 | ///
25 | ///
26 | ///
27 | public delegate void ConnectedEventHandler(IBluetoothSpp sender, EventArgs e);
28 |
29 | ///
30 | /// Received data event. Event is fired when data is received.
31 | ///
32 | public event RxDataEventHandler ReceivedData;
33 |
34 | ///
35 | /// Connected client status changed event, Fired when client connects or disconnects.
36 | /// Check isConnected property for current status.
37 | ///
38 | public event ConnectedEventHandler ConnectedEvent;
39 |
40 | ///
41 | /// Returns true is a client is connected.
42 | ///
43 | bool IsConnected{ get; }
44 |
45 | ///
46 | /// Start the SPP advertising.
47 | ///
48 | /// Device name to use in advert.
49 | ///
50 | bool Start(string deviceName);
51 |
52 | ///
53 | /// Stop advertising and close down.
54 | ///
55 | void Stop();
56 |
57 | ///
58 | /// Send bytes to connected client.
59 | ///
60 | /// Byte[] to send.
61 | /// True if send was successful.
62 | bool SendBytes(byte[] data);
63 |
64 | ///
65 | /// Send string to connected client.
66 | ///
67 | /// String data to send.
68 | /// True if send was successful.
69 | bool SendString(string data);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/SPP/SppReceiveEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Text;
8 |
9 | namespace nanoFramework.Device.Bluetooth.Spp
10 | {
11 | ///
12 | /// Event argument for SPP receive data events
13 | ///
14 | public class SppReceivedDataEventArgs
15 | {
16 | private readonly byte[] _data;
17 |
18 | internal SppReceivedDataEventArgs(byte[] data)
19 | {
20 | _data = data;
21 | }
22 |
23 | ///
24 | /// Received data as byte[].
25 | ///
26 | public byte[] DataBytes { get => _data; }
27 |
28 | ///
29 | /// Received data as string.
30 | ///
31 | public String DataString { get => Encoding.UTF8.GetString(_data, 0, _data.Length); }
32 | }
33 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DeviceBonding.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Runtime.CompilerServices;
8 |
9 | namespace nanoFramework.Device.Bluetooth.Security
10 | {
11 | ///
12 | /// Class to encapsulate the bond store access.
13 | ///
14 | public static class DeviceBonding
15 | {
16 | ///
17 | /// Check if bluetooth address bonded.
18 | ///
19 | /// Bluetooth address to check.
20 | /// True if bonded.
21 | [MethodImpl(MethodImplOptions.InternalCall)]
22 | public static extern bool IsBonded(ulong bluetoothAddress);
23 |
24 | ///
25 | /// Deletes all stored bonds.
26 | ///
27 | [MethodImpl(MethodImplOptions.InternalCall)]
28 | public static extern void DeleteAllBonds();
29 |
30 | ///
31 | /// Deletes bond information for peer.
32 | ///
33 | /// Peer's Bluetooth address.
34 | /// Type of Bluetooth address.
35 | [MethodImpl(MethodImplOptions.InternalCall)]
36 | public static extern void DeleteBondForPeer(ulong peerbluetoothAddress, BluetoothAddressType addressType);
37 |
38 | ///
39 | /// Returns the number of stored bonds.
40 | ///
41 | /// Bond count.
42 | [MethodImpl(MethodImplOptions.InternalCall)]
43 | public static extern int Count();
44 |
45 | ///
46 | /// Get Bonding address for peer at index.
47 | ///
48 | /// The index.
49 | /// The bonded address.
50 | /// Index out range.
51 | /// Bluetooth Stack is not running. run BluetoothLEServer.Start().
52 | [MethodImpl(MethodImplOptions.InternalCall)]
53 | public static extern ulong GetBondInformationAt(int index);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DevicePairingEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Runtime.CompilerServices;
8 | using System.Text;
9 |
10 | namespace nanoFramework.Device.Bluetooth
11 | {
12 | ///
13 | /// This class contains the arguments for the Pairing Complete event.
14 | ///
15 | public class DevicePairingEventArgs
16 | {
17 | private readonly ushort _connectionHandle;
18 | private readonly DevicePairingResultStatus _status;
19 |
20 | internal DevicePairingEventArgs(ushort connectionHandle, DevicePairingResultStatus status)
21 | {
22 | _connectionHandle = connectionHandle;
23 | _status = status;
24 | }
25 |
26 | ///
27 | /// Status code of Pairing operation.
28 | ///
29 | public DevicePairingResultStatus Status { get { return _status; } }
30 | }
31 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DevicePairingIOCapabilities.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Kinds of IO capabilties used for pairing.
10 | ///
11 | public enum DevicePairingIOCapabilities
12 | {
13 | ///
14 | /// Device has just a display.
15 | ///
16 | DisplayOnly = 0,
17 |
18 | ///
19 | /// Device can output numeric data and has a way to input a Yes or No (buttons).
20 | ///
21 | DisplayYesNo = 1,
22 |
23 | ///
24 | /// Device has keyboard.
25 | ///
26 | KeyboardOnly = 2,
27 |
28 | ///
29 | /// Device has no output or input.
30 | /// All pairing uses Just Works.
31 | ///
32 | NoInputNoOutput = 3,
33 |
34 | ///
35 | /// Device has Keyboard and Display (input/Output).
36 | ///
37 | KeyboardDisplay = 4
38 | }
39 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DevicePairingKinds .cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Kinds of paring.
10 | ///
11 | public enum DevicePairingKinds
12 | {
13 | ///
14 | /// No pairing is supported.
15 | ///
16 | None,
17 |
18 | ///
19 | /// The application must confirm they wish to perform the pairing action. You can present an optional confirmation dialog to the user.
20 | /// With a value of ConfirmOnly, call Accept from the event args of the PairingRequested event handler if you want the pairing to complete.
21 | ///
22 | ConfirmOnly = 1,
23 |
24 | ///
25 | /// The application must display the given PIN to the user. The user will then need to enter or confirm that PIN on the device that is being paired.
26 | /// With a value of DisplayPin, call Accept from the event args of the PairingRequested event handler if you want the pairing to complete.
27 | /// If your application cancels the pairing at this point, the device might still be paired. This is because the system and the target
28 | /// device don't need any confirmation for this DevicePairingKinds value.
29 | ///
30 | DisplayPin = 2,
31 |
32 | ///
33 | /// The application must request a PIN from the user. The PIN will typically be displayed on the target device. With a value of ProvidePin,
34 | /// call Accept from the event args of the PairingRequested event handler if you want the pairing to complete. Pass in the PIN as a parameter.
35 | ///
36 | ProvidePin = 4,
37 |
38 | ///
39 | /// The application must display the given PIN to the user and ask the user to confirm that the PIN matches the one show on the target device.
40 | /// With a value of ConfirmPinMatch, call Accept from the event args of the PairingRequested event handler if you want the pairing to complete.
41 | ///
42 | ConfirmPinMatch = 8,
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DevicePairingProtectionLevel.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// The level of protection for pairing.
10 | ///
11 | public enum DevicePairingProtectionLevel
12 | {
13 | ///
14 | /// The default value. This should not be used.
15 | ///
16 | Default = 0,
17 |
18 | ///
19 | /// Pair the device using no levels of protection.
20 | ///
21 | None = 1,
22 |
23 | ///
24 | /// Pair the device using encryption.
25 | ///
26 | Encryption = 2,
27 |
28 | ///
29 | /// Pair the device using encryption and authentication.
30 | ///
31 | EncryptionAndAuthentication = 3
32 | }
33 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DevicePairingRequestedEventArgs.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | using System;
7 | using System.Runtime.CompilerServices;
8 | using System.Text;
9 |
10 | namespace nanoFramework.Device.Bluetooth
11 | {
12 | ///
13 | /// This class contains the arguments for the Pairing event.
14 | ///
15 | public class DevicePairingRequestedEventArgs
16 | {
17 | private readonly DevicePairing _pairing;
18 | private readonly ushort _connectionHandle;
19 | private readonly DevicePairingKinds _kind;
20 | private readonly uint _pin;
21 |
22 | internal DevicePairingRequestedEventArgs(DevicePairing pairing, ushort connectionHandle, DevicePairingKinds kind, uint pin)
23 | {
24 | _pairing = pairing;
25 | _connectionHandle = connectionHandle;
26 | _kind = kind;
27 | _pin = pin;
28 | }
29 |
30 | ///
31 | /// Gets the kind of pairing associated with this pairing event.
32 | ///
33 | public DevicePairingKinds PairingKind { get => _kind; }
34 |
35 | ///
36 | /// Gets the pin associated with a pairing request.
37 | ///
38 | public uint Pin { get => _pin; }
39 |
40 | ///
41 | /// Accepts a PairingRequested event and pairs the device with the application.
42 | ///
43 | public void Accept()
44 | {
45 | NativeAcceptYesNo(_connectionHandle, _kind, 1);
46 | }
47 |
48 | ///
49 | /// Accepts a PairingRequested event and pairs the device with the application.
50 | /// Requires a passkey for pairing purposes.
51 | ///
52 | /// The pass key for pairing.
53 | public void Accept(int passkey)
54 | {
55 | NativeAcceptPasskey(_connectionHandle, _kind, passkey);
56 | }
57 |
58 | ///
59 | /// Accepts a PairingRequested event and pairs the device with the application when
60 | /// a user name and password is required for pairing purposes.
61 | ///
62 | /// The password credential.
63 | public void AcceptWithPasswordCredential(PasswordCredential password)
64 | {
65 | NativeAcceptCredentials(_connectionHandle, _kind, Encoding.UTF8.GetBytes(password.UserName), Encoding.UTF8.GetBytes(password.Password));
66 | }
67 |
68 | #region external calls to native implementations
69 |
70 | [MethodImpl(MethodImplOptions.InternalCall)]
71 | private extern ushort NativeAcceptYesNo(ushort connectionHandle, DevicePairingKinds kind, int YesNo);
72 |
73 | [MethodImpl(MethodImplOptions.InternalCall)]
74 | private extern ushort NativeAcceptPasskey(ushort connectionHandle, DevicePairingKinds kind, int passkey);
75 |
76 | [MethodImpl(MethodImplOptions.InternalCall)]
77 | private extern ushort NativeAcceptCredentials(ushort connectionHandle, DevicePairingKinds kind, byte[] username, byte[] password);
78 |
79 | #endregion
80 | }
81 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DevicePairingResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Contains information about the result of attempting to pair a device.
10 | ///
11 | public class DevicePairingResult
12 | {
13 | private readonly DevicePairingProtectionLevel _protectionLevelUsed;
14 | private readonly DevicePairingResultStatus _status;
15 |
16 | internal DevicePairingResult(DevicePairingProtectionLevel protectionLevelUsed, DevicePairingResultStatus status)
17 | {
18 | _protectionLevelUsed = protectionLevelUsed;
19 | _status = status;
20 | }
21 |
22 | ///
23 | /// Gets the level of protection used to pair the device.
24 | ///
25 | public DevicePairingProtectionLevel ProtectionLevelUsed { get => _protectionLevelUsed; }
26 |
27 | ///
28 | /// Gets the paired status of the device after the pairing action completed.
29 | ///
30 | public DevicePairingResultStatus Status { get => _status; }
31 | }
32 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DevicePairingResultStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// The result of the pairing action.
10 | ///
11 | public enum DevicePairingResultStatus
12 | {
13 | ///
14 | /// The device object is now paired.
15 | ///
16 | Paired = 0,
17 |
18 | ///
19 | /// The device object is not in a state where it can be paired.
20 | ///
21 | NotReadyToPair = 1,
22 |
23 | ///
24 | /// The device object is not currently paired.
25 | ///
26 | NotPaired = 2,
27 |
28 | ///
29 | /// The device object has already been paired.
30 | ///
31 | AlreadyPaired = 3,
32 |
33 | ///
34 | /// The device object rejected the connection.
35 | ///
36 | ConnectionRejected = 4,
37 |
38 | ///
39 | /// The device object indicated it cannot accept any more incoming connections.
40 | ///
41 | TooManyConnections = 5,
42 |
43 | ///
44 | /// The device object indicated there was a hardware failure.
45 | ///
46 | HardwareFailure = 6,
47 |
48 | ///
49 | /// The authentication process timed out before it could complete.
50 | ///
51 | AuthenticationTimeout = 7,
52 |
53 | ///
54 | /// The authentication protocol is not supported, so the device is not paired.
55 | ///
56 | AuthenticationNotAllowed = 8,
57 |
58 | ///
59 | /// Authentication failed, so the device is not paired. Either the device object
60 | /// or the application rejected the authentication.
61 | ///
62 | AuthenticationFailure = 9,
63 |
64 | ///
65 | /// here are no network profiles for this device object to use.
66 | ///
67 | NoSupportedProfiles = 10,
68 |
69 | ///
70 | /// The minimum level of protection is not supported by the device object or the
71 | /// application.
72 | ///
73 | ProtectionLevelCouldNotBeMet = 11,
74 |
75 | ///
76 | /// Your application does not have the appropriate permissions level to pair the
77 | /// device object.
78 | ///
79 | AccessDenied = 12,
80 |
81 | ///
82 | /// The ceremony data was incorrect.
83 | ///
84 | InvalidCeremonyData = 13,
85 |
86 | ///
87 | /// The pairing action was cancelled before completion.
88 | ///
89 | PairingCanceled = 14,
90 |
91 | ///
92 | /// The device object is already attempting to pair or unpair.
93 | ///
94 | OperationAlreadyInProgress = 15,
95 |
96 | ///
97 | /// Either the event handler wasn't registered or a required DevicePairingKinds was
98 | /// not supported.
99 | ///
100 | RequiredHandlerNotRegistered = 16,
101 |
102 | ///
103 | /// The application handler rejected the pairing.
104 | ///
105 | RejectedByHandler = 17,
106 |
107 | ///
108 | /// The remove device already has an association.
109 | ///
110 | RemoteDeviceHasAssociation = 18,
111 |
112 | ///
113 | /// An unknown failure occurred.
114 | ///
115 | Failed = 19
116 | }
117 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DeviceUnpairingResult.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Contains information about the result of attempting to unpair a device.
10 | ///
11 | public class DeviceUnpairingResult
12 | {
13 | private readonly DeviceUnpairingResultStatus _status;
14 |
15 | internal DeviceUnpairingResult(DeviceUnpairingResultStatus status)
16 | {
17 | _status = status;
18 | }
19 |
20 |
21 | ///
22 | /// Gets the paired status of the device after the pairing action completed.
23 | ///
24 | public DeviceUnpairingResultStatus Status => _status;
25 | }
26 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/DeviceUnpairingResultStatus.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// The result of the unpairing action.
10 | ///
11 | public enum DeviceUnpairingResultStatus
12 | {
13 | ///
14 | /// The device object is successfully unpaired.
15 | ///
16 | Unpaired = 0,
17 |
18 | ///
19 | /// The device object is already unpaired.
20 | ///
21 | AlreadyUnpaired = 1,
22 |
23 | ///
24 | /// Upairing operation already in progress.
25 | ///
26 | OperationAlreadyInProgress = 2,
27 |
28 | ///
29 | /// The caller does not have sufficient permissions to unpair the device.
30 | ///
31 | AccessDenied = 3,
32 |
33 | ///
34 | /// An unknown failure occurred.
35 | ///
36 | Failed = 4
37 | }
38 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/Security/PasswordCredential.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) .NET Foundation and Contributors
3 | // See LICENSE file in the project root for full license information.
4 | //
5 |
6 | namespace nanoFramework.Device.Bluetooth
7 | {
8 | ///
9 | /// Class to hold password credentials.
10 | ///
11 | public class PasswordCredential
12 | {
13 | private readonly string _username;
14 | private readonly string _password;
15 |
16 | ///
17 | /// Constructs a Password Credential.
18 | ///
19 | /// User name in credential.
20 | /// Password for user name.
21 | public PasswordCredential(string userName, string password)
22 | {
23 | _username = userName;
24 | _password = password;
25 | }
26 |
27 | ///
28 | /// Gets password from Credential.
29 | ///
30 | public string Password { get => _password; }
31 |
32 | ///
33 | /// Gets User name from Credential.
34 | ///
35 | public string UserName { get => _username; }
36 | }
37 | }
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nanoframework/nanoFramework.Device.Bluetooth/2d3570a78f84764b9bf234b665ae319a3e9ca216/nanoFramework.Device.Bluetooth/key.snk
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/nanoFramework.Device.Bluetooth/packages.lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "dependencies": {
4 | ".NETnanoFramework,Version=v1.0": {
5 | "nanoFramework.CoreLibrary": {
6 | "type": "Direct",
7 | "requested": "[1.17.11, 1.17.11]",
8 | "resolved": "1.17.11",
9 | "contentHash": "HezzAc0o2XrSGf85xSeD/6xsO6ohF9hX6/iMQ1IZS6Zw6umr4WfAN2Jv0BrPxkaYwzEegJxxZujkHoUIAqtOMw=="
10 | },
11 | "nanoFramework.Runtime.Events": {
12 | "type": "Direct",
13 | "requested": "[1.11.32, 1.11.32]",
14 | "resolved": "1.11.32",
15 | "contentHash": "NyLUIwJDlpl5VKSd+ljmdDtO2WHHBvPvruo1ccaL+hd79z+6XMYze1AccOVXKGiZenLBCwDmFHwpgIQyHkM7GA=="
16 | },
17 | "nanoFramework.Runtime.Native": {
18 | "type": "Direct",
19 | "requested": "[1.7.11, 1.7.11]",
20 | "resolved": "1.7.11",
21 | "contentHash": "XPSTltZ9KeBruogVmjQpCphi1nLoJH49mpyp2eGBs8BTjKuL5TkMO20MoI8r73F/PW5AppTq49HvIZZavU5nPQ=="
22 | },
23 | "nanoFramework.System.Collections": {
24 | "type": "Direct",
25 | "requested": "[1.5.67, 1.5.67]",
26 | "resolved": "1.5.67",
27 | "contentHash": "MjSipUB70vrxjqTm1KfKTUqqjd0wbweiNyYFXONi0XClrH6HXsuX2lhDqXM8NWuYnWyYOqx8y20sXbvsH+4brg=="
28 | },
29 | "nanoFramework.System.Text": {
30 | "type": "Direct",
31 | "requested": "[1.3.42, 1.3.42]",
32 | "resolved": "1.3.42",
33 | "contentHash": "68HPjhersNpssbmEMUHdMw3073MHfGTfrkbRk9eILKbNPFfPFck7m4y9BlAi6DaguUJaeKxgyIojXF3SQrF8/A=="
34 | },
35 | "Nerdbank.GitVersioning": {
36 | "type": "Direct",
37 | "requested": "[3.7.115, 3.7.115]",
38 | "resolved": "3.7.115",
39 | "contentHash": "EpXamaAdRfG/BMxGgvZlTM0npRnkmXUjAj8OdNKd17t4oN+2nvjdv/KnFmzOOMDqvlwB49UCwtOHJrAQTfUBtQ=="
40 | }
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3 | "version": "1.1",
4 | "assemblyVersion": {
5 | "precision": "build"
6 | },
7 | "semVer1NumericIdentifierPadding": 3,
8 | "nuGetPackageVersion": {
9 | "semVer": 2.0
10 | },
11 | "publicReleaseRefSpec": [
12 | "^refs/heads/main$",
13 | "^refs/heads/v\\d+(?:\\.\\d+)?$"
14 | ],
15 | "cloudBuild": {
16 | "setAllVariables": true,
17 | "buildNumber": null
18 | },
19 | "release": {
20 | "branchName": "release-v{version}",
21 | "versionIncrement": "build",
22 | "firstUnstableTag": "preview"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------