2025-01-10 14:47:50 +08:00
|
|
|
|
import 'dart:async';
|
2025-01-08 09:14:29 +08:00
|
|
|
|
import 'dart:convert';
|
2024-12-24 10:50:32 +08:00
|
|
|
|
import 'dart:typed_data';
|
|
|
|
|
|
|
2024-12-04 15:00:56 +08:00
|
|
|
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
|
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
|
|
import 'package:star_lock/appRouters.dart';
|
2025-01-08 09:14:29 +08:00
|
|
|
|
import 'package:star_lock/app_settings/app_settings.dart';
|
2025-01-10 14:47:50 +08:00
|
|
|
|
import 'package:star_lock/blue/blue_manage.dart';
|
|
|
|
|
|
import 'package:star_lock/blue/io_protocol/io_openLock.dart';
|
|
|
|
|
|
import 'package:star_lock/blue/io_reply.dart';
|
|
|
|
|
|
import 'package:star_lock/blue/io_tool/io_tool.dart';
|
|
|
|
|
|
import 'package:star_lock/blue/io_tool/manager_event_bus.dart';
|
2025-01-09 14:10:10 +08:00
|
|
|
|
import 'package:star_lock/blue/reciver_data.dart';
|
2025-01-10 14:47:50 +08:00
|
|
|
|
import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_logic.dart';
|
|
|
|
|
|
import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_state.dart';
|
2025-01-08 09:14:29 +08:00
|
|
|
|
import 'package:star_lock/talk/startChart/constant/message_type_constant.dart';
|
2024-12-04 15:00:56 +08:00
|
|
|
|
import 'package:star_lock/talk/startChart/entity/scp_message.dart';
|
|
|
|
|
|
import 'package:star_lock/talk/startChart/handle/scp_message_base_handle.dart';
|
|
|
|
|
|
import 'package:star_lock/talk/startChart/handle/scp_message_handle.dart';
|
|
|
|
|
|
import 'package:star_lock/talk/startChart/proto/ble_message.pbserver.dart';
|
|
|
|
|
|
import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
|
|
|
|
|
|
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
|
2025-01-10 14:47:50 +08:00
|
|
|
|
import 'package:star_lock/tools/bugly/bugly_tool.dart';
|
|
|
|
|
|
import 'package:star_lock/tools/dateTool.dart';
|
|
|
|
|
|
import 'package:star_lock/tools/eventBusEventManage.dart';
|
|
|
|
|
|
import 'package:star_lock/tools/storage.dart';
|
|
|
|
|
|
import 'package:umeng_common_sdk/umeng_common_sdk.dart';
|
2024-12-04 15:00:56 +08:00
|
|
|
|
|
|
|
|
|
|
import '../../start_chart_manage.dart';
|
|
|
|
|
|
|
2024-12-11 09:32:51 +08:00
|
|
|
|
class UdpBlePassThroughHandler extends ScpMessageBaseHandle
|
|
|
|
|
|
implements ScpMessageHandler {
|
2025-01-10 14:47:50 +08:00
|
|
|
|
LockDetailLogic lockDetailLogic = Get.put(LockDetailLogic());
|
|
|
|
|
|
LockDetailState lockDetailState = Get.find<LockDetailLogic>().state;
|
|
|
|
|
|
|
2024-12-04 15:00:56 +08:00
|
|
|
|
@override
|
2024-12-09 09:22:58 +08:00
|
|
|
|
void handleReq(ScpMessage scpMessage) {
|
|
|
|
|
|
//TODO 收到蓝牙透传请求指令
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
2025-01-10 14:47:50 +08:00
|
|
|
|
void handleResp(ScpMessage scpMessage) async {
|
2025-01-08 09:14:29 +08:00
|
|
|
|
final BleResp bleResp = scpMessage.Payload;
|
2025-01-10 14:47:50 +08:00
|
|
|
|
String hexString = bleResp.structData
|
|
|
|
|
|
.map((byte) => byte.toRadixString(16).padLeft(2, '0'))
|
|
|
|
|
|
.join(' ');
|
2025-01-14 13:43:12 +08:00
|
|
|
|
AppLog.log('收到蓝牙透传回复:$hexString');
|
2025-01-10 14:47:50 +08:00
|
|
|
|
|
|
|
|
|
|
await CommandReciverManager.appDataReceive(bleResp.structData);
|
|
|
|
|
|
|
|
|
|
|
|
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
|
|
|
|
|
// 开门
|
|
|
|
|
|
if (reply is OpenDoorReply) {
|
|
|
|
|
|
AppLog.log('收到开门请求命令回复');
|
|
|
|
|
|
_replyOpenLock(reply);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2024-12-09 09:22:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
2024-12-11 09:32:51 +08:00
|
|
|
|
void handleInvalidReq(ScpMessage scpMessage) {}
|
2024-12-09 09:22:58 +08:00
|
|
|
|
|
|
|
|
|
|
@override
|
2024-12-11 09:32:51 +08:00
|
|
|
|
void handleRealTimeData(ScpMessage scpMessage) {}
|
2024-12-24 10:50:32 +08:00
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
deserializePayload(
|
|
|
|
|
|
{required int payloadType,
|
|
|
|
|
|
required int messageType,
|
2024-12-25 18:30:10 +08:00
|
|
|
|
required List<int> byte,
|
2024-12-24 10:50:32 +08:00
|
|
|
|
int? offset,
|
|
|
|
|
|
int? PayloadLength,
|
|
|
|
|
|
int? spTotal,
|
|
|
|
|
|
int? spIndex,
|
|
|
|
|
|
int? messageId}) {
|
2025-01-08 09:14:29 +08:00
|
|
|
|
if (messageType == MessageTypeConstant.Resp) {
|
|
|
|
|
|
final BleResp bleResp = BleResp();
|
|
|
|
|
|
bleResp.mergeFromBuffer(byte);
|
|
|
|
|
|
return bleResp;
|
|
|
|
|
|
} else if (messageType == MessageTypeConstant.Req) {
|
|
|
|
|
|
final BleReq talkExpect = BleReq();
|
|
|
|
|
|
talkExpect.mergeFromBuffer(byte);
|
|
|
|
|
|
return talkExpect;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
String payload = utf8.decode(byte);
|
|
|
|
|
|
return payload;
|
|
|
|
|
|
}
|
2024-12-24 10:50:32 +08:00
|
|
|
|
}
|
2025-01-10 14:47:50 +08:00
|
|
|
|
|
|
|
|
|
|
// 开门数据解析
|
|
|
|
|
|
Future<void> _replyOpenLock(Reply reply) async {
|
|
|
|
|
|
final int status = reply.data[6];
|
|
|
|
|
|
|
|
|
|
|
|
BuglyTool.uploadException(
|
|
|
|
|
|
message: '开锁结果,解析数据',
|
|
|
|
|
|
detail: '开锁结果,解析数据 _replyOpenLock:${reply.data}',
|
|
|
|
|
|
upload: true);
|
|
|
|
|
|
|
|
|
|
|
|
if (status != 6) {
|
|
|
|
|
|
final String getMobile = (await Storage.getMobile())!;
|
|
|
|
|
|
UmengCommonSdk.onEvent('open_lock', {
|
|
|
|
|
|
'lock_name': lockDetailState.keyInfos.value.lockName!,
|
|
|
|
|
|
'account':
|
|
|
|
|
|
getMobile.isNotEmpty ? getMobile : (await Storage.getEmail())!,
|
|
|
|
|
|
'date': DateTool().getNowDateWithType(1),
|
|
|
|
|
|
'open_lock_result': '${reply.data}',
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
|
case 0x00:
|
|
|
|
|
|
//成功
|
|
|
|
|
|
// _showFullScreenOverlay(Get.context!);
|
|
|
|
|
|
lockDetailState.iSClosedUnlockSuccessfulPopup.value = true;
|
|
|
|
|
|
lockDetailLogic.cancelBlueConnetctToastTimer();
|
|
|
|
|
|
lockDetailState.closedUnlockSuccessfulTimer?.cancel();
|
|
|
|
|
|
// EasyLoading.dismiss();
|
|
|
|
|
|
// 如果没有点击关闭弹窗,3秒后自动关闭
|
|
|
|
|
|
lockDetailState.closedUnlockSuccessfulTimer =
|
|
|
|
|
|
Timer.periodic(3.seconds, (Timer timer) {
|
|
|
|
|
|
lockDetailState.iSClosedUnlockSuccessfulPopup.value = false;
|
|
|
|
|
|
timer.cancel();
|
|
|
|
|
|
eventBus.fire(RefreshLockDetailInfoDataEvent());
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 电量
|
|
|
|
|
|
final int power = reply.data[7];
|
|
|
|
|
|
lockDetailState.electricQuantity.value = power;
|
|
|
|
|
|
|
|
|
|
|
|
// 备用电量
|
|
|
|
|
|
if (lockDetailState
|
|
|
|
|
|
.keyInfos.value.lockFeature!.isSupportBackupBattery ==
|
|
|
|
|
|
1) {
|
|
|
|
|
|
final int powerStandby = reply.data[9];
|
|
|
|
|
|
lockDetailState.electricQuantityStandby.value = powerStandby;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 更新电量
|
|
|
|
|
|
await lockDetailLogic.uploadElectricQuantityRequest();
|
|
|
|
|
|
|
|
|
|
|
|
// 开锁成功上报
|
|
|
|
|
|
lockDetailLogic.lockReportLockSuccessfullyUploadData();
|
|
|
|
|
|
|
|
|
|
|
|
lockDetailLogic.resetOpenDoorState();
|
2025-01-14 13:43:12 +08:00
|
|
|
|
lockDetailState.animationController?.stop();
|
2025-01-10 14:47:50 +08:00
|
|
|
|
|
|
|
|
|
|
//锁数据更新
|
|
|
|
|
|
lockDetailLogic.getLockRecordLastUploadDataTime();
|
|
|
|
|
|
if (!EasyLoading.isShow) {
|
|
|
|
|
|
lockDetailLogic.showToast('开门成功'.tr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x06:
|
|
|
|
|
|
//无权限
|
|
|
|
|
|
// 获取token后在重新发送
|
|
|
|
|
|
sendCarryTokenOpenLockMessage(reply);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x16:
|
|
|
|
|
|
// 正在开锁中...
|
|
|
|
|
|
final int isOpen = reply.data[8];
|
|
|
|
|
|
String? msg;
|
|
|
|
|
|
if (isOpen == 0) {
|
|
|
|
|
|
msg = '正在开锁中...'.tr;
|
|
|
|
|
|
} else if (isOpen == 32) {
|
|
|
|
|
|
msg = '正在闭锁中...'.tr;
|
|
|
|
|
|
}
|
|
|
|
|
|
lockDetailLogic.resetOpenDoorState();
|
|
|
|
|
|
if (msg != null) {
|
|
|
|
|
|
lockDetailLogic.showToast(msg, something: () {
|
|
|
|
|
|
lockDetailLogic.cancelBlueConnetctToastTimer();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x0d:
|
|
|
|
|
|
// 钥匙无效
|
|
|
|
|
|
lockDetailLogic.showToast('钥匙无效'.tr);
|
|
|
|
|
|
lockDetailLogic.openDoorError();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x0b:
|
|
|
|
|
|
// 钥匙无效
|
|
|
|
|
|
lockDetailLogic.showToast('钥匙过期'.tr);
|
|
|
|
|
|
lockDetailLogic.openDoorError();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x0a:
|
|
|
|
|
|
// 钥匙不存在
|
|
|
|
|
|
lockDetailLogic.showToast('钥匙不存在'.tr);
|
|
|
|
|
|
lockDetailLogic.openDoorError();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x0c:
|
|
|
|
|
|
// 钥匙数量已到上限
|
|
|
|
|
|
lockDetailLogic.showToast('钥匙数量已到上限'.tr);
|
|
|
|
|
|
lockDetailLogic.openDoorError();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x0e:
|
|
|
|
|
|
// 钥匙已存在
|
|
|
|
|
|
lockDetailLogic.showToast('钥匙已存在'.tr);
|
|
|
|
|
|
lockDetailLogic.openDoorError();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 0x0f:
|
|
|
|
|
|
// 用户已存在
|
|
|
|
|
|
lockDetailLogic.showToast('用户已存在'.tr);
|
|
|
|
|
|
lockDetailLogic.openDoorError();
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
//失败
|
|
|
|
|
|
// AppLog.log('开锁失败');
|
|
|
|
|
|
lockDetailLogic.openDoorError();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void sendCarryTokenOpenLockMessage(Reply reply) async {
|
|
|
|
|
|
/// 无权限开门时,重新发送一个带token信息的开门信息
|
|
|
|
|
|
final List<String>? privateKey =
|
|
|
|
|
|
await Storage.getStringList(saveBluePrivateKey);
|
|
|
|
|
|
final List<int> getPrivateKeyList = changeStringListToIntList(privateKey!);
|
|
|
|
|
|
|
|
|
|
|
|
final List<String>? signKey = await Storage.getStringList(saveBlueSignKey);
|
|
|
|
|
|
final List<int> signKeyDataList = changeStringListToIntList(signKey!);
|
|
|
|
|
|
|
|
|
|
|
|
final List<int> tokenData = reply.data.sublist(2, 6);
|
|
|
|
|
|
final List<String> saveStrList = changeIntListToStringList(tokenData);
|
|
|
|
|
|
Storage.setStringList(saveBlueToken, saveStrList);
|
|
|
|
|
|
|
|
|
|
|
|
final OpenLockCommand openLockCommand = OpenLockCommand(
|
|
|
|
|
|
lockID: BlueManage().connectDeviceName,
|
|
|
|
|
|
userID: await Storage.getUid(),
|
|
|
|
|
|
openMode: lockDetailState.openDoorModel,
|
|
|
|
|
|
openTime: lockDetailLogic.getUTCNetTime(),
|
|
|
|
|
|
onlineToken: lockDetailState.lockNetToken,
|
|
|
|
|
|
token: tokenData,
|
|
|
|
|
|
needAuthor: 1,
|
|
|
|
|
|
signKey: signKeyDataList,
|
|
|
|
|
|
privateKey: getPrivateKeyList,
|
|
|
|
|
|
);
|
|
|
|
|
|
final messageDetail = openLockCommand.packageData();
|
|
|
|
|
|
// 将 List<int> 转换为十六进制字符串
|
|
|
|
|
|
String hexString = messageDetail
|
|
|
|
|
|
.map((byte) => byte.toRadixString(16).padLeft(2, '0'))
|
|
|
|
|
|
.join(' ');
|
|
|
|
|
|
|
|
|
|
|
|
AppLog.log('open lock hexString: $hexString');
|
|
|
|
|
|
// 发送远程开门消息
|
|
|
|
|
|
StartChartManage().sendRemoteUnLockMessage(
|
|
|
|
|
|
bluetoothDeviceName: BlueManage().connectDeviceName,
|
|
|
|
|
|
openLockCommand: messageDetail,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2024-12-04 15:00:56 +08:00
|
|
|
|
}
|