diff --git a/star_lock/images/lan/lan_en.json b/star_lock/images/lan/lan_en.json index b5df7b69..6a8d884e 100644 --- a/star_lock/images/lan/lan_en.json +++ b/star_lock/images/lan/lan_en.json @@ -796,8 +796,32 @@ "购买":"Buy", "实名认证为付费功能,请购买后再使用":"Real-name authentication is a paid function, please use it after purchase", "密码不一致哦":"The passwords are inconsistent", + + "退出添加":"Quit adding", + "管理员已满":"Admin full", + "用户已满": "The user is full", + "锁上面添加指纹已满": "Add fingerprint on lock is full", + "指纹已存在": "The fingerprint already exists.", + "锁上面添加人脸已满": "Lock above add face is full", + "人脸已存在": "The face already exists", + "锁上面添加卡已满":"Lock above add card is full", + "卡已存在": "Card already exists", + "锁上面添加密码已满": "Lock above add password is full", + "密码已存在": "Password already exists", + "请输入密码": "Please enter password", + "真实姓名":"Real name", "身份证号":"ID number", "请输入真实姓名":"Please enter your real name", - "请输入身份证号":"Please enter your ID number" + "请输入身份证号":"Please enter your ID number", + "点击返回设备配对":"Tap Back to device pairing", + "无法连接?尝试升级":"Can't connect?Upgrade attempted", + "固件升级提示":"Firmware upgrade prompt", + "请先获取固件文件到手机本地,再选择升级":"Please obtain the firmware file to the local phone first, and then select Upgrade", + "固件升级中":"The firmware is being upgraded", + "取消升级":"Cancel the upgrade", + "固件传输中":"Firmware in transit", + "关闭":"Shut down", + "传输中'":"In transit" + } diff --git a/star_lock/images/lan/lan_keys.json b/star_lock/images/lan/lan_keys.json index fec4b6cc..42794399 100644 --- a/star_lock/images/lan/lan_keys.json +++ b/star_lock/images/lan/lan_keys.json @@ -823,8 +823,32 @@ "当前剩余数量":"当前剩余数量", "购买":"购买", "实名认证为付费功能,请购买后再使用":"实名认证为付费功能,请购买后再使用", + + "退出添加":"退出添加", + "管理员已满":"管理员已满", + "用户已满": "用户已满", + "锁上面添加指纹已满": "锁上面添加指纹已满", + "指纹已存在": "指纹已存在", + "锁上面添加人脸已满": "锁上面添加人脸已满", + "人脸已存在": "人脸已存在", + "锁上面添加卡已满":"锁上面添加卡已满", + "卡已存在": "卡已存在", + "锁上面添加密码已满": "锁上面添加密码已满", + "密码已存在": "密码已存在", + "请输入密码": "请输入密码", + "真实姓名":"真实姓名", "身份证号":"身份证号", "请输入真实姓名":"请输入真实姓名", - "请输入身份证号":"请输入身份证号" + "请输入身份证号":"请输入身份证号", + + "点击返回设备配对":"点击返回设备配对", + "无法连接?尝试升级":"无法连接?尝试升级", + "固件升级提示":"固件升级提示", + "请先获取固件文件到手机本地,再选择升级":"请先获取固件文件到手机本地,再选择升级", + "固件升级中":"固件升级中", + "取消升级":"取消升级", + "固件传输中":"固件传输中", + "关闭":"关闭", + "传输中'":"传输中" } diff --git a/star_lock/images/lan/lan_zh.json b/star_lock/images/lan/lan_zh.json index 81e1482a..ecb2ac64 100644 --- a/star_lock/images/lan/lan_zh.json +++ b/star_lock/images/lan/lan_zh.json @@ -826,8 +826,33 @@ "当前剩余数量":"当前剩余数量", "购买":"购买", "实名认证为付费功能,请购买后再使用":"实名认证为付费功能,请购买后再使用", + + "退出添加":"退出添加", + "管理员已满":"管理员已满", + "用户已满": "用户已满", + "锁上面添加指纹已满": "锁上面添加指纹已满", + "指纹已存在": "指纹已存在", + "锁上面添加人脸已满": "锁上面添加人脸已满", + "人脸已存在": "人脸已存在", + "锁上面添加卡已满":"锁上面添加卡已满", + "卡已存在": "卡已存在", + "锁上面添加密码已满": "锁上面添加密码已满", + "密码已存在": "密码已存在", + "请输入密码": "请输入密码", + "真实姓名":"真实姓名", "身份证号":"身份证号", "请输入真实姓名":"请输入真实姓名", - "请输入身份证号":"请输入身份证号" + "请输入身份证号":"请输入身份证号", + + "点击返回设备配对":"点击返回设备配对", + "无法连接?尝试升级":"无法连接?尝试升级", + "固件升级提示":"固件升级提示", + "请先获取固件文件到手机本地,再选择升级":"请先获取固件文件到手机本地,再选择升级", + "固件升级中":"固件升级中", + "取消升级":"取消升级", + "固件传输中":"固件传输中", + "关闭":"关闭", + "传输中'":"传输中" + } diff --git a/star_lock/images/ota_upgrade_icon.png b/star_lock/images/ota_upgrade_icon.png new file mode 100644 index 00000000..14618cb5 Binary files /dev/null and b/star_lock/images/ota_upgrade_icon.png differ diff --git a/star_lock/ios/Flutter/AppFrameworkInfo.plist b/star_lock/ios/Flutter/AppFrameworkInfo.plist index 9625e105..7c569640 100644 --- a/star_lock/ios/Flutter/AppFrameworkInfo.plist +++ b/star_lock/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/star_lock/lib/blue/blue_manage.dart b/star_lock/lib/blue/blue_manage.dart index 0c34dd25..72c3ebc7 100644 --- a/star_lock/lib/blue/blue_manage.dart +++ b/star_lock/lib/blue/blue_manage.dart @@ -145,7 +145,8 @@ class BlueManage { _connectionStateSubscription?.cancel(); _connectionStateSubscription = null; - _connectionStateSubscription = bluetoothConnectDevice!.connectionState.listen((state) async { + _connectionStateSubscription = + bluetoothConnectDevice!.connectionState.listen((state) async { bluetoothConnectionState = state; // AppLog.log("蓝牙连接状态:$state"); }); @@ -214,7 +215,9 @@ class BlueManage { completer.complete(); } }, onError: (e) { - AppLog.log("扫描失败:$e",); + AppLog.log( + "扫描失败:$e", + ); }); FlutterBluePlus.cancelWhenScanComplete(subscription); await completer.future; @@ -281,7 +284,9 @@ class BlueManage { // EventBusManager().eventBusFir(scanDevices); // FlutterBluePlus.stopScan(); }, onError: (e) { - AppLog.log("扫描失败:$e",); + AppLog.log( + "扫描失败:$e", + ); }); FlutterBluePlus.cancelWhenScanComplete(subscription); @@ -304,7 +309,9 @@ class BlueManage { } /// 调用发送数据 List senderData, - Future bludSendData(String deviceName, ConnectStateCallBack stateCallBack, {bool isAddEquipment = false}) async { + Future bludSendData( + String deviceName, ConnectStateCallBack stateCallBack, + {bool isAddEquipment = false}) async { FlutterBluePlus.isSupported.then((isAvailable) async { if (isAvailable) { if (_adapterState == BluetoothAdapterState.on) { @@ -336,21 +343,13 @@ class BlueManage { {bool isAddEquipment = false}) async { connectDeviceName = deviceName; List devicesList = scanDevices; - //判断列表里面有设备则不开启扫描 - bool isExistDevice = scanDevices.any((element) => - element.device.platformName == connectDeviceName || - element.advertisementData.advName == connectDeviceName); - if (isAddEquipment == false && isExistDevice == false) { - // AppLog.log("需要开启扫描"); - // startScan(10, (scanDevices){ - startScanSingle(deviceName, 10, (List scanDevices) { - // AppLog.log("扫描到的设备:$scanDevices"); - devicesList = scanDevices; + if (isAddEquipment == false) { + //取消缓存直接使用,存在配对场景设备信息会更变 + startScan(10, (List scanDevices) { _connectDevice(devicesList, deviceName, connectStateCallBack, isAddEquipment: isAddEquipment); }); } else { - // AppLog.log("不需要开启扫描"); _connectDevice(devicesList, deviceName, connectStateCallBack, isAddEquipment: isAddEquipment); } @@ -364,6 +363,7 @@ class BlueManage { final knownDeviceIndex = devicesList.indexWhere((d) => (d.device.platformName == deviceName) || (d.advertisementData.advName == deviceName)); + if (knownDeviceIndex >= 0) { // 存在的时候赋值 connectDeviceMacAddress = @@ -375,6 +375,7 @@ class BlueManage { // AppLog.log('bluetoothConnectDevice: $bluetoothConnectDevice'); scanResult = devicesList[knownDeviceIndex]; + _initGetMtuSubscription(); _initListenConnectionState(); } @@ -446,7 +447,8 @@ class BlueManage { } on Exception catch (e) { bluetoothConnectionState = BluetoothConnectionState.disconnected; connectStateCallBack(bluetoothConnectionState!); - AppLog.log('发现设备时失败 e:$e bluetoothConnectionState:$bluetoothConnectionState'); + AppLog.log( + '发现设备时失败 e:$e bluetoothConnectionState:$bluetoothConnectionState'); rethrow; } } @@ -461,7 +463,7 @@ class BlueManage { _subScribeToCharacteristic(BluetoothCharacteristic characteristic) async { final subscription = characteristic.onValueReceived.listen((data) { - // AppLog.log("订阅获取的数据:$data"); + AppLog.log("订阅获取的数据:$data"); if (data == lastTimeData || data.isEmpty) { return; } else { @@ -477,7 +479,7 @@ class BlueManage { // 判断是否需要分包 dataLen = data[8] * 256 + data[9]; // 高16位用来指示后面数据块内容的长度 // AppLog.log("dataLen1111:$dataLen getDataLength:${data.length} data:$data"); - if (dataLen! + 12 > data.length) { + if (dataLen! + 14 > data.length) { // 当前包的长度小于实际的包时 分包添加 不解析 allData.addAll(data); } else { @@ -492,7 +494,7 @@ class BlueManage { // 当包没有头时 是分包的包 直接添加 allData.addAll(data); // var len = allData[8] * 256 + allData[9]; - // AppLog.log("dataLen3333:$dataLen allData.length:${allData.length} allData:$allData"); + AppLog.log("dataLen3333:$dataLen allData.length:${allData.length} allData:$allData"); if ((dataLen! + 14) <= allData.length) { // 当长度小于等于当前包的数据时 直接解析数据 CommandReciverManager.appDataReceive(allData); @@ -555,15 +557,16 @@ class BlueManage { // 写入 Future writeCharacteristicWithResponse(List value) async { - - List services = await bluetoothConnectDevice!.discoverServices(); + List services = + await bluetoothConnectDevice!.discoverServices(); for (BluetoothService service in services) { // AppLog.log("33333 service.remoteId:${service.remoteId}" // " service.uuid:${service.uuid}\n\n" // " service.characteristics:${service.characteristics}\n\n" // " service.includedServices:${service.includedServices}"); if (service.uuid == _serviceIdConnect) { - for (BluetoothCharacteristic characteristic in service.characteristics) { + for (BluetoothCharacteristic characteristic + in service.characteristics) { // AppLog.log("44444 characteristic.remoteId:${characteristic.remoteId}" // " characteristic.uuid:${characteristic.uuid}\n\n" // " characteristic.secondaryServiceUuid:${characteristic @@ -578,7 +581,9 @@ class BlueManage { for (int i = 0; i < subData.length; i++) { if (characteristic.properties.writeWithoutResponse) { // 使用WRITE_NO_RESPONSE属性写入值 - await characteristic.write(subData[i],withoutResponse: true).then((value) async { + await characteristic + .write(subData[i], withoutResponse: true) + .then((value) async { // await Future.delayed(const Duration(milliseconds: 1)).then(( // value) async { // AppLog.log('分包发送成功了'); @@ -594,7 +599,8 @@ class BlueManage { }); } else { // 特性不支持写入 - throw Exception('This characteristic does not support writing.'); + throw Exception( + 'This characteristic does not support writing.'); } } } on Exception catch (e, s) { diff --git a/star_lock/lib/blue/io_protocol/io_addCardCancel.dart b/star_lock/lib/blue/io_protocol/io_addCardCancel.dart new file mode 100644 index 00000000..e26c7fb1 --- /dev/null +++ b/star_lock/lib/blue/io_protocol/io_addCardCancel.dart @@ -0,0 +1,98 @@ + +import 'dart:convert'; + +import 'package:star_lock/tools/dateTool.dart'; + +import '../../app_settings/app_settings.dart'; +import '../io_tool/io_tool.dart'; +import '../sm4Encipher/sm4.dart'; +import '../io_reply.dart'; +import '../io_sender.dart'; +import '../io_type.dart'; +import 'package:crypto/crypto.dart' as crypto; + +///TODO:取消添加指纹 +class SenderCancelAddCardCommand extends SenderProtocol { + String? keyID; + String? userID; + List? token; + int? needAuthor; + List? signKey; + List? privateKey; + + SenderCancelAddCardCommand({ + this.keyID, + this.userID, + this.token, + this.needAuthor, + this.signKey, + this.privateKey, + }) : super(CommandType.generalExtendedCommond); + + @override + String toString() { + return 'SenderAddFingerprintWithTimeCycleCoercionCommand{keyID: $keyID, ' + 'userID: $userID, token: $token, needAuthor: $needAuthor, signKey: $signKey, privateKey: $privateKey}'; + } + + @override + List messageDetail() { + List data = []; + List subData = []; + List ebcData = []; + + // 指令类型 + data.addAll(intChangList(commandType!.typeValue)); + + // 子命令类型 + data.add(25); + + // keyID 40 + int keyIDLength = utf8.encode(keyID!).length; + subData.addAll(utf8.encode(keyID!)); + subData = getFixedLengthList(subData, 40 - keyIDLength); + + //userID 20 + int userIDLength = utf8.encode(userID!).length; + subData.addAll(utf8.encode(userID!)); + subData = getFixedLengthList(subData, 20 - userIDLength); + + if(needAuthor == 0){ + //AuthCodeLen 1 + subData.add(0); + } else { + List authCodeData = []; + //KeyID + authCodeData.addAll(utf8.encode(keyID!)); + + //authUserID + authCodeData.addAll(utf8.encode(userID!)); + + //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 + authCodeData.addAll(token!); + + authCodeData.addAll(signKey!); + + // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode + var authCode = crypto.md5.convert(authCodeData); + + subData.add(authCode.bytes.length); + subData.addAll(authCode.bytes); + } + + data.add(subData.length); + data.addAll(subData); + + if ((data.length % 16) != 0) { + int add = (16 - data.length % 16); + for (int i = 0; i < add; i++) { + data.add(0); + } + } + + printLog(data); + // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 + ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB); + return ebcData; + } +} diff --git a/star_lock/lib/blue/io_protocol/io_addFace.dart b/star_lock/lib/blue/io_protocol/io_addFace.dart index e4eac68d..24d2bf76 100644 --- a/star_lock/lib/blue/io_protocol/io_addFace.dart +++ b/star_lock/lib/blue/io_protocol/io_addFace.dart @@ -65,8 +65,8 @@ class SenderAddFaceCommand extends SenderProtocol { 'weekRound: $weekRound, ' 'startDate: ${DateTool().dateIntToYMDHNString(startDate)}, ' 'endDate: ${DateTool().dateIntToYMDHNString(endDate)}, ' - 'startTime: ${DateTool().dateToYMDHNString(startTime)}, ' - 'endTime: ${DateTool().dateToYMDHNString(endTime)}, ' + 'startTime: $startTime, ' + 'endTime: $startTime, ' 'needAuthor: $needAuthor, signKey: $signKey, privateKey: $privateKey}'; } @@ -77,13 +77,8 @@ class SenderAddFaceCommand extends SenderProtocol { List ebcData = []; // 指令类型 - // int type = commandType!.typeValue; - // double typeDouble = type / 256; - // int type1 = typeDouble.toInt(); - // int type2 = type % 256; - // data.add(type1); - // data.add(type2); data.addAll(intChangList(commandType!.typeValue)); + // AppLog.log("intChangList(commandType!.typeValue):${intChangList(commandType!.typeValue)}"); // 子命令类型 data.add(81); @@ -92,38 +87,45 @@ class SenderAddFaceCommand extends SenderProtocol { int keyIDLength = utf8.encode(keyID!).length; subData.addAll(utf8.encode(keyID!)); subData = getFixedLengthList(subData, 40 - keyIDLength); + // AppLog.log("keyID:$keyID utf8.encode(keyID!):${utf8.encode(keyID!)}"); //userID 20 int userIDLength = utf8.encode(userID!).length; subData.addAll(utf8.encode(userID!)); subData = getFixedLengthList(subData, 20 - userIDLength); + // AppLog.log("userID:$userID utf8.encode(userID!):${utf8.encode(userID!)}"); // faceNo subData.addAll(intChangList(faceNo!)); - AppLog.log("faceNo:$faceNo intChangList(faceNo!):${intChangList(faceNo!)}"); + // AppLog.log("faceNo:$faceNo intChangList(faceNo!):${intChangList(faceNo!)}"); // UseCountLimit subData.addAll(intChangList(useCountLimit!)); + // AppLog.log("useCountLimit:$useCountLimit intChangList(useCountLimit!):${intChangList(useCountLimit!)}"); // Operate 0:注册 1:修改 2:删除 3:删除全部 subData.add(operate!); - AppLog.log("addFingerprint operate:$operate"); + // AppLog.log("addFingerprint operate:$operate"); // isAdmin subData.add(isAdmin!); - AppLog.log("addFingerprint isAdmin:$isAdmin"); + // AppLog.log("addFingerprint isAdmin:$isAdmin"); // isForce subData.add(isForce!); + // AppLog.log("addFingerprint isForce:$isForce"); // token subData.addAll(token!); + // AppLog.log("addFingerprint token:$token"); // isRound subData.add(isRound!); + // AppLog.log("addFingerprint isRound:$isRound"); // weekRound subData.add(weekRound!); + // AppLog.log("addFingerprint weekRound:$weekRound"); // startDate 4 subData.add((startDate! & 0xff000000) >> 24); @@ -136,7 +138,7 @@ class SenderAddFaceCommand extends SenderProtocol { subData.add((endDate! & 0xff0000) >> 16); subData.add((endDate! & 0xff00) >> 8); subData.add((endDate! & 0xff)); - AppLog.log("addFingerprint startDate:${DateTool().dateToYMDHNString(startDate.toString())} endDate:${DateTool().dateToYMDHNString(endDate.toString())}"); + // AppLog.log("addFingerprint startDate:${DateTool().dateToYMDHNString(startDate.toString())} endDate:${DateTool().dateToYMDHNString(endDate.toString())}"); // startTime 4 List startTimeList = [0,0,0,0]; diff --git a/star_lock/lib/blue/io_protocol/io_addFaceCancel.dart b/star_lock/lib/blue/io_protocol/io_addFaceCancel.dart new file mode 100644 index 00000000..45007715 --- /dev/null +++ b/star_lock/lib/blue/io_protocol/io_addFaceCancel.dart @@ -0,0 +1,98 @@ + +import 'dart:convert'; + +import 'package:star_lock/tools/dateTool.dart'; + +import '../../app_settings/app_settings.dart'; +import '../io_tool/io_tool.dart'; +import '../sm4Encipher/sm4.dart'; +import '../io_reply.dart'; +import '../io_sender.dart'; +import '../io_type.dart'; +import 'package:crypto/crypto.dart' as crypto; + +///TODO:取消添加人脸 +class SenderCancelAddFaceCommand extends SenderProtocol { + String? keyID; + String? userID; + List? token; + int? needAuthor; + List? signKey; + List? privateKey; + + SenderCancelAddFaceCommand({ + this.keyID, + this.userID, + this.token, + this.needAuthor, + this.signKey, + this.privateKey, + }) : super(CommandType.generalExtendedCommond); + + @override + String toString() { + return 'SenderAddFingerprintWithTimeCycleCoercionCommand{keyID: $keyID, ' + 'userID: $userID, token: $token, needAuthor: $needAuthor, signKey: $signKey, privateKey: $privateKey}'; + } + + @override + List messageDetail() { + List data = []; + List subData = []; + List ebcData = []; + + // 指令类型 + data.addAll(intChangList(commandType!.typeValue)); + + // 子命令类型 + data.add(86); + + // keyID 40 + int keyIDLength = utf8.encode(keyID!).length; + subData.addAll(utf8.encode(keyID!)); + subData = getFixedLengthList(subData, 40 - keyIDLength); + + //userID 20 + int userIDLength = utf8.encode(userID!).length; + subData.addAll(utf8.encode(userID!)); + subData = getFixedLengthList(subData, 20 - userIDLength); + + if(needAuthor == 0){ + //AuthCodeLen 1 + subData.add(0); + } else { + List authCodeData = []; + //KeyID + authCodeData.addAll(utf8.encode(keyID!)); + + //authUserID + authCodeData.addAll(utf8.encode(userID!)); + + //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 + authCodeData.addAll(token!); + + authCodeData.addAll(signKey!); + + // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode + var authCode = crypto.md5.convert(authCodeData); + + subData.add(authCode.bytes.length); + subData.addAll(authCode.bytes); + } + + data.add(subData.length); + data.addAll(subData); + + if ((data.length % 16) != 0) { + int add = (16 - data.length % 16); + for (int i = 0; i < add; i++) { + data.add(0); + } + } + + printLog(data); + // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 + ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB); + return ebcData; + } +} diff --git a/star_lock/lib/blue/io_protocol/io_addFingerprintCancel.dart b/star_lock/lib/blue/io_protocol/io_addFingerprintCancel.dart new file mode 100644 index 00000000..7ab344cc --- /dev/null +++ b/star_lock/lib/blue/io_protocol/io_addFingerprintCancel.dart @@ -0,0 +1,98 @@ + +import 'dart:convert'; + +import 'package:star_lock/tools/dateTool.dart'; + +import '../../app_settings/app_settings.dart'; +import '../io_tool/io_tool.dart'; +import '../sm4Encipher/sm4.dart'; +import '../io_reply.dart'; +import '../io_sender.dart'; +import '../io_type.dart'; +import 'package:crypto/crypto.dart' as crypto; + +///TODO:取消添加指纹 +class SenderCancelAddFingerprintCommand extends SenderProtocol { + String? keyID; + String? userID; + List? token; + int? needAuthor; + List? signKey; + List? privateKey; + + SenderCancelAddFingerprintCommand({ + this.keyID, + this.userID, + this.token, + this.needAuthor, + this.signKey, + this.privateKey, + }) : super(CommandType.generalExtendedCommond); + + @override + String toString() { + return 'SenderAddFingerprintWithTimeCycleCoercionCommand{keyID: $keyID, ' + 'userID: $userID, token: $token, needAuthor: $needAuthor, signKey: $signKey, privateKey: $privateKey}'; + } + + @override + List messageDetail() { + List data = []; + List subData = []; + List ebcData = []; + + // 指令类型 + data.addAll(intChangList(commandType!.typeValue)); + + // 子命令类型 + data.add(37); + + // keyID 40 + int keyIDLength = utf8.encode(keyID!).length; + subData.addAll(utf8.encode(keyID!)); + subData = getFixedLengthList(subData, 40 - keyIDLength); + + //userID 20 + int userIDLength = utf8.encode(userID!).length; + subData.addAll(utf8.encode(userID!)); + subData = getFixedLengthList(subData, 20 - userIDLength); + + if(needAuthor == 0){ + //AuthCodeLen 1 + subData.add(0); + } else { + List authCodeData = []; + //KeyID + authCodeData.addAll(utf8.encode(keyID!)); + + //authUserID + authCodeData.addAll(utf8.encode(userID!)); + + //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 + authCodeData.addAll(token!); + + authCodeData.addAll(signKey!); + + // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode + var authCode = crypto.md5.convert(authCodeData); + + subData.add(authCode.bytes.length); + subData.addAll(authCode.bytes); + } + + data.add(subData.length); + data.addAll(subData); + + if ((data.length % 16) != 0) { + int add = (16 - data.length % 16); + for (int i = 0; i < add; i++) { + data.add(0); + } + } + + printLog(data); + // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 + ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB); + return ebcData; + } +} diff --git a/star_lock/lib/blue/io_protocol/io_addFingerprintWithTimeCycleCoercion.dart b/star_lock/lib/blue/io_protocol/io_addFingerprintWithTimeCycleCoercion.dart index f57f0822..e22a4126 100644 --- a/star_lock/lib/blue/io_protocol/io_addFingerprintWithTimeCycleCoercion.dart +++ b/star_lock/lib/blue/io_protocol/io_addFingerprintWithTimeCycleCoercion.dart @@ -56,7 +56,6 @@ class SenderAddFingerprintWithTimeCycleCoercionCommand extends SenderProtocol { this.privateKey, }) : super(CommandType.generalExtendedCommond); - @override String toString() { return 'SenderAddFingerprintWithTimeCycleCoercionCommand{keyID: $keyID, ' @@ -65,8 +64,8 @@ class SenderAddFingerprintWithTimeCycleCoercionCommand extends SenderProtocol { 'weekRound: $weekRound, ' 'startDate:${DateTool().dateIntToYMDHNString(startDate)}, ' 'endDate: ${DateTool().dateIntToYMDHNString(endDate)}, ' - 'startTime: ${DateTool().dateToYMDHNString(startTime)}, ' - 'endTime: ${DateTool().dateToYMDHNString(endTime)}, ' + 'startTime: $startTime, ' + 'endTime: $endTime, ' 'needAuthor: $needAuthor, signKey: $signKey, privateKey: $privateKey}'; } @@ -77,12 +76,6 @@ class SenderAddFingerprintWithTimeCycleCoercionCommand extends SenderProtocol { List ebcData = []; // 指令类型 - // int type = commandType!.typeValue; - // double typeDouble = type / 256; - // int type1 = typeDouble.toInt(); - // int type2 = type % 256; - // data.add(type1); - // data.add(type2); data.addAll(intChangList(commandType!.typeValue)); // 子命令类型 @@ -100,18 +93,18 @@ class SenderAddFingerprintWithTimeCycleCoercionCommand extends SenderProtocol { // fingerNo subData.addAll(intChangList(fingerNo!)); - AppLog.log("fingerNo:$fingerNo intChangList(fingerNo!):${intChangList(fingerNo!)}"); + // AppLog.log("fingerNo:$fingerNo intChangList(fingerNo!):${intChangList(fingerNo!)}"); // UseCountLimit subData.addAll(intChangList(useCountLimit!)); // Operate 0:注册 1:修改 2:删除 3:删除全部 subData.add(operate!); - AppLog.log("addFingerprint operate:$operate"); + // AppLog.log("addFingerprint operate:$operate"); // isAdmin subData.add(isAdmin!); - AppLog.log("addFingerprint isAdmin:$isAdmin"); + // AppLog.log("addFingerprint isAdmin:$isAdmin"); // isForce subData.add(isForce!); diff --git a/star_lock/lib/blue/io_protocol/io_addICCardWithTimeCycleCoercion.dart b/star_lock/lib/blue/io_protocol/io_addICCardWithTimeCycleCoercion.dart index 6fd9ba5c..dbf72707 100644 --- a/star_lock/lib/blue/io_protocol/io_addICCardWithTimeCycleCoercion.dart +++ b/star_lock/lib/blue/io_protocol/io_addICCardWithTimeCycleCoercion.dart @@ -65,8 +65,8 @@ class SenderAddICCardWithTimeCycleCoercionCommand extends SenderProtocol { 'weekRound: $weekRound, ' 'startDate: ${DateTool().dateIntToYMDHNString(startDate)}, ' 'endDate: ${DateTool().dateIntToYMDHNString(endDate)}, ' - 'startTime: ${DateTool().dateToYMDHNString(startTime)}, ' - 'endTime: ${DateTool().dateToYMDHNString(endTime)}, ' + 'startTime: $startTime,' + 'endTime: $endTime, ' 'needAuthor: $needAuthor, signKey: $signKey, privateKey: $privateKey}'; } @@ -77,12 +77,6 @@ class SenderAddICCardWithTimeCycleCoercionCommand extends SenderProtocol { List ebcData = []; // 指令类型 - // int type = commandType!.typeValue; - // double typeDouble = type / 256; - // int type1 = typeDouble.toInt(); - // int type2 = type % 256; - // data.add(type1); - // data.add(type2); data.addAll(intChangList(commandType!.typeValue)); // 子命令类型 @@ -106,15 +100,15 @@ class SenderAddICCardWithTimeCycleCoercionCommand extends SenderProtocol { // Operate 0:注册 1:修改 2:删除 3:删除全部 subData.add(operate!); - AppLog.log("addCard operate:$operate"); + // AppLog.log("addCard operate:$operate"); // isAdmin subData.add(isAdmin!); - AppLog.log("addCard isAdmin:$isAdmin"); + // AppLog.log("addCard isAdmin:$isAdmin"); // isForce subData.add(isForce!); - AppLog.log("addCard isForce:$isForce"); + // AppLog.log("addCard isForce:$isForce"); // token subData.addAll(token!); diff --git a/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart b/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart index c4b37137..3d358a74 100644 --- a/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart +++ b/star_lock/lib/blue/io_protocol/io_otaUpgrade.dart @@ -26,6 +26,7 @@ class OTAUpgradeCommand extends SenderProtocol { List? signKey; List? privateKey; List? token; + bool encrypt; OTAUpgradeCommand( {this.lockID, @@ -40,10 +41,10 @@ class OTAUpgradeCommand extends SenderProtocol { this.needAuthor, this.signKey, this.privateKey, - this.token}) + this.token, + this.encrypt = true}) : super(CommandType.startOATUpgrade); - @override String toString() { return 'OTAUpgradeCommand{lockID: $lockID, userID: $userID, ' @@ -53,6 +54,15 @@ class OTAUpgradeCommand extends SenderProtocol { 'privateKey: $privateKey, token: $token}'; } + @override + int identifierValue() { + if (encrypt) { + return super.identifierValue(); + } else { + return 0x20; + } + } + @override List messageDetail() { List data = []; @@ -66,21 +76,18 @@ class OTAUpgradeCommand extends SenderProtocol { data.add(type1); data.add(type2); - AppLog.log('---> 指令 : $type1 $type2' ); // 锁id 40 int lockIDLength = utf8.encode(lockID!).length; data.addAll(utf8.encode(lockID!)); data = getFixedLengthList(data, 40 - lockIDLength); - AppLog.log('---> 锁id :${utf8.encode(lockID!)}'); //userID 20 int userIDLength = utf8.encode(userID!).length; data.addAll(utf8.encode(userID!)); data = getFixedLengthList(data, 20 - userIDLength); - AppLog.log('---> userID :${utf8.encode(userID!)}'); //platform 2 int platform0 = (platform! & 0xFF00) >> 8; @@ -88,36 +95,31 @@ class OTAUpgradeCommand extends SenderProtocol { data.add(platform0); data.add(platform1); - AppLog.log('---> platform : $platform0 $platform1'); //product 2 // int product0 = (product! & 0xFF00) >> 8; // int product1 = product! & 0xFF; // data.add(product0); // data.add(product1); - data.addAll([0,1]);//先默认是 01 + data.addAll([0, 1]); //先默认是 01 - AppLog.log('---> platform : ${[0,1]}'); //HwVersion 20 int hwVersionLength = utf8.encode(hwVersion!).length; data.addAll(utf8.encode(hwVersion!)); data = getFixedLengthList(data, 20 - hwVersionLength); - //FwVersion 20 int fwVersionLength = utf8.encode(fwVersion!).length; data.addAll(utf8.encode(fwVersion!)); data = getFixedLengthList(data, 20 - fwVersionLength); - //fwSize 4 ByteData bytes = ByteData(4); // 创建一个长度为4的字节数据 bytes.setInt32(0, fwSize!); List byteList = bytes.buffer.asUint8List(); data.addAll(byteList); - // 创建一个16字节的字节数组 Uint8List result = Uint8List(16); // 将每个十六进制字符转换为4位二进制数据,并将其存储到结果字节数组中 @@ -142,11 +144,9 @@ class OTAUpgradeCommand extends SenderProtocol { authCodeData.addAll(utf8.encode(userID!)); //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 - authCodeData.addAll(token!); + authCodeData.addAll(token??[]); - authCodeData.addAll(signKey!); - - AppLog.log('---> ${utf8.encode(keyID!)} ${utf8.encode(userID!)} $token $signKey'); + authCodeData.addAll(signKey??[]); // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode var authCode = crypto.md5.convert(authCodeData); @@ -161,11 +161,17 @@ class OTAUpgradeCommand extends SenderProtocol { data.add(0); } } - printLog(data); - // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 - ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB); - return ebcData; + + if (encrypt) { + + // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 + ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB); + return ebcData; + } else { + data.add(0); + return data; + } } } diff --git a/star_lock/lib/blue/io_sender.dart b/star_lock/lib/blue/io_sender.dart index 8c470f38..045b46d9 100644 --- a/star_lock/lib/blue/io_sender.dart +++ b/star_lock/lib/blue/io_sender.dart @@ -33,8 +33,9 @@ abstract class SenderProtocol extends IOData { _commandIndex = IoManager().commandIndex; } - void printLog(List data){ - AppLog.log("App -> 锁,指令类型:${commandType!.typeName} \n\n参数是:\n${toString()} \n\n加密之前数据是:\n$data"); + void printLog(List data) { + AppLog.log( + "App -> 锁,指令类型:${commandType!.typeName} \n\n参数是:\n${toString()} \n\n加密之前数据是:\n$data"); } //TODO:拼装数据Ï @@ -58,7 +59,8 @@ abstract class SenderProtocol extends IOData { // 包标识 // 指令类型 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节,加密类型取值说明,0:明文,1:AES128,2:SM4(事先约定密钥),3:SM4(设备指定密钥) - commandList.add(commandType!.identifierValue); + int value = identifierValue(); + commandList.add(value); // 数据长度 int dataLen = dataSourceLength(); @@ -84,6 +86,10 @@ abstract class SenderProtocol extends IOData { return commandList; } + // 包标识 + // 指令类型 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节,加密类型取值说明,0:明文,1:AES128,2:SM4(事先约定密钥),3:SM4(设备指定密钥) + int identifierValue() => commandType!.identifierValue; + //TODO:长度 int dataSourceLength() => commandData!.length; diff --git a/star_lock/lib/blue/sender_beforeDataManage.dart b/star_lock/lib/blue/sender_beforeDataManage.dart index 5517c707..ebed1de5 100644 --- a/star_lock/lib/blue/sender_beforeDataManage.dart +++ b/star_lock/lib/blue/sender_beforeDataManage.dart @@ -7,6 +7,7 @@ import 'package:star_lock/blue/sender_manage.dart'; import 'package:star_lock/tools/baseGetXController.dart'; import 'package:star_lock/tools/eventBusEventManage.dart'; +import '../app_settings/app_settings.dart'; import '../main/lockDetail/lockDetail/lockNetToken_entity.dart'; import '../network/api_repository.dart'; import '../tools/commonDataManage.dart'; @@ -83,6 +84,8 @@ class SenderBeforeDataManage { // publicKey: publicKeyDataList, // privateKey: getPrivateKeyList, // token: token); + AppLog.log("startDate111:${CommonDataManage().currentKeyInfo.startDate} endDate:${CommonDataManage().currentKeyInfo.endDate}"); + var addUserData = AddUserCommand( lockID: BlueManage().connectDeviceName, authUserID: CommonDataManage().currentKeyInfo.senderUserId!.toString(), @@ -90,8 +93,8 @@ class SenderBeforeDataManage { userID: await Storage.getUid(), openMode: 1, keyType: 0, - startDate: CommonDataManage().currentKeyInfo.startDate!~/10000, - expireDate: CommonDataManage().currentKeyInfo.endDate!~/10000, + startDate: CommonDataManage().currentKeyInfo.startDate!~/1000, + expireDate: CommonDataManage().currentKeyInfo.endDate!~/1000, role: CommonDataManage().currentKeyInfo.keyRight == 1 ? 1 : 0, password: "123456", needAuthor: 1, @@ -123,8 +126,8 @@ class SenderBeforeDataManage { userID: await Storage.getUid(), openMode: 1, keyType: 0, - startDate: CommonDataManage().currentKeyInfo.startDate!~/10000, - expireDate: CommonDataManage().currentKeyInfo.endDate!~/10000, + startDate: CommonDataManage().currentKeyInfo.startDate!~/1000, + expireDate: CommonDataManage().currentKeyInfo.endDate!~/1000, role: CommonDataManage().currentKeyInfo.keyRight == 1 ? 1 : 0, password: "123456", needAuthor: 1, diff --git a/star_lock/lib/blue/sender_manage.dart b/star_lock/lib/blue/sender_manage.dart index ce6b7c1e..09b035bb 100644 --- a/star_lock/lib/blue/sender_manage.dart +++ b/star_lock/lib/blue/sender_manage.dart @@ -10,6 +10,9 @@ import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart'; import 'package:star_lock/blue/io_protocol/io_queryingFaceStatus.dart'; import 'package:star_lock/blue/io_protocol/io_readAdminPassword.dart'; +import 'io_protocol/io_addCardCancel.dart'; +import 'io_protocol/io_addFaceCancel.dart'; +import 'io_protocol/io_addFingerprintCancel.dart'; import 'io_protocol/io_addFingerprintWithTimeCycleCoercion.dart'; import 'io_protocol/io_addICCardWithTimeCycleCoercion.dart'; import 'io_protocol/io_addStressFingerprint.dart'; @@ -417,6 +420,27 @@ class IoSenderManage { callBack: callBack); } + //todo:取消添加指纹 + static void senderCancelAddFingerprintCommand( + {required String? keyID, + required String? userID, + required List? token, + required int? needAuthor, + required List? signKey, + required List? privateKey, + CommandSendCallBack? callBack}) { + CommandSenderManager().managerSendData( + command: SenderCancelAddFingerprintCommand( + keyID: keyID, + userID: userID, + token: token, + needAuthor: needAuthor, + signKey: signKey, + privateKey: privateKey, + ), + callBack: callBack); + } + //todo:添加卡开始旧版 // static void senderAddICCardCommand( // {required String? keyID, @@ -489,6 +513,27 @@ class IoSenderManage { callBack: callBack); } + //todo:取消添加指纹 + static void senderCancelAddCardCommand( + {required String? keyID, + required String? userID, + required List? token, + required int? needAuthor, + required List? signKey, + required List? privateKey, + CommandSendCallBack? callBack}) { + CommandSenderManager().managerSendData( + command: SenderCancelAddCardCommand( + keyID: keyID, + userID: userID, + token: token, + needAuthor: needAuthor, + signKey: signKey, + privateKey: privateKey, + ), + callBack: callBack); + } + //todo:添加人脸开始 static void senderAddFaceCommand( {required String? keyID, @@ -532,6 +577,27 @@ class IoSenderManage { callBack: callBack); } + //todo:取消添加人脸 + static void senderCancelAddFaceCommand( + {required String? keyID, + required String? userID, + required List? token, + required int? needAuthor, + required List? signKey, + required List? privateKey, + CommandSendCallBack? callBack}) { + CommandSenderManager().managerSendData( + command: SenderCancelAddFaceCommand( + keyID: keyID, + userID: userID, + token: token, + needAuthor: needAuthor, + signKey: signKey, + privateKey: privateKey, + ), + callBack: callBack); + } + //todo:校验时间 static void senderTimingCommand( {required String? lockID, diff --git a/star_lock/lib/main.dart b/star_lock/lib/main.dart index 54dd55eb..5b7c18bc 100644 --- a/star_lock/lib/main.dart +++ b/star_lock/lib/main.dart @@ -20,9 +20,7 @@ FutureOr main() async { // 设置国际化信息 await _initTranslation(); - DebugConsole.listen(() { - runApp(const MyApp()); - }); + runApp(const MyApp()); if (AppPlatform.isAndroid) { SystemUiOverlayStyle systemUiOverlayStyle = diff --git a/star_lock/lib/main/lockDetail/card/addCardType/addCardType_logic.dart b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_logic.dart index d19f57fe..26d33526 100644 --- a/star_lock/lib/main/lockDetail/card/addCardType/addCardType_logic.dart +++ b/star_lock/lib/main/lockDetail/card/addCardType/addCardType_logic.dart @@ -49,8 +49,8 @@ class AddCardTypeLogic extends BaseGetXController{ showToast("失效时间要大于生效时间".tr); return; } - AppLog.log("state.timeLimitBeginTime.value:${state.timeLimitBeginTime.value} startDate:$startDate"); - AppLog.log("state.timeLimitEndTime.value:${state.timeLimitEndTime.value} endDate:$endDate"); + // AppLog.log("state.timeLimitBeginTime.value:${state.timeLimitBeginTime.value} startDate:$startDate"); + // AppLog.log("state.timeLimitEndTime.value:${state.timeLimitEndTime.value} endDate:$endDate"); } else if (state.selectType.value == "2") { if (state.cycleBeginTime.value.isEmpty) { showToast("请选择有效期".tr); diff --git a/star_lock/lib/main/lockDetail/card/addICCard/addICCard_logic.dart b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_logic.dart index ac4b42a6..d35af8ef 100644 --- a/star_lock/lib/main/lockDetail/card/addICCard/addICCard_logic.dart +++ b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_logic.dart @@ -36,11 +36,6 @@ class AddICCardLogic extends BaseGetXController{ if(reply is SenderAddICCardConfirmationReply) { _replyAddICCardConfirmation(reply); } - - // 添加胁迫卡 - // if(reply is SenderAddStressICCardReply) { - // _replyAddICStressCard(reply); - // } }); } @@ -55,6 +50,8 @@ class AddICCardLogic extends BaseGetXController{ // AppLog.log("添加卡号:$cardNumberList cardNumber:$cardNumber"); state.cardNumber.value = cardNumber.toString(); cancelBlueConnetctToastTimer(); + + state.ifAddState.value = true; state.ifConnectScuess.value = true; break; case 0x06: @@ -95,35 +92,49 @@ class AddICCardLogic extends BaseGetXController{ break; default: //失败 + state.ifAddState.value = false; break; } } Future _replyAddICCardConfirmation(Reply reply) async { int status = reply.data[2]; - + state.ifAddState.value = false; switch(status){ case 0x00: //成功 - // if(state.cardNumber.value == (reply.data[6]).toString()){ - // return; - // }else{ - // state.cardNumber.value = (reply.data[6]).toString(); - // } - // if(state.isCoerced.value == "1"){ - // 非胁迫 - int addResultStatus = reply.data[5]; - if(addResultStatus == 0){ - // 成功更新序列号 + //成功 + switch(reply.data[5]){ + case 0xff: + // 注册指纹失败 + showToast("退出添加".tr); + Get.close(1); + break; + case 0xFE: + // 管理员已满 + showToast("管理员已满".tr); + Get.close(1); + break; + case 0xFD: + // 用户已满 + showToast("用户已满".tr); + Get.close(1); + break; + case 0xFC: + // 指纹已满 + showToast("锁上面添加卡已满".tr); + Get.close(1); + break; + case 0xFB: + // 指纹已存在 + showToast("卡已存在".tr); + break; + default: + // 添加指纹中 + // 当前注册数 addICCardData(); - }else if(addResultStatus == 255){ - // 255 自动退出 - Get.close(2); - } - // }else{ - // // 如果是胁迫指纹在 添加完之后以后再调用添加胁迫指纹的 - // addICCardData(); - // } + break; + } break; default: //失败 @@ -131,63 +142,6 @@ class AddICCardLogic extends BaseGetXController{ } } - // Future _replyAddICStressCard(Reply reply) async { - // int status = reply.data[2]; - // - // switch(status){ - // case 0x00: - // //成功 - // AppLog.log("${reply.commandType!.typeValue} 数据解析成功"); - // addICCardData(); - // break; - // case 0x06: - // //无权限 - // var publicKey = await Storage.getStringList(saveBluePublicKey); - // List publicKeyDataList = changeStringListToIntList(publicKey!); - // - // var privateKey = await Storage.getStringList(saveBluePrivateKey); - // List getPrivateKeyList = changeStringListToIntList(privateKey!); - // - // var signKey = await Storage.getStringList(saveBlueSignKey); - // List getSignKeyList = changeStringListToIntList(signKey!); - // - // var token = reply.data.sublist(5, 9); - // var saveStrList = changeIntListToStringList(token); - // Storage.setStringList(saveBlueToken, saveStrList); - // - // AppLog.log("state.isAdministrator.value:${state.isAdministrator.value}"); - // IoSenderManage.senderAddStressICCardCommand( - // keyID:"1", - // userID:await Storage.getUid(), - // icCardNo:state.isAdministrator.value == "2" ? 254 : 1, - // cardType:1, - // useCountLimit:1, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, - // needAuthor:1, - // publicKey:publicKeyDataList, - // privateKey:getPrivateKeyList, - // token: token, - // signKey: getSignKeyList, - // ); - // break; - // case 0x07: - // //无权限 - // AppLog.log("${reply.commandType!.typeValue} 用户无权限"); - // - // break; - // case 0x09: - // // 权限校验错误 - // AppLog.log("${reply.commandType!.typeValue} 权限校验错误"); - // - // break; - // default: - // //失败 - // AppLog.log("${reply.commandType!.typeValue} 失败"); - // break; - // } - // } - // 添加卡片 Future senderAddICCard() async { showBlueConnetctToastTimer(action: (){ @@ -237,39 +191,36 @@ class AddICCardLogic extends BaseGetXController{ }); } - // 添加胁迫卡片 - // Future senderAddStressICCard() async { - // BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { - // if (deviceConnectionState == BluetoothConnectionState.connected){ - // var publicKey = await Storage.getStringList(saveBluePublicKey); - // List publicKeyDataList = changeStringListToIntList(publicKey!); - // - // var privateKey = await Storage.getStringList(saveBluePrivateKey); - // List getPrivateKeyList = changeStringListToIntList(privateKey!); - // - // var signKey = await Storage.getStringList(saveBlueSignKey); - // List getSignKeyList = changeStringListToIntList(signKey!); - // - // var token = await Storage.getStringList(saveBlueToken); - // List getTokenList = changeStringListToIntList(token!); - // - // IoSenderManage.senderAddStressICCardCommand( - // keyID:"1", - // userID:await Storage.getUid(), - // icCardNo:state.isAdministrator.value == "2" ? 254 : 1, - // cardType:1, - // useCountLimit:1, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, - // needAuthor:1, - // publicKey:publicKeyDataList, - // privateKey:getPrivateKeyList, - // token: getTokenList, - // signKey: getSignKeyList, - // ); - // } - // }); - // } + // 取消添加指纹 + Future senderCancelAddCardCommand() async { + BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected){ + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var signKey = await Storage.getStringList(saveBlueSignKey); + List signKeyDataList = changeStringListToIntList(signKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + IoSenderManage.senderCancelAddCardCommand( + keyID:"1", + userID:await Storage.getUid(), + needAuthor:1, + signKey:signKeyDataList, + privateKey:getPrivateKeyList, + token: getTokenList, + ); + }else if (deviceConnectionState == BluetoothConnectionState.disconnected){ + if(state.ifCurrentScreen.value == true){ + showBlueConnetctToast(); + } + cancelBlueConnetctToastTimer(); + Get.close(1); + } + }); + } void addICCardData() async { var entity = await ApiRepository.to.addICCardData( diff --git a/star_lock/lib/main/lockDetail/card/addICCard/addICCard_page.dart b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_page.dart index d8e1bb31..bf4bddf1 100644 --- a/star_lock/lib/main/lockDetail/card/addICCard/addICCard_page.dart +++ b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_page.dart @@ -100,6 +100,10 @@ class _AddICCardPageState extends State with RouteAware { super.didPop(); logic.cancelBlueConnetctToastTimer(); state.ifCurrentScreen.value = false; + + if(state.ifAddState.value){ + logic.senderCancelAddCardCommand(); + } } /// 从下级返回 当前界面即将出现 diff --git a/star_lock/lib/main/lockDetail/card/addICCard/addICCard_state.dart b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_state.dart index 2243469b..2898303d 100644 --- a/star_lock/lib/main/lockDetail/card/addICCard/addICCard_state.dart +++ b/star_lock/lib/main/lockDetail/card/addICCard/addICCard_state.dart @@ -4,6 +4,7 @@ import 'package:get/get.dart'; class AddICCardState{ var ifConnectScuess = false.obs; var ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 + var ifAddState = false.obs;// 是否是添加状态,如果是添加状态,返回上级界面发送取消添加指令 var addFingerprintProcessNumber = 0.obs; final lockId = 0.obs; diff --git a/star_lock/lib/main/lockDetail/face/addFace/addFace_logic.dart b/star_lock/lib/main/lockDetail/face/addFace/addFace_logic.dart index efad5aa7..e133203f 100644 --- a/star_lock/lib/main/lockDetail/face/addFace/addFace_logic.dart +++ b/star_lock/lib/main/lockDetail/face/addFace/addFace_logic.dart @@ -47,6 +47,8 @@ class AddFaceLogic extends BaseGetXController { switch (status) { case 0x00: //成功 + state.ifAddState.value = true; + cancelBlueConnetctToastTimer(); // 最大图片数 state.maxRegCount.value = reply.data[11]; @@ -86,7 +88,10 @@ class AddFaceLogic extends BaseGetXController { break; default: //失败 - + state.ifAddState.value = false; + showToast("添加人脸失败", something: (){ + Get.back(); + }); break; } } @@ -96,24 +101,59 @@ class AddFaceLogic extends BaseGetXController { switch (status) { case 0x00: - //成功 - if (reply.data[5] == 255) { - // 注册人脸失败 - showToast("添加失败"); - Get.close(2); - } else { - // state.addFaceProcessNumber.value++; + switch(reply.data[5]){ + case 0xff: + // 注册人脸失败 + showToast("退出添加".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFE: + // 管理员已满 + showToast("管理员已满".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFD: + // 用户已满 + showToast("用户已满".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFC: + // 指纹已满 + showToast("锁上面添加人脸已满".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFB: + // 指纹已存在 + showToast("人脸已存在".tr); + state.ifAddState.value = false; + break; + default: + // 添加人脸中 // 当前注册数 - state.regIndex.value = reply.data[6]; - // AppLog.log("注册人脸过程state.regIndex.value:${state.regIndex.value}"); + state.regIndex.value = reply.data[6]; + // AppLog.log("注册人脸过程state.regIndex.value:${state.regIndex.value}"); + break; } - break; - case 0x06: - //需要权限 + //成功 + // if (reply.data[5] == 255) { + // // 注册人脸失败 + // showToast("添加失败"); + // Get.close(2); + // } else { + // // state.addFaceProcessNumber.value++; + // // 当前注册数 + // state.regIndex.value = reply.data[6]; + // // AppLog.log("注册人脸过程state.regIndex.value:${state.regIndex.value}"); + // } break; default: //失败 + state.ifAddState.value = false; break; } } @@ -132,14 +172,12 @@ class AddFaceLogic extends BaseGetXController { } else { state.faceNumber.value = faceNumber; } + state.ifAddState.value = false; addFaceData(); - break; - case 0x06: - //需要权限 - break; default: //失败 + state.ifAddState.value = false; break; } } @@ -192,6 +230,37 @@ class AddFaceLogic extends BaseGetXController { }); } + // 取消添加指纹 + Future senderCancelAddFaceCommand() async { + BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected){ + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var signKey = await Storage.getStringList(saveBlueSignKey); + List signKeyDataList = changeStringListToIntList(signKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + IoSenderManage.senderCancelAddFaceCommand( + keyID:"1", + userID:await Storage.getUid(), + needAuthor:1, + signKey:signKeyDataList, + privateKey:getPrivateKeyList, + token: getTokenList, + ); + }else if (deviceConnectionState == BluetoothConnectionState.disconnected){ + if(state.ifCurrentScreen.value == true){ + showBlueConnetctToast(); + } + cancelBlueConnetctToastTimer(); + Get.close(1); + } + }); + } + // 添加人脸 void addFaceData() async { var entity = await ApiRepository.to.addFaceData( diff --git a/star_lock/lib/main/lockDetail/face/addFace/addFace_page.dart b/star_lock/lib/main/lockDetail/face/addFace/addFace_page.dart index 024736d7..c46a14b6 100644 --- a/star_lock/lib/main/lockDetail/face/addFace/addFace_page.dart +++ b/star_lock/lib/main/lockDetail/face/addFace/addFace_page.dart @@ -126,6 +126,10 @@ class _AddFacePageState extends State with RouteAware { super.didPop(); logic.cancelBlueConnetctToastTimer(); state.ifCurrentScreen.value = false; + + if(state.ifAddState.value){ + logic.senderCancelAddFaceCommand(); + } } /// 从下级返回 当前界面即将出现 diff --git a/star_lock/lib/main/lockDetail/face/addFace/addFace_state.dart b/star_lock/lib/main/lockDetail/face/addFace/addFace_state.dart index 5183d2ac..ff19b918 100644 --- a/star_lock/lib/main/lockDetail/face/addFace/addFace_state.dart +++ b/star_lock/lib/main/lockDetail/face/addFace/addFace_state.dart @@ -2,6 +2,7 @@ import 'package:get/get.dart'; class AddFaceState { var ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 + var ifAddState = false.obs;// 是否是添加状态,如果是添加状态,返回上级界面发送取消添加指令 var ifConnectScuess = false.obs; var maxRegCount = 0.obs; // 最大注册次数 diff --git a/star_lock/lib/main/lockDetail/face/faceList/faceList_logic.dart b/star_lock/lib/main/lockDetail/face/faceList/faceList_logic.dart index c039f0b2..64a555e3 100644 --- a/star_lock/lib/main/lockDetail/face/faceList/faceList_logic.dart +++ b/star_lock/lib/main/lockDetail/face/faceList/faceList_logic.dart @@ -1,3 +1,4 @@ + import 'dart:async'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart index e6891d85..3f816d04 100644 --- a/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_logic.dart @@ -39,11 +39,6 @@ class AddFingerprintLogic extends BaseGetXController { if(reply is SenderAddFingerprintConfirmationReply) { _replyAddFingerprintConfirmation(reply); } - - // 添加胁迫指纹 - // if(reply is SenderAddStressFingerprintReply) { - // _replyAddStressFingerprint(reply); - // } }); } @@ -54,6 +49,8 @@ class AddFingerprintLogic extends BaseGetXController { case 0x00: //成功 state.ifConnectScuess.value = true; + state.ifAddState.value = true; + cancelBlueConnetctToastTimer(); // 最大图片数 state.maxRegCount.value = reply.data[11]; @@ -92,20 +89,9 @@ class AddFingerprintLogic extends BaseGetXController { token: token, ); break; - case 0x07: - //无权限 - showToast("添加指纹失败", something: (){ - Get.back(); - }); - break; - case 0x09: - // 权限校验错误 - showToast("添加指纹失败", something: (){ - Get.back(); - }); - break; default: //失败 + state.ifAddState.value = false; showToast("添加指纹失败", something: (){ Get.back(); }); @@ -119,23 +105,47 @@ class AddFingerprintLogic extends BaseGetXController { switch(status){ case 0x00: //成功 - if(reply.data[5] == 255){ - // 注册指纹失败 - showToast("添加失败"); - Get.close(2); - }else{ - // state.addFingerprintProcessNumber.value++; - - // 当前注册数 - state.regIndex.value = reply.data[6]; - AppLog.log("当前注册数 state.regIndex.value:${state.regIndex.value}"); + switch(reply.data[5]){ + case 0xff: + // 注册指纹失败 + showToast("退出添加".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFE: + // 管理员已满 + showToast("管理员已满".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFD: + // 用户已满 + showToast("用户已满".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFC: + // 指纹已满 + showToast("锁上面添加指纹已满".tr); + state.ifAddState.value = false; + Get.close(1); + break; + case 0xFB: + // 指纹已存在 + showToast("指纹已存在".tr); + state.ifAddState.value = false; + break; + default: + // 添加指纹中 + // 当前注册数 + state.regIndex.value = reply.data[6]; + // AppLog.log("当前注册数 state.regIndex.value:${state.regIndex.value}"); + break; } break; - case 0x06: - //需要权限 - break; default: //失败 + state.ifAddState.value = false; break; } } @@ -156,71 +166,20 @@ class AddFingerprintLogic extends BaseGetXController { } // if(state.isCoerced.value == "1"){ // 调用添加指纹接口 - addFingerprintsData(); + state.ifAddState.value = false; + addFingerprintsData(); // }else{ // // 如果是胁迫指纹在 添加完之后以后再调用添加胁迫指纹的 // senderAddStressFingerprint(); // } break; - case 0x06: - //需要权限 - break; default: //失败 + state.ifAddState.value = false; break; } } - // Future _replyAddStressFingerprint(Reply reply) async { - // int status = reply.data[2]; - // - // switch(status){ - // case 0x00: - // //成功 - // addFingerprintsData(); - // break; - // case 0x06: - // //需要权限 - // var privateKey = await Storage.getStringList(saveBluePrivateKey); - // List getPrivateKeyList = changeStringListToIntList(privateKey!); - // - // var publicKey = await Storage.getStringList(saveBluePublicKey); - // List publicKeyDataList = changeStringListToIntList(publicKey!); - // - // var signKey = await Storage.getStringList(saveBlueSignKey); - // List getSignKeyList = changeStringListToIntList(signKey!); - // - // var token = reply.data.sublist(5, 9); - // var saveStrList = changeIntListToStringList(token); - // Storage.setStringList(saveBlueToken, saveStrList); - // - // IoSenderManage.senderAddStressFingerprintCommand( - // keyID:"1", - // userID:await Storage.getUid(), - // fingerNo:state.isAdministrator.value == "2" ? 254 : 1, - // fingerType:1, - // useCountLimit:1, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, - // needAuthor:1, - // publicKey:publicKeyDataList, - // privateKey:getPrivateKeyList, - // token: token, - // signKey: getSignKeyList - // ); - // break; - // case 0x07: - // //无权限 - // break; - // case 0x09: - // // 权限校验错误 - // break; - // default: - // //失败 - // break; - // } - // } - // 添加指纹开始 Future senderAddFingerprint() async { showBlueConnetctToastTimer(action: (){ @@ -228,8 +187,6 @@ class AddFingerprintLogic extends BaseGetXController { }); BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { if (deviceConnectionState == BluetoothConnectionState.connected){ - cancelBlueConnetctToastTimer(); - var privateKey = await Storage.getStringList(saveBluePrivateKey); List getPrivateKeyList = changeStringListToIntList(privateKey!); @@ -266,79 +223,38 @@ class AddFingerprintLogic extends BaseGetXController { Get.close(1); } }); - - // BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { - // if (deviceConnectionState == BluetoothConnectionState.connected){ - // cancelBlueConnetctToastTimer(); - // // var publicKey = await Storage.getStringList(saveBluePublicKey); - // // List publicKeyDataList = changeStringListToIntList(publicKey!); - // - // var privateKey = await Storage.getStringList(saveBluePrivateKey); - // List getPrivateKeyList = changeStringListToIntList(privateKey!); - // - // var signKey = await Storage.getStringList(saveBlueSignKey); - // List signKeyDataList = changeStringListToIntList(signKey!); - // - // var token = await Storage.getStringList(saveBlueToken); - // List getTokenList = changeStringListToIntList(token!); - // - // IoSenderManage.senderAddFingerprintCommand( - // keyID:"1", - // userID:await Storage.getUid(), - // fingerNo:state.isAdministrator.value == "2" ? 254 : 1, - // useCountLimit:0xff, - // // startTime:0x11223344, - // // endTime:0x11223344, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, - // needAuthor:1, - // signKey:signKeyDataList, - // privateKey:getPrivateKeyList, - // token: getTokenList, - // ); - // }else if (deviceConnectionState == BluetoothConnectionState.disconnected){ - // if(state.ifCurrentScreen.value == true){ - // showBlueConnetctToast(); - // } - // cancelBlueConnetctToastTimer(); - // Get.close(1); - // } - // }); } - // 添加胁迫指纹 - // Future senderAddStressFingerprint() async { - // BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { - // if (deviceConnectionState == BluetoothConnectionState.connected){ - // var publicKey = await Storage.getStringList(saveBluePublicKey); - // List publicKeyDataList = changeStringListToIntList(publicKey!); - // - // var privateKey = await Storage.getStringList(saveBluePrivateKey); - // List getPrivateKeyList = changeStringListToIntList(privateKey!); - // - // var signKey = await Storage.getStringList(saveBlueSignKey); - // List getSignKeyList = changeStringListToIntList(signKey!); - // - // var token = await Storage.getStringList(saveBlueToken); - // List getTokenList = changeStringListToIntList(token!); - // - // IoSenderManage.senderAddStressFingerprintCommand( - // keyID:"1", - // userID:await Storage.getUid(), - // fingerNo:state.isAdministrator.value == "2" ? 254 : 1, - // fingerType:1, - // useCountLimit:1, - // startTime:int.parse(state.startDate.value)~/1000, - // endTime:int.parse(state.endDate.value)~/1000, - // needAuthor:1, - // publicKey:publicKeyDataList, - // privateKey:getPrivateKeyList, - // token: getTokenList, - // signKey: getSignKeyList - // ); - // } - // }); - // } + // 取消添加指纹 + Future senderCancelAddFingerprintCommand() async { + BlueManage().bludSendData(BlueManage().connectDeviceName, (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected){ + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + + var signKey = await Storage.getStringList(saveBlueSignKey); + List signKeyDataList = changeStringListToIntList(signKey!); + + var token = await Storage.getStringList(saveBlueToken); + List getTokenList = changeStringListToIntList(token!); + + IoSenderManage.senderCancelAddFingerprintCommand( + keyID:"1", + userID:await Storage.getUid(), + needAuthor:1, + signKey:signKeyDataList, + privateKey:getPrivateKeyList, + token: getTokenList, + ); + }else if (deviceConnectionState == BluetoothConnectionState.disconnected){ + if(state.ifCurrentScreen.value == true){ + showBlueConnetctToast(); + } + cancelBlueConnetctToastTimer(); + Get.close(1); + } + }); + } // 添加指纹 void addFingerprintsData() async{ diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart index 74d970a0..b966d9df 100644 --- a/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_page.dart @@ -171,6 +171,10 @@ class _AddFingerprintPageState extends State with RouteAware super.didPop(); logic.cancelBlueConnetctToastTimer(); state.ifCurrentScreen.value = false; + + if(state.ifAddState.value){ + logic.senderCancelAddFingerprintCommand(); + } } /// 从下级返回 当前界面即将出现 diff --git a/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_state.dart b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_state.dart index 6a0e5f06..a6b5e492 100644 --- a/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_state.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/addFingerprint/addFingerprint_state.dart @@ -3,6 +3,7 @@ import 'package:get/get.dart'; class AddFingerprintState{ var ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 + var ifAddState = false.obs;// 是否是添加状态,如果是添加状态,返回上级界面发送取消添加指令 var ifConnectScuess = false.obs; var maxRegCount = 0.obs;// 最大注册次数 diff --git a/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart index 8642bafa..0ce9a349 100644 --- a/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart +++ b/star_lock/lib/main/lockDetail/fingerprint/fingerprintList/fingerprintList_page.dart @@ -142,7 +142,7 @@ class _FingerprintListPageState extends State with RouteAwa ShowTipView().showIosTipWithContentDialog("确定要删除吗?".tr, () async { state.isDeletAll = false; state.deletKeyID = fingerprintItemData.fingerprintId.toString(); - state.deletFingerNo = int.parse(fingerprintItemData.faceNumber!); + state.deletFingerNo = int.parse(fingerprintItemData.fingerprintNumber!); logic.senderAddFingerprint(); }); }, diff --git a/star_lock/lib/main/lockDetail/lockSet/lockSet/lockSet_logic.dart b/star_lock/lib/main/lockDetail/lockSet/lockSet/lockSet_logic.dart index 7fb4a80f..f2dff1ce 100644 --- a/star_lock/lib/main/lockDetail/lockSet/lockSet/lockSet_logic.dart +++ b/star_lock/lib/main/lockDetail/lockSet/lockSet/lockSet_logic.dart @@ -130,17 +130,11 @@ class LockSetLogic extends BaseGetXController { privateKey: getPrivateKeyList, token: getTokenList); break; - case 0x07: - //无权限 - dismissEasyLoading(); - break; - case 0x09: - // 权限校验错误 - dismissEasyLoading(); - break; default: //失败 dismissEasyLoading(); + cancelBlueConnetctToastTimer(); + showDeletAlertTipDialog(); break; } } diff --git a/star_lock/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_logic.dart b/star_lock/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_logic.dart index 793ff193..1362d523 100644 --- a/star_lock/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_logic.dart +++ b/star_lock/lib/main/lockDetail/lockSet/remoteUnlocking/remoteUnlocking_logic.dart @@ -85,11 +85,14 @@ class RemoteUnlockingLogic extends BaseGetXController { dismissEasyLoading(); remoteUnlockingOpenOrClose(); break; - case 0x06: - //无权限 - - break; + // case 0x06: + // //无权限 + // + // break; default: + state.sureBtnState.value = 0; + cancelBlueConnetctToastTimer(); + dismissEasyLoading(); break; } } diff --git a/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart index bf2a84bc..a9fecb85 100644 --- a/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart +++ b/star_lock/lib/main/lockDetail/passwordKey/passwordKey_perpetual/passwordKey_perpetual_logic.dart @@ -183,11 +183,11 @@ class PasswordKeyPerpetualLogic extends BaseGetXController { Future checkKeyboardpwdNameRequest() async { if (state.nameController.text.isEmpty) { - showToast("请输入姓名"); + showToast("请输入姓名".tr); return; } if (state.pwdController.text.isEmpty) { - showToast("请输入密码"); + showToast("请输入密码".tr); return; } var entity = await ApiRepository.to.checkKeyboardpwdName( @@ -212,13 +212,46 @@ class PasswordKeyPerpetualLogic extends BaseGetXController { switch (status) { case 0x00: //成功 + dismissEasyLoading(); + cancelBlueConnetctToastTimer(); + state.sureBtnState.value = 0; state.pwdNumber.value = listChangInt(reply.data.sublist(9, 11)); // AppLog.log("密码编号:${state.pwdNumber.value}"); - dismissEasyLoading(); - cancelBlueConnetctToastTimer(); - addKeyboardPwdRequest(); + switch(reply.data[11]){ + case 0: + // 成功 + addKeyboardPwdRequest(); + break; + case 0xff: + // 注册人脸失败 + showToast("退出添加".tr); + Get.close(1); + break; + case 0xFE: + // 管理员已满 + showToast("管理员已满".tr); + Get.close(1); + break; + case 0xFD: + // 用户已满 + showToast("用户已满".tr); + Get.close(1); + break; + case 0xFC: + // 指纹已满 + showToast("锁上面添加密码已满".tr); + Get.close(1); + break; + case 0xFB: + // 指纹已存在 + showToast("密码已存在".tr); + break; + default: + // 添加密码 + break; + } break; case 0x06: //无权限 @@ -276,12 +309,12 @@ class PasswordKeyPerpetualLogic extends BaseGetXController { var endDate = DateTool().dateToTimestamp(state.customEndTime.value, 1); //非永久 须有时限 if (state.isPermanent.value == false) { - if (startDate < DateTool().dateToTimestamp(DateTool().getNowDateWithType(3), 1)) { - showToast("生效时间不能小于当前时间"); + if (startDate <= DateTool().dateToTimestamp(DateTool().getNowDateWithType(2), 1)) { + showToast("生效时间要大于当前时间"); return; } - if (endDate < startDate) { + if (endDate <= startDate) { showToast("失效时间需大于生效时间"); return; } diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart index 05cd0e47..1e6faeba 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart @@ -1,10 +1,20 @@ - import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:crypto/crypto.dart'; +import 'package:file_picker/file_picker.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:star_lock/blue/io_protocol/io_getPrivateKey.dart'; import 'package:star_lock/blue/io_protocol/io_getPublicKey.dart'; +import 'package:star_lock/blue/io_protocol/io_otaUpgrade.dart'; +import 'package:star_lock/blue/io_protocol/io_processOtaUpgrade.dart'; +import 'package:star_lock/mine/addLock/nearbyLock/nearbyLock_page.dart'; +import 'package:star_lock/permission/permission_dialog.dart'; import 'package:star_lock/tools/baseGetXController.dart'; import '../../../appRouters.dart'; @@ -21,6 +31,15 @@ import 'nearbyLock_state.dart'; class NearbyLockLogic extends BaseGetXController { final NearbyLockState state = NearbyLockState(); + int otaCount = 0; + int otaIndex = 0; + Uint8List? otaBin; + int startSecond = 0; + Map? headJson; + + String? deviceName; + StreamSubscription? _replySubscription; + // 点击连接设备 void connect(String deviceName) { showTitleEasyLoading("获取锁信息 1/3"); @@ -30,11 +49,12 @@ class NearbyLockLogic extends BaseGetXController { // state.sureBtnState.value = 1; // showEasyLoading(); - showBlueConnetctToastTimer(action: (){ + showBlueConnetctToastTimer(action: () { dismissEasyLoading(); // state.sureBtnState.value = 0; }); - BlueManage().bludSendData(deviceName, (BluetoothConnectionState state) async { + BlueManage().bludSendData(deviceName, + (BluetoothConnectionState state) async { AppLog.log("点击要添加的设备了"); if (state == BluetoothConnectionState.connected) { AppLog.log("开始获取公钥"); @@ -45,12 +65,11 @@ class NearbyLockLogic extends BaseGetXController { }, isAddEquipment: true); } - // 获取解析后的数据 - late StreamSubscription _replySubscription; void _initReplySubscription() { - _replySubscription = EventBusManager().eventBus!.on().listen((reply) { + _replySubscription = + EventBusManager().eventBus!.on().listen((reply) { if (reply is GetPublicKeyReply) { - _replyGetPublicKey(reply); + _replyGetPublicKey(reply); } if (reply is GetPrivateKeyReply) { @@ -61,6 +80,23 @@ class NearbyLockLogic extends BaseGetXController { if (reply is GetStarLockStatuInfoReply) { _replyGetStarLockStatusInfo(reply); } + + if (reply is OTAUpgradeReply) { + if (reply.status == 0x00) { + //验证通过,开始发送数据包 + dismissEasyLoading(); + startOTAData(); + processOtaUpgrade(); + } else if (reply.status == 0x06) { + blueOTAUpgrade(headJson!, reply.token); + } + } else if (reply is ProcessOtaUpgradeReply && reply.status == 0x00) { + otaIndex++; + processOtaUpgrade(); + } else if (reply is ConfirmationOTAUpgradeReply && reply.status == 0x00) { + showToast('固件升级完成'.tr); + closeOTADAta(); + } }); } @@ -197,8 +233,10 @@ class NearbyLockLogic extends BaseGetXController { // 重置次数 var restoreCounter = reply.data.sublist(133, 135); - state.lockInfo["restoreCount"] = restoreCounter[0] * 256 + restoreCounter[1]; - AppLog.log("重置次数 restoreCounter:${restoreCounter[0] * 256 + restoreCounter[1]}"); + state.lockInfo["restoreCount"] = + restoreCounter[0] * 256 + restoreCounter[1]; + AppLog.log( + "重置次数 restoreCounter:${restoreCounter[0] * 256 + restoreCounter[1]}"); // 重置时间 var restoreDate = reply.data.sublist(135, 139); @@ -312,21 +350,6 @@ class NearbyLockLogic extends BaseGetXController { } } - // List charListChangeIntList(List featureValue){ - // // 字符数组转化为16进制字符串 - // String featureValueStr = asciiString(featureValue); - // // 16进制字符串转化为2进制的字符串 获取的是逆序的需要倒序 前面有0会消失 需要自动补全 暂时定位57个功能 要补全60 - // String featureValueTwoStr = int.parse(featureValueStr,radix: 16).toRadixString(2); - // List featureValueTwoList = []; - // for(int i = 0;i _getStarLockStatus() async { // 进来之后首先连接 @@ -334,39 +357,26 @@ class NearbyLockLogic extends BaseGetXController { // if (state == BluetoothConnectionState.connected) { // dismissEasyLoading(); - AppLog.log("开始获取锁状态"); - var privateKey = await Storage.getStringList(saveBluePrivateKey); - List getPrivateKeyList = changeStringListToIntList(privateKey!); - // IoSenderManage.senderGetLockStatu( - // lockID:BlueManage().connectDeviceName, - // userID:await Storage.getUid(), - // privateKey:getPrivateKeyList, - // ); - IoSenderManage.senderGetStarLockStatuInfo( - lockID: BlueManage().connectDeviceName, - userID: await Storage.getUid(), - isBeforeAddUser: true, - privateKey: getPrivateKeyList, - ); + AppLog.log("开始获取锁状态"); + var privateKey = await Storage.getStringList(saveBluePrivateKey); + List getPrivateKeyList = changeStringListToIntList(privateKey!); + // IoSenderManage.senderGetLockStatu( + // lockID:BlueManage().connectDeviceName, + // userID:await Storage.getUid(), + // privateKey:getPrivateKeyList, + // ); + IoSenderManage.senderGetStarLockStatuInfo( + lockID: BlueManage().connectDeviceName, + userID: await Storage.getUid(), + isBeforeAddUser: true, + privateKey: getPrivateKeyList, + ); // } else if (state == BluetoothConnectionState.disconnected) { // dismissEasyLoading(); // } // }, isAddEquipment: true); } - // late StreamSubscription>_scanListDiscoveredDeviceSubscription; - // void _scanListDiscoveredDeviceSubscriptionAction() { - // _scanListDiscoveredDeviceSubscription = EventBusManager().eventBus!.on>().listen((List list) { - // state.devices.clear(); - // for (int i = 0; i < list.length; i++) { - // ScanResult device = list[i]; - // if (((device.advertisementData.serviceUuids.isNotEmpty ? device.advertisementData.serviceUuids[0] : "").toString()[31] != "1")) { - // state.devices.add(list[i]); - // } - // } - // }); - // } - void startScanBlueList() { BlueManage().startScan(2000, (List list) { state.devices.clear(); @@ -388,30 +398,234 @@ class NearbyLockLogic extends BaseGetXController { BlueManage().stopScan(); } + // 点击连接设备,升级 ota 固件 + void oTAUpgrade(String deviceName) { + showTitleEasyLoading("连接设备中..."); + this.deviceName = deviceName; + BlueManage().bludSendData(deviceName, + (BluetoothConnectionState state) async { + AppLog.log("连接设备"); + if (state == BluetoothConnectionState.connected) { + AppLog.log("连接成功"); + dismissEasyLoading(); + otaUpdate(); + } else if (state == BluetoothConnectionState.disconnected) { + AppLog.log("连接失败"); + dismissEasyLoading(); + } + }, isAddEquipment: true); + } + + //手动升级 + Future otaUpdate() async { + var status = await PermissionDialog.request( + Permission.storage, '需要访问读写权限才能使用手动升级固件'.tr); + if (status != true) { + return; + } + FilePickerResult? result = await FilePicker.platform.pickFiles(); + if (result == null || result.files.single.path is! String) { + return; + } + File file = File(result.files.single.path!); + Uint8List data = await file.readAsBytes(); + headJson = await getHeadFile(data); + if (headJson is! Map) { + return; + } + otaBin = await checkFile(data, headJson!); + if (otaBin == null) { + return; + } + String md5Str = md5.convert(otaBin!).toString(); + headJson!['fwMd5'] = md5Str; + blueOTAUpgrade(headJson!, [0, 0, 0, 0]); + } + + //蓝牙操作 ota 升级 + void blueOTAUpgrade(Map data, List token) { + if (deviceName == null) { + AppLog.log('blueOTAUpgrade:设备名字为 null'); + return; + } + BlueManage().bludSendData(deviceName!, + (BluetoothConnectionState deviceConnectionState) async { + if (deviceConnectionState == BluetoothConnectionState.connected) { + String uid = await Storage.getUid() ?? ''; + BlueManage().writeCharacteristicWithResponse(OTAUpgradeCommand( + lockID: deviceName, + userID: uid, + keyID: deviceName, + platform: int.tryParse(data['platform']) ?? 0, + product: int.tryParse(data['product']) ?? 0, + hwVersion: data['hwVersion'], + fwVersion: data['fwVersion'], + fwSize: data['fwSize'], + fwMD5: data['fwMd5'], + needAuthor: 1, + token: token, + encrypt: false, + ).packageData()); + showTitleEasyLoading("连接设备中..."); + } else if (deviceConnectionState == + BluetoothConnectionState.disconnected) {} + },isAddEquipment: true); + } + + //循环传输升级固件包 + Future processOtaUpgrade() async { + if (!state.otaUpdateIng.value) { + return; + } + int length = otaBin?.length ?? 0; + if (otaCount == 0) { + //首次 + int difference = length % 240; + otaCount = length ~/ 240 + (difference > 0 ? 1 : 0); + startSecond = DateTime.now().millisecondsSinceEpoch ~/ 1000; + } + if (otaCount <= otaIndex) { + int now = DateTime.now().millisecondsSinceEpoch ~/ 1000; + String msg = + '传输完成 时间:${now - startSecond}秒 otaCount:$otaCount otaIndex:$otaIndex '; + closeOTADAta(); + AppLog.log(msg); + // showToast(msg); + return; + } + int star = otaIndex * 240; + int end = (otaIndex + 1) * 240; + if (end > length) { + end = length; + } + int size = end - star; + List data = otaBin!.sublist(star, end); + state.otaProgress.value = otaIndex / otaCount; + await BlueManage().writeCharacteristicWithResponse( + ProcessOtaUpgradeCommand(index: otaIndex, size: size, data: data) + .packageData()); + } + + //开始 ota升级 + void startOTAData() { + state.otaUpdateIng.value = true; + state.oTAProgressDialog = true; + Get.dialog( + OTAProgressDialog( + logic: this, + ), + barrierDismissible: false) + .then((value) => state.oTAProgressDialog = false); + } + + //清楚 ata 安装文件 + void closeOTADAta() { + if (state.oTAProgressDialog) { + Get.back(); + } + state.otaUpdateIng.value = false; + state.otaProgress.value = 0; + otaIndex = 0; + otaCount = 0; + startSecond = 0; + otaBin = null; + } + + // 拦截返回事件 + void getBack() { + if (state.otaUpdateIng.value) { + closeOTADAta(); + } else { + Get.back(); + } + } + +// 检查文件头 + Future getHeadFile(Uint8List data) async { + if (data.length <= 16) { + showToast('错误固件,请选择正确的文件'.tr); + return null; + } + // 检查文件头 + String header; + try { + header = utf8.decode(data.sublist(0, 12)); + } catch (e) { + showToast('非SYD固件,请选择正确的文件'.tr); + return null; + } + if (header != 'SYD-BIN-DATA') { + showToast('非SYD固件,请选择正确的文件'.tr); + return null; + } + // 解析元数据长度 + Uint8List metaLenList; + int metaLen; + try { + metaLenList = data.sublist(12, 16); + metaLen = ByteData.sublistView(metaLenList).getUint32(0); + } catch (e) { + showToast('文件校验失败 0x01'.tr); + return null; + } + if (metaLen < 2 || metaLen > 10240) { + showToast('文件校验失败 0x01'.tr); + return null; + } + // 读取和解析元数据 + Uint8List metaStrList; + String metaStr; + try { + metaStrList = data.sublist(16, 16 + metaLen); + metaStr = utf8.decode(metaStrList); + } catch (e) { + showToast('解析元数据失败,请选择正确的文件'.tr); + return null; + } + AppLog.log(metaStr); + var meta = jsonDecode(metaStr); + if (meta is! Map) { + showToast('解析元数据失败,请选择正确的文件'.tr); + return null; + } + return meta..['metaLen'] = metaLen; + } + + //检测升级文件并读取 bin + Future checkFile(Uint8List data, Map meta) async { + num binOffset = 16 + (meta['metaLen'] ?? 0); + // 获取固件数据部分 + Uint8List bin = data.sublist(binOffset.toInt(), data.length); + //md5 校验有问题,暂时不解析 + String md5Str = md5.convert(bin).toString().toUpperCase(); + AppLog.log('---> $md5Str ${meta['fwMd5']}'); + if (md5Str != meta['fwMd5']) { + showToast('文件校验失败 0x02'.tr); + return null; + } + if (bin.length != meta['fwSize']) { + showToast('文件校验失败 0x03'.tr); + return null; + } + return bin; + } + @override void onReady() { - // TODO: implement onReady super.onReady(); - _initReplySubscription(); - // _scanListDiscoveredDeviceSubscriptionAction(); - state.ifCurrentScreen.value = true; - startScanBlueList(); } @override void onInit() { - // TODO: implement onInit super.onInit(); } @override void onClose() { - // TODO: implement onClose super.onClose(); - _replySubscription.cancel(); - // _scanListDiscoveredDeviceSubscription.cancel(); + _replySubscription?.cancel(); } } diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart index a474bc92..3740694b 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_page.dart @@ -23,12 +23,6 @@ class _NearbyLockPageState extends State with RouteAware { final logic = Get.put(NearbyLockLogic()); final state = Get.find().state; - @override - void initState() { - // TODO: implement initState - super.initState(); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -60,32 +54,62 @@ class _NearbyLockPageState extends State with RouteAware { ]), ), body: Obx(() { - return ListView.separated( - itemCount: state.devices.length, - itemBuilder: (c, index) { - return nearbyLockItem( - 'images/icon_lockGroup_item.png', state.devices[index], () { - // Navigator.pushNamed(context, Routers.lockAddressPage); - // logic.getPublicKey(state.devices[index].serviceUuids[0].toString()); - state.selectLockName.value = - state.devices[index].advertisementData.advName; - logic.connect(state.devices[index].advertisementData.advName); - // Get.toNamed(Routers.lockAddressGaoDePage); - }); - }, - separatorBuilder: (BuildContext context, int index) { - return Divider( - height: 1, - color: AppColors.greyLineColor, - indent: 20.w, - endIndent: 0, - ); - }, - ); + return listView(); }), ); } + Widget listView() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: ListView.separated( + itemCount: state.devices.length, + itemBuilder: (c, index) { + return nearbyLockItem( + 'images/icon_lockGroup_item.png', state.devices[index], () { + String advName = state.devices[index].advertisementData.advName; + state.selectLockName.value = advName; + if (state.otaState.value) { + logic.oTAUpgrade(advName); + } else { + logic.connect(advName); + } + }); + }, + separatorBuilder: (BuildContext context, int index) { + return Divider( + height: 1, + color: AppColors.greyLineColor, + indent: 20.w, + endIndent: 0, + ); + }, + ), + ), + Padding( + padding: EdgeInsets.only(left: 15.w, bottom: 10.h), + child: TextButton( + onPressed: () async { + bool skip = false; + if (!state.otaState.value) { + skip = await Get.dialog( + const _TipDialog(), + ); + } + state.otaState.value = skip; + }, + child: Text( + state.otaState.value ? '点击返回设备配对'.tr : '无法连接?尝试升级'.tr, + style: TextStyle(fontSize: 22.sp), + ), + ), + ), + ], + ); + } + Widget nearbyLockItem( String lockTypeIcon, ScanResult scanResult, Function() action) { return GestureDetector( @@ -97,7 +121,6 @@ class _NearbyLockPageState extends State with RouteAware { ? action : null, child: Column( - // mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 89.h, @@ -141,9 +164,12 @@ class _NearbyLockPageState extends State with RouteAware { ), Expanded(child: SizedBox(width: 20.w)), Image.asset( - 'images/main/icon_main_addLock.png', + state.otaState.value + ? 'images/ota_upgrade_icon.png' + : 'images/main/icon_main_addLock.png', width: 36.w, height: 36.w, + color: AppColors.mainColor, ), SizedBox(width: 30.w), ], @@ -156,7 +182,6 @@ class _NearbyLockPageState extends State with RouteAware { @override void didChangeDependencies() { - // TODO: implement didChangeDependencies super.didChangeDependencies(); /// 路由订阅 @@ -165,7 +190,6 @@ class _NearbyLockPageState extends State with RouteAware { @override void dispose() { - // TODO: implement dispose /// 取消路由订阅 AppRouteObserver().routeObserver.unsubscribe(this); super.dispose(); @@ -183,11 +207,9 @@ class _NearbyLockPageState extends State with RouteAware { super.didPop(); EasyLoading.isShow ? EasyLoading.dismiss() : null; - state.ifCurrentScreen.value = false; logic.cancelBlueConnetctToastTimer(); logic.stopScanBlueList(); - BlueManage().disconnect(); } /// 从下级返回 当前界面即将出现 @@ -203,10 +225,88 @@ class _NearbyLockPageState extends State with RouteAware { @override void didPushNext() { super.didPushNext(); - - state.ifCurrentScreen.value = false; - logic.cancelBlueConnetctToastTimer(); - logic.stopScanBlueList(); - BlueManage().disconnect(); + if (!logic.state.otaState.value) { + state.ifCurrentScreen.value = false; + logic.cancelBlueConnetctToastTimer(); + logic.stopScanBlueList(); + } + } +} + +class _TipDialog extends StatelessWidget { + const _TipDialog({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return CupertinoAlertDialog( + title: Text( + '固件升级提示'.tr, + ), + content: Text('请先获取固件文件到手机本地,再选择升级'.tr), + actions: [ + TextButton( + onPressed: () { + Get.back(); + }, + child: Text( + '取消'.tr, + style: TextStyle(fontSize: 22.sp, color: AppColors.blackColor), + ), + ), + TextButton( + onPressed: () async { + Get.back(result: true); + }, + child: Text( + '确定'.tr, + style: TextStyle(fontSize: 22.sp, color: AppColors.blackColor), + ), + ), + ], + ); + } +} + +class OTAProgressDialog extends StatelessWidget { + NearbyLockLogic logic; + + OTAProgressDialog({required this.logic, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Obx(() { + return CupertinoAlertDialog( + title: Text( + '固件升级中'.tr, + ), + content: Row( + children: [ + Text( + '传输中'.tr, + style: TextStyle(fontSize: 22.sp, color: AppColors.mainColor), + ), + SizedBox( + width: 15.w, + ), + Expanded( + child: LinearProgressIndicator( + value: logic.state.otaProgress.value, + color: AppColors.mainColor, + )), + ], + ), + actions: [ + TextButton( + onPressed: () { + logic.closeOTADAta(); + }, + child: Text( + '取消升级'.tr, + style: TextStyle(fontSize: 22.sp, color: AppColors.blackColor), + ), + ), + ], + ); + }); } } diff --git a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart index 4e7d61c2..82a63f33 100644 --- a/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart +++ b/star_lock/lib/mine/addLock/nearbyLock/nearbyLock_state.dart @@ -1,9 +1,7 @@ - import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:get/get.dart'; class NearbyLockState { - RxList devices = [].obs; var ifCurrentScreen = true.obs; // 是否是当前界面,用于判断是否需要针对当前界面进行展示 // var sureBtnState = 0.obs;// 0可点击 1 不可点击 @@ -16,4 +14,8 @@ class NearbyLockState { var featureSettingValue = ''; var featureSettingParams = []; + var otaState = false.obs; //ota 升级 + var otaUpdateIng = false.obs; + var otaProgress = 0.00.obs; + bool oTAProgressDialog = false; } diff --git a/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart b/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart index 45b0012d..77b63947 100644 --- a/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart +++ b/star_lock/lib/mine/addLock/saveLock/saveLock_logic.dart @@ -96,10 +96,6 @@ class SaveLockLogic extends BaseGetXController { // 添加管理员密码 Future _replySenderCustomPasswords(Reply reply) async { - var token = reply.data.sublist(5, 9); - var saveStrList = changeIntListToStringList(token); - Storage.setStringList(saveBlueToken, saveStrList); - int status = reply.data[2]; switch (status) { @@ -116,6 +112,10 @@ class SaveLockLogic extends BaseGetXController { var signKey = await Storage.getStringList(saveBlueSignKey); List signKeyDataList = changeStringListToIntList(signKey!); + var token = reply.data.sublist(5, 9); + var saveStrList = changeIntListToStringList(token); + Storage.setStringList(saveBlueToken, saveStrList); + IoSenderManage.senderCustomPasswordsCommand( keyID: "1", userID: await Storage.getUid(), diff --git a/star_lock/pubspec.yaml b/star_lock/pubspec.yaml index 6d82873c..51a35272 100644 --- a/star_lock/pubspec.yaml +++ b/star_lock/pubspec.yaml @@ -102,7 +102,7 @@ dependencies: url_launcher: ^6.1.10 #蓝牙 # flutter_reactive_ble: ^5.1.1 - flutter_blue_plus: ^1.31.16 + flutter_blue_plus: 1.31.16 # event_bus: ^2.0.0 #菊花