# Conflicts:
#	star_lock/lib/network/request_interceptor.dart
This commit is contained in:
Daisy 2023-08-16 17:51:39 +08:00
commit 3c37828adb
19 changed files with 586 additions and 259 deletions

View File

@ -4,6 +4,7 @@ import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:star_lock/blue/sender_manage.dart'; import 'package:star_lock/blue/sender_manage.dart';
import '../app_settings/app_settings.dart'; import '../app_settings/app_settings.dart';
import 'io_tool/io_manager.dart';
import 'io_tool/io_tool.dart'; import 'io_tool/io_tool.dart';
import 'io_tool/manager_event_bus.dart'; import 'io_tool/manager_event_bus.dart';
import 'reciver_data.dart'; import 'reciver_data.dart';
@ -52,7 +53,6 @@ class BlueManage{
} else { } else {
_scanDevices.add(device); _scanDevices.add(device);
} }
// EventBusManager().eventBusFir(_scanDevices);
scanResultCallBack(_scanDevices); scanResultCallBack(_scanDevices);
} }
// _pushState(); // _pushState();
@ -62,13 +62,15 @@ class BlueManage{
} }
/// ///
Future<void> connect(String deviceMAC) async { Future<void> connect(String deviceMAC, String deviceName) async {
print("connect:$deviceMAC"); print("connect:$deviceMAC");
_flutterReactiveBle!.connectToDevice(id: deviceMAC).listen((connectionStateUpdate) { _flutterReactiveBle!.connectToDevice(id: deviceMAC).listen((connectionStateUpdate) {
print('ConnectionState for device $deviceMAC : ${connectionStateUpdate.connectionState}'); print('ConnectionState for device $deviceMAC : ${connectionStateUpdate.connectionState}');
// EventBusManager().eventBusFir(connectionStateUpdate); // EventBusManager().eventBusFir(connectionStateUpdate);
if(connectionStateUpdate.connectionState == DeviceConnectionState.connected){ if(connectionStateUpdate.connectionState == DeviceConnectionState.connected){
// getPublicKey(update.deviceId); // getPublicKey(update.deviceId);
// lockId
IoManager().configCurrentDeviceLockId(deviceName);
// //
discoverServices(deviceMAC); discoverServices(deviceMAC);
} }
@ -137,7 +139,7 @@ class BlueManage{
_flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) { _flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) {
// code to handle incoming data // code to handle incoming data
print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data"); print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data");
CommandReciverManager.appDataReceive(data, ""); CommandReciverManager.appDataReceive(data);
}, onError: (dynamic error) { }, onError: (dynamic error) {
print("subscribeToCharacteristic error:$error"); print("subscribeToCharacteristic error:$error");
}); });
@ -145,7 +147,7 @@ class BlueManage{
// //
Future<void> writeCharacteristicWithResponse(QualifiedCharacteristic characteristic, List<int> value) async { Future<void> writeCharacteristicWithResponse(QualifiedCharacteristic characteristic, List<int> value) async {
print('Write with characteristicId${characteristic.characteristicId} serviceId${characteristic.serviceId} deviceId${characteristic.deviceId} value : $value \nhexStr:${radixString(value)}'); print('Write with characteristicId${characteristic.characteristicId} serviceId${characteristic.serviceId} deviceId${characteristic.deviceId} value : $value \nhexStr:${radixHex16String(value)}');
try { try {
List<int> valueList = value; List<int> valueList = value;

View File

@ -1,13 +1,18 @@
import 'dart:convert';
import '../../tools/storage.dart';
import '../io_tool/io_manager.dart';
import '../io_tool/io_tool.dart'; import '../io_tool/io_tool.dart';
import '../sm4Encipher/sm4.dart';
import 'io_reply.dart'; import 'io_reply.dart';
import 'io_sender.dart'; import 'io_sender.dart';
import 'io_type.dart'; import 'io_type.dart';
import 'package:crypto/crypto.dart' as crypto;
//TODO: //TODO:
class AddUserCommand extends SenderProtocol { class AddUserCommand extends SenderProtocol {
int? cmdID;
String? lockID; String? lockID;
String? authUserID; String? authUserID;
String? keyID; String? keyID;
@ -18,11 +23,11 @@ class AddUserCommand extends SenderProtocol {
int? expireDate; int? expireDate;
int? role; int? role;
String? password; String? password;
int? token; int? needAuthor;
int? authCodeLen; List<int>? publicKey;
String? authCode; List<int>? privateKey;
List<int>? token;
AddUserCommand({ AddUserCommand({
this.cmdID,
this.lockID, this.lockID,
this.authUserID, this.authUserID,
this.keyID, this.keyID,
@ -33,28 +38,127 @@ class AddUserCommand extends SenderProtocol {
this.expireDate, this.expireDate,
this.role, this.role,
this.password, this.password,
this.token, this.needAuthor,
this.authCodeLen, this.publicKey,
this.authCode, this.privateKey,
this.token
}) : super(CommandType.addUser); }) : super(CommandType.addUser);
@override @override
List<int> messageDetail() { List<int> messageDetail() {
List<int> data = []; List<int> data = [];
// data.add(0x21); List<int> ebcData = [];
// int d = direction!.toInt();
// data.addAll(intToByte2ListHigh(d)); //
// data.add(0x22); int type = commandType!.typeValue;
// int s = speed!.toInt(); double typeDouble = type / 256;
// data.add(s); int type1 = typeDouble.toInt();
return data; int type2 = type % 256;
data.add(type1);
data.add(type2);
// id 40
int lockIDLength = utf8.encode(lockID!).length;
data.addAll(utf8.encode(lockID!));
data = getFixedLengthList(data, 40 - lockIDLength);
//authUserID 20
int authUserIDLength = utf8.encode(authUserID!).length;
data.addAll(utf8.encode(authUserID!));
data = getFixedLengthList(data, 20 - authUserIDLength);
//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(authUserID!).length;
data.addAll(utf8.encode(authUserID!));
data = getFixedLengthList(data, 20 - authUserIDLength);
// openModel
data.add(openMode!);
// keyType
data.add(keyType!);
int? d1, d2;
if(role == 255){
d1 = 0;//Date.parse(new Date()) / 1000;
d2 = 0xffffffff;//d1 + 86440;
}else{
d1 = startDate;
d2 = expireDate;
}
// StartDate 4
data.add((d1! & 0xff000000) >> 24);
data.add((d1 & 0xff0000) >> 16);
data.add((d1 & 0xff00) >> 8);
data.add((d1 & 0xff));
// expireDate 4
data.add((d2! & 0xff000000) >> 24);
data.add((d2 & 0xff0000) >> 16);
data.add((d2 & 0xff00) >> 8);
data.add((d2 & 0xff));
// role 1 010xff
data.add(role!);
//password 20
int passwordLength = utf8.encode(password!).length;
data.addAll(utf8.encode(password!));
data = getFixedLengthList(data, 20 - passwordLength);
if(needAuthor == 0){
// token失效或者第一次发送的时候token为0
//Token 4
data.addAll(token!);
//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!));
//token 4 Token 0
data.addAll([0, 0, 0, 0]);
authCodeData.addAll(publicKey!);
// KeyIDauthUserIDmd5加密之后就是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 AddUserReply extends Reply { class AddUserReply extends Reply {
AddUserReply.parseData(CommandType commandType, List<int> dataDetail) AddUserReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) { : super.parseData(commandType, dataDetail) {
int index = 0; data = dataDetail;
} }
} }

View File

@ -3,13 +3,16 @@ import 'dart:convert';
import 'package:star_lock/blue/sm4Encipher/sm4.dart'; import 'package:star_lock/blue/sm4Encipher/sm4.dart';
import '../../tools/storage.dart'; import '../../tools/storage.dart';
import '../io_tool/io_manager.dart';
import '../io_tool/io_tool.dart'; import '../io_tool/io_tool.dart';
import '../sender_manage.dart';
import 'io_reply.dart'; import 'io_reply.dart';
import 'io_sender.dart'; import 'io_sender.dart';
import 'io_type.dart'; import 'io_type.dart';
import 'package:crypto/crypto.dart' as a; import 'package:crypto/crypto.dart' as crypto;
import 'package:convert/convert.dart';
List<int>publicKeyDataList = [];
class GetPrivateKeyCommand extends SenderProtocol { class GetPrivateKeyCommand extends SenderProtocol {
String? lockID; String? lockID;
@ -29,6 +32,7 @@ class GetPrivateKeyCommand extends SenderProtocol {
@override @override
List<int> messageDetail() { List<int> messageDetail() {
publicKeyDataList = publicKeyData!;
List<int> data = []; List<int> data = [];
List<int> ebcData = []; List<int> ebcData = [];
// print("lockID${lockID!} lockID.utf8.encode${utf8.encode(lockID!)}"); // print("lockID${lockID!} lockID.utf8.encode${utf8.encode(lockID!)}");
@ -88,19 +92,10 @@ class GetPrivateKeyCommand extends SenderProtocol {
authCodeData.add((d1 & 0xff00) >> 8); authCodeData.add((d1 & 0xff00) >> 8);
authCodeData.add((d1 & 0xff)); authCodeData.add((d1 & 0xff));
// String pubKey = "";
// Storage.getData("bluePublicKey").then((res) => {
// pubKey = res
// });
// var pubKey = "ovOvAHuL5+dBCw7L3Qt7IQ==";
// print("pubKey:$pubKey");
// List<int> pubKeyData = base64.decode(pubKey.toString());
// print("pubKeyData:$pubKeyData");
authCodeData.addAll(publicKeyData!); authCodeData.addAll(publicKeyData!);
// KeyIDauthUserIDmd5加密之后就是authCode // KeyIDauthUserIDmd5加密之后就是authCode
var authCode = a.md5.convert(authCodeData); var authCode = crypto.md5.convert(authCodeData);
// print("authCodeData:$authCodeData \nauthCode:$authCode \nauthCodeBytes:${authCode.bytes}");
data.add(authCode.bytes.length); data.add(authCode.bytes.length);
data.addAll(authCode.bytes); data.addAll(authCode.bytes);
@ -112,13 +107,10 @@ class GetPrivateKeyCommand extends SenderProtocol {
data.add(0); data.add(0);
} }
} }
print("SM4Data:$data"); // print("SM4Data:$data");
// LockId进行SM4 ECB加密 key:544d485f633335373034383064613864 // LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
String key = SM4.createHexKey(key: 'TMH_c3570480da8d'); ebcData = SM4.encrypt(data, key: utf8.encode(IoManager().getCurrentDeviceLockId), mode: SM4CryptoMode.ECB);
ebcData = SM4.encrypt(data, key: key, mode: SM4CryptoMode.ECB);
ebcData.removeRange(ebcData.length - 16, ebcData.length);
// ebcData = utf8.encode(getSM4Str(data, "TMH_c3570480da8d"));
print("ebcData:$ebcData");
return ebcData; return ebcData;
} }
} }
@ -126,24 +118,8 @@ class GetPrivateKeyCommand extends SenderProtocol {
class GetPrivateKeyReply extends Reply { class GetPrivateKeyReply extends Reply {
GetPrivateKeyReply.parseData(CommandType commandType, List<int> dataDetail) GetPrivateKeyReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) { : super.parseData(commandType, dataDetail) {
print('获取私钥'); data = dataDetail.sublist(2);
switch(dataDetail[0]){ status = data[0];
case 0x00: // print("getData:$getData");
//
break;
case 0x07:
//
break;
case 0x0f:
//
break;
default:
//
break;
}
} }
} }

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import '../../tools/storage.dart'; import '../../tools/storage.dart';
import '../io_tool/io_manager.dart';
import '../io_tool/io_tool.dart'; import '../io_tool/io_tool.dart';
import '../sender_manage.dart'; import '../sender_manage.dart';
import 'io_reply.dart'; import 'io_reply.dart';
@ -26,15 +27,15 @@ class GetPublicKeyCommand extends SenderProtocol {
int type2 = type%256; int type2 = type%256;
data.add(type1); data.add(type1);
data.add(type2); data.add(type2);
print("type:$type"); // print("type:$type");
print("type1:$type1"); // print("type1:$type1");
print("type2:$type2"); // print("type2:$type2");
print("lockID${lockID!} lockID.utf8.encode${utf8.encode(lockID!)}"); print("lockID${lockID!} lockID.utf8.encode${utf8.encode(lockID!)}");
int length = utf8.encode(lockID!).length; int length = utf8.encode(lockID!).length;
data.addAll(utf8.encode(lockID!)); data.addAll(utf8.encode(lockID!));
data = getFixedLengthList(data, 40 - length); data = getFixedLengthList(data, 40 - length);
print("dataaaaaa:$data"); // print("dataaaaaa:$data");
return data; return data;
} }
} }
@ -42,29 +43,7 @@ class GetPublicKeyCommand extends SenderProtocol {
class GetPublicKeyReply extends Reply { class GetPublicKeyReply extends Reply {
GetPublicKeyReply.parseData(CommandType commandType, List<int> dataDetail) GetPublicKeyReply.parseData(CommandType commandType, List<int> dataDetail)
: super.parseData(commandType, dataDetail) { : super.parseData(commandType, dataDetail) {
var tokenData = dataDetail.sublist(3); status = dataDetail[2];
print('获取公钥:dataDetail$dataDetail tokenData:$tokenData'); data = dataDetail;
switch(dataDetail[2]){
case 0x00:
//
String stringEncoded = base64.encode(tokenData);
print('获取公钥成功 publickey:$stringEncoded');
//
Storage.setData("bluePublicKey", stringEncoded);
IoSenderManage.getPrivateKey("TMH_c3570480da8d", "1", "1", 1, tokenData, 1);
break;
case 0x07:
//
break;
case 0x0f:
//
break;
default:
//
break;
}
} }
} }

View File

@ -1,22 +1,13 @@
import 'io_type.dart'; import 'io_type.dart';
abstract class Reply{ abstract class Reply{
//value字节长度
int? packetHeader = 4; // 4
int? packetType = 1; // 1
int? packetNumber = 1; //
int? packetIdentifier = 1; //
int? packetLength = 4; //
CommandType? commandType; CommandType? commandType;
int? packetMcrc = 2; //
//command key flag //command key flag
int commandKey = 0; int status = 0;
List<int> data = [];
Reply.parseData(this.commandType, List<int> dataDetail); Reply.parseData(this.commandType, List<int> dataDetail);
// Reply({this.result});
// bool get isSuccessfully => packetHeader == EF01EE02;
} }

View File

@ -48,17 +48,9 @@ abstract class SenderProtocol extends IOData {
// print("_commandIndex:$_commandIndex commandIndexChang1$commandIndexChang1 commandIndexChang2:$commandIndexChang2"); // print("_commandIndex:$_commandIndex commandIndexChang1$commandIndexChang1 commandIndexChang2:$commandIndexChang2");
// //
// // 4 4 1 01AES1282SM43SM4
int type = commandType!.typeValue; commandList.add(commandType!.identifierValue);
if(type == 0x3090){ print("commandType!.identifierValue:${commandType!.identifierValue}");
//
identifier = 0x20;
}else if(type == 0x3091){
//
identifier = 0x22;
}
commandList.add(identifier);
// print("identifier:$identifier");
// //
int dataLen = dataSourceLength(); int dataLen = dataSourceLength();

View File

@ -1,4 +1,6 @@
//TODO: //TODO:
import 'package:get/get.dart';
enum CommandType { enum CommandType {
addUser, // = 0x3001 addUser, // = 0x3001
deletUser , // = 0x3002 deletUser , // = 0x3002
@ -164,6 +166,22 @@ extension ExtensionCommandType on CommandType {
return type; return type;
} }
int get identifierValue {
int type = 0x23;
switch(this){
case CommandType.getLockPublicKey:
type = 0x20;
break;
case CommandType.getLockPrivateKey:
type = 0x22;
break;
default:
type = 0x23;
break;
}
return type;
}
String get typeName { String get typeName {
String t = ''; String t = '';
switch(typeValue){ switch(typeValue){

View File

@ -3,6 +3,11 @@ enum DataTransmissionMode {
ble, ble,
} }
const saveBluePublicKey = "BluePublicKey";
const saveBluePrivateKey = "BluePrivateKey";
const saveBlueSignKey = "BlueSignKey";
const saveBlueToken = "BlueToken";
class IoManager { class IoManager {
static IoManager? _ioManager; static IoManager? _ioManager;
@ -21,18 +26,20 @@ class IoManager {
/// ///
void bleTransmission() => _dataTransmissionMode = DataTransmissionMode.ble; void bleTransmission() => _dataTransmissionMode = DataTransmissionMode.ble;
int _commandIndex = 1; // ///
int _commandIndex = 1;
configCommandIdx(int idx) => _commandIndex = idx; configCommandIdx(int idx) => _commandIndex = idx;
Future<void> increaseCommandIndex() async { Future<void> increaseCommandIndex() async {
_commandIndex < 255 ? _commandIndex++ : _commandIndex = 0; _commandIndex < 255 ? _commandIndex++ : _commandIndex = 0;
} }
void resetCommandIndex() => _commandIndex = 0;
void resetCommandIndex(){
_commandIndex = 0;
}
int get commandIndex => _commandIndex; int get commandIndex => _commandIndex;
/// lockId
String _currentDeviceLockId = "";
configCurrentDeviceLockId(String lockId) => _currentDeviceLockId = lockId;
String get getCurrentDeviceLockId => _currentDeviceLockId;
void resetAllFlags() { void resetAllFlags() {
resetCommandIndex(); resetCommandIndex();
} }

View File

@ -4,28 +4,44 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:encrypt/encrypt.dart' as ddd; import 'package:encrypt/encrypt.dart' as ddd;
// import 'package:sm_crypto/sm_crypto.dart';
// String getSM4Str(List<int>data, String key) { List<String> changeIntListToStringList(List<int> list){
// String dataStr = radixString(data); List<String> strList = [];
// String iv = SM4.createHexKey(key: key); for(int i = 0; i<list.length; i++)
{
strList.add(list[i].toRadixString(16));
}
return strList;
}
// String cbcEncryptData = SM4.encrypt( List<int> changeStringListToIntList(List<String> list){
// data: dataStr, List<int> intList = [];
// key: iv, for(int i = 0; i<list.length; i++)
// mode: SM4CryptoMode.ECB, {
// iv: iv, intList.add(_hexToInt(list[i]));
// ); }
return intList;
}
// print("getDNSAPIStrData:$data \ngetDNSAPIStrkey:$key \ngetDNSAPIStrDataStr:$dataStr \niv:$iv\ncbcEncryptData:$cbcEncryptData"); int _hexToInt(String hex) {
// return cbcEncryptData; int val = 0;
int len = hex.length;
// // final iv = ddd.IV.fromLength(32); for (int i = 0; i < len; i++) {
// // final encrypter = ddd.Encrypter(ddd.AES(ddd.Key.fromUtf8(key), mode: ddd.AESMode.ecb, padding: 'PKCS7')); int hexDigit = hex.codeUnitAt(i);
// // final encrypted = encrypter.encrypt(key, iv: iv); if (hexDigit >= 48 && hexDigit <= 57) {
// // val += (hexDigit - 48) * (1 << (4 * (len - 1 - i)));
// // return encrypted; } else if (hexDigit >= 65 && hexDigit <= 70) {
// } // A..F
val += (hexDigit - 55) * (1 << (4 * (len - 1 - i)));
} else if (hexDigit >= 97 && hexDigit <= 102) {
// a..f
val += (hexDigit - 87) * (1 << (4 * (len - 1 - i)));
} else {
throw new FormatException("Invalid hexadecimal value");
}
}
return val;
}
String md5Crypto(List<int> data) { String md5Crypto(List<int> data) {
final dig = md5.convert(data); final dig = md5.convert(data);
@ -238,7 +254,7 @@ List<List<T>> splitList<T>(List<T> list, int len) {
//TODO:int-> List () WiFi用到的!!!! //TODO:int-> List () WiFi用到的!!!!
List<int> intToByte2ListLow(int value) => [value >> 8, value]; List<int> intToByte2ListLow(int value) => [value >> 8, value];
String radixString(List<int> codeUnits) { String radixHex16String(List<int> codeUnits) {
String result = ''; String result = '';
codeUnits.forEach((value) { codeUnits.forEach((value) {
result += value.toRadixString(16).padLeft(2, '0'); result += value.toRadixString(16).padLeft(2, '0');

View File

@ -1,18 +1,22 @@
import 'dart:convert';
import '../tools/storage.dart';
import 'io_protocol/io_addUser.dart'; import 'io_protocol/io_addUser.dart';
import 'io_protocol/io_getPrivateKey.dart'; import 'io_protocol/io_getPrivateKey.dart';
import 'io_protocol/io_getPublicKey.dart'; import 'io_protocol/io_getPublicKey.dart';
import 'io_protocol/io_openDoor.dart'; import 'io_protocol/io_openDoor.dart';
import 'io_protocol/io_reply.dart'; import 'io_protocol/io_reply.dart';
import 'io_protocol/io_type.dart'; import 'io_protocol/io_type.dart';
import 'io_tool/io_manager.dart';
import 'io_tool/io_tool.dart'; import 'io_tool/io_tool.dart';
import 'io_tool/manager_event_bus.dart'; import 'io_tool/manager_event_bus.dart';
import 'sm4Encipher/sm4.dart'; import 'sm4Encipher/sm4.dart';
class CommandReciverManager { class CommandReciverManager {
static void appDataReceive(List<int> data, String lockId) async { static void appDataReceive(List<int> data) async {
/// ///
if(data.isEmpty){ if(data.isEmpty){
return; return;
@ -22,7 +26,7 @@ class CommandReciverManager {
if(data_size < 13){ if(data_size < 13){
return; return;
} }
print("appDataReceiveData:$data"); // print("appDataReceiveData:$data");
if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)&&(data[4] == 0x11)){ if((data[0] == 0xEF)&&(data[1] == 0x01)&&(data[2] == 0xEE)&&(data[3] == 0x02)&&(data[4] == 0x11)){
var tmpType = (data[7] & 0x0f);// var tmpType = (data[7] & 0x0f);//
print("temType:$tmpType"); print("temType:$tmpType");
@ -36,33 +40,36 @@ class CommandReciverManager {
// for (var i = 0; i < oriLen ; i++) { // for (var i = 0; i < oriLen ; i++) {
// oriDataList.add(data[12 + i]); // oriDataList.add(data[12 + i]);
// } // }
oriDataList = data.sublist(12, 12 + oriLen); oriDataList = data.sublist(12, 12 + dataLen);
print("不加密 oriDataList:$oriDataList"); print("不加密 oriDataList:$oriDataList");
break; break;
case 1: case 1:
//AES128 //AES128
break; break;
case 2: case 2:
//SM4 // SM4
String key = SM4.createHexKey(key: 'TMH_c3570480da8d'); //
oriDataList = SM4.decrypt(data, key: key, mode: SM4CryptoMode.ECB); var getDataList = data.sublist(12, 12 + dataLen);
//
// String key = SM4.createHexKey(key: IoManager().getCurrentDeviceLockId);
oriDataList = SM4.decrypt(getDataList, key: utf8.encode(IoManager().getCurrentDeviceLockId), mode: SM4CryptoMode.ECB);
oriDataList = oriDataList.sublist(0, oriLen);
print("SM4 oriDataList:$oriDataList"); print("SM4 oriDataList:$oriDataList");
break; break;
case 3: //SM4 case 3:
// for (var i = 0; i < dataLen ; i++) { //SM4
// dataView[i] = uint8Recv[12 + i]; //
// } var getDataList = data.sublist(12, 12 + dataLen);
// console.log("dataView.length = ", dataView.length);
// console.log("currCommStru.pairCommKey = ", currCommStru.pairCommKey); var res = await Storage.getStringList(saveBluePrivateKey);
// var commKey1 = base64js.toByteArray(currCommStru.pairCommKey); List<int> getPrivateKeyList = changeStringListToIntList(res!);
// console.log("commKey1 = ", commKey1);
// var d_cbc = cbc.decrypt_ecb(dataView, commKey1, false, "nobase64"); //
// console.log("d_cbc = ", d_cbc); // String key = SM4.createHexKey(key: radixHex16String(getPrivateKeyList!));
// console.log("oriLen = ", oriLen); oriDataList = SM4.decrypt(getDataList, key: getPrivateKeyList, mode: SM4CryptoMode.ECB);
// for (var i = 0; i < oriLen ; i++) { oriDataList = oriDataList.sublist(0, oriLen);
// oriDataView[i] = d_cbc[i]; print("SM4 oriDataList:$oriDataList");
// }
// console.log("oriDataView = ", oriDataView);
break; break;
} }
@ -77,6 +84,7 @@ class CommandReciverManager {
if(data.isNotEmpty){ if(data.isNotEmpty){
var cmd = data[0] * 256 + data[1]; var cmd = data[0] * 256 + data[1];
CommandType commandType = ExtensionCommandType.getCommandType(cmd); CommandType commandType = ExtensionCommandType.getCommandType(cmd);
await IoManager().increaseCommandIndex();
// data.removeRange(0, 2); // data.removeRange(0, 2);
print("111111data cmd:$cmd commandType:$commandType data:$data"); print("111111data cmd:$cmd commandType:$commandType data:$data");
var reply; var reply;

View File

@ -24,9 +24,9 @@ class CommandSenderManager {
bool canSendControlCommand = false; bool canSendControlCommand = false;
//TODO: //TODO:
void managerSendData ({ Future<void> managerSendData ({
required SenderProtocol command, required SenderProtocol command,
CommandSendCallBack? callBack}) { CommandSendCallBack? callBack}) async {
if (callBack != null) { if (callBack != null) {
// if (!BluetoothManager().connected) { // if (!BluetoothManager().connected) {
print('❌ 蓝牙断开了'); print('❌ 蓝牙断开了');
@ -38,7 +38,7 @@ class CommandSenderManager {
return; return;
} }
List<int> value = command.packageData(); List<int> value = await command.packageData();
// print("sendData:${value}"); // print("sendData:${value}");
_sendNormalData(value); _sendNormalData(value);
} }

View File

@ -8,50 +8,66 @@ import 'sender_data.dart';
class IoSenderManage { class IoSenderManage {
//todo: //todo:
static void getPublicKey(String lockId ,{CommandSendCallBack? callBack}) { static void getPublicKey({String? lockId ,CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(command: GetPublicKeyCommand( CommandSenderManager().managerSendData(command: GetPublicKeyCommand(
lockID: lockId, lockID: lockId,
), callBack:callBack); ), callBack:callBack);
} }
//todo: //todo:
static void getPrivateKey( static void getPrivateKey({
String? lockId, String? lockId,
String? keyID, // ID String? keyID, // ID
String? authUserID,// ID String? authUserID,// ID
int? nowTime, int? nowTime,
List<int>? publicKeyData, List<int>? publicKeyData,
int? needAuthor, {CommandSendCallBack? callBack}) { int? needAuthor,
CommandSendCallBack? callBack}) {
CommandSenderManager().managerSendData(command: GetPrivateKeyCommand( CommandSenderManager().managerSendData(command: GetPrivateKeyCommand(
lockID: lockId, lockID: lockId,
keyID: keyID, keyID: keyID,
authUserID: authUserID, authUserID: authUserID,
nowTime: nowTime, nowTime: nowTime,
publicKeyData:publicKeyData, publicKeyData:publicKeyData,
needAuthor: needAuthor, needAuthor: needAuthor,
), callBack:callBack); ), callBack:callBack);
} }
//todo: //todo:
// static void senderAddUser({CommandSendCallBack? callBack}) { static void senderAddUser({
// CommandSenderManager().managerSendData( String? lockID,
// command: AddUserCommand( String? authUserID,
// cmdID: 0, String? keyID,
// lockID: "", String? userID,
// authUserID: "", int? openMode,
// keyID: "", int? keyType,
// userID: "", int? startDate,
// openMode: 0, int? expireDate,
// keyType: 0, int? role,
// startDate: 0, String? password,
// expireDate: 0, int? needAuthor,
// role: 0, List<int>? publicKey,
// password: "", List<int>? privateKey,
// token: 0, List<int>? token,
// authCodeLen: 0, CommandSendCallBack? callBack}) {
// authCode: "", CommandSenderManager().managerSendData(
// ), callBack:callBack); command: AddUserCommand(
// } lockID: lockID,
authUserID: authUserID,
keyID: keyID,
userID: userID,
openMode: openMode,
keyType: keyType,
startDate: startDate,
expireDate: expireDate,
role: role,
password: password,
needAuthor: needAuthor,
publicKey: publicKey,
privateKey: privateKey,
token: token
), callBack:callBack);
}
//todo: //todo:
// static void senderOpenDoor({CommandSendCallBack? callBack}) { // static void senderOpenDoor({CommandSendCallBack? callBack}) {

View File

@ -359,8 +359,8 @@ class SM4 {
return roundKey; return roundKey;
} }
static void setKey(String key) { static void setKey(List<int> key) {
List<int> keyBytes = SMUtils.hexStringToBytes(key); List<int> keyBytes = key;
List<int> intermediateKeys = List<int>.filled(36, 0); List<int> intermediateKeys = List<int>.filled(36, 0);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
intermediateKeys[i] = _readUint32BE(keyBytes, i * 4) ^ FK[i]; intermediateKeys[i] = _readUint32BE(keyBytes, i * 4) ^ FK[i];
@ -411,9 +411,11 @@ class SM4 {
} }
return paddedList; return paddedList;
} else { } else {
final lastByte = input.last; // final lastByte = input.last;
final cutLen = input.length - lastByte; // final cutLen = input.length - lastByte;
return input.sublist(0, cutLen); // print("object input.length${input.length} lastByte:$lastByte input:$input cutLen:$cutLen");
// return input.sublist(0, cutLen);
return input;
} }
} }
@ -518,7 +520,7 @@ class SM4 {
} }
static List<int> encrypt(List<int> data, static List<int> encrypt(List<int> data,
{String? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) { {List<int>? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) {
if (key != null) setKey(key); if (key != null) setKey(key);
List<int> input = data; List<int> input = data;
List<int> output = _crypto(input, SM4_ENCRYPT, mode, iv); List<int> output = _crypto(input, SM4_ENCRYPT, mode, iv);
@ -534,7 +536,7 @@ class SM4 {
// } // }
static decrypt(List<int> data, static decrypt(List<int> data,
{String? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) { {List<int>? key, SM4CryptoMode mode = SM4CryptoMode.ECB, String? iv}) {
if (key != null) setKey(key); if (key != null) setKey(key);
List<int> input = data; List<int> input = data;
List<int> output = _crypto(input, SM4_DECRYPT, mode, iv); List<int> output = _crypto(input, SM4_DECRYPT, mode, iv);

View File

@ -2,12 +2,20 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:get_storage/get_storage.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/tools/baseGetXController.dart'; import 'package:star_lock/tools/baseGetXController.dart';
import '../../../blue/blue_manage.dart'; import '../../../blue/blue_manage.dart';
import '../../../blue/io_protocol/io_addUser.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_model.dart';
import '../../../blue/io_tool/io_tool.dart';
import '../../../blue/io_tool/manager_event_bus.dart'; import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart'; import '../../../blue/sender_manage.dart';
import '../../../tools/storage.dart';
import 'nearbyLock_state.dart'; import 'nearbyLock_state.dart';
class NearbyLockLogic extends BaseGetXController{ class NearbyLockLogic extends BaseGetXController{
@ -15,26 +23,18 @@ class NearbyLockLogic extends BaseGetXController{
final NearbyLockState state = NearbyLockState(); final NearbyLockState state = NearbyLockState();
// //
void connect(String lockId){ void connect(String lockId, String deviceName){
BlueManage().connect(lockId); BlueManage().connect(lockId, deviceName);
} }
// //
late StreamSubscription _streamSubscription; late StreamSubscription _streamSubscription;
void _startListenIO(){ void _startListenIO(){
_streamSubscription = EventBusManager().eventBus!.on<QualifiedCharacteristic>().listen((event) async { _streamSubscription = EventBusManager().eventBus!.on<QualifiedCharacteristic>().listen((event) async {
IoSenderManage.getPublicKey(state.seletLockName.value); IoSenderManage.getPublicKey(lockId:state.seletLockName.value);
}); });
} }
// 线
// Future<void> scanDiscoverServices(String lockId) async {
// //
// List<DiscoveredService> list = await BlueManage().discoverServices(lockId);
// //
// IoSenderManage.getPublicKey(state.seletLockName.value);
// }
// //
// void getPublicKey(String lockId){ // void getPublicKey(String lockId){
// // print("seletGetPublicKey:${lockId}"); // // print("seletGetPublicKey:${lockId}");
@ -57,6 +57,146 @@ class NearbyLockLogic extends BaseGetXController{
}); });
} }
late StreamSubscription<Reply> _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on<Reply>().listen((reply) {
if(reply is GetPublicKeyReply) {
_replyGetPublicKey(reply);
}
if(reply is GetPrivateKeyReply) {
_replyGetPrivateKeyKey(reply);
}
if(reply is AddUserReply) {
_replyAddUserKey(reply);
}
});
}
void _replyGetPublicKey(Reply reply){
//
switch(reply.status){
case 0x00:
//
//
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:
//
break;
case 0x0f:
//
break;
default:
//
break;
}
}
void _replyGetPrivateKeyKey(Reply reply){
switch(reply.status){
case 0x00:
//
print('获取私钥成功');
reply.data.removeAt(0);
//
List<int> privateKey = reply.data.sublist(0, 16);
var savePrivateKeyList = changeIntListToStringList(privateKey);
Storage.setStringList(saveBluePrivateKey, savePrivateKeyList);
// signKey
List<int> signKey = reply.data.sublist(16);
var savesignKeyList = changeIntListToStringList(signKey);
Storage.setStringList(saveBlueSignKey, savesignKeyList);
print("privateKey:$privateKey signKey:$signKey");
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:privateKey,
token: [0,0,0,0]
);
break;
case 0x07:
//
print('获取私钥无权限');
break;
case 0x0f:
//
print('获取私钥:用户已存在');
break;
default:
//
print('获取私钥失败');
break;
}
}
void _replyAddUserKey(Reply reply){
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("需要鉴权");
break;
case 0x07:
//
print("用户无权限");
break;
case 0x09:
//
print("权限校验错误");
break;
default:
//
print("领锁失败");
break;
}
}
@override @override
void onReady() { void onReady() {
// TODO: implement onReady // TODO: implement onReady
@ -65,6 +205,7 @@ class NearbyLockLogic extends BaseGetXController{
_startListenIO(); _startListenIO();
_initSendStreamSubscription(); _initSendStreamSubscription();
_initReplySubscription();
} }
@override @override
@ -75,10 +216,8 @@ class NearbyLockLogic extends BaseGetXController{
// //
BlueManage().startScan((v){ BlueManage().startScan((v){
bool isHave = state.devices.any((element) => element.id == v[0].id); state.devices.clear();
if (isHave == false){ state.devices.addAll(v);
state.devices.addAll(v);
}
}); });
} }
@ -88,6 +227,7 @@ class NearbyLockLogic extends BaseGetXController{
super.onClose(); super.onClose();
_streamSubscription.cancel(); _streamSubscription.cancel();
_sendStreamSubscription.cancel(); _sendStreamSubscription.cancel();
_replySubscription.cancel();
} }
} }

View File

@ -61,7 +61,7 @@ class _NearbyLockPageState extends State<NearbyLockPage> {
// Navigator.pushNamed(context, Routers.lockAddressPage); // Navigator.pushNamed(context, Routers.lockAddressPage);
// logic.getPublicKey(state.devices[index].serviceUuids[0].toString()); // logic.getPublicKey(state.devices[index].serviceUuids[0].toString());
state.seletLockName.value = state.devices[index].name; state.seletLockName.value = state.devices[index].name;
logic.connect(state.devices[index].id); logic.connect(state.devices[index].id, state.devices[index].name);
}); });
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {

View File

@ -6,6 +6,6 @@ import 'package:get/get.dart';
class NearbyLockState { class NearbyLockState {
var devices = <DiscoveredDevice>[].obs; RxList<DiscoveredDevice> devices = <DiscoveredDevice>[].obs;
var seletLockName = "".obs; var seletLockName = "".obs;
} }

View File

@ -1,4 +1,3 @@
import 'dart:convert'; import 'dart:convert';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -8,47 +7,44 @@ import '../../login/login/entity/LoginEntity.dart';
import '../../tools/storage.dart'; import '../../tools/storage.dart';
class StarLockMineState { class StarLockMineState {
final loginData = LoginEntity().obs; final loginData = LoginEntity().obs;
/// ///
void saveLoginData(LoginEntity data) async { void saveLoginData(LoginEntity data) async {
print("saveLoginData:${data.data!.mobile}"); print("saveLoginData:${data.data!.mobile}");
await Storage.setData('userLoginData',jsonEncode(data)); await Storage.setString('userLoginData', jsonEncode(data));
loginData.value=data; loginData.value = data;
} }
/// ///
void initLoginData() async { void initLoginData() async {
final data = await Storage.getData<String>('userLoginData'); final data = await Storage.getString('userLoginData');
print("getLoginData:$data"); print("getLoginData:$data");
if(data != null && data.isNotEmpty){ if (data != null && data.isNotEmpty) {
loginData.value = LoginEntity.fromJson(jsonDecode(data)); loginData.value = LoginEntity.fromJson(jsonDecode(data));
} }
} }
///退 ///退
void logOut() async { void logOut() async {
await Storage.setData('userLoginData',''); await Storage.setString('userLoginData', '');
loginData.value = LoginEntity(); loginData.value = LoginEntity();
} }
///token ///token
String token(){ String token() {
return loginData.value.data?.accessToken??''; return loginData.value.data?.accessToken ?? '';
} }
String mobile(){ String mobile() {
return loginData.value.data?.mobile??'-'; return loginData.value.data?.mobile ?? '-';
} }
/// ///
String headUrl(){ String headUrl() {
return loginData.value.data!.headUrl??''; return loginData.value.data!.headUrl ?? '';
// return "https://img2.woyaogexing.com/2022/04/14/156cdbabd5bc496abee2cd0fca527434!400x400.jpeg"; // return "https://img2.woyaogexing.com/2022/04/14/156cdbabd5bc496abee2cd0fca527434!400x400.jpeg";
} }
void onClose() { void onClose() {}
}
}
}

View File

@ -16,7 +16,7 @@ FutureOr<Request> requestInterceptor(Request request) async {
// request.headers['token'] = StoreService.to.userToken!; // request.headers['token'] = StoreService.to.userToken!;
// print("11111${StoreService.to.userToken}"); // print("11111${StoreService.to.userToken}");
String? xToken = ''; String? xToken = '';
final data = await Storage.getData<String>('userLoginData'); final data = await Storage.getString('userLoginData');
if (data != null && data.isNotEmpty) { if (data != null && data.isNotEmpty) {
xToken = LoginEntity.fromJson(jsonDecode(data)).data!.accessToken; xToken = LoginEntity.fromJson(jsonDecode(data)).data!.accessToken;
} }

View File

@ -3,34 +3,114 @@
* */ * */
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
class Storage{ class Storage {
/// // Storage._internal();
static Future<void> setData(key, value) async { //
// factory Storage() => _instance;
//
// static late final Storage _instance = Storage._internal();
//
// static late SharedPreferences _preferences;
//
// static Future<Storage> getInstance() async {
// _preferences = await SharedPreferences.getInstance();
// return _instance;
// }
// ///
// static Future<void> setData(key, value) async {
// SharedPreferences sp = await SharedPreferences.getInstance();
// if (value is int) {
// await sp.setInt(key, value);
// } else if (value is bool) {
// await sp.setBool(key, value);
// } else if (value is double) {
// await sp.setDouble(key, value);
// } else if (value is String) {
// await sp.setString(key, value);
// } else if (value is List<String>) {
// await sp.setStringList(key, value);
// }
// }
//
// ///
// ///
// static Future<T?> getData<T>(key) async {
// SharedPreferences sp = await SharedPreferences.getInstance();
// switch(T){
// case int: return (sp.getInt(key) ?? 0) as T;
// case bool: return (sp.getBool(key) ?? false) as T;
// case double: return (sp.getDouble(key) ?? 0.0) as T;
// case String: return (sp.getString(key) ?? '') as T;
// case List: return (sp.getStringList(key) ?? []) as T;
// default: return null;
// }
// }
// int
static Future<void> setInt(key, value) async {
SharedPreferences sp = await SharedPreferences.getInstance(); SharedPreferences sp = await SharedPreferences.getInstance();
if (value is int) { sp.setInt(key, value);
await sp.setInt(key, value);
} else if (value is bool) {
await sp.setBool(key, value);
} else if (value is double) {
await sp.setDouble(key, value);
} else if (value is String) {
await sp.setString(key, value);
} else if (value is List<String>) {
await sp.setStringList(key, value);
}
} }
/// static Future<int?> getInt(key) async {
///
static Future<T?> getData<T>(key) async {
SharedPreferences sp = await SharedPreferences.getInstance(); SharedPreferences sp = await SharedPreferences.getInstance();
switch(T){ return sp.getInt(key);
case int: return (sp.getInt(key) ?? 0) as T;
case bool: return (sp.getBool(key) ?? false) as T;
case double: return (sp.getDouble(key) ?? 0.0) as T;
case String: return (sp.getString(key) ?? '') as T;
case List: return (sp.getStringList(key) ?? []) as T;
default: return null;
}
} }
}
// bool
static Future<void> setBool(key, value) async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.setBool(key, value);
}
static Future<bool?> getBool(key) async {
SharedPreferences sp = await SharedPreferences.getInstance();
return sp.getBool(key);
}
// double
static Future<void> setDouble(key, value) async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.setDouble(key, value);
}
static Future<double?> getDouble(key) async {
SharedPreferences sp = await SharedPreferences.getInstance();
return sp.getDouble(key);
}
// string
static Future<void> setString(key, value) async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.setString(key, value);
}
static Future<String?> getString(key) async {
SharedPreferences sp = await SharedPreferences.getInstance();
return sp.getString(key);
}
//
static Future<void> setStringList(key, value) async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.setStringList(key, value);
}
static Future<List<String>?> getStringList(key) async {
SharedPreferences sp = await SharedPreferences.getInstance();
return sp.getStringList(key);
}
//
static Future<void> removeData(key) async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.remove(key);
}
//
static Future<void> clearAll() async {
SharedPreferences sp = await SharedPreferences.getInstance();
sp.clear();
}
}