251 lines
8.6 KiB
Dart
251 lines
8.6 KiB
Dart
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,
|
||
);
|
||
}
|
||
}
|