Skip to content
This repository was archived by the owner on May 20, 2024. It is now read-only.

Commit 63e9b08

Browse files
committed
Save Bluetooth-Pairing result
Connect to devices on startup
1 parent 755ea77 commit 63e9b08

15 files changed

+236
-67
lines changed

Nuki UWP/App.xaml.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
7373
if (shell == null) {
7474
// Create a Shell which navigates to the first page
7575
shell = new Shell();
76-
76+
shell.BeginLoad();
7777
// hook-up shell root frame navigation events
7878
shell.RootFrame.NavigationFailed += OnNavigationFailed;
7979
shell.RootFrame.Navigated += OnNavigated;

Nuki UWP/Assets/nuki_initial.jpg

2.46 KB
Loading

Nuki UWP/Nuki.csproj

-2
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
<DependentUpon>Setup03NamePage.xaml</DependentUpon>
124124
</Compile>
125125
<Compile Include="Settings\NukiAppSettings.cs" />
126-
<Compile Include="Settings\NukiDeviceSetting.cs" />
127126
<Compile Include="Shell.xaml.cs">
128127
<DependentUpon>Shell.xaml</DependentUpon>
129128
</Compile>
@@ -142,7 +141,6 @@
142141
</Compile>
143142
<Compile Include="Presentation\Command.cs" />
144143
<Compile Include="Presentation\MenuItem.cs" />
145-
<Compile Include="Presentation\NotifyPropertyChanged.cs" />
146144
<Compile Include="Presentation\ObjectToMenuItemConverter.cs" />
147145
<Compile Include="Presentation\ShellViewModel.cs" />
148146
<Compile Include="SwipeableSplitView.cs" />

Nuki UWP/Pages/Setup/Setup04PairDevice.xaml.cs

+8-8
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ await this.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
106106
Debug.WriteLine($"{keyValue.Key} = {keyValue.Value}");
107107
}
108108

