529 lines
16 KiB
Dart
529 lines
16 KiB
Dart
|
||
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;
|
||
}
|
||
|
||
} |