C8;U^BKqGX-yf?mBJru_az(;j2ShOG++Kco%3_ZcnY^QTLn~u2)kk$-iq+G7v&bg(i8w@41*!I@4S==Www3!A
z@s~|%3#D2<%i;|IbgK50HUQQvajO7^q$6|K8&-XWJSy!4r44|qrbsm;PAGl)0hPsV
z#d@E1A+fB@lxkcO$Z3vhd{cXof@R%5Dar`Tj%Ic+Cxz!0HncM06^-?
zDq&KW6q4=XIZw^L)FeOz0O|=K$@Yi2ohQKx`319?(1rg|{oVh0e1ouoW@Kgug41mBA3`OQ<0QB)`6f1%}EY_M>3`HDW
z>J2akq1A>r_+S+A6@!
zKbN*rAw6qx%!*Wef_ew5t!^Ii25kVWxo4Kvd88mjy>>2g#(|0ZC#h8J?5ZjNysdMo
zNP~s0TG6Idbc)q)b+DCG5~gibs{$ZW&TO{1F;Nt{Q4K!>Ogy^Y%D@GHJq$qfqY3~P
zTPymvSyQiC#?&;cq@qouU}9s)MPg$JzCVbKAv+QKU7Zp2z9N#e{EZ=!?y?k@ywdTt&}GvNm6%B5LEHL;
ztzm7dmp9sL5CPTyw>KD
z;JiINwymoZ|6%RZ1IP3B@RnpN=zs{E)gS$iPi#tHJRcANFu5FOH;MxyKvZcbjh7Ut
z7+dZ5xLZbhM4>>IZ*30D#lLLx)A9f3<|o1`9Cjqonsi8|lP!
z)w2LX6Ez0_8-&6AbS&c3!<$(-+M)B<(Kgy?Uujq_0AN+HpnroAI%_@GfhTTF6WN1O7}44?s2jy%cpX)
z0DwUtg^F?eoNDb3OIf)Z<4Bxjn$7;n1^^H>VF`~WMvyqk)GW^52Dn)Pka7>beBm~P
z>f0t#x{g=6xqH(1vjc!Z5d3x??hQFckf>PB&V10f2mp-HJ&a`cKzDa{uV@LtEBzkM
z-U*$~J+v4>!q+eAgPBE0fC`;VxL}N6DDELkGt~6&G*?|tcdvK}Pz_MpUdH#;_x$xW
z?n2KcQoBVK!W1O|YLXxpBPiBAEZN-~j0C8GU{ERK#K)@4b`WnW!HSds)ua-8{;~#8
z>VzMHyEixqPhd%5CEt^Kum^z9lBgo$fc%s`+#FG0ALUlkwT7~7c{us
z#h?HH5adoFmr%*uXQdC)3y=n#%RMZml6Ud|V094sXw)@rEK6;MrvT`@6*Oec8mZo0oe#{68ByqXeWa7JKr@|G#&F}ZuAlmOMF65-h1
zDdbosZwX;&4M{L~2~ZIsVWf3VArCRN+XoP%0RVdjVhWk=w@%4Qr<}2eF{<6nqXGaJ
zv}ufB$f@1QO8{P>(Gx>sF@gm1i>c)8!{|{Pfz8RW^^UFR%|olJrZ_Vgq8x3mvyGH!
zdP2V*34|IY^D)=aseqbMDDFb;vVuyi834`%FRi;70Htxn
zc|0=!oC#i9cQXJ== 1.8.0)
+ - amap_flutter_location (0.0.1):
+ - AMapLocation
+ - Flutter
+ - amap_flutter_map (0.0.1):
+ - AMap3DMap
+ - Flutter
+ - AMapFoundation (1.8.2)
+ - AMapLocation (2.10.0):
+ - AMapFoundation (>= 1.8.0)
- device_info_plus (0.0.1):
- Flutter
- Flutter (1.0.0)
@@ -16,6 +27,8 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
+ - permission_handler_apple (9.1.1):
+ - Flutter
- Protobuf (3.23.4)
- reactive_ble_mobile (0.0.1):
- Flutter
@@ -31,6 +44,8 @@ PODS:
DEPENDENCIES:
- aj_captcha_flutter (from `.symlinks/plugins/aj_captcha_flutter/ios`)
+ - amap_flutter_location (from `.symlinks/plugins/amap_flutter_location/ios`)
+ - amap_flutter_map (from `.symlinks/plugins/amap_flutter_map/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`)
- flutter_native_contact_picker (from `.symlinks/plugins/flutter_native_contact_picker/ios`)
@@ -38,12 +53,16 @@ DEPENDENCIES:
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
+ - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- reactive_ble_mobile (from `.symlinks/plugins/reactive_ble_mobile/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
trunk:
+ - AMap3DMap
+ - AMapFoundation
+ - AMapLocation
- Protobuf
- SwiftProtobuf
- Toast
@@ -51,6 +70,10 @@ SPEC REPOS:
EXTERNAL SOURCES:
aj_captcha_flutter:
:path: ".symlinks/plugins/aj_captcha_flutter/ios"
+ amap_flutter_location:
+ :path: ".symlinks/plugins/amap_flutter_location/ios"
+ amap_flutter_map:
+ :path: ".symlinks/plugins/amap_flutter_map/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
Flutter:
@@ -65,6 +88,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
+ permission_handler_apple:
+ :path: ".symlinks/plugins/permission_handler_apple/ios"
reactive_ble_mobile:
:path: ".symlinks/plugins/reactive_ble_mobile/ios"
shared_preferences_foundation:
@@ -74,6 +99,11 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
aj_captcha_flutter: dd7af1aa064bdd621ae335b819bab07309c3c023
+ AMap3DMap: dce25dd3e51e6b92109caa7d0c97fc6055830fb3
+ amap_flutter_location: 44ff5beb64f42e0bf5feb402fe299dac0013af6f
+ amap_flutter_map: 979e54d227cedac6c7504a2151bfbf3bcf96760a
+ AMapFoundation: 9885c48fc3a78fdfb84a0299a2293e56ea3c9fec
+ AMapLocation: 5248aec2455ebb5d104b367813c946430a2ee033
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_native_contact_picker: bd430ba0fbf82768bb50c2c52a69a65759a8f907
@@ -81,6 +111,7 @@ SPEC CHECKSUMS:
image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
+ permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
Protobuf: c6bc59bbab3d38a71c67f62d7cb7ca8f8ea4eca1
reactive_ble_mobile: 9ce6723d37ccf701dbffd202d487f23f5de03b4c
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
diff --git a/star_lock/ios/Runner.xcodeproj/project.pbxproj b/star_lock/ios/Runner.xcodeproj/project.pbxproj
index 6fa290ed..f1877154 100644
--- a/star_lock/ios/Runner.xcodeproj/project.pbxproj
+++ b/star_lock/ios/Runner.xcodeproj/project.pbxproj
@@ -34,6 +34,7 @@
09D8B2FA2B26BA5BFF31AB2A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 33BF41252A96174D009D92E2 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
@@ -114,6 +115,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
+ 33BF41252A96174D009D92E2 /* Runner.entitlements */,
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
@@ -149,6 +151,7 @@
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ D9B107A6B141D5F15BC356F2 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -259,6 +262,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
+ D9B107A6B141D5F15BC356F2 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Copy Pods Resources";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -351,6 +371,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 7NLFRKNVY3;
ENABLE_BITCODE = NO;
@@ -478,6 +499,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 7NLFRKNVY3;
ENABLE_BITCODE = NO;
@@ -498,6 +520,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 7NLFRKNVY3;
ENABLE_BITCODE = NO;
diff --git a/star_lock/ios/Runner/Info.plist b/star_lock/ios/Runner/Info.plist
index 705a553a..c9c9e8bf 100644
--- a/star_lock/ios/Runner/Info.plist
+++ b/star_lock/ios/Runner/Info.plist
@@ -24,6 +24,11 @@
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
LSRequiresIPhoneOS
NSBluetoothAlwaysUsageDescription
@@ -38,6 +43,12 @@
用于音频插件
NSPhotoLibraryUsageDescription
用于相册
+ NSLocationWhenInUseUsageDescription
+ 应用在前台的时候可以搜到更新的位置信息
+ NSLocationAlwaysUsageDescription
+ 应用在后台的时候可以搜到更新的位置信息
+ NSLocationAlwaysAndWhenInUseUsageDescription
+ 应用在前台和后台的时候可以搜到更新的位置信息
UIApplicationSupportsIndirectInputEvents
UIBackgroundModes
diff --git a/star_lock/ios/Runner/Runner.entitlements b/star_lock/ios/Runner/Runner.entitlements
new file mode 100644
index 00000000..0c67376e
--- /dev/null
+++ b/star_lock/ios/Runner/Runner.entitlements
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/star_lock/lib/blue/blue_manage.dart b/star_lock/lib/blue/blue_manage.dart
index 1cd981c4..a8513887 100644
--- a/star_lock/lib/blue/blue_manage.dart
+++ b/star_lock/lib/blue/blue_manage.dart
@@ -95,6 +95,10 @@ class BlueManage{
print("connectDeviceId:$connectDeviceId connectDeviceName:$connectDeviceName");
EasyLoading.show();
+ Future.delayed(const Duration(seconds: 30), () { //asynchronous delay
+ print("30s之后 菊花没有隐藏的话,强制隐藏菊花");
+ EasyLoading.dismiss();
+ });
_flutterReactiveBle!.connectToDevice(id: connectDeviceId, connectionTimeout: const Duration(seconds: 15)).listen((connectionStateUpdate) async {
// 获取状态
deviceConnectionState = connectionStateUpdate.connectionState;
@@ -174,6 +178,10 @@ class BlueManage{
Future judgeReconnect(String deviceMAC, String deviceName, ConnectStateCallBack? connectStateCallBack) async {
if(deviceConnectionState == DeviceConnectionState.connected){
EasyLoading.show();
+ Future.delayed(const Duration(seconds: 30), () { //asynchronous delay
+ print("30s之后 菊花没有隐藏的话,强制隐藏菊花");
+ EasyLoading.dismiss();
+ });
connectStateCallBack!(deviceConnectionState!);
}else{
connect(deviceMAC, deviceName, connectStateCallBack: (state){
diff --git a/star_lock/lib/blue/io_protocol/io_factoryDataReset.dart b/star_lock/lib/blue/io_protocol/io_factoryDataReset.dart
new file mode 100644
index 00000000..9a219511
--- /dev/null
+++ b/star_lock/lib/blue/io_protocol/io_factoryDataReset.dart
@@ -0,0 +1,105 @@
+
+//TODO:添加用户
+import 'dart:convert';
+
+import '../../tools/storage.dart';
+import '../blue_manage.dart';
+import '../io_tool/io_manager.dart';
+import '../io_tool/io_tool.dart';
+import '../sender_manage.dart';
+import '../sm4Encipher/sm4.dart';
+import 'io_reply.dart';
+import 'io_sender.dart';
+import 'io_type.dart';
+import 'package:crypto/crypto.dart' as crypto;
+
+class FactoryDataResetCommand extends SenderProtocol {
+
+ String? lockID;
+ String? userID;
+ String? keyID;
+ List? publicKey;
+ List? privateKey;
+ List? token;
+ int? needAuthor;
+ FactoryDataResetCommand({
+ this.lockID,
+ this.userID,
+ this.keyID,
+ this.token,
+ this.needAuthor,
+ this.publicKey,
+ this.privateKey,
+ }) : super(CommandType.factoryDataReset);
+
+ @override
+ List messageDetail() {
+ List data = [];
+ List ebcData = [];
+
+ // 指令类型
+ int type = commandType!.typeValue;
+ double typeDouble = type / 256;
+ int type1 = typeDouble.toInt();
+ int type2 = type % 256;
+ data.add(type1);
+ data.add(type2);
+
+ // 锁id 40
+ int lockIDLength = utf8.encode(lockID!).length;
+ // print("${commandType!.typeValue}LockIDLength:$lockIDLength utf8.encode(lockID!)${utf8.encode(lockID!)}");
+ data.addAll(utf8.encode(lockID!));
+ data = getFixedLengthList(data, 40 - lockIDLength);
+
+ //userID 20
+ int userIDLength = utf8.encode(userID!).length;
+ // print("${commandType!.typeValue}IDLength:$authUserIDLength utf8.encode(authUserID!)${utf8.encode(authUserID!)}");
+ data.addAll(utf8.encode(userID!));
+ data = getFixedLengthList(data, 20 - userIDLength);
+
+ // token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 当token失效或者第一次发送的时候token为0
+ data.addAll(token!);
+ print("恢复出厂设置、pubToken:$token");
+
+ if(needAuthor == 0){
+ //AuthCodeLen 1
+ data.add(0);
+ } else {
+ List authCodeData = [];
+
+ //userID
+ authCodeData.addAll(utf8.encode(lockID!));
+
+ //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
+ authCodeData.addAll(token!);
+
+ authCodeData.addAll(publicKey!);
+
+ print("${commandType!.typeValue}-authCodeData:$authCodeData");
+
+ // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
+ var authCode = crypto.md5.convert(authCodeData);
+
+ data.add(authCode.bytes.length);
+ data.addAll(authCode.bytes);
+ }
+
+ if ((data.length % 16) != 0) {
+ int add = (16 - data.length % 16);
+ for (int i = 0; i < add; i++) {
+ data.add(0);
+ }
+ }
+ print("${commandType!.typeName} SM4Data:$data");
+ // 拿到数据之后通过LockId进行SM4 ECB加密 key:544d485f633335373034383064613864
+ ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
+ return ebcData;
+ }
+}
+
+class FactoryDataResetReply extends Reply {
+ FactoryDataResetReply.parseData(CommandType commandType, List dataDetail)
+ : super.parseData(commandType, dataDetail) {
+ data = dataDetail;
+ }
+}
\ No newline at end of file
diff --git a/star_lock/lib/blue/io_protocol/io_transferPermissions.dart b/star_lock/lib/blue/io_protocol/io_transferPermissions.dart
new file mode 100644
index 00000000..eae821fc
--- /dev/null
+++ b/star_lock/lib/blue/io_protocol/io_transferPermissions.dart
@@ -0,0 +1,125 @@
+
+import 'dart:convert';
+
+import '../io_tool/io_tool.dart';
+import '../sm4Encipher/sm4.dart';
+import 'io_reply.dart';
+import 'io_sender.dart';
+import 'io_type.dart';
+import 'package:crypto/crypto.dart' as crypto;
+
+//TODO:转移权限
+class TransferPermissionsCommand extends SenderProtocol {
+
+ String? lockID;
+ String? authUserID;
+ String? keyID;
+ String? oldUserID;
+ String? newUserID;
+ int? needAuthor;
+ List? publicKey;
+ List? privateKey;
+ List? token;
+ TransferPermissionsCommand({
+ this.lockID,
+ this.authUserID,
+ this.keyID,
+ this.oldUserID,
+ this.newUserID,
+ this.needAuthor,
+ this.publicKey,
+ this.privateKey,
+ this.token
+ }) : super(CommandType.transferPermissions);
+
+ @override
+ List messageDetail() {
+ List data = [];
+ List ebcData = [];
+
+ // 指令类型
+ int type = commandType!.typeValue;
+ double typeDouble = type / 256;
+ int type1 = typeDouble.toInt();
+ int type2 = type % 256;
+ data.add(type1);
+ data.add(type2);
+
+ // 锁id 40
+ int lockIDLength = utf8.encode(lockID!).length;
+ print("${commandType!.typeValue} lockID:$lockID LockIDLength:$lockIDLength utf8.encode(lockID!)${utf8.encode(lockID!)}");
+ data.addAll(utf8.encode(lockID!));
+ data = getFixedLengthList(data, 40 - lockIDLength);
+
+ //authUserID 20
+ int authUserIDLength = utf8.encode(authUserID!).length;
+ // print("${commandType!.typeValue}IDLength:$authUserIDLength utf8.encode(authUserID!)${utf8.encode(authUserID!)}");
+ data.addAll(utf8.encode(authUserID!));
+ data = getFixedLengthList(data, 20 - authUserIDLength);
+
+ //KeyID 40
+ int keyIDLength = utf8.encode(keyID!).length;
+ // print("${commandType!.typeValue}keyIDLength:$keyIDLength utf8.encode(keyID!)${utf8.encode(keyID!)}");
+ data.addAll(utf8.encode(keyID!));
+ data = getFixedLengthList(data, 40 - keyIDLength);
+
+ //oldUserID 20
+ int oldUserIDLength = utf8.encode(oldUserID!).length;
+ // print("${commandType!.typeValue}userIDLength:$userIDLength utf8.encode(userID!)${utf8.encode(userID!)}");
+ data.addAll(utf8.encode(oldUserID!));
+ data = getFixedLengthList(data, 20 - oldUserIDLength);
+
+ //newUserID 20
+ int newUserIDLength = utf8.encode(newUserID!).length;
+ // print("${commandType!.typeValue}userIDLength:$userIDLength utf8.encode(userID!)${utf8.encode(userID!)}");
+ data.addAll(utf8.encode(newUserID!));
+ data = getFixedLengthList(data, 20 - newUserIDLength);
+
+ // token 长度4 首次请求 Token 填 0,如果锁需要鉴权 操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。 当token失效或者第一次发送的时候token为0
+ data.addAll(token!);
+ print("pubToken:$token");
+
+ if(needAuthor == 0){
+ //AuthCodeLen 1
+ data.add(0);
+ } else {
+ List authCodeData = [];
+
+ //authUserID
+ authCodeData.addAll(utf8.encode(authUserID!));
+
+ //KeyID
+ authCodeData.addAll(utf8.encode(keyID!));
+
+ //token 4 首次请求 Token 填 0,如果锁需要鉴权操作者身份,则会分配动态口令并在应答消息中返回,二次请求时带上。
+ authCodeData.addAll(token!);
+
+ authCodeData.addAll(publicKey!);
+
+ print("${commandType!.typeValue}-authCodeData:$authCodeData");
+
+ // 把KeyID、authUserID、时间戳、公钥通过md5加密之后就是authCode
+ var authCode = crypto.md5.convert(authCodeData);
+
+ data.add(authCode.bytes.length);
+ data.addAll(authCode.bytes);
+ }
+
+ if ((data.length % 16) != 0) {
+ int add = (16 - data.length % 16);
+ for (int i = 0; i < add; i++) {
+ data.add(0);
+ }
+ }
+ print("${commandType!.typeName} SM4Data:$data");
+ ebcData = SM4.encrypt(data, key: privateKey, mode: SM4CryptoMode.ECB);
+ return ebcData;
+ }
+}
+
+class TransferPermissionsReply extends Reply {
+ TransferPermissionsReply.parseData(CommandType commandType, List dataDetail)
+ : super.parseData(commandType, dataDetail) {
+ data = dataDetail;
+ }
+}
\ No newline at end of file
diff --git a/star_lock/lib/blue/io_tool/io_manager.dart b/star_lock/lib/blue/io_tool/io_manager.dart
index bd200c3e..07a4e7d8 100644
--- a/star_lock/lib/blue/io_tool/io_manager.dart
+++ b/star_lock/lib/blue/io_tool/io_manager.dart
@@ -7,6 +7,8 @@ const saveBluePublicKey = "BluePublicKey";
const saveBluePrivateKey = "BluePrivateKey";
const saveBlueSignKey = "BlueSignKey";
const saveBlueToken = "BlueGetToken";
+const currentConnectionLockId = "CurrentConnectionLockId";
+const currentConnectionMacAddress = "CurrentConnectionMacAddress";
class IoManager {
diff --git a/star_lock/lib/blue/reciver_data.dart b/star_lock/lib/blue/reciver_data.dart
index 5b0de909..5814d185 100644
--- a/star_lock/lib/blue/reciver_data.dart
+++ b/star_lock/lib/blue/reciver_data.dart
@@ -6,7 +6,9 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:star_lock/blue/blue_manage.dart';
import 'package:star_lock/blue/io_protocol/io_deletUser.dart';
import 'package:star_lock/blue/io_protocol/io_editUser.dart';
+import 'package:star_lock/blue/io_protocol/io_factoryDataReset.dart';
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
+import 'package:star_lock/blue/io_protocol/io_transferPermissions.dart';
import '../tools/storage.dart';
import 'io_protocol/io_addUser.dart';
@@ -73,10 +75,9 @@ class CommandReciverManager {
// print("getPrivateKeyList$getPrivateKeyList");
// 解密
- // String key = SM4.createHexKey(key: radixHex16String(getPrivateKeyList!));
oriDataList = SM4.decrypt(getDataList, key: getPrivateKeyList, mode: SM4CryptoMode.ECB);
oriDataList = oriDataList.sublist(0, oriLen);
- // print("SM4 oriDataList:$oriDataList");
+ print("SM4 oriDataList:$oriDataList");
break;
}
@@ -132,6 +133,16 @@ class CommandReciverManager {
reply = EditUserReply.parseData(commandType, data);
}
break;
+ case CommandType.transferPermissions:
+ {
+ reply = TransferPermissionsReply.parseData(commandType, data);
+ }
+ break;
+ case CommandType.factoryDataReset:
+ {
+ reply = FactoryDataResetReply.parseData(commandType, data);
+ }
+ break;
}
return reply;
}
diff --git a/star_lock/lib/blue/sender_manage.dart b/star_lock/lib/blue/sender_manage.dart
index ff2c89be..9a471bdc 100644
--- a/star_lock/lib/blue/sender_manage.dart
+++ b/star_lock/lib/blue/sender_manage.dart
@@ -4,9 +4,11 @@ import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
import 'io_protocol/io_addUser.dart';
import 'io_protocol/io_editUser.dart';
+import 'io_protocol/io_factoryDataReset.dart';
import 'io_protocol/io_getPrivateKey.dart';
import 'io_protocol/io_getPublicKey.dart';
import 'io_protocol/io_openLock.dart';
+import 'io_protocol/io_transferPermissions.dart';
import 'sender_data.dart';
class IoSenderManage {
@@ -170,4 +172,53 @@ class IoSenderManage {
privateKey: privateKey,
), callBack:callBack);
}
+
+ //todo:转移权限
+ static void senderTransferPermissions({
+ String? lockID,
+ String? authUserID,
+ String? keyID,
+ String? oldUserID,
+ String? newUserID,
+ int? needAuthor,
+ List? publicKey,
+ List? privateKey,
+ List? token,
+ CommandSendCallBack? callBack}) {
+ CommandSenderManager().managerSendData(
+ command: TransferPermissionsCommand(
+ lockID: lockID,
+ authUserID: authUserID,
+ keyID: keyID,
+ oldUserID: oldUserID,
+ newUserID: newUserID,
+ needAuthor: needAuthor,
+ publicKey: publicKey,
+ privateKey: privateKey,
+ token: token
+ ), callBack:callBack);
+ }
+
+ //todo:恢复出厂设置
+ static void senderFactoryDataReset({
+ String? lockID,
+ String? userID,
+ String? keyID,
+ List? publicKey,
+ List? privateKey,
+ List? token,
+ int? needAuthor,
+ CommandSendCallBack? callBack}) {
+ CommandSenderManager().managerSendData(
+ command: FactoryDataResetCommand(
+ lockID: lockID,
+ userID: userID,
+ keyID: keyID,
+ needAuthor: needAuthor,
+ publicKey: publicKey,
+ privateKey: privateKey,
+ token: token
+ ), callBack:callBack);
+ }
+
}
\ No newline at end of file
diff --git a/star_lock/lib/main.dart b/star_lock/lib/main.dart
index 76da243e..a220b85f 100644
--- a/star_lock/lib/main.dart
+++ b/star_lock/lib/main.dart
@@ -31,7 +31,11 @@ class MyApp extends StatefulWidget {
State createState() => _MyAppState();
}
+// 注册 RouteObserver 作为 navigation observer.
+final RouteObserver routeObserver = RouteObserver();
+
class _MyAppState extends State with WidgetsBindingObserver, BaseWidget {
+
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
@@ -41,6 +45,7 @@ class _MyAppState extends State with WidgetsBindingObserver, BaseWidget {
GetMaterialApp _initMaterialApp() => GetMaterialApp(
title: 'Star Lock',
+ navigatorObservers: [routeObserver],
translations: TranslationMessage(),
supportedLocales: appDept.deptSupportedLocales,
localizationsDelegates: const [
@@ -134,4 +139,4 @@ Future _setCommonServices() async {
await Get.putAsync(() => PlatformInfoService().init());
await Get.putAsync(() => DeviceInfoService().init());
Get.log(PlatformInfoService.to.info.version);
-}
+}
\ No newline at end of file
diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart
index 43f9c6b0..27a97f78 100644
--- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart
+++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_logic.dart
@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:star_lock/blue/io_protocol/io_editUser.dart';
+import 'package:star_lock/blue/io_protocol/io_factoryDataReset.dart';
import 'package:star_lock/blue/io_protocol/io_getLockStatu.dart';
import 'package:star_lock/blue/io_protocol/io_type.dart';
@@ -10,7 +11,6 @@ import '../../../blue/blue_manage.dart';
import '../../../blue/io_protocol/io_openLock.dart';
import '../../../blue/io_protocol/io_reply.dart';
import '../../../blue/io_tool/io_manager.dart';
-import '../../../blue/io_tool/io_model.dart';
import '../../../blue/io_tool/io_tool.dart';
import '../../../blue/io_tool/manager_event_bus.dart';
import '../../../blue/sender_manage.dart';
@@ -21,9 +21,11 @@ import 'lockDetail_state.dart';
class LockDetailLogic extends BaseGetXController{
final LockDetailState state = LockDetailState();
+ // 监听设备返回的数据
late StreamSubscription _replySubscription;
void _initReplySubscription() {
_replySubscription = EventBusManager().eventBus!.on().listen((reply) async {
+ // 开门
if(reply is OpenDoorReply) {
_replyOpenLock(reply);
}
@@ -37,9 +39,15 @@ class LockDetailLogic extends BaseGetXController{
if(reply is EditUserReply){
_replyEditUserKey(reply);
}
+
+ // 恢复出厂设置
+ if(reply is FactoryDataResetReply){
+ _replyFactoryDataResetKey(reply);
+ }
});
}
+ // 开门数据解析
Future _replyOpenLock(Reply reply) async {
var privateKey = await Storage.getStringList(saveBluePrivateKey);
List getPrivateKeyList = changeStringListToIntList(privateKey!);
@@ -97,6 +105,7 @@ class LockDetailLogic extends BaseGetXController{
}
}
+ // 获取锁状态数据解析
Future _replyGetLockStatus(Reply reply) async {
int status = reply.data[2];
switch(status){
@@ -169,6 +178,7 @@ class LockDetailLogic extends BaseGetXController{
}
}
+ // 编辑用户数据解析
Future _replyEditUserKey(Reply reply) async {
var token = reply.data.sublist(2, 6);
var saveStrList = changeIntListToStringList(token);
@@ -217,7 +227,7 @@ class LockDetailLogic extends BaseGetXController{
break;
case 0x09:
// 权限校验错误
- print("${reply.commandType!.typeValue} 添加用户权限校验错误");
+ print("${reply.commandType!.typeValue} 权限校验错误");
break;
default:
@@ -228,6 +238,63 @@ class LockDetailLogic extends BaseGetXController{
}
}
+ // 恢复出厂设置数据解析
+ Future _replyFactoryDataResetKey(Reply reply) async {
+ var token = reply.data.sublist(2, 6);
+ var saveStrList = changeIntListToStringList(token);
+ print("_replyFactoryDataResetKeyToken:$token");
+ Storage.setStringList(saveBlueToken, saveStrList);
+
+ int status = reply.data[6];
+ print("status:$status");
+
+ switch(status){
+ case 0x00:
+ //成功
+ print("${reply.commandType!.typeValue} 数据解析成功");
+
+ break;
+ case 0x06:
+ //无权限
+ print("${reply.commandType!.typeValue} 需要鉴权");
+ var privateKey = await Storage.getStringList(saveBluePrivateKey);
+ List getPrivateKeyList = changeStringListToIntList(privateKey!);
+
+ var publicKey = await Storage.getStringList(saveBluePublicKey);
+ List publicKeyDataList = changeStringListToIntList(publicKey!);
+
+ var token = await Storage.getStringList(saveBlueToken);
+ List getTokenList = changeStringListToIntList(token!);
+
+ IoSenderManage.senderFactoryDataReset(
+ lockID:BlueManage().connectDeviceName,
+ userID:"100001",
+ keyID:"1",
+ needAuthor:1,
+ publicKey:publicKeyDataList,
+ privateKey:getPrivateKeyList,
+ token: getTokenList
+ );
+ break;
+ case 0x07:
+ //无权限
+ print("${reply.commandType!.typeValue} 用户无权限");
+
+ break;
+ case 0x09:
+ // 权限校验错误
+ print("${reply.commandType!.typeValue} 权限校验错误");
+
+ break;
+ default:
+ //失败
+ print("${reply.commandType!.typeValue} 失败");
+
+ break;
+ }
+ }
+
+ // 点击开门事件
Future openDoorAction() async {
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected){
@@ -255,6 +322,7 @@ class LockDetailLogic extends BaseGetXController{
});
}
+ // 编辑用户事件
Future editLockUserAction() async {
BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
if (state == DeviceConnectionState.connected){
@@ -289,19 +357,75 @@ class LockDetailLogic extends BaseGetXController{
});
}
+ // 转移权限
+ Future transferPermissionsAction() async {
+ BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
+ if (state == DeviceConnectionState.connected){
+ var privateKey = await Storage.getStringList(saveBluePrivateKey);
+ List getPrivateKeyList = changeStringListToIntList(privateKey!);
+
+ var publicKey = await Storage.getStringList(saveBluePublicKey);
+ List publicKeyDataList = changeStringListToIntList(publicKey!);
+
+ var token = await Storage.getStringList(saveBlueToken);
+ List getTokenList = changeStringListToIntList(token!);
+ print("openDoorTokenPubToken:$getTokenList");
+
+ IoSenderManage.senderTransferPermissions(
+ lockID:BlueManage().connectDeviceName,
+ authUserID:"100001",
+ keyID:"1",
+ oldUserID:"100001",
+ newUserID:"100002",
+ needAuthor:1,
+ publicKey:publicKeyDataList,
+ privateKey:getPrivateKeyList,
+ token: getTokenList
+ );
+ }
+ });
+ }
+
+ // 恢复出厂设置
+ Future factoryDataResetAction() async {
+ BlueManage().judgeReconnect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", (DeviceConnectionState state) async {
+ if (state == DeviceConnectionState.connected){
+ var privateKey = await Storage.getStringList(saveBluePrivateKey);
+ List getPrivateKeyList = changeStringListToIntList(privateKey!);
+
+ var publicKey = await Storage.getStringList(saveBluePublicKey);
+ List publicKeyDataList = changeStringListToIntList(publicKey!);
+
+ var token = await Storage.getStringList(saveBlueToken);
+ List getTokenList = changeStringListToIntList(token!);
+
+ IoSenderManage.senderFactoryDataReset(
+ lockID:BlueManage().connectDeviceName,
+ userID:"100001",
+ keyID:"1",
+ needAuthor:1,
+ publicKey:publicKeyDataList,
+ privateKey:getPrivateKeyList,
+ token: getTokenList
+ );
+ }
+ });
+ }
+
+ // 备用逻辑,进入管理钥匙界面默认连接
Future connectBlue() async {
// 进来之后首先连接
- // BlueManage().connect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", connectStateCallBack: (DeviceConnectionState state) async {
- // if (state == DeviceConnectionState.connected){
- // var privateKey = await Storage.getStringList(saveBluePrivateKey);
- // List getPrivateKeyList = changeStringListToIntList(privateKey!);
- // IoSenderManage.senderGetLockStatu(
- // lockID:BlueManage().connectDeviceName,
- // userID:"100001",
- // privateKey:getPrivateKeyList,
- // );
- // }
- // });
+ BlueManage().connect("AD01447A-30B5-A780-E778-DED3BDCB613E", "TMH_c3570480da8d", connectStateCallBack: (DeviceConnectionState state) async {
+ if (state == DeviceConnectionState.connected){
+ var privateKey = await Storage.getStringList(saveBluePrivateKey);
+ List getPrivateKeyList = changeStringListToIntList(privateKey!);
+ IoSenderManage.senderGetLockStatu(
+ lockID:BlueManage().connectDeviceName,
+ userID:"100001",
+ privateKey:getPrivateKeyList,
+ );
+ }
+ });
}
@override
@@ -310,6 +434,10 @@ class LockDetailLogic extends BaseGetXController{
super.onReady();
print("onReady()");
_initReplySubscription();
+
+ BlueManage().startScan((v){
+
+ });
}
@override
@@ -318,8 +446,11 @@ class LockDetailLogic extends BaseGetXController{
super.onInit();
print("onInit()");
+ BlueManage().connectDeviceName = "TMH_c3570480da8d";
+ BlueManage().connectDeviceId = "AD01447A-30B5-A780-E778-DED3BDCB613E";
+
// 进来第一步开始扫描
- connectBlue();
+ // connectBlue();
}
@override
diff --git a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart
index d09d89f0..368942ae 100644
--- a/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart
+++ b/star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart
@@ -4,6 +4,8 @@ import 'package:get/get.dart';
import '../../../appRouters.dart';
import '../../../app_settings/app_colors.dart';
+import '../../../blue/io_tool/io_manager.dart';
+import '../../../tools/storage.dart';
import '../../../tools/titleAppBar.dart';
import '../../../translations/trans_lib.dart';
import 'lockDetail_logic.dart';
@@ -21,6 +23,7 @@ class _LockDetailPageState extends State {
@override
Widget build(BuildContext context) {
+
return Scaffold(
backgroundColor: Colors.white,
appBar: TitleAppBar(
@@ -76,8 +79,10 @@ class _LockDetailPageState extends State {
Center(
child: GestureDetector(
onTap: (){
+ // logic.transferPermissionsAction();
// logic.openDoorAction();
- logic.editLockUserAction();
+ // logic.editLockUserAction();
+ logic.factoryDataResetAction();
},
child: Image.asset('images/main/icon_main_openLockBtn.png',
width: 268.w, height: 268.w),
diff --git a/star_lock/lib/main/lockMian/lockMain_binding.dart b/star_lock/lib/main/lockMian/lockMain_binding.dart
index 8634e968..512fc14c 100644
--- a/star_lock/lib/main/lockMian/lockMain_binding.dart
+++ b/star_lock/lib/main/lockMian/lockMain_binding.dart
@@ -1,6 +1,5 @@
import 'package:get/get.dart';
-
import 'lockMain_logic.dart';
class LockMainBinding extends Bindings {
diff --git a/star_lock/lib/mine/addLock/lockAddress/lockAddressGaoDe_page.dart b/star_lock/lib/mine/addLock/lockAddress/lockAddressGaoDe_page.dart
new file mode 100644
index 00000000..7a4cdbcf
--- /dev/null
+++ b/star_lock/lib/mine/addLock/lockAddress/lockAddressGaoDe_page.dart
@@ -0,0 +1,319 @@
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:amap_flutter_location/amap_flutter_location.dart';
+import 'package:amap_flutter_location/amap_location_option.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:permission_handler/permission_handler.dart';
+import 'package:amap_flutter_map/amap_flutter_map.dart';
+import 'package:amap_flutter_base/amap_flutter_base.dart';
+
+import '../../../app_settings/app_colors.dart';
+import '../../../main.dart';
+
+class LockAddressGaoDePage extends StatefulWidget {
+ const LockAddressGaoDePage({Key? key}) : super(key: key);
+
+ @override
+ State createState() => _LockAddressGaoDePageState();
+}
+
+class _LockAddressGaoDePageState extends State{
+ // 高德地图
+ Map? _locationResult;
+ StreamSubscription