app-starlock/lib/talk/startChart/handle/impl/udp_ble_passthrough_handler.dart

251 lines
8.6 KiB
Dart
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: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<LockDetailLogic>().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<Reply>().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<int> 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<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();
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<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,
);
}
}