import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; import 'package:star_lock/appRouters.dart'; import 'package:star_lock/app_settings/app_settings.dart'; 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'; import 'package:star_lock/blue/reciver_data.dart'; import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_logic.dart'; import 'package:star_lock/main/lockDetail/lockDetail/lockDetail_state.dart'; import 'package:star_lock/talk/startChart/constant/message_type_constant.dart'; 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'; 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'; import '../../start_chart_manage.dart'; class UdpBlePassThroughHandler extends ScpMessageBaseHandle implements ScpMessageHandler { LockDetailLogic lockDetailLogic = Get.put(LockDetailLogic()); LockDetailState lockDetailState = Get.find().state; @override void handleReq(ScpMessage scpMessage) { //TODO 收到蓝牙透传请求指令 } @override void handleResp(ScpMessage scpMessage) async { final BleResp bleResp = scpMessage.Payload; String hexString = bleResp.structData .map((byte) => byte.toRadixString(16).padLeft(2, '0')) .join(' '); AppLog.log('收到蓝牙透传回复:$hexString'); await CommandReciverManager.appDataReceive(bleResp.structData); EventBusManager().eventBus!.on().listen((Reply reply) async { // 开门 if (reply is OpenDoorReply) { AppLog.log('收到开门请求命令回复'); _replyOpenLock(reply); } }); } @override void handleInvalidReq(ScpMessage scpMessage) {} @override void handleRealTimeData(ScpMessage scpMessage) {} @override deserializePayload( {required int payloadType, required int messageType, required List byte, int? offset, int? PayloadLength, int? spTotal, int? spIndex, int? messageId}) { 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; } } // 开门数据解析 Future _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(); lockDetailState.animationController?.stop(); //锁数据更新 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? privateKey = await Storage.getStringList(saveBluePrivateKey); final List getPrivateKeyList = changeStringListToIntList(privateKey!); final List? signKey = await Storage.getStringList(saveBlueSignKey); final List signKeyDataList = changeStringListToIntList(signKey!); final List tokenData = reply.data.sublist(2, 6); final List 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 转换为十六进制字符串 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, ); } }