app-starlock/lib/blue/io_sender.dart

389 lines
6.9 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 'dart:typed_data';
import 'package:star_lock/app_settings/app_settings.dart';
import 'io_tool/io_manager.dart';
import 'io_tool/io_tool.dart';
import 'io_type.dart';
abstract class IOData {
List<int> messageDetail();
}
abstract class SenderProtocol extends IOData {
// var uint8View1 = Uint8List(300);
CommandType? commandType; //指令类型
final List<int> header = [
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 = []; //数据块
// final int? tail = 0xFF; //用来校验包的完整性,采用 CRC 校验方法,长度为 2 个字节
SenderProtocol(this.commandType) {
_commandIndex = IoManager().commandIndex;
}
void printLog(List<int> data) {
AppLog.log(
"App -> 锁,指令类型:${commandType!.typeName} ${commandType!.typeValue == 0x3030
? '子命令:${data[3]}' : ''} \n参数是:\n${toString()} \n加密之前数据是:\n$data 长度是:${data.length}");
}
//TODO:拼装数据
List<int> packageData() {
commandData = messageDetail();
List<int> commandList = [];
// 帧头
commandList.addAll(header);
//包类型
commandList.add(ask); //包类型
// 包序号
int commandIndexChange = _commandIndex!;
double commandIndexChangeDouble = commandIndexChange / 256;
int commandIndexChang1 = commandIndexChangeDouble.toInt();
int commandIndexChang2 = commandIndexChange % 256;
commandList.add(commandIndexChang1);
commandList.add(commandIndexChang2);
// 包标识
// 指令类型 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节加密类型取值说明0明文1AES1282SM4事先约定密钥3SM4设备指定密钥
int value = identifierValue();
commandList.add(value);
// 数据长度
int dataLen = dataSourceLength();
// commandList.add(dataLength);
// var dataLen = 42;
double dataLength = dataLen / 256;
commandList.add(dataLength.toInt());
commandList.add(dataLen % 256);
commandList.add(dataLength.toInt());
commandList.add(dataLen % 256);
// 数据块
commandList.addAll(commandData!); //数据块
// 校验位
var mcrc = crc_16(commandList);
double mcrcDouble = mcrc / 256;
int mcrcDouble1 = mcrcDouble.toInt();
int mcrcDouble2 = mcrc % 256;
commandList.add(mcrcDouble1); //帧尾
commandList.add(mcrcDouble2);
return commandList;
}
// 包标识
// 指令类型 高 4 位表示包版本,低 4 位用来指示后面数据的加密类型,长度为 1 字节加密类型取值说明0明文1AES1282SM4事先约定密钥3SM4设备指定密钥
int identifierValue() => commandType!.identifierValue;
//TODO:长度
int dataSourceLength() => commandData!.length;
var crcTable = [
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(buffer) {
var len = buffer.length;
var value_ = 0x0000; //0xa635; //初始值根据CRC类型设定
var tmp;
for (var 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(data) {
var i;
var temp = 0;
for (i = 0; i < 8; i++) {
//字节反转
temp |= ((data >> i) & 0x01) << (7 - i);
}
return temp;
}
int reverse16(data) {
var i;
var temp = 0;
for (i = 0; i < 16; i++) {
//反转
temp |= ((data >> i) & 0x0001) << (15 - i);
}
return temp;
}
}