2023-10-21 15:42:25 +08:00

529 lines
16 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/blue/io_protocol/io_editUser.dart';
import 'package:star_lock/blue/io_protocol/io_factoryDataReset.dart';
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
import 'package:star_lock/blue/io_type.dart';
import 'package:star_lock/tools/toast.dart';
import '../../../blue/blue_manage.dart';
import '../../../blue/io_protocol/io_getStarLockStatusInfo.dart';
import '../../../blue/io_protocol/io_openLock.dart';
import '../../../blue/io_reply.dart';
import '../../../blue/io_tool/io_manager.dart';
import '../../../blue/io_tool/io_tool.dart';
import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart';
import '../../../login/login/entity/LoginData.dart';
import '../../../login/login/entity/LoginEntity.dart';
import '../../../network/api_repository.dart';
import '../../../tools/baseGetXController.dart';
import '../../../tools/eventBusEventManage.dart';
import '../../../tools/storage.dart';
import 'lockDetail_state.dart';
class LockDetailLogic extends BaseGetXController{
final LockDetailState state = LockDetailState();
// 监听设备返回的数据
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) async {
// 开门
if(reply is OpenDoorReply) {
_replyOpenLock(reply);
}
// 获取锁状态
if(reply is GetLockStatuReply) {
_replyGetLockStatus(reply);
}
// 编辑锁用户
if(reply is EditUserReply){
_replyEditUserKey(reply);
}
// 获取星锁状态信息
if(reply is GetStarLockStatuInfoReply){
_replyGetStarLockStatusInfo(reply);
}
});
}
// 开门数据解析
Future<void> _replyOpenLock(Reply reply) async {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var signKey = await Storage.getStringList(saveBlueSignKey);
List<int> signKeyDataList = changeStringListToIntList(signKey!);
var tokenData = reply.data.sublist(2, 6);
var saveStrList = changeIntListToStringList(tokenData);
print("openDoorToken:$tokenData");
Storage.setStringList(saveBlueToken, saveStrList);
// 电量
int power = reply.data[7];
int status = reply.data[6];
print("status:$status");
switch(status){
case 0x00:
//成功
print("${reply.commandType}数据解析成功");
state.lockState.value = 2;
state.animationController.reset();
state.animationController.forward();
// state.animationController.isCompleted;
break;
case 0x06:
//无权限
print("${reply.commandType}需要鉴权");
print("millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch~/1000}");
IoSenderManage.senderOpenLock(
keyID: BlueManage().connectDeviceName,
userID: await Storage.getUid(),
openMode: 1,
openTime: DateTime.now().millisecondsSinceEpoch~/1000,
token: tokenData,
needAuthor: 1,
signKey: signKeyDataList,
privateKey: getPrivateKeyList,
);
break;
case 0x07:
//无权限
print("${reply.commandType}用户无权限");
break;
case 0x09:
// 权限校验错误
print("${reply.commandType}校验错误");
break;
default:
//失败
print("${reply.commandType}失败");
break;
}
}
// 获取锁状态数据解析
Future<void> _replyGetLockStatus(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//成功
print("${reply.commandType}数据解析成功");
var softVersion = reply.data.sublist(3, 7);
print("softVersion:$softVersion");
var power = reply.data[7];
print("power:$power");
// APP 用户数量
var appUserCount = reply.data.sublist(50, 53);
print("appUserCount:$appUserCount");
// 黑名单用户数量
var blacklistCount = reply.data[53];
print("blacklistCount:$blacklistCount");
// 蓝牙钥匙数量
var bleKeyCount = reply.data[54];
print("bleKeyCount:$bleKeyCount");
// 剩余可添加用户数量
var remainCount = reply.data.sublist(54, 56);
print("remainCount:$remainCount");
// 未上传开锁记录数量
var notUploadCount = reply.data.sublist(56, 58);
print("notUploadCount:$notUploadCount");
// 已设置开门密码数量
var pwdCount = reply.data[58];
print("pwdCount:$pwdCount");
// 已设置开门指纹数量
var fingerprintCount = reply.data[59];
print("fingerprintCount:$fingerprintCount");
// 锁当前时间
var lockTime = reply.data.sublist(60, 64);
print("lockTime:$lockTime");
// 硬件版本信息,为固件升级提供判断依据
var hardVersion = reply.data.sublist(64, 68);
print("hardVersion:$hardVersion");
break;
case 0x06:
//无权限
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//无权限
print("${reply.commandType}用户无权限");
break;
case 0x09:
// 权限校验错误
print("${reply.commandType}权限校验错误");
break;
default:
//失败
print("${reply.commandType}失败");
break;
}
}
// 编辑用户数据解析
Future<void> _replyEditUserKey(Reply reply) async {
var token = reply.data.sublist(2, 6);
var saveStrList = changeIntListToStringList(token);
print("_replyEditUserKeyToken:$token");
Storage.setStringList(saveBlueToken, saveStrList);
int status = reply.data[6];
print("status:$status");
switch(status){
case 0x00:
//成功
print("${reply.commandType!.typeValue} 数据解析成功");
break;
case 0x06:
//无权限
print("${reply.commandType!.typeValue} 需要鉴权");
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var publicKey = await Storage.getStringList(saveBluePublicKey);
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
IoSenderManage.senderEditUser(
lockID:BlueManage().connectDeviceName,
authUserID:await Storage.getUid(),
keyID:"1",
userID:await Storage.getUid(),
openMode:1,
keyType:1,
startDate:0x11223344,
expireDate:0x11223344,
role:255,
password:"123456",
needAuthor:1,
publicKey:publicKeyDataList,
privateKey:getPrivateKeyList,
token: token
);
break;
case 0x07:
//无权限
print("${reply.commandType!.typeValue} 用户无权限");
break;
case 0x09:
// 权限校验错误
print("${reply.commandType!.typeValue} 权限校验错误");
break;
default:
//失败
print("${reply.commandType!.typeValue} 失败");
break;
}
}
Future<void> _replyGetStarLockStatusInfo(Reply reply) async {
int status = reply.data[2];
switch(status){
case 0x00:
//成功
print("${reply.commandType}数据解析成功");
// 厂商名称
var vendor = reply.data.sublist(3, 23);
print("vendor:$vendor");
// 锁设备类型
var product = reply.data[23];
print("product:$product");
// 产品名称
var model = reply.data.sublist(24, 44);
print("model:$model");
// 软件版本
var fwVersion = reply.data.sublist(44, 64);
print("fwVersion:$fwVersion");
// 硬件版本
var hwVersion = reply.data.sublist(64, 84);
print("hwVersion:$hwVersion");
// 厂商序列号
var serialNum0 = reply.data.sublist(84, 100);
print("serialNum0:$serialNum0");
// 成品商序列号
var serialNum1 = reply.data.sublist(100, 116);
print("serialNum1:$serialNum1");
// 蓝牙名称
var btDeviceName = reply.data.sublist(116, 132);
print("btDeviceName:$btDeviceName");
// 电池剩余电量
var battRemCap = reply.data[132];
print("battRemCap:$battRemCap");
// 重置次数
var restoreCounter = reply.data.sublist(133, 135);
print("restoreCounter:$restoreCounter");
// 重置时间
var restoreDate = reply.data.sublist(135, 139);
print("restoreDate:$restoreDate");
// 主控芯片型号
var icPartNo = reply.data.sublist(139, 149);
print("icPartNo:$icPartNo");
// 有效时间
var indate = reply.data.sublist(149, 153);
print("indate:$indate");
break;
case 0x06:
//无权限
print("${reply.commandType}需要鉴权");
break;
case 0x07:
//无权限
print("${reply.commandType}用户无权限");
break;
case 0x09:
// 权限校验错误
print("${reply.commandType}权限校验错误");
break;
default:
//失败
print("${reply.commandType}失败");
break;
}
}
// 点击开门事件
Future<void> openDoorAction() async {
// if(BlueManage().connectDeviceMacAddress.isEmpty){
// Toast.show(msg: "正在连接设备,请稍等。");
// return;
// }
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, state.keyInfos.value.bluetooth!.bluetoothDeviceName!, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected){
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var signKey = await Storage.getStringList(saveBlueSignKey);
List<int> signKeyDataList = changeStringListToIntList(signKey!);
bool isHave = await Storage.ifHaveKey(saveBlueToken);
List<int> getTokenList;
if(isHave){
var token = await Storage.getStringList(saveBlueToken);
getTokenList = changeStringListToIntList(token!);
}else{
getTokenList = [0,0,0,0];
}
print("openDoorTokenPubToken:$getTokenList");
print("millisecondsSinceEpoch/1000:${DateTime.now().millisecondsSinceEpoch~/1000}");
IoSenderManage.senderOpenLock(
keyID: BlueManage().connectDeviceName,
userID: await Storage.getUid(),
openMode: 1,
openTime: DateTime.now().millisecondsSinceEpoch~/1000,
token: getTokenList,
needAuthor: 1,
signKey: signKeyDataList,
privateKey: getPrivateKeyList,
);
}
}, isShowLoading: false);
}
// 编辑用户事件
Future<void> editLockUserAction() async {
BlueManage().judgeReconnect(BlueManage().connectDeviceMacAddress, BlueManage().connectDeviceName, (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected){
var publicKey = await Storage.getStringList(saveBluePublicKey);
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
var token = await Storage.getStringList(saveBlueToken);
List<int> getTokenList = changeStringListToIntList(token!);
print("openDoorTokenPubToken:$getTokenList");
print("publicKey:$publicKey publicKeyDataList:$publicKeyDataList privateKey:$privateKey getPrivateKeyList:$getPrivateKeyList token:$token getTokenList:$getTokenList");
IoSenderManage.senderEditUser(
lockID:BlueManage().connectDeviceName,
authUserID:await Storage.getUid(),
keyID:"1",
userID:await Storage.getUid(),
openMode:1,
keyType:1,
startDate:0x11223344,
expireDate:0x11223344,
role:255,
password:"123456",
needAuthor:1,
publicKey:publicKeyDataList,
privateKey:getPrivateKeyList,
token: getTokenList
);
}
});
}
// 备用逻辑,进入管理钥匙界面获取锁状态
Future<void> connectBlue(String bluetoothDeviceId, String bluetoothDeviceName) async {
// 进来之后首先连接
BlueManage().connect(bluetoothDeviceId, bluetoothDeviceName, connectStateCallBack: (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected){
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
// IoSenderManage.senderGetLockStatu(
// lockID:BlueManage().connectDeviceName,
// userID:await Storage.getUid(),
// privateKey:getPrivateKeyList,
// );
IoSenderManage.senderGetStarLockStatuInfo(
lockID:BlueManage().connectDeviceName,
userID:await Storage.getUid(),
privateKey:getPrivateKeyList,
);
}
}, isShowLoading: false);
}
void startScanAction(){
BlueManage().startScan(true, (v){
print("startScanAllDevice:${v}");
final knownDeviceIndex = v.indexWhere((d) => d.name == state.keyInfos.value.bluetooth!.bluetoothDeviceName!);
// 当扫描到的时候
if (knownDeviceIndex >= 0) {
BlueManage().connectDeviceMacAddress = v[knownDeviceIndex].id;
connectBlue(v[knownDeviceIndex].id, state.keyInfos.value.bluetooth!.bluetoothDeviceName!);
eventBus.fire(ScanAllDeviceFindCurrentDeviceConnectedEvent(v[knownDeviceIndex].serviceUuids[0].toString()));
BlueManage().stopScan();
}
});
}
//开始连接
startConnect() {
state.lockState.value = 1;
state.animationController.forward();
openDoorAction();
Future.delayed(const Duration(seconds: 10), () {
if(state.lockState.value == 1){
stopConnect();
state.lockState.value = 4;
Toast.show(msg: "连接设备失败,请确保在设备附近,设备未被连接,设备已打开");
state.animationController.reset();
state.animationController.forward();
}
});
}
//关闭连接
stopConnect() {
}
@override
void onReady() {
// TODO: implement onReady
super.onReady();
print("onReady()");
_initReplySubscription();
if(Platform.isIOS){
startScanAction();
}else{
getMicrophonePermission()
.then((value) {
if (value) {
// 有权限
startScanAction();
}else{
//没有权限
openAppSettings();//打开app系统设置
}
});
}
}
@override
void onInit() {
// TODO: implement onInit
super.onInit();
print("lockDetail_onInit()");
// 进来获取锁状态
// connectBlue();
// factoryDataResetAction();
}
@override
void onClose() {
// TODO: implement onClose
_replySubscription.cancel();
}
///请求录音相机权限
Future<bool> getMicrophonePermission() async {
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetoothScan,
Permission.bluetoothConnect,
Permission.location,
].request();
//granted 通过denied 被拒绝permanentlyDenied 拒绝且不在提示
if (statuses[Permission.bluetoothScan]!.isGranted &&
statuses[Permission.bluetoothConnect]!.isGranted &&
statuses[Permission.location]!.isGranted) {
return true;
}
return false;
}
}