Setup code works with new version
This commit is contained in:
@@ -54,7 +54,13 @@
|
|||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
||||||
<key>NSLocalNetworkUsageDescription</key>
|
<key>NSLocalNetworkUsageDescription</key>
|
||||||
<string>This app uses the local network for debugging and development.</string>
|
<string>Allow the app to find and connect to the Dart VM for debugging purposes.</string>
|
||||||
|
|
||||||
|
<key>NSBonjourServices</key>
|
||||||
|
<array>
|
||||||
|
<string>_dartvm._tcp</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import 'package:socket_io_client/socket_io_client.dart' as IO;
|
|||||||
String local = Platform.isAndroid ? '10.0.2.2' : 'localhost';
|
String local = Platform.isAndroid ? '10.0.2.2' : 'localhost';
|
||||||
String fromDevice = '192.168.1.190';
|
String fromDevice = '192.168.1.190';
|
||||||
|
|
||||||
String host = local;
|
String host = fromDevice;
|
||||||
int port = 3000;
|
int port = 3000;
|
||||||
String socketString = "$scheme://$host:$port";
|
String socketString = "$scheme://$host:$port";
|
||||||
String scheme = 'http';
|
String scheme = 'http';
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ class _AddDeviceState extends State<AddDevice> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildScanResultTiles() {
|
Widget _buildScanResultTiles() {
|
||||||
final res = _scanResults.where((r) => r.advertisementData.advName == "BlindMaster Device" && r.rssi > -55);
|
// final res = _scanResults.where((r) => r.advertisementData.advName == "BlindMaster Device" && r.rssi > -55);
|
||||||
|
final res = _scanResults.where((r) => r.advertisementData.advName == "BlindMaster-C6");
|
||||||
return (res.isNotEmpty)
|
return (res.isNotEmpty)
|
||||||
? ListView(
|
? ListView(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class DeviceSetup extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _DeviceSetupState extends State<DeviceSetup> {
|
class _DeviceSetupState extends State<DeviceSetup> {
|
||||||
|
bool refreshing = false;
|
||||||
List<BluetoothService> _services = [];
|
List<BluetoothService> _services = [];
|
||||||
|
|
||||||
List<Map<String, dynamic>> networks = [];
|
List<Map<String, dynamic>> networks = [];
|
||||||
@@ -82,7 +83,8 @@ class _DeviceSetupState extends State<DeviceSetup> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final val = utf8.decode(rawData);
|
final val = utf8.decode(rawData);
|
||||||
networks = json.decode(val) as List<Map<String, dynamic>>;
|
final decoded = json.decode(val) as List;
|
||||||
|
networks = decoded.map((e) => e as Map<String, dynamic>).toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if(!mounted)return;
|
if(!mounted)return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
|
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
|
||||||
@@ -118,6 +120,12 @@ class _DeviceSetupState extends State<DeviceSetup> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
try {
|
||||||
|
await ssidRefreshChar.write(utf8.encode("Done"), withoutResponse: ssidRefreshChar.properties.writeWithoutResponse);
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception ("Handshake Termination Error. Restart setup process.");
|
||||||
|
}
|
||||||
|
refreshing = false;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if(!mounted)return;
|
if(!mounted)return;
|
||||||
@@ -242,7 +250,9 @@ class _DeviceSetupState extends State<DeviceSetup> {
|
|||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(dialogContext, passControl.text);
|
Navigator.pop(dialogContext, (ent ?
|
||||||
|
{"uname": unameControl.text, "password": passControl.text}
|
||||||
|
: (open ? {} : {"password": passControl.text})));
|
||||||
passControl.clear();
|
passControl.clear();
|
||||||
unameControl.clear();
|
unameControl.clear();
|
||||||
},
|
},
|
||||||
@@ -286,7 +296,8 @@ class _DeviceSetupState extends State<DeviceSetup> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final connectConfirmChar = _services[0].characteristics.lastWhere((c) => c.uuid.str == "0005");
|
final connectConfirmChar = _services[0].characteristics.lastWhere((c) => c.uuid.str == "0005");
|
||||||
final tokenEntryChar = _services[0].characteristics.lastWhere((c) => c.uuid.str == "0003");
|
final tokenEntryChar = _services[0].characteristics.lastWhere((c) => c.uuid.str == "0002");
|
||||||
|
final authConfirmChar = _services[0].characteristics.lastWhere((c) => c.uuid.str == "0003");
|
||||||
await connectConfirmChar.setNotifyValue(true);
|
await connectConfirmChar.setNotifyValue(true);
|
||||||
_confirmSub = connectConfirmChar.onValueReceived.listen((List<int> connectVal) {
|
_confirmSub = connectConfirmChar.onValueReceived.listen((List<int> connectVal) {
|
||||||
try {
|
try {
|
||||||
@@ -297,7 +308,7 @@ class _DeviceSetupState extends State<DeviceSetup> {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => SetDeviceName(tokenEntryChar: tokenEntryChar, device: widget.device),
|
builder: (context) => SetDeviceName(tokenEntryChar: tokenEntryChar, authConfirmChar: authConfirmChar, device: widget.device),
|
||||||
)
|
)
|
||||||
).then((_) {
|
).then((_) {
|
||||||
if (widget.device.isConnected) {
|
if (widget.device.isConnected) {
|
||||||
@@ -318,6 +329,8 @@ class _DeviceSetupState extends State<DeviceSetup> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future refreshWifiList() async{
|
Future refreshWifiList() async{
|
||||||
|
if (refreshing) return;
|
||||||
|
refreshing = true;
|
||||||
final ssidRefreshChar = _services[0].characteristics.lastWhere((c) => c.uuid.str == "0004");
|
final ssidRefreshChar = _services[0].characteristics.lastWhere((c) => c.uuid.str == "0004");
|
||||||
setState(() {
|
setState(() {
|
||||||
wifiList = null;
|
wifiList = null;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:blind_master/BlindMasterResources/error_snackbar.dart';
|
import 'package:blind_master/BlindMasterResources/error_snackbar.dart';
|
||||||
@@ -10,8 +11,9 @@ import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
|||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
class SetDeviceName extends StatefulWidget {
|
class SetDeviceName extends StatefulWidget {
|
||||||
const SetDeviceName({super.key, required this.tokenEntryChar, required this.device});
|
const SetDeviceName({super.key, required this.tokenEntryChar, required this.authConfirmChar, required this.device});
|
||||||
final BluetoothCharacteristic tokenEntryChar;
|
final BluetoothCharacteristic tokenEntryChar;
|
||||||
|
final BluetoothCharacteristic authConfirmChar;
|
||||||
final BluetoothDevice device;
|
final BluetoothDevice device;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -21,6 +23,7 @@ class SetDeviceName extends StatefulWidget {
|
|||||||
class _SetDeviceNameState extends State<SetDeviceName> {
|
class _SetDeviceNameState extends State<SetDeviceName> {
|
||||||
final deviceNameController = TextEditingController();
|
final deviceNameController = TextEditingController();
|
||||||
Widget? screen;
|
Widget? screen;
|
||||||
|
StreamSubscription<List<int>>? _authSub;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -30,6 +33,7 @@ class _SetDeviceNameState extends State<SetDeviceName> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_authSub?.cancel();
|
||||||
deviceNameController.dispose();
|
deviceNameController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
@@ -75,18 +79,22 @@ class _SetDeviceNameState extends State<SetDeviceName> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up authentication confirmation listener
|
||||||
try {
|
try {
|
||||||
try {
|
await widget.authConfirmChar.setNotifyValue(true);
|
||||||
await widget.tokenEntryChar.write(utf8.encode(token), withoutResponse: widget.tokenEntryChar.properties.writeWithoutResponse);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception("Token Write Error");
|
if (!mounted) return;
|
||||||
}
|
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(Exception("Failed to set up authentication listener")));
|
||||||
} catch (e){
|
|
||||||
if(!mounted)return;
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_authSub = widget.authConfirmChar.onValueReceived.listen((List<int> authVal) async {
|
||||||
|
try {
|
||||||
|
final authResponse = utf8.decode(authVal);
|
||||||
|
if (authResponse == "Authenticated") {
|
||||||
|
if (!mounted) return;
|
||||||
|
_authSub?.cancel();
|
||||||
|
|
||||||
await widget.device.disconnectAndUpdateStream().catchError((e) {
|
await widget.device.disconnectAndUpdateStream().catchError((e) {
|
||||||
if(!mounted) return;
|
if(!mounted) return;
|
||||||
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
|
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
|
||||||
@@ -98,6 +106,36 @@ class _SetDeviceNameState extends State<SetDeviceName> {
|
|||||||
MaterialPageRoute(builder: (context) => HomeScreen()),
|
MaterialPageRoute(builder: (context) => HomeScreen()),
|
||||||
(route) => false,
|
(route) => false,
|
||||||
);
|
);
|
||||||
|
} else if (authResponse == "Error") {
|
||||||
|
_authSub?.cancel();
|
||||||
|
throw Exception("Authentication failed. Please try again.");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (!mounted) return;
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
|
||||||
|
setState(() {
|
||||||
|
initScreen();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Write the token
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
await widget.tokenEntryChar.write(utf8.encode(token), withoutResponse: widget.tokenEntryChar.properties.writeWithoutResponse);
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception("Token Write Error");
|
||||||
|
}
|
||||||
|
} catch (e){
|
||||||
|
if(!mounted)return;
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(errorSnackbar(e));
|
||||||
|
_authSub?.cancel();
|
||||||
|
setState(() {
|
||||||
|
initScreen();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future onPressed() async {
|
Future onPressed() async {
|
||||||
@@ -120,7 +158,17 @@ class _SetDeviceNameState extends State<SetDeviceName> {
|
|||||||
body: SizedBox(
|
body: SizedBox(
|
||||||
height: MediaQuery.of(context).size.height * 0.6,
|
height: MediaQuery.of(context).size.height * 0.6,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: screen ?? CircularProgressIndicator(color: Theme.of(context).primaryColorLight),
|
child: screen ?? Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
CircularProgressIndicator(color: Theme.of(context).primaryColorLight),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Text(
|
||||||
|
"Authenticating device...",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user