app-starlock/lib/blue/io_sender.dart
2025-02-06 10:03:18 +08:00

386 lines
7.0 KiB
Dart
Executable File
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 'package:star_lock/app_settings/app_settings.dart';
import 'io_tool/io_manager.dart';
import 'io_type.dart';
abstract class IOData {
List<int> messageDetail();
}
abstract class SenderProtocol extends IOData {
//数据块
// final int? tail = 0xFF; //用来校验包的完整性,采用 CRC 校验方法,长度为 2 个字节
SenderProtocol(this.commandType) {
_commandIndex = IoManager().commandIndex;
}
// var uint8View1 = Uint8List(300);
CommandType? commandType; //指令类型
final List<int> header = <int>[
0XEF,
0X01,
0XEE,
0X02
]; //帧头 固定取值 0XEF01EE02长度 4 字节
final int ask = 0X01; // 包类型0X01 表示请求包0X11 表示应答包,长度 1 字节
int _commandIndex = 1; //包序号
int identifier =
0x20; // 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节加密类型取值说明0明文1AES1282SM4事先约定密钥3SM4设备指定密钥
List<int>? commandData = <int>[];
void printLog(List<int> data) {
AppLog.log(
"App -> 锁,指令类型:${commandType!.typeName} ${commandType!.typeValue == 0x3030 ? '子命令:${data[3]}' : ''} \n参数是:\n${toString()} \n加密之前数据是:\n$data 长度是:${data.length}");
}
// 拼装数据
List<int> packageData() {
commandData = messageDetail();
final List<int> commandList = <int>[];
// 帧头
commandList.addAll(header);
//包类型
commandList.add(ask); //包类型
// 包序号
final int commandIndexChange = _commandIndex;
final double commandIndexChangeDouble = commandIndexChange / 256;
final int commandIndexChang1 = commandIndexChangeDouble.toInt();
final int commandIndexChang2 = commandIndexChange % 256;
commandList.add(commandIndexChang1);
commandList.add(commandIndexChang2);
// 包标识
// 指令类型 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节加密类型取值说明0明文1AES1282SM4事先约定密钥3SM4设备指定密钥
final int value = identifierValue();
commandList.add(value);
// 数据长度
final int dataLen = dataSourceLength();
// commandList.add(dataLength);
// var dataLen = 42;
final double dataLength = dataLen / 256;
commandList.add(dataLength.toInt());
commandList.add(dataLen % 256);
commandList.add(dataLength.toInt());
commandList.add(dataLen % 256);
// 数据块
commandList.addAll(commandData!); //数据块
// 校验位
final int mcrc = crc_16(commandList);
final double mcrcDouble = mcrc / 256;
final int mcrcDouble1 = mcrcDouble.toInt();
final int mcrcDouble2 = mcrc % 256;
commandList.add(mcrcDouble1); //帧尾
commandList.add(mcrcDouble2);
return commandList;
}
// 包标识
// 指令类型 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节加密类型取值说明0明文1AES1282SM4事先约定密钥3SM4设备指定密钥
int identifierValue() => commandType!.identifierValue;
// 长度
int dataSourceLength() => commandData!.length;
List<int> crcTable = <int>[
0x0000,
0x1021,
0x2042,
0x3063,
0x4084,
0x50a5,
0x60c6,
0x70e7,
0x8108,
0x9129,
0xa14a,
0xb16b,
0xc18c,
0xd1ad,
0xe1ce,
0xf1ef,
0x1231,
0x0210,
0x3273,
0x2252,
0x52b5,
0x4294,
0x72f7,
0x62d6,
0x9339,
0x8318,
0xb37b,
0xa35a,
0xd3bd,
0xc39c,
0xf3ff,
0xe3de,
0x2462,
0x3443,
0x0420,
0x1401,
0x64e6,
0x74c7,
0x44a4,
0x5485,
0xa56a,
0xb54b,
0x8528,
0x9509,
0xe5ee,
0xf5cf,
0xc5ac,
0xd58d,
0x3653,
0x2672,
0x1611,
0x0630,
0x76d7,
0x66f6,
0x5695,
0x46b4,
0xb75b,
0xa77a,
0x9719,
0x8738,
0xf7df,
0xe7fe,
0xd79d,
0xc7bc,
0x48c4,
0x58e5,
0x6886,
0x78a7,
0x0840,
0x1861,
0x2802,
0x3823,
0xc9cc,
0xd9ed,
0xe98e,
0xf9af,
0x8948,
0x9969,
0xa90a,
0xb92b,
0x5af5,
0x4ad4,
0x7ab7,
0x6a96,
0x1a71,
0x0a50,
0x3a33,
0x2a12,
0xdbfd,
0xcbdc,
0xfbbf,
0xeb9e,
0x9b79,
0x8b58,
0xbb3b,
0xab1a,
0x6ca6,
0x7c87,
0x4ce4,
0x5cc5,
0x2c22,
0x3c03,
0x0c60,
0x1c41,
0xedae,
0xfd8f,
0xcdec,
0xddcd,
0xad2a,
0xbd0b,
0x8d68,
0x9d49,
0x7e97,
0x6eb6,
0x5ed5,
0x4ef4,
0x3e13,
0x2e32,
0x1e51,
0x0e70,
0xff9f,
0xefbe,
0xdfdd,
0xcffc,
0xbf1b,
0xaf3a,
0x9f59,
0x8f78,
0x9188,
0x81a9,
0xb1ca,
0xa1eb,
0xd10c,
0xc12d,
0xf14e,
0xe16f,
0x1080,
0x00a1,
0x30c2,
0x20e3,
0x5004,
0x4025,
0x7046,
0x6067,
0x83b9,
0x9398,
0xa3fb,
0xb3da,
0xc33d,
0xd31c,
0xe37f,
0xf35e,
0x02b1,
0x1290,
0x22f3,
0x32d2,
0x4235,
0x5214,
0x6277,
0x7256,
0xb5ea,
0xa5cb,
0x95a8,
0x8589,
0xf56e,
0xe54f,
0xd52c,
0xc50d,
0x34e2,
0x24c3,
0x14a0,
0x0481,
0x7466,
0x6447,
0x5424,
0x4405,
0xa7db,
0xb7fa,
0x8799,
0x97b8,
0xe75f,
0xf77e,
0xc71d,
0xd73c,
0x26d3,
0x36f2,
0x0691,
0x16b0,
0x6657,
0x7676,
0x4615,
0x5634,
0xd94c,
0xc96d,
0xf90e,
0xe92f,
0x99c8,
0x89e9,
0xb98a,
0xa9ab,
0x5844,
0x4865,
0x7806,
0x6827,
0x18c0,
0x08e1,
0x3882,
0x28a3,
0xcb7d,
0xdb5c,
0xeb3f,
0xfb1e,
0x8bf9,
0x9bd8,
0xabbb,
0xbb9a,
0x4a75,
0x5a54,
0x6a37,
0x7a16,
0x0af1,
0x1ad0,
0x2ab3,
0x3a92,
0xfd2e,
0xed0f,
0xdd6c,
0xcd4d,
0xbdaa,
0xad8b,
0x9de8,
0x8dc9,
0x7c26,
0x6c07,
0x5c64,
0x4c45,
0x3ca2,
0x2c83,
0x1ce0,
0x0cc1,
0xef1f,
0xff3e,
0xcf5d,
0xdf7c,
0xaf9b,
0xbfba,
0x8fd9,
0x9ff8,
0x6e17,
0x7e36,
0x4e55,
0x5e74,
0x2e93,
0x3eb2,
0x0ed1,
0x1ef0
];
int crc_16(List<int> buffer) {
int value_ = 0x0000; //0xa635; //初始值根据CRC类型设定
int tmp;
for (int i = 0; i < buffer.length; i++) {
tmp = reverse8(buffer[i]);
value_ =
((value_ << 8) ^ crcTable[((value_ >> 8) ^ tmp) & 0xFF]) & 0xFFFF;
}
value_ = reverse16(value_);
return value_;
}
int reverse8(int data) {
int i;
int temp = 0;
for (i = 0; i < 8; i++) {
//字节反转
temp |= ((data >> i) & 0x01) << (7 - i);
}
return temp;
}
int reverse16(int data) {
int i;
int temp = 0;
for (i = 0; i < 16; i++) {
//反转
temp |= ((data >> i) & 0x0001) << (15 - i);
}
return temp;
}
}