调试开锁协议、获取锁状态协议
This commit is contained in:
parent
796cd3a0f6
commit
9cfa39bd5e
@ -1,10 +1,14 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
import 'package:star_lock/blue/sender_manage.dart';
|
||||
|
||||
import '../app_settings/app_settings.dart';
|
||||
import '../tools/storage.dart';
|
||||
import 'io_tool/io_manager.dart';
|
||||
import 'io_tool/io_model.dart';
|
||||
import 'io_tool/io_tool.dart';
|
||||
import 'io_tool/manager_event_bus.dart';
|
||||
import 'reciver_data.dart';
|
||||
@ -19,6 +23,11 @@ class BlueManage{
|
||||
Uuid serviceId = Uuid.parse('0000FFF0-0000-1000-8000-00805F9B34FB');
|
||||
final int _limitLen = 20;
|
||||
|
||||
// 监听发送事件
|
||||
StreamSubscription<EventSendModel>? _sendStreamSubscription;
|
||||
// 监听蓝牙连接状态
|
||||
DeviceConnectionState? deviceConnectionState;
|
||||
|
||||
static BlueManage? _manager;
|
||||
BlueManage._init();
|
||||
|
||||
@ -33,6 +42,22 @@ class BlueManage{
|
||||
|
||||
void _initBlue(){
|
||||
_flutterReactiveBle = FlutterReactiveBle();
|
||||
|
||||
_initSendStreamSubscription();
|
||||
}
|
||||
|
||||
void _initSendStreamSubscription() {
|
||||
_sendStreamSubscription = EventBusManager().eventBus!.on<EventSendModel>().listen((
|
||||
EventSendModel model) {
|
||||
if (model.sendChannel == DataChannel.ble) {
|
||||
// managerAppWriteData(model.data);
|
||||
writeCharacteristicWithResponse(QualifiedCharacteristic(
|
||||
deviceId:qualifiedCharacteristic!.deviceId,
|
||||
characteristicId: qualifiedCharacteristic!.characteristicId,
|
||||
serviceId: serviceId),
|
||||
model.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// 开始扫描蓝牙设备
|
||||
@ -64,15 +89,16 @@ class BlueManage{
|
||||
/// 连接监听状态
|
||||
Future<void> connect(String deviceMAC, String deviceName) async {
|
||||
print("connect:$deviceMAC");
|
||||
_flutterReactiveBle!.connectToDevice(id: deviceMAC).listen((connectionStateUpdate) {
|
||||
_flutterReactiveBle!.connectToDevice(id: deviceMAC).listen((connectionStateUpdate) async {
|
||||
print('ConnectionState for device $deviceMAC : ${connectionStateUpdate.connectionState}');
|
||||
// EventBusManager().eventBusFir(connectionStateUpdate);
|
||||
deviceConnectionState = connectionStateUpdate.connectionState;
|
||||
if(connectionStateUpdate.connectionState == DeviceConnectionState.connected){
|
||||
// getPublicKey(update.deviceId);
|
||||
// 先配置lockId
|
||||
IoManager().configCurrentDeviceLockId(deviceName);
|
||||
// 如果状态是连接的开始发现服务
|
||||
discoverServices(deviceMAC);
|
||||
await discoverServices(deviceMAC);
|
||||
}
|
||||
}, onError: (Object e){
|
||||
print('Connecting to device $deviceMAC resulted in error $e');
|
||||
@ -170,8 +196,6 @@ class BlueManage{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 读取
|
||||
Future<List<int>> readCharacteristic(QualifiedCharacteristic characteristic) async {
|
||||
try {
|
||||
@ -197,4 +221,7 @@ class BlueManage{
|
||||
}
|
||||
}
|
||||
|
||||
disposed(){
|
||||
_sendStreamSubscription?.cancel();
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../tools/storage.dart';
|
||||
import '../io_tool/io_manager.dart';
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import 'io_reply.dart';
|
||||
@ -59,23 +57,27 @@ class AddUserCommand extends SenderProtocol {
|
||||
|
||||
// 锁id 40
|
||||
int lockIDLength = utf8.encode(lockID!).length;
|
||||
print("addUserLockIDLength:$lockIDLength utf8.encode(lockID!)${utf8.encode(lockID!)}");
|
||||
data.addAll(utf8.encode(lockID!));
|
||||
data = getFixedLengthList(data, 40 - lockIDLength);
|
||||
|
||||
//authUserID 20
|
||||
int authUserIDLength = utf8.encode(authUserID!).length;
|
||||
print("authUserIDLength:$authUserIDLength utf8.encode(authUserID!)${utf8.encode(authUserID!)}");
|
||||
data.addAll(utf8.encode(authUserID!));
|
||||
data = getFixedLengthList(data, 20 - authUserIDLength);
|
||||
|
||||
//KeyID 40
|
||||
int keyIDLength = utf8.encode(keyID!).length;
|
||||
print("keyIDLength:$keyIDLength utf8.encode(keyID!)${utf8.encode(keyID!)}");
|
||||
data.addAll(utf8.encode(keyID!));
|
||||
data = getFixedLengthList(data, 40 - keyIDLength);
|
||||
|
||||
//userID 要接受钥匙的用户的useid 20
|
||||
int userIDLength = utf8.encode(authUserID!).length;
|
||||
data.addAll(utf8.encode(authUserID!));
|
||||
data = getFixedLengthList(data, 20 - authUserIDLength);
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
print("userIDLength:$userIDLength utf8.encode(userID!)${utf8.encode(userID!)}");
|
||||
data.addAll(utf8.encode(userID!));
|
||||
data = getFixedLengthList(data, 20 - userIDLength);
|
||||
|
||||
// openModel
|
||||
data.add(openMode!);
|
||||
@ -112,30 +114,30 @@ class AddUserCommand extends SenderProtocol {
|
||||
data.addAll(utf8.encode(password!));
|
||||
data = getFixedLengthList(data, 20 - passwordLength);
|
||||
|
||||
if(needAuthor == 0){
|
||||
// 当token失效或者第一次发送的时候token为0
|
||||
//Token 4
|
||||
data.addAll(token!);
|
||||
// token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 当token失效或者第一次发送的时候token为0
|
||||
data.addAll(token!);
|
||||
print("pubToken:$token");
|
||||
|
||||
if(needAuthor == 0){
|
||||
//AuthCodeLen 1
|
||||
data.add(0);
|
||||
} else {
|
||||
// token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||
data.addAll(token!);
|
||||
|
||||
List<int> authCodeData = [];
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//authUserID
|
||||
authCodeData.addAll(utf8.encode(authUserID!));
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
|
||||
data.addAll([0, 0, 0, 0]);
|
||||
print("token!.reversed.toList():${token!.reversed.toList()}");
|
||||
authCodeData.addAll(token!);
|
||||
|
||||
authCodeData.addAll(publicKey!);
|
||||
|
||||
print("addUser-authCodeData:$authCodeData");
|
||||
|
||||
// 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
|
||||
var authCode = crypto.md5.convert(authCodeData);
|
||||
|
||||
|
||||
65
star_lock/lib/blue/io_protocol/io_getLockStatu.dart
Normal file
65
star_lock/lib/blue/io_protocol/io_getLockStatu.dart
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
//TODO:获取锁状态
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_tool/io_tool.dart';
|
||||
import '../sm4Encipher/sm4.dart';
|
||||
import 'io_reply.dart';
|
||||
import 'io_sender.dart';
|
||||
import 'io_type.dart';
|
||||
|
||||
class GetLockStatuCommand extends SenderProtocol {
|
||||
|
||||
String? lockID;
|
||||
String? userID;
|
||||
List<int>? privateKey;
|
||||
GetLockStatuCommand({
|
||||
this.lockID,
|
||||
this.userID,
|
||||
this.privateKey
|
||||
}) : super(CommandType.readLockStatusInfo);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
List<int> ebcData = [];
|
||||
|
||||
// 指令类型
|
||||
int type = commandType!.typeValue;
|
||||
double typeDouble = type / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
// 锁id 40
|
||||
int lockIDLength = utf8.encode(lockID!).length;
|
||||
print("addUserLockIDLength:$lockIDLength utf8.encode(lockID!)${utf8.encode(lockID!)}");
|
||||
data.addAll(utf8.encode(lockID!));
|
||||
data = getFixedLengthList(data, 40 - lockIDLength);
|
||||
|
||||
//userID 要接受钥匙的用户的useid 20
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
print("userIDLength:$userIDLength utf8.encode(userID!)${utf8.encode(userID!)}");
|
||||
data.addAll(utf8.encode(userID!));
|
||||
data = getFixedLengthList(data, 20 - userIDLength);
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
int add = (16 - data.length % 16);
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
print("addUserSM4Data:$data");
|
||||
// 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class GetLockStatuReply extends Reply {
|
||||
GetLockStatuReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
@ -77,12 +77,12 @@ class GetPrivateKeyCommand extends SenderProtocol {
|
||||
} else {
|
||||
List<int> authCodeData = [];
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//authUserID
|
||||
authCodeData.addAll(utf8.encode(authUserID!));
|
||||
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//NowTime 4
|
||||
// DateTime now = DateTime.now();
|
||||
// int timestamp = now.millisecondsSinceEpoch;
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import '../io_tool/io_tool.dart';
|
||||
import 'io_reply.dart';
|
||||
import 'io_sender.dart';
|
||||
import 'io_type.dart';
|
||||
|
||||
//TODO:开门
|
||||
class OpenDoorCommand extends SenderProtocol {
|
||||
|
||||
int? cmdID;
|
||||
String? keyID;
|
||||
String? userID;
|
||||
int? openMode;
|
||||
int? openTime;
|
||||
int? token;
|
||||
int? authCodeLen;
|
||||
String? authCode;
|
||||
OpenDoorCommand({
|
||||
this.cmdID,
|
||||
this.keyID,
|
||||
this.userID,
|
||||
this.openMode,
|
||||
this.openTime,
|
||||
this.token,
|
||||
this.authCodeLen,
|
||||
this.authCode,
|
||||
}) : super(CommandType.openDoor);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
data.addAll(intToInt8List(cmdID!));
|
||||
data.addAll(utf8.encode(keyID!));
|
||||
data.addAll(utf8.encode(userID!));
|
||||
data.addAll(intToInt8List(openMode!));
|
||||
data.addAll(intToInt8List(openTime!));
|
||||
data.addAll(intToInt8List(token!));
|
||||
data.addAll(intToInt8List(authCodeLen!));
|
||||
data.addAll(utf8.encode(authCode!));
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class OpenDoorReply extends Reply {
|
||||
OpenDoorReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
int index = 0;
|
||||
|
||||
}
|
||||
}
|
||||
110
star_lock/lib/blue/io_protocol/io_openLock.dart
Normal file
110
star_lock/lib/blue/io_protocol/io_openLock.dart
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
import 'dart:convert';
|
||||
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 OpenLockCommand extends SenderProtocol {
|
||||
String? keyID;
|
||||
String? userID;
|
||||
int? openMode;
|
||||
int? openTime;
|
||||
List<int>? token;
|
||||
int? needAuthor;
|
||||
List<int>? signKey;
|
||||
List<int>? privateKey;
|
||||
OpenLockCommand({
|
||||
this.keyID,
|
||||
this.userID,
|
||||
this.openMode,
|
||||
this.openTime,
|
||||
this.token,
|
||||
this.needAuthor,
|
||||
this.signKey,
|
||||
this.privateKey
|
||||
}) : super(CommandType.openLock);
|
||||
|
||||
@override
|
||||
List<int> messageDetail() {
|
||||
List<int> data = [];
|
||||
List<int> ebcData = [];
|
||||
|
||||
// 指令类型
|
||||
int type = commandType!.typeValue;
|
||||
double typeDouble = type / 256;
|
||||
int type1 = typeDouble.toInt();
|
||||
int type2 = type % 256;
|
||||
data.add(type1);
|
||||
data.add(type2);
|
||||
|
||||
//KeyID 40
|
||||
int keyIDLength = utf8.encode(keyID!).length;
|
||||
data.addAll(utf8.encode(keyID!));
|
||||
data = getFixedLengthList(data, 40 - keyIDLength);
|
||||
|
||||
//userID 要接受钥匙的用户的useid 20
|
||||
int userIDLength = utf8.encode(userID!).length;
|
||||
print("openDoorUserId:${utf8.encode(userID!)} utf8.encode(userID!).length:${utf8.encode(userID!).length}");
|
||||
data.addAll(utf8.encode(userID!));
|
||||
data = getFixedLengthList(data, 20 - userIDLength);
|
||||
|
||||
// openModel
|
||||
data.add(openMode!);
|
||||
|
||||
// OpenTime 4
|
||||
int? d1 = openTime;
|
||||
data.add((d1! & 0xff000000) >> 24);
|
||||
data.add((d1 & 0xff0000) >> 16);
|
||||
data.add((d1 & 0xff00) >> 8);
|
||||
data.add((d1 & 0xff));
|
||||
|
||||
// token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 当token失效或者第一次发送的时候token为0
|
||||
data.addAll(token!);
|
||||
print("pubToken:$token");
|
||||
|
||||
if(needAuthor == 0){
|
||||
//AuthCodeLen 1
|
||||
data.add(0);
|
||||
} else {
|
||||
List<int> authCodeData = [];
|
||||
//KeyID
|
||||
authCodeData.addAll(utf8.encode(keyID!));
|
||||
|
||||
//UserID
|
||||
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);
|
||||
|
||||
data.add(authCode.bytes.length);
|
||||
data.addAll(authCode.bytes);
|
||||
}
|
||||
|
||||
if ((data.length % 16) != 0) {
|
||||
int add = (16 - data.length % 16);
|
||||
for (int i = 0; i < add; i++) {
|
||||
data.add(0);
|
||||
}
|
||||
}
|
||||
print("addUserSM4Data:$data");
|
||||
// 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
|
||||
ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
|
||||
return ebcData;
|
||||
}
|
||||
}
|
||||
|
||||
class OpenDoorReply extends Reply {
|
||||
OpenDoorReply.parseData(CommandType commandType, List<int> dataDetail)
|
||||
: super.parseData(commandType, dataDetail) {
|
||||
data = dataDetail;
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,7 @@ enum CommandType {
|
||||
deletUser , //删除用户 = 0x3002
|
||||
modifyingUser , //修改用户 = 0x3003
|
||||
factoryDataReset , //恢复出厂设置 = 0x3004
|
||||
openDoor , //开门 = 0x3005
|
||||
openLock , //开门 = 0x3005
|
||||
readLockStatusInfo, //读取锁状态信息 = 0x300A
|
||||
transferPermissions, //转移权限 = 0x300B
|
||||
reportDoorOpenRecord, //开门记录上报 = 0x3020
|
||||
@ -47,7 +47,7 @@ extension ExtensionCommandType on CommandType {
|
||||
break;
|
||||
case 0x3005:
|
||||
{
|
||||
type = CommandType.openDoor;
|
||||
type = CommandType.openLock;
|
||||
}
|
||||
break;
|
||||
case 0x300A:
|
||||
@ -124,7 +124,7 @@ extension ExtensionCommandType on CommandType {
|
||||
case CommandType.factoryDataReset:
|
||||
type = 0x3004;
|
||||
break;
|
||||
case CommandType.openDoor:
|
||||
case CommandType.openLock:
|
||||
type = 0x3005;
|
||||
break;
|
||||
case CommandType.readLockStatusInfo:
|
||||
|
||||
@ -6,7 +6,7 @@ enum DataTransmissionMode {
|
||||
const saveBluePublicKey = "BluePublicKey";
|
||||
const saveBluePrivateKey = "BluePrivateKey";
|
||||
const saveBlueSignKey = "BlueSignKey";
|
||||
const saveBlueToken = "BlueToken";
|
||||
const saveBlueToken = "BlueGetToken";
|
||||
|
||||
class IoManager {
|
||||
|
||||
|
||||
@ -2,11 +2,13 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
||||
|
||||
import '../tools/storage.dart';
|
||||
import 'io_protocol/io_addUser.dart';
|
||||
import 'io_protocol/io_getPrivateKey.dart';
|
||||
import 'io_protocol/io_getPublicKey.dart';
|
||||
import 'io_protocol/io_openDoor.dart';
|
||||
import 'io_protocol/io_openLock.dart';
|
||||
import 'io_protocol/io_reply.dart';
|
||||
import 'io_protocol/io_type.dart';
|
||||
import 'io_tool/io_manager.dart';
|
||||
@ -64,6 +66,7 @@ class CommandReciverManager {
|
||||
|
||||
var res = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(res!);
|
||||
print("getPrivateKeyList$getPrivateKeyList");
|
||||
|
||||
// 解密
|
||||
// String key = SM4.createHexKey(key: radixHex16String(getPrivateKeyList!));
|
||||
@ -104,11 +107,16 @@ class CommandReciverManager {
|
||||
reply = AddUserReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case CommandType.openDoor:
|
||||
case CommandType.openLock:
|
||||
{
|
||||
reply = OpenDoorReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
case CommandType.readLockStatusInfo:
|
||||
{
|
||||
reply = GetLockStatuReply.parseData(commandType, data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
@ -29,16 +29,16 @@ class CommandSenderManager {
|
||||
CommandSendCallBack? callBack}) async {
|
||||
if (callBack != null) {
|
||||
// if (!BluetoothManager().connected) {
|
||||
print('❌ 蓝牙断开了');
|
||||
if (callBack != null) {
|
||||
print('managerSendData ❌ callBack');
|
||||
// EasyLoading.dismiss();
|
||||
callBack(ErrorType.notConnected);
|
||||
}
|
||||
return;
|
||||
print('❌ 蓝牙断开了');
|
||||
if (callBack != null) {
|
||||
print('managerSendData ❌ callBack');
|
||||
// EasyLoading.dismiss();
|
||||
callBack(ErrorType.notConnected);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<int> value = await command.packageData();
|
||||
List<int> value = command.packageData();
|
||||
// print("sendData:${value}");
|
||||
_sendNormalData(value);
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
|
||||
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
||||
|
||||
import 'io_protocol/io_addUser.dart';
|
||||
import 'io_protocol/io_getPrivateKey.dart';
|
||||
import 'io_protocol/io_getPublicKey.dart';
|
||||
import 'io_protocol/io_openDoor.dart';
|
||||
import 'io_protocol/io_openLock.dart';
|
||||
import 'sender_data.dart';
|
||||
|
||||
class IoSenderManage {
|
||||
@ -70,17 +72,40 @@ class IoSenderManage {
|
||||
}
|
||||
|
||||
//todo:开锁
|
||||
// static void senderOpenDoor({CommandSendCallBack? callBack}) {
|
||||
// CommandSenderManager().managerSendData(
|
||||
// command: OpenDoorCommand(
|
||||
// cmdID: 0,
|
||||
// keyID: "",
|
||||
// userID: "",
|
||||
// openMode: 0,
|
||||
// openTime: 0,
|
||||
// token: 0,
|
||||
// authCodeLen: 0,
|
||||
// authCode: "",
|
||||
// ), callBack:callBack);
|
||||
// }
|
||||
static void senderOpenLock({
|
||||
String? keyID,
|
||||
String? userID,
|
||||
int? openMode,
|
||||
int? openTime,
|
||||
List<int>? token,
|
||||
int? needAuthor,
|
||||
List<int>? signKey,
|
||||
List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: OpenLockCommand(
|
||||
keyID: keyID,
|
||||
userID: userID,
|
||||
openMode: openMode,
|
||||
openTime: openTime,
|
||||
token: token,
|
||||
needAuthor: needAuthor,
|
||||
signKey: signKey,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
|
||||
//todo:获取锁状态
|
||||
static void senderGetLockStatu({
|
||||
String? lockID,
|
||||
String? userID,
|
||||
List<int>? privateKey,
|
||||
CommandSendCallBack? callBack}) {
|
||||
CommandSenderManager().managerSendData(
|
||||
command: GetLockStatuCommand(
|
||||
lockID: lockID,
|
||||
userID: userID,
|
||||
privateKey: privateKey,
|
||||
), callBack:callBack);
|
||||
}
|
||||
}
|
||||
232
star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart
Normal file
232
star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart
Normal file
@ -0,0 +1,232 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
|
||||
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
|
||||
|
||||
import '../../../blue/blue_manage.dart';
|
||||
import '../../../blue/io_protocol/io_openLock.dart';
|
||||
import '../../../blue/io_protocol/io_reply.dart';
|
||||
import '../../../blue/io_tool/io_manager.dart';
|
||||
import '../../../blue/io_tool/io_model.dart';
|
||||
import '../../../blue/io_tool/io_tool.dart';
|
||||
import '../../../blue/io_tool/manager_event_bus.dart';
|
||||
import '../../../blue/sender_manage.dart';
|
||||
import '../../../tools/baseGetXController.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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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("开锁数据解析成功");
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("开锁需要鉴权");
|
||||
IoSenderManage.senderOpenLock(
|
||||
keyID: "1",
|
||||
userID: "100001",
|
||||
openMode: 1,
|
||||
openTime: 0x11223344,
|
||||
token: tokenData,
|
||||
needAuthor: 1,
|
||||
signKey: signKeyDataList,
|
||||
privateKey: getPrivateKeyList,
|
||||
);
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("开锁用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("开锁权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("开锁协议领锁失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _replyGetLockStatus(Reply reply) async {
|
||||
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");
|
||||
|
||||
int status = reply.data[2];
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("获取锁状态数据解析成功");
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
print("获取锁状态需要鉴权");
|
||||
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
print("获取锁状态用户无权限");
|
||||
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("获取锁状态权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
print("获取锁状态领锁失败");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> openDoorAction() async {
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
IoSenderManage.senderGetLockStatu(
|
||||
lockID:IoManager().getCurrentDeviceLockId,
|
||||
userID:"100001",
|
||||
privateKey:getPrivateKeyList,
|
||||
);
|
||||
|
||||
// var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
// List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
//
|
||||
// var signKey = await Storage.getStringList(saveBlueSignKey);
|
||||
// List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
||||
//
|
||||
// var token = await Storage.getStringList(saveBlueToken);
|
||||
// List<int> getTokenList = changeStringListToIntList(token!);
|
||||
// print("openDoorTokenPubToken:$getTokenList");
|
||||
//
|
||||
// IoSenderManage.senderOpenLock(
|
||||
// keyID: "1",
|
||||
// userID: "100001",
|
||||
// openMode: 1,
|
||||
// openTime: 0x11223344,
|
||||
// token: getTokenList,
|
||||
// needAuthor: 1,
|
||||
// signKey: signKeyDataList,
|
||||
// privateKey: getPrivateKeyList,
|
||||
// );
|
||||
}
|
||||
|
||||
Future<void> connectBlue() async {
|
||||
await BlueManage().connect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d");
|
||||
// var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
// List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
// IoSenderManage.senderGetLockStatu(
|
||||
// lockID:IoManager().getCurrentDeviceLockId,
|
||||
// userID:"100001",
|
||||
// privateKey:getPrivateKeyList,
|
||||
// );
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
print("onReady()");
|
||||
// _initSendStreamSubscription();
|
||||
_initReplySubscription();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
// TODO: implement onInit
|
||||
super.onInit();
|
||||
print("onInit()");
|
||||
|
||||
// 进来第一步开始扫描
|
||||
connectBlue();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
// _sendStreamSubscription.cancel();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import '../../../appRouters.dart';
|
||||
import '../../../app_settings/app_colors.dart';
|
||||
import '../../../tools/titleAppBar.dart';
|
||||
import '../../../translations/trans_lib.dart';
|
||||
import 'lockDetail_logic.dart';
|
||||
|
||||
class LockDetailPage extends StatefulWidget {
|
||||
const LockDetailPage({Key? key}) : super(key: key);
|
||||
@ -15,6 +16,9 @@ class LockDetailPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _LockDetailPageState extends State<LockDetailPage> {
|
||||
final logic = Get.put(LockDetailLogic());
|
||||
final state = Get.find<LockDetailLogic>().state;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@ -70,8 +74,13 @@ class _LockDetailPageState extends State<LockDetailPage> {
|
||||
child: Stack(
|
||||
children: [
|
||||
Center(
|
||||
child: Image.asset('images/main/icon_main_openLockBtn.png',
|
||||
width: 268.w, height: 268.w)),
|
||||
child: GestureDetector(
|
||||
onTap: (){
|
||||
logic.openDoorAction();
|
||||
},
|
||||
child: Image.asset('images/main/icon_main_openLockBtn.png',
|
||||
width: 268.w, height: 268.w),
|
||||
)),
|
||||
Align(
|
||||
alignment: const Alignment(0.6, 1),
|
||||
child: Image.asset(
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
class LockDetailState {
|
||||
|
||||
}
|
||||
@ -27,7 +27,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
BlueManage().connect(lockId, deviceName);
|
||||
}
|
||||
|
||||
// 监听蓝牙连接的状态
|
||||
// 监听获取的特征值
|
||||
late StreamSubscription _streamSubscription;
|
||||
void _startListenIO(){
|
||||
_streamSubscription = EventBusManager().eventBus!.on<QualifiedCharacteristic>().listen((event) async {
|
||||
@ -42,20 +42,20 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
// }
|
||||
|
||||
// 组装好数据后监听要发送消息的事件
|
||||
late StreamSubscription<EventSendModel> _sendStreamSubscription;
|
||||
void _initSendStreamSubscription() {
|
||||
_sendStreamSubscription = EventBusManager().eventBus!.on<EventSendModel>().listen((
|
||||
EventSendModel model) {
|
||||
if (model.sendChannel == DataChannel.ble) {
|
||||
// print("fsdfgsdfgsdfgsdfgsdfgsdfg:${BlueManage().qualifiedCharacteristic}");
|
||||
BlueManage().writeCharacteristicWithResponse(QualifiedCharacteristic(
|
||||
deviceId:BlueManage().qualifiedCharacteristic!.deviceId,
|
||||
characteristicId: BlueManage().qualifiedCharacteristic!.characteristicId,
|
||||
serviceId: BlueManage().serviceId),
|
||||
model.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
// late StreamSubscription<EventSendModel> _sendStreamSubscription;
|
||||
// void _initSendStreamSubscription() {
|
||||
// _sendStreamSubscription = EventBusManager().eventBus!.on<EventSendModel>().listen((
|
||||
// EventSendModel model) {
|
||||
// if (model.sendChannel == DataChannel.ble) {
|
||||
// // print("fsdfgsdfgsdfgsdfgsdfgsdfg:${BlueManage().qualifiedCharacteristic}");
|
||||
// BlueManage().writeCharacteristicWithResponse(QualifiedCharacteristic(
|
||||
// deviceId:BlueManage().qualifiedCharacteristic!.deviceId,
|
||||
// characteristicId: BlueManage().qualifiedCharacteristic!.characteristicId,
|
||||
// serviceId: BlueManage().serviceId),
|
||||
// model.data);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
late StreamSubscription<Reply> _replySubscription;
|
||||
void _initReplySubscription() {
|
||||
@ -79,34 +79,36 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
switch(reply.status){
|
||||
case 0x00:
|
||||
//成功
|
||||
print("获取公钥成功");
|
||||
// 储存公钥
|
||||
var tokenData = reply.data.sublist(3);
|
||||
var saveStrList = changeIntListToStringList(tokenData);
|
||||
Storage.setStringList(saveBluePublicKey, saveStrList);
|
||||
IoSenderManage.getPrivateKey(
|
||||
lockId:IoManager().getCurrentDeviceLockId,
|
||||
keyID:"1",
|
||||
authUserID:"1",
|
||||
nowTime:1,
|
||||
publicKeyData:tokenData,
|
||||
needAuthor:1);
|
||||
var tokenData = reply.data.sublist(3);
|
||||
var saveStrList = changeIntListToStringList(tokenData);
|
||||
Storage.setStringList(saveBluePublicKey, saveStrList);
|
||||
|
||||
IoSenderManage.getPrivateKey(
|
||||
lockId:IoManager().getCurrentDeviceLockId,
|
||||
keyID:"1",
|
||||
authUserID:"1",
|
||||
nowTime:1,
|
||||
publicKeyData:tokenData,
|
||||
needAuthor:1);
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
|
||||
print("获取公钥无权限");
|
||||
break;
|
||||
case 0x0f:
|
||||
//用户已存在
|
||||
|
||||
//用户已存在
|
||||
print("获取公钥用户已存在");
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
|
||||
print("获取公钥失败");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _replyGetPrivateKeyKey(Reply reply){
|
||||
Future<void> _replyGetPrivateKeyKey(Reply reply) async {
|
||||
switch(reply.status){
|
||||
case 0x00:
|
||||
//成功
|
||||
@ -123,6 +125,12 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
var savesignKeyList = changeIntListToStringList(signKey);
|
||||
Storage.setStringList(saveBlueSignKey, savesignKeyList);
|
||||
|
||||
var token = await Storage.getStringList(saveBlueToken);
|
||||
List<int> getTokenList = [0,0,0,0];
|
||||
if(token != null){
|
||||
getTokenList = changeStringListToIntList(token);
|
||||
}
|
||||
|
||||
print("privateKey:$privateKey signKey:$signKey");
|
||||
IoSenderManage.senderAddUser(
|
||||
lockID:IoManager().getCurrentDeviceLockId,
|
||||
@ -138,7 +146,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
needAuthor:1,
|
||||
publicKey:publicKeyDataList,
|
||||
privateKey:privateKey,
|
||||
token: [0,0,0,0]
|
||||
token: getTokenList
|
||||
);
|
||||
break;
|
||||
case 0x07:
|
||||
@ -147,37 +155,59 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
|
||||
break;
|
||||
case 0x0f:
|
||||
//用户已存在
|
||||
//用户已存在
|
||||
print('获取私钥:用户已存在');
|
||||
|
||||
break;
|
||||
default:
|
||||
//失败
|
||||
//失败
|
||||
print('获取私钥失败');
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _replyAddUserKey(Reply reply){
|
||||
Future<void> _replyAddUserKey(Reply reply) async {
|
||||
var lockId = reply.data.sublist(2, 42);
|
||||
print("lockId:$lockId");
|
||||
|
||||
var token = reply.data.sublist(42, 46);
|
||||
List<String> strTokenList = changeIntListToStringList(token);
|
||||
Storage.setStringList(saveBlueToken, strTokenList);
|
||||
print("token:$token");
|
||||
|
||||
int status = reply.data[46];
|
||||
print("status:$status");
|
||||
|
||||
switch(status){
|
||||
case 0x00:
|
||||
//成功
|
||||
//成功
|
||||
print("添加用户数据解析成功");
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//无权限
|
||||
//无权限
|
||||
print("需要鉴权");
|
||||
var privateKey = await Storage.getStringList(saveBluePrivateKey);
|
||||
List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
||||
|
||||
var publicKey = await Storage.getStringList(saveBluePublicKey);
|
||||
List<int> publicKeyDataList = changeStringListToIntList(publicKey!);
|
||||
|
||||
IoSenderManage.senderAddUser(
|
||||
lockID:IoManager().getCurrentDeviceLockId,
|
||||
authUserID:"100001",
|
||||
keyID:"1",
|
||||
userID:"100001",
|
||||
openMode:1,
|
||||
keyType:1,
|
||||
startDate:0x11223344,
|
||||
expireDate:0x11223344,
|
||||
role:255,
|
||||
password:"123456",
|
||||
needAuthor:1,
|
||||
publicKey:publicKeyDataList,
|
||||
privateKey:getPrivateKeyList,
|
||||
token: token
|
||||
);
|
||||
break;
|
||||
case 0x07:
|
||||
//无权限
|
||||
@ -186,7 +216,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
break;
|
||||
case 0x09:
|
||||
// 权限校验错误
|
||||
print("权限校验错误");
|
||||
print("添加用户权限校验错误");
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -204,7 +234,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
print("onReady()");
|
||||
|
||||
_startListenIO();
|
||||
_initSendStreamSubscription();
|
||||
// _initSendStreamSubscription();
|
||||
_initReplySubscription();
|
||||
}
|
||||
|
||||
@ -226,7 +256,7 @@ class NearbyLockLogic extends BaseGetXController{
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
_streamSubscription.cancel();
|
||||
_sendStreamSubscription.cancel();
|
||||
// _sendStreamSubscription.cancel();
|
||||
_replySubscription.cancel();
|
||||
}
|
||||
|
||||
|
||||
@ -61,6 +61,7 @@ class _NearbyLockPageState extends State<NearbyLockPage> {
|
||||
// Navigator.pushNamed(context, Routers.lockAddressPage);
|
||||
// logic.getPublicKey(state.devices[index].serviceUuids[0].toString());
|
||||
state.seletLockName.value = state.devices[index].name;
|
||||
print("connect-lockId:${state.devices[index].id} deviceName:${state.devices[index].name}");
|
||||
logic.connect(state.devices[index].id, state.devices[index].name);
|
||||
});
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user