109-
if (deviceInfo.Name.StartsWith("Nuki_",StringComparison.OrdinalIgnoreCase) &&
110-
!ResultCollection.Contains(deviceInfo) &&
109+
if (deviceInfo.Name.StartsWith("Nuki_", StringComparison.OrdinalIgnoreCase) &&
110+
!ResultCollection.Contains(deviceInfo) &&
111111
!string.IsNullOrEmpty(deviceInfo.Name))
112112
{
113113
StatusText.Text = $"{deviceInfo.Name} gefunden, starte pairing...";
@@ -200,6 +200,7 @@ private async Task<bool> TryToPairDevice(DeviceInformation deviceInfo)
200200
if (deviceInfo.Pairing.IsPaired != true)
201201
{
202202
paired = false;
203+
203204
DevicePairingKinds ceremoniesSelected = DevicePairingKinds.ConfirmOnly | DevicePairingKinds.DisplayPin | DevicePairingKinds.ProvidePin | DevicePairingKinds.ConfirmPinMatch;
204205
DevicePairingProtectionLevel protectionLevel = DevicePairingProtectionLevel.Default;
205206

@@ -272,13 +273,13 @@ private void StartBLEWatcher()
272273
{
273274
await Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
274275
{
275-
Debug.WriteLine("OnBLEAdded: " + deviceInfo.Id);
276+
Debug.WriteLine("OnBLEAdded: " + deviceInfo.Id + ", Name: " + deviceInfo.Name);
276277

277-
var blCon = BluetoothConnection.Connections[deviceInfo.Id];
278+
var blCon = BluetoothConnection.Connections[deviceInfo.Name];
278279

279280
if (await blCon.Connect(deviceInfo.Id))
280281
{
281-
var pairResult = await blCon.PairDevice();
282+
var pairResult = await blCon.PairDevice("MyLock");
282283
var status = pairResult.Status;
283284

284285
switch (status)
@@ -287,9 +288,8 @@ await Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
287288
btnProceed.IsEnabled = true;
288289
StatusText.Text = "Pairing erfolgreich";
289290
progressRing.IsActive = false;
290-
var settings = await NukiAppSettings.Load();
291-
settings.PairdLocks.Add(new NukiDeviceSetting { Name = "New Lock", ConnectionInfo = pairResult.ConnectionInfo });
292-
await settings.Save();
291+
Shell.Current.AppSettings.PairdLocks.Add( pairResult.ConnectionInfo );
292+
await Shell.Current.AppSettings.Save();
293293
break;
294294
case BlutoothPairStatus.Failed:
295295
case BlutoothPairStatus.Timeout:

Nuki UWP/Presentation/MenuItem.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using Nuki.Communication.Util;
2+
using System;
23
using System.Collections.Generic;
34
using System.ComponentModel;
45
using System.Linq;

Nuki UWP/Presentation/ShellViewModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using System.Threading.Tasks;
77
using System.Windows.Input;
88
using Windows.UI.Xaml;
9-
using Windows.UI.Xaml.Controls;
9+
using Nuki.Communication.Util;
1010

1111
namespace Nuki.Presentation
1212
{

Nuki UWP/Settings/NukiAppSettings.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using Nuki.Communication.Connection;
2+
using System;
23
using System.Collections.Generic;
34
using System.Collections.ObjectModel;
45
using System.Linq;
@@ -29,10 +30,10 @@ public Task Save()
2930
#endregion
3031

3132

32-
public ObservableCollection<NukiDeviceSetting> PairdLocks
33+
public ObservableCollection<BluetoothConnectionInfo> PairdLocks
3334
{
3435
get; private set;
35-
} = new ObservableCollection<NukiDeviceSetting>();
36+
} = new ObservableCollection<BluetoothConnectionInfo>();
3637

3738
public NukiAppSettings()
3839
{

Nuki UWP/Settings/NukiDeviceSetting.cs

-17
This file was deleted.

Nuki UWP/Shell.xaml.cs

+23
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
using System.Threading.Tasks;
2424
using Nuki.Communication.Connection;
2525
using Windows.UI.Core;
26+
using Nuki.Settings;
2627

2728
namespace Nuki
2829
{
2930

3031
public sealed partial class Shell : UserControl
3132
{
33+
public NukiAppSettings AppSettings { get; private set; }
3234
public Shell()
3335
{
3436
this.InitializeComponent();
@@ -50,6 +52,27 @@ public Shell()
5052
transitions.Add(transition);
5153
this.Frame.ContentTransitions = transitions;
5254
this.ViewModel.PropertyChanged += ViewModel_PropertyChanged;
55+
base.Loading += Shell_Loading;
56+
}
57+
58+
private async void Shell_Loading(FrameworkElement sender, object args)
59+
{
60+
await BeginLoad();
61+
}
62+
63+
private Task m_initTask = null;
64+
public Task BeginLoad()
65+
{
66+
if (m_initTask == null)
67+
{
68+
m_initTask = Task.Run(async () =>
69+
{
70+
AppSettings = await NukiAppSettings.Load();
71+
BluetoothConnectionMonitor.Start(AppSettings.PairdLocks);
72+
});
73+
}
74+
else { }
75+
return m_initTask;
5376
}
5477

5578
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)

Nuki.Communication/Connection/BluetoothConnection.cs

+26-25
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ public class BluetoothConnection : IConnectionContext
3232
private BluetoothGattCharacteristicConnection m_pairingGDIO = null;
3333
private BluetoothGattCharacteristicConnection m_GDIO = null;
3434
private BluetoothGattCharacteristicConnection m_UGDIO = null;
35-
public string DeviceID { get; private set; }
35+
public string DeviceName => m_connectionInfo.DeviceName;
3636
public static Collection Connections => Collection.Instance;
37-
private BluetoothConnectionInfo connectionInfo = new BluetoothConnectionInfo();
38-
public ClientPublicKey ClientPublicKey => connectionInfo.ClientPublicKey;
39-
public SmartLockPublicKey SmartLockPublicKey => connectionInfo.SmartLockPublicKey;
40-
public SharedKey SharedKey => connectionInfo.SharedKey;
41-
public UniqueClientID UniqueClientID => connectionInfo.UniqueClientID;
42-
public SmartLockUUID SmartLockUUID => connectionInfo.SmartLockUUID;
37+
private BluetoothConnectionInfo m_connectionInfo = new BluetoothConnectionInfo();
38+
public ClientPublicKey ClientPublicKey => m_connectionInfo.ClientPublicKey;
39+
public SmartLockPublicKey SmartLockPublicKey => m_connectionInfo.SmartLockPublicKey;
40+
public SharedKey SharedKey => m_connectionInfo.SharedKey;
41+
public UniqueClientID UniqueClientID => m_connectionInfo.UniqueClientID;
42+
public SmartLockUUID SmartLockUUID => m_connectionInfo.SmartLockUUID;
4343

4444
public SmartLockNonce SmartLockNonce
4545
{
@@ -66,36 +66,37 @@ private string RemoveServiceID(string strDeviceID)
6666
var matches = regex.Matches(strDeviceID);
6767
return matches[matches.Count - 1]?.Groups["GUID"]?.Value ?? strDeviceID;
6868
}
69-
public BluetoothConnection this[string strDeviceID]
69+
public BluetoothConnection this[string strDeviceName]
7070
{
7171
get
7272
{
7373
BluetoothConnection connection = null;
74-
string strUniqueID = RemoveServiceID(strDeviceID);
75-
if (!s_Connections.TryGetValue(strUniqueID, out connection))
74+
if (!s_Connections.TryGetValue(strDeviceName, out connection))
7675
{
77-
s_Connections.TryAdd(strUniqueID, new BluetoothConnection(strUniqueID));
78-
s_Connections.TryGetValue(strUniqueID, out connection);
76+
s_Connections.TryAdd(strDeviceName, new BluetoothConnection(strDeviceName));
77+
s_Connections.TryGetValue(strDeviceName, out connection);
7978
}
8079
else { }
8180
return connection;
8281
}
8382
}
8483
}
8584

86-
private BluetoothConnection(string strUniqeDeviceID)
85+
private BluetoothConnection(string strDeviceName)
8786
{
88-
DeviceID = strUniqeDeviceID;
89-
connectionInfo.UniqueClientID = new UniqueClientID(5);
87+
m_connectionInfo.DeviceName = strDeviceName;
88+
m_connectionInfo.UniqueClientID = new UniqueClientID(5);
9089
m_pairingGDIO = new BluetoothGattCharacteristicConnection();
9190
m_GDIO = new BluetoothGattCharacteristicConnection();
9291
m_UGDIO = new BluetoothGattCharacteristicConnection();
9392
}
94-
public async Task<bool> Connect(string strDeviceID)
93+
public async Task<bool> Connect(string strDeviceID, BluetoothConnectionInfo connectionInfo = null)
9594
{
9695
bool blnRet = false;
9796
try
9897
{
98+
if (connectionInfo != null)
99+
m_connectionInfo = connectionInfo;
99100
var deviceService = await GattDeviceService.FromIdAsync(strDeviceID);
100101
if (deviceService != null)
101102
{
@@ -104,15 +105,14 @@ public async Task<bool> Connect(string strDeviceID)
104105
if (character.Uuid == KeyTurnerGDIO.Value)
105106
{
106107
m_GDIO.SetConnection(character);
107-
connectionInfo.DeviceID = strDeviceID;
108108
}
109109
else if (character.Uuid == KeyTurnerPairingGDIO.Value)
110110
{
111111
m_pairingGDIO.SetConnection(character);
112112
}
113113
else if (character.Uuid == KeyTurnerUGDIO.Value)
114114
{
115-
connectionInfo.DeviceID = strDeviceID;
115+
116116
m_UGDIO.SetConnection(character);
117117
}
118118
}
@@ -134,7 +134,7 @@ public async Task<bool> Connect(string strDeviceID)
134134

135135

136136

137-
public async Task<BluetoothPairResult> PairDevice()
137+
public async Task<BluetoothPairResult> PairDevice(string strConnectionName)
138138
{
139139
BlutoothPairStatus status = BlutoothPairStatus.Failed;
140140
try
@@ -146,7 +146,8 @@ public async Task<BluetoothPairResult> PairDevice()
146146

147147
SendBaseCommand cmd = new SendRequestDataCommand(CommandTypes.PublicKey);
148148
Sodium.KeyPair keyPair = Sodium.PublicKeyBox.GenerateKeyPair();
149-
connectionInfo.ClientPublicKey = new ClientPublicKey(keyPair.Public);
149+
m_connectionInfo.ClientPublicKey = new ClientPublicKey(keyPair.Public);
150+
m_connectionInfo.ConnectionName = strConnectionName;
150151
if (await m_pairingGDIO.Send(cmd)) //3.
151152
{
152153
var response = await m_pairingGDIO.Recieve(2000); //4.
@@ -160,12 +161,12 @@ public async Task<BluetoothPairResult> PairDevice()
160161

161162
if (await m_pairingGDIO.Send(cmd)) //6.
162163
{
163-
connectionInfo.SmartLockPublicKey = ((RecievePublicKeyCommand)response).PublicKey;
164+
m_connectionInfo.SmartLockPublicKey = ((RecievePublicKeyCommand)response).PublicKey;
164165

165166
byte[] byDH1 = Sodium.ScalarMult.Mult(keyPair.Secret, SmartLockPublicKey);
166167
var _0 = new byte[16];
167168
var sigma = System.Text.Encoding.UTF8.GetBytes("expand 32-byte k");
168-
connectionInfo.SharedKey = new SharedKey(Sodium.KDF.HSalsa20(_0, byDH1, sigma)); //8
169+
m_connectionInfo.SharedKey = new SharedKey(Sodium.KDF.HSalsa20(_0, byDH1, sigma)); //8
169170

170171
response = await m_pairingGDIO.Recieve(2000);
171172

@@ -193,8 +194,8 @@ public async Task<BluetoothPairResult> PairDevice()
193194

194195
if (response?.CommandType == CommandTypes.AuthorizationID) //19
195196
{
196-
connectionInfo.UniqueClientID = ((RecieveAuthorizationIDCommand)response).UniqueClientID;
197-
connectionInfo.SmartLockUUID = ((RecieveAuthorizationIDCommand)response).SmartLockUUID;
197+
m_connectionInfo.UniqueClientID = ((RecieveAuthorizationIDCommand)response).UniqueClientID;
198+
m_connectionInfo.SmartLockUUID = ((RecieveAuthorizationIDCommand)response).SmartLockUUID;
198199
this.SmartLockNonce = ((RecieveAuthorizationIDCommand)response).SmartLockNonce;
199200
cmd = new SendAuthorization­IDConfirmationCommand(UniqueClientID, this);
200201

@@ -289,7 +290,7 @@ public async Task<BluetoothPairResult> PairDevice()
289290
Debug.WriteLine("Error in pairing: {0}", ex);
290291
status = BlutoothPairStatus.Failed;
291292
}
292-
return new BluetoothPairResult(status, (status == BlutoothPairStatus.Successfull) ? connectionInfo : null);
293+
return new BluetoothPairResult(status, (status == BlutoothPairStatus.Successfull) ? m_connectionInfo : null);
293294
}
294295

295296
public ClientNonce CreateNonce()
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Nuki.Communication.SemanticTypes;
2+
using Nuki.Communication.Util;
23
using System;
34
using System.Collections.Generic;
45
using System.Linq;
@@ -7,14 +8,50 @@
78

89
namespace Nuki.Communication.Connection
910
{
10-
public class BluetoothConnectionInfo
11+
public class BluetoothConnectionInfo : NotifyPropertyChanged
1112
{
12-
public ClientPublicKey ClientPublicKey { get; set; }
13-
public SharedKey SharedKey { get; set; }
14-
public UniqueClientID UniqueClientID { get; set; }
15-
public SmartLockPublicKey SmartLockPublicKey { get; set; }
16-
public SmartLockUUID SmartLockUUID { get; set; }
13+
private ClientPublicKey m_ClientPublicKey = null;
14+
private SharedKey m_SharedKey = null;
15+
private UniqueClientID m_UniqueClientID = null;
16+
private SmartLockPublicKey m_SmartLockPublicKey = null;
17+
private SmartLockUUID m_SmartLockUUID = null;
18+
private string m_strConnectionName = null;
19+
private string m_strDeviceName = null;
1720

18-
public string DeviceID { get; set; }
21+
public ClientPublicKey ClientPublicKey
22+
{
23+
get { return m_ClientPublicKey; }
24+
set { Set(ref this.m_ClientPublicKey, value); }
25+
}
26+
public SharedKey SharedKey
27+
{
28+
get { return m_SharedKey; }
29+
set { Set(ref this.m_SharedKey, value); }
30+
}
31+
public UniqueClientID UniqueClientID
32+
{
33+
get { return m_UniqueClientID; }
34+
set { Set(ref this.m_UniqueClientID, value); }
35+
}
36+
public SmartLockPublicKey SmartLockPublicKey
37+
{
38+
get { return m_SmartLockPublicKey; }
39+
set { Set(ref this.m_SmartLockPublicKey, value); }
40+
}
41+
public SmartLockUUID SmartLockUUID
42+
{
43+
get { return m_SmartLockUUID; }
44+
set { Set(ref this.m_SmartLockUUID, value); }
45+
}
46+
public string ConnectionName
47+
{
48+
get { return m_strConnectionName; }
49+
set { Set(ref this.m_strConnectionName, value); }
50+
}
51+
public string DeviceName
52+
{
53+
get { return m_strDeviceName; }
54+
set { Set(ref this.m_strDeviceName, value); }
55+
}
1956
}
2057
}

0 commit comments

Comments
 (0)