establishDtlsHandshake static method
Establish a DTLS handshake with the bridge.
Returns true
if the handshake was successful, false
otherwise.
The bridge
parameter is the bridge to establish the handshake with.
decrypter
When the old tokens are read from local storage, they are
decrypted. This parameter allows you to provide your own decryption
method. This will be used in addition to the default decryption method.
This will be performed after the default decryption method.
May throw ExpiredAccessTokenException if trying to connect to the bridge remotely and the token is expired. If this happens, refresh the token with TokenRepo.refreshRemoteToken.
Implementation
static Future<bool> establishDtlsHandshake({
required Bridge bridge,
required DtlsData dtlsData,
String Function(String)? decrypter,
}) async {
final String? bridgeIpAddr = bridge.ipAddress;
final String? clientKey = bridge.clientKey;
final String? appKey = bridge.applicationKey;
if (bridgeIpAddr == null) return false;
if (clientKey == null) return false;
if (appKey == null) return false;
final String? appId = await _fetchAppId(bridgeIpAddr, appKey, decrypter);
if (appId == null) return false;
List<int> clientKeyBytes = [];
for (int i = 0; i < clientKey.length; i += 2) {
String hex = clientKey.substring(i, i + 2);
clientKeyBytes.add(int.parse(hex, radix: 16));
}
final DtlsClientContext clientContext = DtlsClientContext(
verify: true,
withTrustedRoots: true,
ciphers: 'PSK-AES128-GCM-SHA256',
pskCredentialsCallback: (_) {
return PskCredentials(
identity: utf8.encode(appId),
preSharedKey: clientKeyBytes,
);
},
);
List<String>? possibleIpAddresses = await _fetchIpAddr();
if (possibleIpAddresses == null) return false;
// Flush out old connection data.
await dtlsData.tryDispose();
for (String ipAddress in possibleIpAddresses) {
try {
dtlsData.dtlsClient = await DtlsClient.bind(ipAddress, 0);
} catch (e) {
continue;
}
try {
dtlsData.connection = await dtlsData.dtlsClient!.connect(
InternetAddress(bridgeIpAddr),
2100,
clientContext,
timeout: const Duration(seconds: 5),
);
break;
} catch (e) {
await dtlsData.tryCloseClient();
continue;
}
}
if (dtlsData.dtlsClient == null) return false;
if (dtlsData.connection == null) {
await dtlsData.tryCloseClient();
return false;
}
return true;
}