Browse Source

废弃 ota plugin,OTA 升级全部走 device_jieli

- ota plugin 用的是 JL_OTALib v1.0 旧版静态库,跟 device_jieli 引入的
  v2.4.1 xcframework ABI 不兼容,且 framework 同名导致 CocoaPods 在
  build phase 双拷贝 → "Multiple commands produce" 错误
- 把 lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart
  迁到 device_jieli 的 OTA API(otaStart/otaCancel + OtaStateEvent /
  OtaErrorEvent),事件 schema 重新映射到 OtaCoreService 状态码
- pubspec.yaml 移除 ota 依赖,整个 local_plugins/ota/ 目录将在下一个
  commit 删除
- device_jieli.podspec 重新加回 JL_OTALib / JL_AdvParse / JL_HashPair /
  JLLogHelper(之前为避免与 ota plugin 冲突而删了 vendor,现在 ota 废
  弃后由 device_jieli 独家提供,与 ble_service 提供的 JLAudioUnitKit
  共存且不冲突)
- device_plugin_interface.podspec 修掉空 LICENSE 引用警告

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
weicu
liwei1dao 5 months ago
parent
commit
ed2ef5a8fd
  1. 108
      lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart
  2. 14
      local_plugins/device_jieli/ios/device_jieli.podspec
  3. 2
      local_plugins/device_plugin_interface/ios/device_plugin_interface.podspec
  4. 33
      local_plugins/ota/.gitignore
  5. 33
      local_plugins/ota/.metadata
  6. 3
      local_plugins/ota/CHANGELOG.md
  7. 1
      local_plugins/ota/LICENSE
  8. 15
      local_plugins/ota/README.md
  9. 4
      local_plugins/ota/analysis_options.yaml
  10. 9
      local_plugins/ota/android/.gitignore
  11. 68
      local_plugins/ota/android/build.gradle
  12. BIN
      local_plugins/ota/android/libs/jl_bt_ota_V1.11.0_11015-release.aar
  13. 1
      local_plugins/ota/android/settings.gradle
  14. 4
      local_plugins/ota/android/src/main/AndroidManifest.xml
  15. 415
      local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt
  16. 91
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BTEventCbHelper.kt
  17. 204
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BluetoothHelper.kt
  18. 12
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackImpl.kt
  19. 23
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackRunnable.kt
  20. 38
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OnBTEventCallback.kt
  21. 54
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OtaConstant.kt
  22. 187
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/config/ConfigHelper.kt
  23. 172
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/OTAManager.kt
  24. 175
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleEventCallbackManager.java
  25. 1197
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleManager.java
  26. 295
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/SendBleDataThread.java
  27. 68
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/BleEventCallback.java
  28. 108
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleEventCallback.java
  29. 16
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleOp.java
  30. 14
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnThreadStateListener.java
  31. 25
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnWriteDataCallback.java
  32. 155
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleDevice.java
  33. 99
      local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleScanInfo.java
  34. 38
      local_plugins/ota/ios/.gitignore
  35. 0
      local_plugins/ota/ios/Assets/.gitkeep
  36. 22
      local_plugins/ota/ios/Classes/BleManager/HandleBroadcastPtl.h
  37. 53
      local_plugins/ota/ios/Classes/BleManager/HandleBroadcastPtl.m
  38. 27
      local_plugins/ota/ios/Classes/BleManager/JLBleEntity.h
  39. 25
      local_plugins/ota/ios/Classes/BleManager/JLBleEntity.m
  40. 122
      local_plugins/ota/ios/Classes/BleManager/JLBleManager.h
  41. 601
      local_plugins/ota/ios/Classes/BleManager/JLBleManager.m
  42. 60
      local_plugins/ota/ios/Classes/OtaPlugin.swift
  43. BIN
      local_plugins/ota/ios/Frameworks/DFUnits.framework/DFUnits
  44. 28
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/AESx.h
  45. 82
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFAction.h
  46. 173
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFAudio.h
  47. 123
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFCircleTextView.h
  48. 39
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFContacts.h
  49. 33
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFCrc16.h
  50. 32
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFFadeLabel.h
  51. 125
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFFile.h
  52. 25
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFGzip.h
  53. 24
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFHmacMD5.h
  54. 70
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFHttp.h
  55. 29
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFHttp1.h
  56. 57
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFImage.h
  57. 534
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFLabel.h
  58. 51
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFNetPlayer.h
  59. 56
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFNotice.h
  60. 312
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFPing.h
  61. 52
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFRing.h
  62. 32
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFSort.h
  63. 115
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFTime.h
  64. 496
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFTips.h
  65. 161
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFTools.h
  66. 21
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUIAnimation.h
  67. 46
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUIPullView.h
  68. 215
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUITools.h
  69. 51
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUnits.h
  70. 38
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFVideo.h
  71. 59
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/OPenALM.h
  72. 224
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/TPCircularBuffer.h
  73. 317
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/queue.h
  74. 97
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/queue_internal.h
  75. 26
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/tcp_client.h
  76. 29
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/tcp_server.h
  77. BIN
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Info.plist
  78. 6
      local_plugins/ota/ios/Frameworks/DFUnits.framework/Modules/module.modulemap
  79. 19
      local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Headers/JLLogHelper.h
  80. 75
      local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Headers/JLLogManager.h
  81. BIN
      local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Info.plist
  82. BIN
      local_plugins/ota/ios/Frameworks/JLLogHelper.framework/JLLogHelper
  83. 6
      local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Modules/module.modulemap
  84. BIN
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Frameworks/JLLogHelper.framework/Info.plist
  85. BIN
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Frameworks/JLLogHelper.framework/JLLogHelper
  86. 67
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLAdvParse.h
  87. 64
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLChargingBoxAdv.h
  88. 54
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLDevicesAdv.h
  89. 47
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLEarphoneAdv.h
  90. 25
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLOtaAdv.h
  91. 19
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLSoundBoxAdv.h
  92. 19
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLSoundCardAdv.h
  93. 70
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLTwsAdv.h
  94. 35
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLWatchAdv.h
  95. 27
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JL_AdvParse.h
  96. BIN
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Info.plist
  97. BIN
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/JL_AdvParse
  98. 6
      local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Modules/module.modulemap
  99. BIN
      local_plugins/ota/ios/Frameworks/JL_HashPair.framework/Frameworks/JLLogHelper.framework/Info.plist
  100. BIN
      local_plugins/ota/ios/Frameworks/JL_HashPair.framework/Frameworks/JLLogHelper.framework/JLLogHelper

108
lib/modules/ota_upgrade/controllers/ota_upgrade_controller.dart

@ -1,9 +1,11 @@
import 'dart:async';
import 'package:classic_bluetooth/classic_bluetooth.dart';
import 'package:device_jieli/device_jieli.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
// import 'package:logger/web.dart';
import 'package:get_storage/get_storage.dart';
import 'package:ota/ota.dart';
import '../../../data/services/ble_manager.dart';
import 'ota_core_contropller.dart';
import 'ota_download_contropller.dart';
@ -18,7 +20,8 @@ class OtaUpgradeController extends GetxController {
final _downloadService = OtaDownloadService();
final _uiService = OtaUpgradePopUp();
final _bleManager = Get.find<BleManager>();
final _jlota = Ota.instance;
final _jlota = Jielihome.instance;
StreamSubscription<JieliEvent>? _otaEventSub;
// 状态管理
final RxString errorMessage = ''.obs;
@ -52,7 +55,9 @@ class OtaUpgradeController extends GetxController {
@override
void onClose() {
_jlota.onOtaClose();
_jlota.otaCancel();
_otaEventSub?.cancel();
_otaEventSub = null;
_bleManager.setEnterOta(false);
isUpgrade.value = false;
super.onClose();
@ -160,7 +165,8 @@ class OtaUpgradeController extends GetxController {
try {
await _bleManager.setEnterOta(true);
await Future.delayed(const Duration(seconds: 2));
_jlota.init();
// device_jieli 已经在全局 InitialBinding 里 initialize 过;
// 这里无需重复 init —— 直接订阅 OTA 事件流即可。
isDownloading.value = true;
showDetailedStatus.value = true;
@ -194,13 +200,13 @@ class OtaUpgradeController extends GetxController {
detailedStatus.value = 'otaPreparingConnection'.tr;
await Future.delayed(const Duration(milliseconds: 500));
detailedStatus.value = 'otaConnectingDevice'.tr;
_jlota.startUpgrading(address: _address, filePath: filePath);
_jlota.otaStart(address: _address, firmwareFilePath: filePath);
}
/// 停止升级
/// 关闭OTA连接
void stopUpgrading() {
_jlota.onOtaClose();
_jlota.otaCancel();
}
/// 重试连接
@ -218,44 +224,70 @@ class OtaUpgradeController extends GetxController {
}
/// 监听OTA事件
/// 设置OTA事件流的监听器
/// 订阅 device_jieli 的统一事件流,过滤 OTA 相关事件并转发到分发器。
void _listenToOtaEvents() {
_jlota.eventStream.listen((event) {
_handleOtaEvent(event);
});
_otaEventSub?.cancel();
_otaEventSub = _jlota.events.listen(_handleOtaEvent);
}
/// 处理OTA事件
/// [event] OTA事件对象
/// 根据不同的事件类型执行相应的处理逻辑
void _handleOtaEvent(dynamic event) {
switch (event.event) {
case 'onProgress':
if (event.type != null && event.progress != null) {
progress.value = event.progress!;
type.value = event.type!;
/// 处理 device_jieli 抛出的 OTA / 连接事件。
/// - [OtaStateEvent]: 进度 / 状态机推进
/// - [OtaErrorEvent]: 升级失败
/// - [ConnectionStateEvent]: 设备连接 / 断开(OTA 期间用于"中断"指示)
void _handleOtaEvent(JieliEvent event) {
if (event is OtaStateEvent) {
switch (event.state) {
case OtaState.entering:
case OtaState.inquiring:
case OtaState.notifyingSize:
type.value = OtaCoreService.START_UPGRADING;
isUpgrade.value = true;
detailedStatus.value = 'otaUpgradeStarted'.tr;
break;
case OtaState.transferring:
if (event.percent >= 0) {
// device_jieli 发的是 0..100 整数;UI 这边按 0..1 浮点用。
progress.value = event.percent / 100.0;
type.value = OtaCoreService.ONUPGRADE;
isUpgrade.value = true;
detailedStatus.value = 'otaUpgradeProgressWithPercent'
.trParams({'percent': event.percent.toStringAsFixed(1)});
}
break;
case OtaState.verifying:
detailedStatus.value = 'otaUpgradeStarted'.tr;
break;
case OtaState.rebooting:
// 设备重启等待,仍在升级中
isUpgrade.value = true;
detailedStatus.value =
'otaUpgradeProgressWithPercent'.trParams({'percent': (event.progress! * 100).toStringAsFixed(1)});
}
break;
case 'onStartOTA':
type.value = OtaCoreService.START_UPGRADING;
isUpgrade.value = true;
detailedStatus.value = 'otaUpgradeStarted'.tr;
break;
case 'onStopOTA':
_handleUpgradeSuccess();
break;
case 'onError':
_handleUpgradeError(event.code);
break;
case 'NOCONNECTION':
break;
case OtaState.done:
_handleUpgradeSuccess();
break;
case OtaState.failed:
_handleUpgradeError(-1);
break;
case OtaState.cancelled:
isUpgrade.value = false;
showDetailedStatus.value = false;
break;
case OtaState.idle:
break;
}
return;
}
if (event is OtaErrorEvent) {
_handleUpgradeError(event.code);
return;
}
if (event is ConnectionStateEvent) {
if (event.state == ConnectionStateEvent.connectionDisconnect &&
isUpgrade.value) {
_handleConnectionLost();
break;
case 'CONNECTION_SUCCESS':
} else if (event.state == ConnectionStateEvent.connectionOk &&
isUpgrade.value) {
_handleConnectionSuccess();
break;
}
}
}

14
local_plugins/device_jieli/ios/device_jieli.podspec

@ -16,14 +16,16 @@ android/src/main/kotlin/com/jielihome/jielihome.
s.platform = :ios, '12.0'
s.swift_version = '5.0'
# 只 vendor 本插件独家依赖。其他 framework 由 sibling 插件已经引入:
# - JL_OTALib / JL_AdvParse / JL_HashPair / JLLogHelper —— `ota` 插件
# 的 vendored_frameworks 已提供(local_plugins/ota/ios/Frameworks/)
# - JLAudioUnitKit —— `ble_service` 的 SPM binary target 已提供
# 重复 vendor 同名 framework 会触发 Xcode "Multiple commands produce ..."
# 报错(两个 build phase 各拷一份到 Runner.app/Frameworks/)。
# `ota` plugin 已废弃,OTA 全部走本插件。Vendor 完整的 JieLi SDK
# framework 集合(来自 JIELI-Release 同一套,版本一致,避免 ABI 漂移)。
# JLAudioUnitKit 不在此列表 —— `ble_service` 的 SPM binary target 已提供,
# 同名 vendor 会触发 Xcode "Multiple commands produce ..." 错误。
s.vendored_frameworks = [
'Frameworks/JL_BLEKit.xcframework',
'Frameworks/JL_OTALib.xcframework',
'Frameworks/JL_AdvParse.xcframework',
'Frameworks/JL_HashPair.xcframework',
'Frameworks/JLLogHelper.xcframework',
'Frameworks/JLAV2Lib.framework'
]

2
local_plugins/device_plugin_interface/ios/device_plugin_interface.podspec

@ -8,7 +8,7 @@ The Dart layer holds the actual abstract contracts; vendor plugins (e.g. device_
implement them in their own native code and depend on this package only at the Flutter level.
DESC
s.homepage = 'https://example.com'
s.license = { :type => 'MIT', :file => '../LICENSE' }
s.license = { :type => 'MIT' }
s.author = { 'AI Agent' => 'liwei1dao@gmail.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*.{h,m,swift}'

33
local_plugins/ota/.gitignore

@ -1,33 +0,0 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
build/

33
local_plugins/ota/.metadata

@ -1,33 +0,0 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "ea121f8859e4b13e47a8f845e4586164519588bc"
channel: "stable"
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
- platform: android
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
- platform: ios
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

3
local_plugins/ota/CHANGELOG.md

@ -1,3 +0,0 @@
## 0.0.1
* TODO: Describe initial release.

1
local_plugins/ota/LICENSE

@ -1 +0,0 @@
TODO: Add your license here.

15
local_plugins/ota/README.md

@ -1,15 +0,0 @@
# ota
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/to/develop-plugins),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

4
local_plugins/ota/analysis_options.yaml

@ -1,4 +0,0 @@
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

9
local_plugins/ota/android/.gitignore

@ -1,9 +0,0 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.cxx

68
local_plugins/ota/android/build.gradle

@ -1,68 +0,0 @@
group = "com.example.ota"
version = "1.0-SNAPSHOT"
buildscript {
ext.kotlin_version = "1.8.22"
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.7.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
android {
namespace = "com.example.ota"
compileSdk = 35
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
}
sourceSets {
main.java.srcDirs += "src/main/kotlin"
test.java.srcDirs += "src/test/kotlin"
}
defaultConfig {
minSdk = 21
}
dependencies {
implementation("com.jieli.jl_bt_ota:jl_bt_ota:1.11.0")
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.mockito:mockito-core:5.0.0")
add("compileOnly", project(":ble_service"))
}
testOptions {
unitTests.all {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}

BIN
local_plugins/ota/android/libs/jl_bt_ota_V1.11.0_11015-release.aar

Binary file not shown.

1
local_plugins/ota/android/settings.gradle

@ -1 +0,0 @@
rootProject.name = 'ota'

4
local_plugins/ota/android/src/main/AndroidManifest.xml

@ -1,4 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ota">
</manifest>

415
local_plugins/ota/android/src/main/kotlin/com/example/ota/OtaPlugin.kt

@ -1,415 +0,0 @@
package com.example.ota
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import android.bluetooth.BluetoothDevice
import android.content.Context
import com.jieli.otasdk.tool.ota.OTAManager
import com.jieli.jl_bt_ota.constant.StateCode
import com.jieli.jl_bt_ota.interfaces.BtEventCallback
import com.jieli.jl_bt_ota.interfaces.IUpgradeCallback
import com.jieli.jl_bt_ota.model.base.BaseError
import com.jieli.otasdk.tool.bluetooth.BluetoothHelper
import android.util.Log
import com.jieli.otasdk.tool.config.ConfigHelper
import com.yunqiinnovation.ble_service.BleService
import com.yunqiinnovation.ble_service.BleConst
import android.os.Handler
import android.os.Looper
import io.flutter.plugin.common.EventChannel
class CustomUpdateCallback(
val device: BluetoothDevice?,
private val streamSink: EventChannel.EventSink?
) : IUpgradeCallback {
companion object {
private const val TAG = "JlOtaPlugin"
private const val CHANNEL_NAME = "com.example.ota"
private const val EVENT_CHANNEL_NAME = "com.example.ota/events"
}
override fun onStartOTA() {
Log.d(TAG, "onStartOTA开始升级")
if (streamSink != null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
streamSink.success(
mapOf(
"event" to "onStartOTA"
)
)
}
}
}
override fun onNeedReconnect(addr: String?, isNewReconnectWay: Boolean) {
Log.d(TAG, "onNeedReconnect需要重新链接")
if (streamSink != null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
streamSink.success(
mapOf(
"event" to "onNeedReconnect",
"addr" to addr,
"isNewReconnectWay" to isNewReconnectWay
)
)
}
}
}
override fun onProgress(type: Int, progress: Float) {
Log.d(TAG, "onProgress正在进展")
if (streamSink != null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
streamSink.success(
mapOf(
"event" to "onProgress",
"type" to type,
"progress" to progress
)
)
} else {
// Handler(Looper.getMainLooper()).post {
// streamSink.success(
// mapOf(
// "event" to "onDecodeStream"
// //"data" to data
// )
// )
// }
}
}
}
override fun onStopOTA() {
Log.d(TAG, "onStartOTA停止升级")
if (streamSink != null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
streamSink.success(
mapOf(
"event" to "onStopOTA",
)
)
}
}
BleService.isEnterOta = false
}
override fun onCancelOTA() {
Log.d(TAG, "onCancelOTA取消升级")
if (streamSink != null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
streamSink.success(
mapOf(
"event" to "onCancelOTA",
)
)
}
}
}
override fun onError(error: BaseError?) {
val errorMessage = error?.message ?: "Unknown error"
Log.d(TAG, "升级失败: ${error?.message ?: "未知错误"}")
if (streamSink != null) {
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.d(
TAG,
"升级失败:error?.message ${error?.message}未知错误 error?.code${error?.code}"
)
streamSink.success(
mapOf(
"event" to "onError",
"code" to (error?.code ?: 255), // 确保值是正确的类型
"message" to (error?.message ?: "Unknown error") // 确保值是正确的类型
)
)
}
}
// 如果需要打印完整错误对象信息(假设BaseError有重写toString())
Log.d(TAG, "完整错误对象: ${error ?: "null"}")
}
}
/** OtaPlugin */
class OtaPlugin : BleService.Callback, FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel: MethodChannel
private lateinit var context: Context
private lateinit var otaDevice: BluetoothDevice
private var bluetoothHelper: BluetoothHelper? = null
private var otaManager: OTAManager? = null
private lateinit var filePath: String//升级文件路径
private var isDisconnect = false//是否主动断开
private var streamSink: EventChannel.EventSink? = null
private lateinit var eventChannel: EventChannel
// 是否已注册BLE回调
private var isRegisteredToBle = false
// 添加主线程Handler用于确保在主线程回调
private val mainHandler = Handler(Looper.getMainLooper())
companion object {
private const val TAG = "OtaPlugin"
private const val CHANNEL_NAME = "com.example.ota"
private const val EVENT_CHANNEL_NAME = "com.example.ota/events"
}
// 在主线程上安全发送事件
private fun sendEventOnMainThread(event: Map<String, Any?>) {
if (streamSink == null) return
if (Looper.myLooper() == Looper.getMainLooper()) {
// 如果已经在主线程,直接发送
streamSink?.success(event)
} else {
// 否则切换到主线程
mainHandler.post {
streamSink?.success(event)
}
}
}
// 在主线程上安全返回结果
private fun sendResultOnMainThread(result: Result, value: Any?) {
if (Looper.myLooper() == Looper.getMainLooper()) {
// 如果已经在主线程,直接返回
result.success(value)
} else {
// 否则切换到主线程
mainHandler.post {
result.success(value)
}
}
}
// 在主线程上安全返回错误
private fun sendErrorOnMainThread(
result: Result,
errorCode: String,
errorMessage: String,
errorDetails: Any?
) {
if (Looper.myLooper() == Looper.getMainLooper()) {
// 如果已经在主线程,直接返回
result.error(errorCode, errorMessage, errorDetails)
} else {
// 否则切换到主线程
mainHandler.post {
result.error(errorCode, errorMessage, errorDetails)
}
}
}
private val bluetoothCallback = object : BtEventCallback() {
override fun onConnection(device: BluetoothDevice?, status: Int) {
if ((status == StateCode.CONNECTION_FAILED || status == StateCode.CONNECTION_DISCONNECT) && bluetoothHelper?.getConnectedDevice() != null) {
bluetoothHelper?.disconnectDevice(bluetoothHelper?.getConnectedDevice())
}
otaDevice = device!!
// sendEventOnMainThread(
// mapOf(
// "event" to "NOCONNECTION"
// )
// )
// 更新连接状态的 LiveData,用于通知 UI 或其他逻辑
// otaConnectionMLD.value = DeviceConnection(device, status)
Log.d("bluetoothCallback", "onConnection,status${status}")
if (status == StateCode.CONNECTION_OK) {
Log.d("TAG", "startUpgrade")
sendEventOnMainThread(
mapOf(
"event" to "CONNECTION_SUCCESS"
)
)
Log.d("TAG", "startUpgrade,filePath=${filePath}")
otaManager?.bluetoothOption?.firmwareFilePath = filePath
otaManager?.startOTA(
CustomUpdateCallback(
otaManager?.bluetoothHelper?.getConnectedDevice(), streamSink
)
)
}
}
override fun onMandatoryUpgrade(device: BluetoothDevice?) {
// mandatoryUpgradeMLD.postValue(device!!)
Log.d("bluetoothCallback", "onMandatoryUpgrade")
}
}
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "ota")
channel.setMethodCallHandler(this)
eventChannel = EventChannel(flutterPluginBinding.binaryMessenger, EVENT_CHANNEL_NAME)
eventChannel.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
streamSink = events
}
override fun onCancel(arguments: Any?) {
streamSink = null
}
})
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "init") {
// 初始化 otaManager 和 bluetoothHelper
ConfigHelper.initialize(context)
otaManager = OTAManager(context)
bluetoothHelper = BluetoothHelper(context)
// 如果需要额外的初始化逻辑,请在这里添加
otaManager!!.registerBluetoothCallback(bluetoothCallback)
// 初始化BleService
// 2. 初始化BleService并注册回调
if (BleService.initialize(context)) {
if (BleService.addCallback(this)) {
isRegisteredToBle = true
Log.d(TAG, "已注册BLE回调")
} else {
Log.w(TAG, "BLE回调注册失败")
}
} else {
Log.e(TAG, "BLE服务初始化失败")
}
Log.i("TAG", "onAttachedToEngine")
result.success("")
} else if (call.method == "startUpgrading") {
Log.d("TAG", "startUpgrading")
// 接收传入的参数
val arguments = call.arguments as? Map<String, Any>
filePath = (arguments?.get("filePath") as? String).toString()
if (filePath != null) {
Log.d("TAG", "Received filePath: $filePath")
// 在这里使用 filePath 参数,例如传递给其他方法或类
} else {
Log.d("TAG", "filePath 参数为空")
}
BleService.isEnterOta = true
val bluetoothGatt = BleService.bluetoothGatt
if (bluetoothGatt?.device != null) {
isDisconnect = true
otaDevice = bluetoothGatt.device
BleService.disconnect()
} else if (otaDevice != null) {
isDisconnect = true
BleService.disconnect()
} else {
Log.e("TAG", "BluetoothGatt 或 device 为 null,无法执行操作")
sendEventOnMainThread(
mapOf(
"event" to "NOCONNECTION"
)
)
BleService.isEnterOta = false
}
result.success("")
} else if (call.method == "onOtaClose") {
BleService.isEnterOta = false
isDisconnect = false
if(otaManager!= null) {
BleService.removeCallback(this)
otaManager?.release()
otaManager= null
bluetoothHelper=null
}
result.success("")
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
eventChannel.setStreamHandler(null)
// 取消BLE回调注册
if (isRegisteredToBle) {
BleService.removeCallback(this)
isRegisteredToBle = false
}
isDisconnect = false
// 释放其他资源
streamSink = null
BleService.isEnterOta = false
Log.d(TAG, "OtaPlugin 已释放资源")
}
// BleService.Callback 接口实现
override fun onScanResult(devices: List<Map<String, Any>>) {
// 不处理扫描结果
}
override fun onConnectionStateChanged(state: Int) {
if (state == BleConst.STATE_DISCONNECTED && isDisconnect) {
Log.d("TAG", "Ble设备已断开,onConnectionStateChanged")
Handler(Looper.getMainLooper()).postDelayed({
otaManager?.bluetoothHelper?.startScan(otaDevice)
}, 2000) // 2000 毫秒 = 2 秒
}
}
override fun onAudioDataReceived(data: ByteArray,channel:Int) {
// 可选:处理音频数据
}
/**
* 处理唤醒信号
* 在收到唤醒信号时启动语音识别
*/
override fun onWakeupSignalReceived() {
}
// 处理开始 AI 单次对话
override fun onStartSingleDialogReceived() {
// 不处理开始对话
}
// 处理结束 AI 单次对话
override fun onEndSingleDialogReceived() {
// 不处理结束对话
}
override fun onDeviceInfoReceived(infoType: Int, infoData: Map<String, Any>) {
// 不处理设备信息
}
override fun onWakeupVoiceUpgradeProgressReceived(progress: Int) {
// 不处理升级进度
}
override fun onWakeupVoiceUpgradeSuccess() {
}
override fun onWakeupVoiceUpgradeFailed() {
}
}

91
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BTEventCbHelper.kt

@ -1,91 +0,0 @@
package com.jieli.otasdk.tool.bluetooth
import android.bluetooth.BluetoothDevice
import android.os.Handler
import android.os.Looper
import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo
import java.util.*
/**
* @author zqjasonZhong
* @since 2022/9/14
* @email zhongzhuocheng@zh-jieli.com
* @desc 蓝牙事件回调辅助类
*/
class BTEventCbHelper : OnBTEventCallback() {
private val callbacks = mutableListOf<OnBTEventCallback>()
private val uiHandler = Handler(Looper.getMainLooper())
fun registerCallback(callback: OnBTEventCallback) {
if (callbacks.contains(callback)) return
callbacks.add(callback)
}
fun unregisterCallback(callback: OnBTEventCallback) {
if (callbacks.isEmpty()) return
callbacks.remove(callback)
}
fun release() {
callbacks.clear()
uiHandler.removeCallbacksAndMessages(null)
}
override fun onAdapterChange(bEnabled: Boolean) {
callbackEvent(object : CallbackImpl<OnBTEventCallback> {
override fun onCallback(callback: OnBTEventCallback) {
callback.onAdapterChange(bEnabled)
}
})
}
override fun onDiscoveryChange(bStart: Boolean, scanType: Int) {
callbackEvent(object : CallbackImpl<OnBTEventCallback> {
override fun onCallback(callback: OnBTEventCallback) {
callback.onDiscoveryChange(bStart, scanType)
}
})
}
override fun onDiscovery(device: BluetoothDevice?, bleScanMessage: BleScanInfo?) {
callbackEvent(object : CallbackImpl<OnBTEventCallback> {
override fun onCallback(callback: OnBTEventCallback) {
callback.onDiscovery(device, bleScanMessage)
}
})
}
override fun onDeviceConnection(device: BluetoothDevice?, way: Int, status: Int) {
callbackEvent(object : CallbackImpl<OnBTEventCallback> {
override fun onCallback(callback: OnBTEventCallback) {
callback.onDeviceConnection(device, way, status)
}
})
}
override fun onReceiveData(device: BluetoothDevice?, way: Int, uuid: UUID?, data: ByteArray?) {
callbackEvent(object : CallbackImpl<OnBTEventCallback> {
override fun onCallback(callback: OnBTEventCallback) {
callback.onReceiveData(device, way, uuid, data)
}
})
}
override fun onBleMtuChange(device: BluetoothDevice?, mtu: Int, status: Int) {
callbackEvent(object : CallbackImpl<OnBTEventCallback> {
override fun onCallback(callback: OnBTEventCallback) {
callback.onBleMtuChange(device, mtu, status)
}
})
}
private fun callbackEvent(impl: CallbackImpl<OnBTEventCallback>?) {
if (null == impl) return
val runnable = CallbackRunnable(callbacks, impl)
if (Thread.currentThread().id == Looper.getMainLooper().thread.id) {
runnable.run()
} else {
uiHandler.post(runnable)
}
}
}

204
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/BluetoothHelper.kt

@ -1,204 +0,0 @@
package com.jieli.otasdk.tool.bluetooth
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothProfile
import android.content.Context
import com.jieli.jl_bt_ota.util.BluetoothUtil
import com.jieli.jl_bt_ota.util.CHexConver
import com.jieli.otasdk.tool.config.ConfigHelper
import com.jieli.otasdk.tool.ota.ble.BleManager
import com.jieli.otasdk.tool.ota.ble.interfaces.BleEventCallback
import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo
import com.jieli.otasdk.tool.bluetooth.OtaConstant
import java.util.*
import android.util.Log
/**
* @author zqjasonZhong
* @since 2022/9/14
* @email zhongzhuocheng@zh-jieli.com
* @desc 蓝牙操作辅助类
*/
class BluetoothHelper(private val context: Context) {
private val configHelper = ConfigHelper.getInstance()
private val bleManager = BleManager.getInstance(context)!!
private val btEventCbHelper = BTEventCbHelper()
companion object {
const val TAG: String = "BluetoothHelper"
@Volatile
private var instance: BluetoothHelper? = null
fun getInstance(context: Context): BluetoothHelper = instance ?: synchronized(this) {
instance ?: BluetoothHelper(context).also { instance = it }
}
}
private val bleEventCallback = object : BleEventCallback() {
override fun onAdapterChange(bEnabled: Boolean) {
btEventCbHelper.onAdapterChange(bEnabled)
}
override fun onDiscoveryBleChange(bStart: Boolean) {
btEventCbHelper.onDiscoveryChange(bStart, OtaConstant.PROTOCOL_BLE)
}
override fun onDiscoveryBle(device: BluetoothDevice?, bleScanMessage: BleScanInfo?) {
btEventCbHelper.onDiscovery(device, bleScanMessage)
}
override fun onBleConnection(device: BluetoothDevice?, status: Int) {
btEventCbHelper.onDeviceConnection(device, OtaConstant.PROTOCOL_BLE, status)
}
override fun onBleDataNotification(
device: BluetoothDevice?,
serviceUuid: UUID?,
characteristicsUuid: UUID?,
data: ByteArray?
) {
btEventCbHelper.onReceiveData(
device,
OtaConstant.PROTOCOL_BLE,
characteristicsUuid,
data
)
}
override fun onBleDataBlockChanged(device: BluetoothDevice?, block: Int, status: Int) {
btEventCbHelper.onBleMtuChange(device, block, status)
}
}
init {
// if (configHelper.isBleWay()) {
bleManager.registerBleEventCallback(bleEventCallback)
// } else {
// }
}
fun destroy() {
bleManager.unregisterBleEventCallback(bleEventCallback)
bleManager.destroy()
btEventCbHelper.release()
instance = null
}
fun registerCallback(callback: OnBTEventCallback) {
btEventCbHelper.registerCallback(callback)
}
fun unregisterCallback(callback: OnBTEventCallback) {
btEventCbHelper.unregisterCallback(callback)
}
fun isConnected(): Boolean {
return getConnectedDevice() != null
}
fun isDeviceConnected(device: BluetoothDevice?): Boolean {
return BluetoothUtil.deviceEquals(getConnectedDevice(), device)
}
fun isScanning(): Boolean =
bleManager.isBleScanning
fun isConnecting(): Boolean =
bleManager.isBleScanning
fun getConnectedDevice(): BluetoothDevice? {
return bleManager.connectedBtDevice
}
fun getConnectedGatt(): BluetoothGatt? {
return if (configHelper.isBleWay()) {
bleManager.getConnectedBtGatt(getConnectedDevice())
} else {
null
}
}
fun getBleMtu(): Int {
return if (configHelper.isBleWay()) {
return bleManager.getBleMtu(getConnectedDevice())
} else {
20
}
}
fun startScan(device: BluetoothDevice?) {
Log.i(TAG, ", startScan" + device);
bleManager.startLeScan(device)
}
fun stopScan() {
bleManager.stopLeScan()
}
fun connectDevice(device: BluetoothDevice?): Boolean =
bleManager.connectBleDevice(device)
fun disconnectDevice(device: BluetoothDevice?) {
bleManager.disconnectBleDevice(device)
}
fun connectBleDevice(device: BluetoothDevice?): Boolean =
bleManager.connectBleDevice(device)
fun reconnectDevice(address: String?, isUseNewAdv: Boolean) {
if (configHelper.isBleWay()) {
bleManager.reconnectDevice(address, isUseNewAdv)
} else {
//TODO:需要增加SPP自定义回连方式
}
}
fun writeDataToDevice(bluetoothDevice: BluetoothDevice?, byteArray: ByteArray?): Boolean {
if (null == bluetoothDevice || null == byteArray || byteArray.isEmpty()) return false
if (bleManager.connectedBtDevice != null) {//目前连接的设备是ble
bleManager.writeDataByBleAsync(
bluetoothDevice,
BleManager.BLE_UUID_SERVICE,
BleManager.BLE_UUID_WRITE,
byteArray
) { device, serviceUUID, characteristicUUID, result, data ->
Log.i(
TAG,
"-writeDataByBleAsync- device:${
printDeviceInfo(device)
}, result = $result,\ndata:[${
CHexConver.byte2HexStr(data)
}]"
)
}
}
return true
}
private fun printDeviceInfo(device: BluetoothDevice?): String? {
//return AppUtil.printBtDeviceInfo(device)
//注释掉
return "返回设备信息"
}
}

12
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackImpl.kt

@ -1,12 +0,0 @@
package com.jieli.otasdk.tool.bluetooth
/**
* @author zqjasonZhong
* @since 2022/9/14
* @email zhongzhuocheng@zh-jieli.com
* @desc 回调实现类
*/
interface CallbackImpl<T> {
fun onCallback(callback: T)
}

23
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/CallbackRunnable.kt

@ -1,23 +0,0 @@
package com.jieli.otasdk.tool.bluetooth
/**
* @author zqjasonZhong
* @since 2022/9/14
* @email zhongzhuocheng@zh-jieli.com
* @desc 回调处理类
*/
class CallbackRunnable<T> constructor(
private val callbacks: MutableList<T>,
private val impl: CallbackImpl<T>?
) :
Runnable {
override fun run() {
if (callbacks.isEmpty() || impl == null) return
val temp = mutableListOf<T>()
temp.addAll(callbacks)
temp.forEach {
impl.onCallback(it)
}
}
}

38
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OnBTEventCallback.kt

@ -1,38 +0,0 @@
package com.jieli.otasdk.tool.bluetooth
import android.bluetooth.BluetoothDevice
import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo
import java.util.*
/**
* @author zqjasonZhong
* @since 2022/9/14
* @email zhongzhuocheng@zh-jieli.com
* @desc 蓝牙事件回调
*/
open class OnBTEventCallback {
open fun onAdapterChange(bEnabled: Boolean) {
}
open fun onDiscoveryChange(bStart: Boolean, scanType: Int) {
}
open fun onDiscovery(device: BluetoothDevice?, bleScanMessage: BleScanInfo?) {
}
open fun onDeviceConnection(device: BluetoothDevice?, way: Int, status: Int) {
}
open fun onReceiveData(device: BluetoothDevice?, way: Int, uuid: UUID?, data: ByteArray?) {
}
open fun onBleMtuChange(device: BluetoothDevice?, mtu: Int, status: Int) {
}
}

54
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/bluetooth/OtaConstant.kt

@ -1,54 +0,0 @@
package com.jieli.otasdk.tool.bluetooth
import java.util.*
/**
* 常量声明
*
* @author zqjasonZhong
* @date 2019/12/30
*/
class OtaConstant {
companion object {
val UUID_A2DP: UUID = UUID.fromString("0000110b-0000-1000-8000-00805f9b34fb")
val UUID_SPP: UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb")
//Ble协议
const val PROTOCOL_BLE = 0
//Spp协议
const val PROTOCOL_SPP = 1
const val CURRENT_PROTOCOL = PROTOCOL_BLE
//是否使用设备认证
const val IS_NEED_DEVICE_AUTH = true
//是否HID设备连接
const val HID_DEVICE_WAY = false
//是否需要自定义连接方式
const val NEED_CUSTOM_RECONNECT_WAY = false
//是否使用SPP多通道连接
const val USE_SPP_MULTIPLE_CHANNEL = false
//是否使用自动化测试
const val AUTO_TEST_OTA = false
//自动化测试次数
const val AUTO_TEST_COUNT = 30
//是否自动化测试时允许容错
const val AUTO_FAULT_TOLERANT = false
//容错次数
const val AUTO_FAULT_TOLERANT_COUNT = 1
//dir
const val DIR_ROOT = "JieLiOTA"
const val DIR_UPGRADE = "upgrade"
const val DIR_LOGCAT = "logcat"
const val SCAN_TIMEOUT = 16 * 1000L
}
}

187
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/config/ConfigHelper.kt

@ -1,187 +0,0 @@
package com.jieli.otasdk.tool.config
import android.annotation.SuppressLint
import android.content.Context
import androidx.annotation.IntRange
import com.jieli.jl_bt_ota.constant.BluetoothConstant
import com.jieli.otasdk.tool.bluetooth.OtaConstant
/**
* @author zqjasonZhong
* @since 2022/9/8
* @email zhongzhuocheng@zh-jieli.com
* @desc 配置辅助类
*/
open class ConfigHelper private constructor(context: Context) {
companion object {
//download文件夹
private const val KEY_DOWNLOAD_URI = "download_uri"
//通讯方式
private const val KEY_COMMUNICATION_WAY = "communication_way"
//是否使用设备认证
private const val KEY_IS_USE_DEVICE_AUTH = "is_use_device_auth"
//是否HID设备
private const val KEY_IS_HID_DEVICE = "is_hid_device"
//是否使用自定义回连方式
private const val KEY_USE_CUSTOM_RECONNECT_WAY = "use_custom_reconnect_way"
//BLE的MTU请求值
private const val KEY_BLE_MTU_VALUE = "ble_mtu_value"
//是否启用SPP多通道
private const val KEY_SPP_MULTIPLE_CHANNEL = "spp_multiple_channel"
//自定义SPP通道
private const val KEY_SPP_CUSTOM_UUID = "spp_custom_uuid"
//是否自动测试OTA
private const val KEY_AUTO_TEST_OTA = "auto_test_ota"
//自动化测试次数
private const val KEY_AUTO_TEST_COUNT = "auto_test_count"
//是否自动测试OTA时,允许容错
private const val KEY_FAULT_TOLERANT = "fault_tolerant"
//容错次数
private const val KEY_FAULT_TOLERANT_COUNT = "fault_tolerant_count"
//扫描过滤参数
private const val KEY_SCAN_FILTER_STRING = "scan_filter_string"
//开发者模式
private const val KEY_DEVELOP_MODE = "develop_mode"
// 广播音箱模式
private const val KEY_BROADCAST_BOX = "broadcast_box_switch"
@Volatile
private var instance: ConfigHelper? = null
// 双重校验锁初始化
fun initialize(context: Context) = instance ?: synchronized(this) {
instance ?: ConfigHelper(context.applicationContext).also {
instance = it
}
}
// 安全获取实例方法
fun getInstance(): ConfigHelper = instance ?: throw IllegalStateException(
"Call ConfigHelper.initialize() first"
)
}
private val preferences = context.getSharedPreferences("ota_config_data", Context.MODE_PRIVATE)
fun isBleWay(): Boolean = preferences.getInt(
KEY_COMMUNICATION_WAY,
OtaConstant.CURRENT_PROTOCOL
) == OtaConstant.PROTOCOL_BLE
fun setBleWay(isBle: Boolean) {
val way = if (isBle) OtaConstant.PROTOCOL_BLE else OtaConstant.PROTOCOL_SPP
preferences.edit().putInt(KEY_COMMUNICATION_WAY, way).apply()
}
fun isUseDeviceAuth(): Boolean =
preferences.getBoolean(KEY_IS_USE_DEVICE_AUTH, OtaConstant.IS_NEED_DEVICE_AUTH)
fun setUseDeviceAuth(isAuth: Boolean) {
preferences.edit().putBoolean(KEY_IS_USE_DEVICE_AUTH, isAuth).apply()
}
fun isHidDevice(): Boolean =
preferences.getBoolean(KEY_IS_HID_DEVICE, OtaConstant.HID_DEVICE_WAY)
fun setHidDevice(isHid: Boolean) {
preferences.edit().putBoolean(KEY_IS_HID_DEVICE, isHid).apply()
}
fun isUseCustomReConnectWay(): Boolean = preferences.getBoolean(
KEY_USE_CUSTOM_RECONNECT_WAY,
OtaConstant.NEED_CUSTOM_RECONNECT_WAY
)
fun setUseCustomReConnectWay(isCustom: Boolean) {
preferences.edit().putBoolean(KEY_USE_CUSTOM_RECONNECT_WAY, isCustom).apply()
}
fun getBleRequestMtu(): Int =
preferences.getInt(KEY_BLE_MTU_VALUE, 509)
fun setBleRequestMtu(@IntRange(from = 20, to = 509) mtu: Int) {
preferences.edit().putInt(KEY_BLE_MTU_VALUE, mtu).apply()
}
fun isUseMultiSppChannel(): Boolean = preferences.getBoolean(
KEY_SPP_MULTIPLE_CHANNEL,
OtaConstant.USE_SPP_MULTIPLE_CHANNEL
)
fun setUseMultiSppChannel(isUseMulti: Boolean) {
preferences.edit().putBoolean(KEY_SPP_MULTIPLE_CHANNEL, isUseMulti).apply()
}
fun getCustomSppChannel(): String? =
preferences.getString(KEY_SPP_CUSTOM_UUID, OtaConstant.UUID_SPP.toString())
fun setCustomSppChannel(uuid: String?) {
preferences.edit().putString(KEY_SPP_CUSTOM_UUID, uuid).apply()
}
fun isAutoTest(): Boolean = preferences.getBoolean(KEY_AUTO_TEST_OTA, OtaConstant.AUTO_TEST_OTA)
fun setAutoTest(isAutoTest: Boolean) {
preferences.edit().putBoolean(KEY_AUTO_TEST_OTA, isAutoTest).apply()
}
fun getAutoTestCount(): Int = preferences.getInt(
KEY_AUTO_TEST_COUNT,
OtaConstant.AUTO_TEST_COUNT
)
fun setAutoTestCount(count: Int) {
if (!isAutoTest()) return
preferences.edit().putInt(KEY_AUTO_TEST_COUNT, count).apply()
}
fun isFaultTolerant(): Boolean = preferences.getBoolean(KEY_FAULT_TOLERANT, OtaConstant.AUTO_FAULT_TOLERANT)
fun setFaultTolerant(isFaultTolerant: Boolean) {
preferences.edit().putBoolean(KEY_FAULT_TOLERANT, isFaultTolerant).apply()
}
fun getFaultTolerantCount(): Int = preferences.getInt(
KEY_FAULT_TOLERANT_COUNT,
OtaConstant.AUTO_FAULT_TOLERANT_COUNT
)
fun setFaultTolerantCount(count: Int) {
if (!isFaultTolerant()) return
preferences.edit().putInt(KEY_FAULT_TOLERANT_COUNT, count).apply()
}
fun getScanFilter(): String? =
preferences.getString(KEY_SCAN_FILTER_STRING, "")
fun setScanFilter(scanFilter: String?) {
preferences.edit().putString(KEY_SCAN_FILTER_STRING, scanFilter).apply()
}
fun isDevelopMode(): Boolean =
preferences.getBoolean(KEY_DEVELOP_MODE, false)
fun setDevelopMode(developMode: Boolean) {
preferences.edit().putBoolean(KEY_DEVELOP_MODE, developMode).apply()
}
fun isEnableBroadcastBox(): Boolean =
preferences.getBoolean(KEY_BROADCAST_BOX, false)
fun enableBroadcastBox(enable: Boolean) {
preferences.edit().putBoolean(KEY_BROADCAST_BOX, enable).apply()
}
}

172
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/OTAManager.kt

@ -1,172 +0,0 @@
package com.jieli.otasdk.tool.ota
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.content.Context
import com.jieli.jl_bt_ota.constant.BluetoothConstant
import com.jieli.jl_bt_ota.constant.StateCode
import com.jieli.jl_bt_ota.impl.BluetoothOTAManager
import com.jieli.jl_bt_ota.impl.RcspAuth
import com.jieli.jl_bt_ota.model.BluetoothOTAConfigure
import com.jieli.jl_bt_ota.util.BluetoothUtil
import com.jieli.jl_bt_ota.util.CHexConver
import com.jieli.otasdk.tool.bluetooth.BluetoothHelper
import com.jieli.otasdk.tool.bluetooth.OnBTEventCallback
import com.jieli.otasdk.tool.config.ConfigHelper
import com.jieli.otasdk.tool.bluetooth.OtaConstant
import java.util.*
import android.util.Log
/**
* 用于RCSP的第三方SDK接入OTA流程
*/
class OTAManager(context: Context) : BluetoothOTAManager(context) {
val configHelper = ConfigHelper.getInstance()
val bluetoothHelper = BluetoothHelper.getInstance(context)
/**
* 转换成OTA库的连接状态
*
* @param status 连接状态
* @return 库的连接状态
*/
fun changeConnectStatus(status: Int): Int {
var changeStatus = StateCode.CONNECTION_DISCONNECT
when (status) {
2 -> {
changeStatus = StateCode.CONNECTION_OK
}
1 -> {
changeStatus = StateCode.CONNECTION_CONNECTING
}
}
return changeStatus
}
val btEventCallback = object : OnBTEventCallback() {
override fun onDeviceConnection(device: BluetoothDevice?, way: Int, status: Int) {
super.onDeviceConnection(device, way, status)
val connectionState = changeConnectStatus(status)
// Log.i(
// TAG, "onConnection >>> device : ${printDeviceInfo(device)}, way = $way" +
// " status :$status, change status : $connectionState"
// )
// onBtDeviceConnection(device, connectionState)
//注释掉
Log.i(
TAG, "onConnection >>> device : ${device}, way = $way" +
" status :$status, change status : $connectionState"
)
onBtDeviceConnection(device, connectionState)
}
override fun onReceiveData(
device: BluetoothDevice?,
way: Int,
uuid: UUID?,
data: ByteArray?
) {
super.onReceiveData(device, way, uuid, data)
Log.d(
TAG, "onReceiveData >>> ${printDeviceInfo(device)}, way = $way,\n" +
"uuid = $uuid, data :${CHexConver.byte2HexStr(data)} "
)
// if (way == OtaConstant.PROTOCOL_SPP && SppManager.UUID_SPP != uuid) {
// Log.d(
// TAG, "onReceiveData >>> skip spec"
// )
// return
// }
onReceiveDeviceData(device, data)
}
override fun onBleMtuChange(device: BluetoothDevice?, mtu: Int, status: Int) {
super.onBleMtuChange(device, mtu, status)
onMtuChanged(bluetoothHelper.getConnectedGatt(), mtu, status)
}
}
init {
// ConfigHelper.initialize(context)
val bluetoothOption = BluetoothOTAConfigure()
//选择通讯方式
bluetoothOption.priority =
BluetoothOTAConfigure.PREFER_BLE
//是否需要自定义回连方式(默认不需要,如需要自定义回连方式,需要客户自行实现)
bluetoothOption.isUseReconnect =
(configHelper.isUseCustomReConnectWay() && configHelper.isHidDevice())
Log.d(
TAG,
"是否启用设备认证流程(与固件工程师确认) >>> ${configHelper.isUseDeviceAuth()} >>> ${bluetoothOption.isUseReconnect} "
)
//是否启用设备认证流程(与固件工程师确认)
bluetoothOption.isUseAuthDevice = false
//设置BLE的MTU
bluetoothOption.mtu = BluetoothConstant.BLE_MTU_MIN
//是否需要改变BLE的MTU
bluetoothOption.isNeedChangeMtu = false
//是否启用杰理服务器(暂时不支持)
bluetoothOption.isUseJLServer = false
//配置OTA参数
configure(bluetoothOption)
RcspAuth.setAuthTimeout(5000)
bluetoothHelper.registerCallback(btEventCallback)
if (bluetoothHelper.isConnected()) {
onBtDeviceConnection(bluetoothHelper.getConnectedDevice(), StateCode.CONNECTION_OK)
if (configHelper.isBleWay()) {
onMtuChanged(
bluetoothHelper.getConnectedGatt(),
bluetoothHelper.getBleMtu() + 3,
BluetoothGatt.GATT_SUCCESS
)
}
}
}
override fun getConnectedDevice(): BluetoothDevice? = bluetoothHelper.getConnectedDevice()
override fun getConnectedBluetoothGatt(): BluetoothGatt? = bluetoothHelper.getConnectedGatt()
override fun connectBluetoothDevice(bluetoothDevice: BluetoothDevice?) {
//仅仅作为回连设备,回连设备现在仅支持BLE
val result: Boolean = bluetoothHelper.connectBleDevice(bluetoothDevice)
if (!result) {
onBtDeviceConnection(bluetoothDevice, StateCode.CONNECTION_FAILED)
}
}
override fun disconnectBluetoothDevice(bluetoothDevice: BluetoothDevice?) {
bluetoothHelper.disconnectDevice(bluetoothDevice)
}
override fun sendDataToDevice(bluetoothDevice: BluetoothDevice?, bytes: ByteArray?): Boolean {
Log.d(
TAG,
"sendDataToDevice : device = ${printDeviceInfo(bluetoothDevice)}\n" +
"data = [${CHexConver.byte2HexStr(bytes)}]"
)
return bluetoothHelper.writeDataToDevice(bluetoothDevice, bytes)
}
override fun release() {
super.release()
bluetoothHelper.unregisterCallback(btEventCallback)
}
fun setReconnectAddr(addr: String?) {
// setReconnectAddress(addr)
}
private fun printDeviceInfo(device: BluetoothDevice?): String? {
return BluetoothUtil.printBtDeviceInfo(context, device)
}
}

175
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleEventCallbackManager.java

@ -1,175 +0,0 @@
package com.jieli.otasdk.tool.ota.ble;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattService;
import android.os.Handler;
import android.os.Looper;
import com.jieli.otasdk.tool.ota.ble.interfaces.BleEventCallback;
import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Ble事件回调管理器
*
* @author zqjasonZhong
* @since 2020/12/24
*/
class BleEventCallbackManager extends BleEventCallback {
private final ArrayList<BleEventCallback> mCallbacks = new ArrayList<>();
private final Handler mHandler = new Handler(Looper.getMainLooper());
public void registerBleEventCallback(BleEventCallback callback) {
if (callback != null && !mCallbacks.contains(callback)) {
mCallbacks.add(callback);
}
}
public void unregisterBleEventCallback(BleEventCallback callback) {
if (callback != null && !mCallbacks.isEmpty()) {
mCallbacks.remove(callback);
}
}
public void release() {
mCallbacks.clear();
mHandler.removeCallbacksAndMessages(null);
}
@Override
public void onAdapterChange(final boolean bEnabled) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onAdapterChange(bEnabled);
}
});
}
@Override
public void onDiscoveryBleChange(final boolean bStart) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onDiscoveryBleChange(bStart);
}
});
}
@Override
public void onDiscoveryBle(final BluetoothDevice device, final BleScanInfo bleScanMessage) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onDiscoveryBle(device, bleScanMessage);
}
});
}
@Override
public void onBleConnection(final BluetoothDevice device, final int status) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onBleConnection(device, status);
}
});
}
@Override
public void onBleServiceDiscovery(final BluetoothDevice device, final int status, final List<BluetoothGattService> services) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onBleServiceDiscovery(device, status, services);
}
});
}
@Override
public void onBleNotificationStatus(final BluetoothDevice device, final UUID serviceUuid, final UUID characteristicUuid, final int status) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onBleNotificationStatus(device, serviceUuid, characteristicUuid, status);
}
});
}
@Override
public void onBleDataBlockChanged(final BluetoothDevice device, final int block, final int status) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onBleDataBlockChanged(device, block, status);
}
});
}
@Override
public void onBleDataNotification(final BluetoothDevice device, final UUID serviceUuid, final UUID characteristicsUuid, final byte[] data) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onBleDataNotification(device, serviceUuid, characteristicsUuid, data);
}
});
}
@Override
public void onBleWriteStatus(final BluetoothDevice device, final UUID serviceUuid, final UUID characteristicsUuid, final byte[] data, final int status) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onBleWriteStatus(device, serviceUuid, characteristicsUuid, data, status);
}
});
}
@Override
public void onConnectionUpdated(final BluetoothDevice device, final int interval, final int latency, final int timeout, final int status) {
callbackBleEvent(new BleEventCallbackImpl() {
@Override
public void onCallback(BleEventCallback callback) {
callback.onConnectionUpdated(device, interval, latency, timeout, status);
}
});
}
private void callbackBleEvent(BleEventCallbackImpl impl) {
if (null == impl) return;
OnBleEventRunnable runnable = new OnBleEventRunnable(impl);
if (Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId()) {
runnable.run();
} else {
mHandler.post(runnable);
}
}
private static abstract class BleEventCallbackImpl {
public abstract void onCallback(BleEventCallback callback);
}
private class OnBleEventRunnable implements Runnable {
private final BleEventCallbackImpl mImpl;
public OnBleEventRunnable(BleEventCallbackImpl impl) {
mImpl = impl;
}
@Override
public void run() {
if (!mCallbacks.isEmpty() && mImpl != null) {
for (BleEventCallback callback : new ArrayList<>(mCallbacks)) {
if (callback != null) {
mImpl.onCallback(callback);
}
}
}
}
}
}

1197
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/BleManager.java

File diff suppressed because it is too large

295
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/SendBleDataThread.java

@ -1,295 +0,0 @@
package com.jieli.otasdk.tool.ota.ble;
import android.bluetooth.BluetoothGatt;
import com.jieli.jl_bt_ota.util.JL_Log;
import com.jieli.otasdk.tool.ota.ble.interfaces.IBleOp;
import com.jieli.otasdk.tool.ota.ble.interfaces.OnThreadStateListener;
import com.jieli.otasdk.tool.ota.ble.interfaces.OnWriteDataCallback;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 发送BLE数据线程
*
* @author zqjasonZhong
* @date 2019/10/8
*/
public class SendBleDataThread extends Thread {
private final static String TAG = "SendBleDataThread";
private final LinkedBlockingQueue<BleSendTask> mQueue = new LinkedBlockingQueue<>();
private volatile boolean isDataSend = false;
private volatile boolean isThreadWaiting = false;
private volatile boolean isWaitingForCallback = false;
private volatile int retryNum = 0;
private final IBleOp mBleManager;
private final OnThreadStateListener mListener;
private BleSendTask mCurrentTask;
public SendBleDataThread(IBleOp manager, OnThreadStateListener listener) {
super(TAG);
mBleManager = manager;
mListener = listener;
}
public boolean isRunning() {
return isDataSend;
}
public boolean addSendTask(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) {
if (null == mBleManager || null == gatt || null == serviceUUID || null == characteristicUUID || null == data || data.length == 0) {
return false;
}
int mtu = mBleManager.getBleMtu();
JL_Log.d(TAG, "addSendTask : " + mtu);
int dataLen = data.length;
int blockCount = dataLen / mtu;
boolean ret = false;
for (int i = 0; i < blockCount; i++) {
byte[] mBlockData = new byte[mtu];
System.arraycopy(data, i * mtu, mBlockData, 0, mBlockData.length);
ret = addSendData(gatt, serviceUUID, characteristicUUID, mBlockData, callback);
}
if (0 != dataLen % mtu) {
JL_Log.d(TAG, "addSendTask : " + mtu);
byte[] noBlockData = new byte[dataLen % mtu];
System.arraycopy(data, dataLen - dataLen % mtu, noBlockData, 0, noBlockData.length);
ret = addSendData(gatt, serviceUUID, characteristicUUID, noBlockData, callback);
}
return ret;
}
public void wakeupSendThread(BleSendTask sendTask) {
if (null == sendTask || mCurrentTask != null && mCurrentTask.equals(sendTask)) {
if (sendTask != null) {
sendTask.setCallback(mCurrentTask.getCallback());
mCurrentTask = sendTask;
}
synchronized (mQueue) {
if (isThreadWaiting) {
if (isWaitingForCallback) {
mQueue.notifyAll();
} else {
mQueue.notify();
}
} else if (isWaitingForCallback) {
mQueue.notify();
}
}
}
}
private boolean addSendData(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) {
boolean ret = false;
if (isDataSend) {
BleSendTask sendTask = new BleSendTask(gatt, serviceUUID, characteristicUUID, data, callback);
try {
mQueue.put(sendTask);
ret = true;
} catch (InterruptedException e) {
e.printStackTrace();
}
if (ret && isThreadWaiting && !isWaitingForCallback) {
isThreadWaiting = false;
synchronized (mQueue) {
mQueue.notify();
}
}
}
return ret;
}
@Override
public synchronized void start() {
isDataSend = true;
super.start();
}
public synchronized void stopThread() {
isDataSend = false;
wakeupSendThread(null);
}
private void callbackResult(BleSendTask task, boolean result) {
if (task != null && task.getCallback() != null) {
if (task.getBleGatt() == null) return;
task.getCallback().onBleResult(task.getBleGatt().getDevice(), task.getServiceUUID(),
task.getCharacteristicUUID(), result, task.getData());
} else {
JL_Log.i(TAG, "getCallback is null.");
}
}
@Override
public void run() {
JL_Log.d(TAG, "send ble data thread is started.");
if (mListener != null) {
mListener.onStart(getId(), getName());
}
if (mBleManager != null) {
synchronized (mQueue) {
while (isDataSend) {
mCurrentTask = null;
isThreadWaiting = false;
isWaitingForCallback = false;
if (mQueue.isEmpty()) {
isThreadWaiting = true;
JL_Log.d(TAG, "queue is empty, so waiting for data");
try {
mQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
mCurrentTask = mQueue.peek();
if (mCurrentTask != null) {
isWaitingForCallback = mBleManager.writeDataByBle(mCurrentTask.mGatt, mCurrentTask.getServiceUUID(),
mCurrentTask.getCharacteristicUUID(), mCurrentTask.getData());
if (isWaitingForCallback) {
try {
mQueue.wait(BleManager.SEND_DATA_MAX_TIMEOUT);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
mCurrentTask.setStatus(-1);
}
JL_Log.d(TAG, "data send ret :" + mCurrentTask.getStatus());
if (mCurrentTask.getStatus() != BluetoothGatt.GATT_SUCCESS) { //发送失败
retryNum++;
if (retryNum >= 3) { //重发次数超过限制
callbackResult(mCurrentTask, false);
mQueue.clear();
} else {
if (mCurrentTask.getStatus() != -1) {
mCurrentTask.setStatus(-1);
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
continue;
}
} else { //发送成功
callbackResult(mCurrentTask, true);
}
}
retryNum = 0;
if (!mQueue.isEmpty()) mQueue.poll();
}
}
}
isWaitingForCallback = false;
isThreadWaiting = false;
mQueue.clear();
if (mListener != null) {
mListener.onEnd(getId(), getName());
}
JL_Log.d(TAG, "send ble data thread exit.");
}
}
public static class BleSendTask {
private BluetoothGatt mGatt;
private UUID serviceUUID;
private UUID characteristicUUID;
private byte[] data;
private int status = -1;
private OnWriteDataCallback mCallback;
public BleSendTask(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) {
this.mGatt = gatt;
this.serviceUUID = serviceUUID;
this.characteristicUUID = characteristicUUID;
this.data = data;
this.mCallback = callback;
}
public BluetoothGatt getBleGatt() {
return mGatt;
}
public void setDevice(BluetoothGatt gatt) {
mGatt = gatt;
}
public UUID getServiceUUID() {
return serviceUUID;
}
public void setServiceUUID(UUID serviceUUID) {
this.serviceUUID = serviceUUID;
}
public UUID getCharacteristicUUID() {
return characteristicUUID;
}
public void setCharacteristicUUID(UUID characteristicUUID) {
this.characteristicUUID = characteristicUUID;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public OnWriteDataCallback getCallback() {
return mCallback;
}
public void setCallback(OnWriteDataCallback callback) {
mCallback = callback;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
@Override
public String toString() {
return "BleSendTask{" +
"mGatt=" + mGatt +
", serviceUUID=" + serviceUUID +
", characteristicUUID=" + characteristicUUID +
", data=" + Arrays.toString(data) +
", status=" + status +
", mCallback=" + mCallback +
'}';
}
@Override
public int hashCode() {
if (mGatt != null && serviceUUID != null && characteristicUUID != null) {
return mGatt.hashCode() + serviceUUID.hashCode() + characteristicUUID.hashCode();
}
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BleSendTask) {
BleSendTask other = (BleSendTask) obj;
if (mGatt != null && serviceUUID != null && characteristicUUID != null) {
return mGatt.equals(other.getBleGatt()) && serviceUUID.equals(other.getServiceUUID())
&& characteristicUUID.equals(other.getCharacteristicUUID());
}
}
return false;
}
}
}

68
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/BleEventCallback.java

@ -1,68 +0,0 @@
package com.jieli.otasdk.tool.ota.ble.interfaces;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattService;
import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo;
import java.util.List;
import java.util.UUID;
/**
* Ble事件回调抽象类
*
* @author zqjasonZhong
* @since 2020/7/16
*/
public abstract class BleEventCallback implements IBleEventCallback {
@Override
public void onAdapterChange(boolean bEnabled) {
}
@Override
public void onDiscoveryBleChange(boolean bStart) {
}
@Override
public void onDiscoveryBle(BluetoothDevice device, BleScanInfo bleScanMessage) {
}
@Override
public void onBleConnection(BluetoothDevice device, int status) {
}
@Override
public void onBleServiceDiscovery(BluetoothDevice device, int status, List<BluetoothGattService> services) {
}
@Override
public void onBleNotificationStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicUuid, int status) {
}
@Override
public void onBleDataBlockChanged(BluetoothDevice device, int block, int status) {
}
@Override
public void onBleDataNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data) {
}
@Override
public void onBleWriteStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data, int status) {
}
@Override
public void onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout, int status) {
}
}

108
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleEventCallback.java

@ -1,108 +0,0 @@
package com.jieli.otasdk.tool.ota.ble.interfaces;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattService;
import com.jieli.otasdk.tool.ota.ble.model.BleScanInfo;
import java.util.List;
import java.util.UUID;
/**
* Ble事件回调
*
* @author zqjasonZhong
* @since 2020/7/16
*/
public interface IBleEventCallback {
/**
* 蓝牙适配器开关回调
*
* @param bEnabled 开关
*/
void onAdapterChange(boolean bEnabled);
/**
* 搜索蓝牙设备的状态回调
*
* @param bStart 搜索状态
*/
void onDiscoveryBleChange(boolean bStart);
/**
* 发现蓝牙设备的回调
*
* @param device 蓝牙设备对象
* @param bleScanInfo BLE扫描数据
*/
void onDiscoveryBle(BluetoothDevice device, BleScanInfo bleScanInfo);
/**
* BLE连接状态回调
*
* @param device 蓝牙设备对象
* @param status 连接状态
*/
void onBleConnection(BluetoothDevice device, int status);
/**
* BLE服务发现回调
*
* @param device 蓝牙设备对象
* @param status 状态
* @param services 服务列表
*/
void onBleServiceDiscovery(BluetoothDevice device, int status, List<BluetoothGattService> services);
/**
* BLE特征状态回调
*
* @param device 蓝牙设备对象
* @param serviceUuid 服务UUID
* @param characteristicUuid 特征值UUID
* @param status 状态
*/
void onBleNotificationStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicUuid, int status);
/**
* BLE MTU改变回调
*
* @param device 蓝牙设备对象
* @param block 协商后的MTU
* @param status 状态
*/
void onBleDataBlockChanged(BluetoothDevice device, int block, int status);
/**
* BLE数据回调
*
* @param device 蓝牙设备对象
* @param serviceUuid 服务UUID
* @param characteristicsUuid 特征值UUID
* @param data 数据
*/
void onBleDataNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data);
/**
* BLE 写数据回调
*
* @param device 蓝牙设备对象
* @param serviceUuid 服务UUID
* @param characteristicsUuid 特征值UUID
* @param data 数据
* @param status 状态
*/
void onBleWriteStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data, int status);
/**
* BLE 连接参数回调
*
* @param device 蓝牙设备对象
* @param interval 发数间隔
* @param latency 延时参数
* @param timeout 超时时间
* @param status 状态
*/
void onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout, int status);
}

16
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/IBleOp.java

@ -1,16 +0,0 @@
package com.jieli.otasdk.tool.ota.ble.interfaces;
import android.bluetooth.BluetoothGatt;
import java.util.UUID;
/**
* @author zqjasonZhong
* @since 2020/12/24
*/
public interface IBleOp {
int getBleMtu();
boolean writeDataByBle(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data);
}

14
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnThreadStateListener.java

@ -1,14 +0,0 @@
package com.jieli.otasdk.tool.ota.ble.interfaces;
/**
* 线程生命周期监听器
*
* @author zqjasonZhong
* @date 2019/9/20
*/
public interface OnThreadStateListener {
void onStart(long id, String name);
void onEnd(long id, String name);
}

25
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/interfaces/OnWriteDataCallback.java

@ -1,25 +0,0 @@
package com.jieli.otasdk.tool.ota.ble.interfaces;
import android.bluetooth.BluetoothDevice;
import java.util.UUID;
/**
* 写数据的结果回调
*
* @author zqjasonZhong
* @date 2019/9/25
*/
public interface OnWriteDataCallback {
/**
* 回调BLE发送结果
*
* @param device 蓝牙设备
* @param serviceUUID 服务UUID
* @param characteristicUUID 特征值UUID
* @param result 发送结果
* @param data 发送数据
*/
void onBleResult(BluetoothDevice device, UUID serviceUUID, UUID characteristicUUID, boolean result, byte[] data);
}

155
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleDevice.java

@ -1,155 +0,0 @@
package com.jieli.otasdk.tool.ota.ble.model;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import androidx.annotation.NonNull;
import com.jieli.jl_bt_ota.constant.BluetoothConstant;
import com.jieli.jl_bt_ota.util.CHexConver;
import com.jieli.otasdk.tool.ota.ble.SendBleDataThread;
import com.jieli.otasdk.tool.ota.ble.interfaces.IBleOp;
import com.jieli.otasdk.tool.ota.ble.interfaces.OnThreadStateListener;
import com.jieli.otasdk.tool.ota.ble.interfaces.OnWriteDataCallback;
//import com.jieli.otasdk.util.AppUtil;
import java.util.UUID;
import android.util.Log;
/**
* @author zqjasonZhong
* @email zhongzhuocheng@zh-jieli.com
* @desc BLE设备
* @since 2022/12/5
*/
public class BleDevice {
private final String tag = "BleManager";
private final Context context; //上下文
private final BluetoothGatt gatt; //BleGatt控制对象
private int mtu = BluetoothConstant.BLE_MTU_MIN; //MTU
private long connectedTime; //连接的时间戳
private SendBleDataThread sendDataThread; //发送数据线程
public BleDevice(@NonNull Context context, @NonNull BluetoothGatt gatt) {
this.context = context;
this.gatt = gatt;
}
@NonNull
public BluetoothGatt getGatt() {
return gatt;
}
public int getMtu() {
if (mtu > 128) {
mtu -= 6;
}
return mtu;
}
public void setMtu(int mtu) {
this.mtu = mtu;
}
public long getConnectedTime() {
return connectedTime;
}
public void setConnectedTime(long connectedTime) {
this.connectedTime = connectedTime;
}
public void startSendDataThread() {
if (sendDataThread == null || !sendDataThread.isRunning()) {
sendDataThread = new SendBleDataThread(new IBleOp() {
@Override
public int getBleMtu() {
return getMtu();
}
@Override
public boolean writeDataByBle(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data) {
Log.d(tag, "writeDataByBle " + gatt +"serviceUUID "+ serviceUUID + "characteristicUUID "+ characteristicUUID + data );
return writeDataToDeviceByBle(gatt, serviceUUID, characteristicUUID, data);
}
}, new OnThreadStateListener() {
@Override
public void onStart(long id, String name) {
}
@Override
public void onEnd(long id, String name) {
if (sendDataThread != null && sendDataThread.getId() == id) {
sendDataThread = null;
}
}
});
sendDataThread.start();
}
}
public void stopSendDataThread() {
if (sendDataThread != null) {
sendDataThread.stopThread();
}
}
public void wakeupSendThread(SendBleDataThread.BleSendTask task) {
if (sendDataThread != null && task != null && gatt.equals(task.getBleGatt())) {
sendDataThread.wakeupSendThread(task);
}
}
public boolean addSendTask(UUID serviceUUID, UUID characteristicUUID, byte[] data, OnWriteDataCallback callback) {
boolean ret = false;
if (sendDataThread != null && sendDataThread.isRunning()) {
ret = sendDataThread.addSendTask(gatt, serviceUUID, characteristicUUID, data, callback);
}
return ret;
}
@SuppressLint("MissingPermission")
private boolean writeDataToDeviceByBle(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID, byte[] data) {
if (gatt == null || null == serviceUUID || null == characteristicUUID || null == data || data.length == 0
// || !AppUtil.checkHasConnectPermission(this.context)
) {
Log.d(tag, "writeDataByBle : param is invalid.");
return false;
}
BluetoothGattService gattService = gatt.getService(serviceUUID);
if (null == gattService) {
Log.d(tag, "writeDataByBle : service is null.");
return false;
}
BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(characteristicUUID);
if (null == gattCharacteristic) {
Log.d(tag, "writeDataByBle : characteristic is null");
return false;
}
boolean ret = false;
try {
gattCharacteristic.setValue(data);
ret = gatt.writeCharacteristic(gattCharacteristic);
} catch (Exception e) {
e.printStackTrace();
}
Log.d(tag, "writeDataByBle : send ret : " + ret + ", data = " + CHexConver.byte2HexStr(data));
return ret;
}
@Override
public String toString() {
return "BleDevice{" +
"context=" + context +
", gatt=" + gatt +
", mtu=" + mtu +
", connectedTime=" + connectedTime +
", sendDataThread=" + sendDataThread +
'}';
}
}

99
local_plugins/ota/android/src/main/kotlin/com/example/ota/tool/ota/ble/model/BleScanInfo.java

@ -1,99 +0,0 @@
package com.jieli.otasdk.tool.ota.ble.model;
import android.os.Parcel;
import android.os.Parcelable;
import com.jieli.jl_bt_ota.util.CHexConver;
/**
* BLE 设备扫描信息
* <p>
* Created by zqjasonzhong on 2018/10/17.
*/
public class BleScanInfo implements Parcelable {
/**
* 原始数据
*/
private byte[] rawData;
/**
* 信号强度
*/
private int rssi;
/**
* 是否允许连接
* <p>说明: 默认允许连接,特殊情况不允许</p>
*/
private boolean isEnableConnect = true;
public BleScanInfo() {
}
protected BleScanInfo(Parcel in) {
rawData = in.createByteArray();
rssi = in.readInt();
isEnableConnect = in.readByte() != 0;
}
public static final Creator<BleScanInfo> CREATOR = new Creator<BleScanInfo>() {
@Override
public BleScanInfo createFromParcel(Parcel in) {
return new BleScanInfo(in);
}
@Override
public BleScanInfo[] newArray(int size) {
return new BleScanInfo[size];
}
};
public byte[] getRawData() {
return rawData;
}
public BleScanInfo setRawData(byte[] rawData) {
this.rawData = rawData;
return this;
}
public int getRssi() {
return rssi;
}
public BleScanInfo setRssi(int rssi) {
this.rssi = rssi;
return this;
}
public boolean isEnableConnect() {
return isEnableConnect;
}
public BleScanInfo setEnableConnect(boolean enableConnect) {
isEnableConnect = enableConnect;
return this;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByteArray(rawData);
dest.writeInt(rssi);
dest.writeByte((byte) (isEnableConnect ? 1 : 0));
}
@Override
public String toString() {
return "BleScanMessage{" +
"rawData=" + CHexConver.byte2HexStr(rawData) +
", rssi=" + rssi +
", isEnableConnect=" + isEnableConnect +
'}';
}
}

38
local_plugins/ota/ios/.gitignore

@ -1,38 +0,0 @@
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh

0
local_plugins/ota/ios/Assets/.gitkeep

22
local_plugins/ota/ios/Classes/BleManager/HandleBroadcastPtl.h

@ -1,22 +0,0 @@
//
// HandleBroadcastPtl.h
// JL_OTA
//
// Created by EzioChan on 2023/1/30.
// Copyright © 2023 Zhuhia Jieli Technology. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface HandleBroadcastPtl : NSObject
@property(nonatomic,strong,readonly)NSHashTable *delegates;
@property(nonatomic,strong)NSLock *delegateLock;
-(void)addDelegate:(id)delegate;
-(void)removeDelegate:(id)delegate;
-(void)removeAll;
@end
NS_ASSUME_NONNULL_END

53
local_plugins/ota/ios/Classes/BleManager/HandleBroadcastPtl.m

@ -1,53 +0,0 @@
//
// HandleBroadcastPtl.m
// JL_OTA
//
// Created by EzioChan on 2023/1/30.
// Copyright © 2023 Zhuhia Jieli Technology. All rights reserved.
//
#import "HandleBroadcastPtl.h"
@interface HandleBroadcastPtl()
@end
@implementation HandleBroadcastPtl
- (instancetype)init
{
self = [super init];
if (self) {
_delegates = [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory];
}
return self;
}
-(NSLock *)delegateLock{
if (_delegateLock == nil) {
_delegateLock = [NSLock new];
}
return _delegateLock;
}
-(void)addDelegate:(id)delegate{
[self.delegateLock lock];
if (![self.delegates containsObject:delegate]) {
[self.delegates addObject:delegate];
}
[self.delegateLock unlock];
}
-(void)removeDelegate:(id)delegate{
[self.delegateLock lock];
if ([self.delegates containsObject:delegate]) {
[self.delegates removeObject:delegate];
}
[self.delegateLock unlock];
}
-(void)removeAll{
[self.delegateLock lock];
[self.delegates removeAllObjects];
[self.delegateLock unlock];
}
@end

27
local_plugins/ota/ios/Classes/BleManager/JLBleEntity.h

@ -1,27 +0,0 @@
//
// JLBleEntity.h
// JL_OTA
//
// Created by 凌煊峰 on 2021/10/11.
//
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
NS_ASSUME_NONNULL_BEGIN
@interface JLBleEntity : NSObject //蓝牙设备模型
@property (strong, nonatomic) NSNumber *mRSSI;
@property (strong, nonatomic) CBPeripheral *mPeripheral;
@property (strong, nonatomic) NSString *mName;
@property (strong, nonatomic) NSString *bleMacAddress;
@property (strong, nonatomic) NSString *edrMacAddress;
@property (assign, nonatomic) uint8_t mType;
@property (assign, nonatomic) uint16_t pid;
@property (assign, nonatomic) uint16_t uid;
@end
NS_ASSUME_NONNULL_END

25
local_plugins/ota/ios/Classes/BleManager/JLBleEntity.m

@ -1,25 +0,0 @@
//
// JLBleEntity.m
// JL_OTA
//
// Created by 凌煊峰 on 2021/10/11.
//
#import "JLBleEntity.h"
@implementation JLBleEntity
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
JLBleEntity *entity = [[self class] allocWithZone:zone];
entity.mRSSI = self.mRSSI;
entity.mPeripheral = self.mPeripheral;
entity.mName = self.mName;
entity.bleMacAddress = self.bleMacAddress;
entity.edrMacAddress = self.edrMacAddress;
entity.pid = self.pid;
entity.uid = self.uid;
entity.mType = self.mType;
return entity;
}
@end

122
local_plugins/ota/ios/Classes/BleManager/JLBleManager.h

@ -1,122 +0,0 @@
//
// JLBleManager.h
// JL_OTA
//
// Created by 凌煊峰 on 2021/10/11.
//
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import <UIKit/UIKit.h>
#import <DFUnits/DFUnits.h>
#import "JLBleEntity.h"
#import "HandleBroadcastPtl.h"
#import <JL_OTALib/JL_OTALib.h>
#import <JL_HashPair/JL_HashPair.h>
#import <JL_AdvParse/JL_AdvParse.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
#pragma mark - BLE状态通知
extern NSString *kFLT_BLE_FOUND; //发现设备
extern NSString *kFLT_BLE_PAIRED; //已配对
extern NSString *kFLT_BLE_CONNECTED; //已连接
extern NSString *kFLT_BLE_DISCONNECTED; //断开连接
@protocol JLBleManagerOtaDelegate <NSObject>
@required
/**
* ota升级过程状态回调
*/
- (void)otaProgressWithOtaResult:(JL_OTAResult)result withProgress:(float)progress;
@end
@interface JLBleManager : HandleBroadcastPtl
@property (assign, nonatomic) CBManagerState mBleManagerState;
@property (strong, nonatomic) CBPeripheral *__nullable mBlePeripheral;
/// 连接蓝牙是否需要认证配对
@property (assign, nonatomic) BOOL isPaired;
/// 配对秘钥(默认为空)
@property (assign, nonatomic) NSData *pairKey;
/// 连接设备的MTU(单次最大发送数据)
@property (assign, nonatomic) NSInteger bleMtu;
/// 上一次连接的蓝牙UUID
@property (strong, nonatomic) NSString *lastUUID;
/// 上一次连接的蓝牙地址
@property (strong, nonatomic) NSString *__nullable lastBleMacAddress;
@property (strong, nonatomic) JL_OTAManager *otaManager;
@property (assign,nonatomic)BOOL isConnected;
@property (strong, nonatomic) JLBleEntity *__nullable currentEntity;
@property (nonatomic, copy, nullable) FlutterEventSink flutterEventSink;
/**
开始搜索
*/
-(void)startScanBLE:(NSString * _Nullable)address filePath:(NSString * _Nullable)filePath;
/**
停止搜索
*/
-(void)stopScanBLE;
/**
连接设备
@param peripheral 蓝牙设备类
*/
-(void)connectBLE:(CBPeripheral*)peripheral;
/**
断开连接
*/
-(void)disconnectBLE;
/**
使用UUID,重连设备。
*/
-(void)connectPeripheralWithUUID:(NSString *)uuid;
/// HID设备重连
/// - Parameter uuid: 设备 identifyString
-(void)findHid:(NSString *)uuid;
#pragma mark - 杰理蓝牙库OTA流程相关业务
typedef void(^GET_DEVICE_CALLBACK)(BOOL needForcedUpgrade);
typedef void(^CANCEL_CALLBACK)(uint8_t status);
/**
* 获取已连接的蓝牙设备信息
*/
- (void)getDeviceInfo:(GET_DEVICE_CALLBACK _Nonnull)callback;
/**
* OTA升级
*/
- (void)otaFuncWithFilePath:(NSString *)otaFilePath;
- (void)otaFuncCancel:(CANCEL_CALLBACK _Nonnull)result;
- (void)releaseAllResources;
@end
NS_ASSUME_NONNULL_END

601
local_plugins/ota/ios/Classes/BleManager/JLBleManager.m

@ -1,601 +0,0 @@
//
// JLBleManager.m
// JL_OTA
//
// Created by 凌煊峰 on 2021/10/11.
//
#import "JLBleManager.h"
#define SENDBYSINGLE 0 //1:通过信号检测发送 0:通过直接塞数据发送
NSString *kFLT_BLE_FOUND = @"FLT_BLE_FOUND"; //发现设备
NSString *kFLT_BLE_PAIRED = @"FLT_BLE_PAIRED"; //BLE已配对
NSString *kFLT_BLE_CONNECTED = @"FLT_BLE_CONNECTED"; //BLE已连接
NSString *kFLT_BLE_DISCONNECTED = @"FLT_BLE_DISCONNECTED"; //BLE断开连接
NSString *FLT_BLE_SERVICE = @"AE00"; //服务号
NSString *FLT_BLE_RCSP_W = @"AE01"; //命令“写”通道
NSString *FLT_BLE_RCSP_R = @"AE02"; //命令“读”通道
@interface JLBleManager() <CBCentralManagerDelegate, CBPeripheralDelegate,JL_OTAManagerDelegate,JLHashHandlerDelegate>
@property (strong, nonatomic) CBCentralManager *bleManager;
@property (strong, nonatomic) JLHashHandler *pairHash;
@property (assign, nonatomic) BOOL pairStatus;
@property (strong, nonatomic) NSMutableArray<JLBleEntity *> *blePeripheralArr;
@property (strong, nonatomic) CBPeripheral *bleCurrentPeripheral;
@property (strong, nonatomic) CBService * mService;
@property (strong, nonatomic) CBCharacteristic *mRcspWrite;
@property (strong, nonatomic) CBCharacteristic *mRcspRead;
@property (strong, nonatomic) NSString *selectedOtaFilePath;
@property (strong, nonatomic) NSString *connectByUUID;
@property (strong, nonatomic) GET_DEVICE_CALLBACK getCallback;
@property (strong, nonatomic) NSString *lastAddress;
@property (strong, nonatomic) NSString *lastFilePath;
@end
@implementation JLBleManager
- (instancetype)init {
self = [super init];
if (self) {
_isPaired = NO;
_pairStatus = NO;
_bleManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
/*--- JLSDK ADD ---*/
_otaManager = [JL_OTAManager getOTAManager];
[JL_OTAManager logSDKVersion];
[JLHashHandler sdkVersion];
[_otaManager logSendData:false];
_otaManager.delegate = self;
self.pairHash = [[JLHashHandler alloc] init];
self.pairHash.delegate = self;
_connectByUUID = nil;
}
return self;
}
- (void)setIsPaired:(BOOL)isPaired {
_isPaired = isPaired;
}
#pragma mark - 扫描设备相关
#pragma mark 开始扫描
- (void)startScanBLE:(NSString * _Nullable)address filePath:(NSString * _Nullable)filePath {
kJLLog(JLLOG_DEBUG, @"BLE ---> startScanBLE.");
self.lastAddress = address;
self.lastFilePath = filePath;
_blePeripheralArr = [NSMutableArray new];
if (_bleManager) {
if (_bleManager.state == CBManagerStatePoweredOn) {
[_bleManager scanForPeripheralsWithServices:nil options:nil];
} else {
__weak typeof(self) weakSelf = self;
dispatch_after(0.5, dispatch_get_main_queue(), ^{
if (weakSelf.bleManager.state == CBManagerStatePoweredOn) {
[weakSelf.bleManager scanForPeripheralsWithServices:nil options:nil];
}
});
}
}
}
#pragma mark 停止扫描
- (void)stopScanBLE {
if (_bleManager) [_bleManager stopScan];
}
#pragma mark - 蓝牙设备连接相关
#pragma mark 断开当前蓝牙设备连接
- (void)disconnectBLE {
if (_bleCurrentPeripheral) {
kJLLog(JLLOG_DEBUG, @"BLE --->To disconnectBLE.");
[_bleManager cancelPeripheralConnection:_bleCurrentPeripheral];
self.isConnected = false;
self.currentEntity = nil;
}
}
#pragma mark 连接蓝牙设备
- (void)connectBLE:(CBPeripheral*)peripheral {
if(_bleCurrentPeripheral){
[_bleManager cancelPeripheralConnection:_bleCurrentPeripheral];
}
_bleCurrentPeripheral = peripheral;
[_bleCurrentPeripheral setDelegate:self];
[_bleManager connectPeripheral:_bleCurrentPeripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
[_bleManager stopScan];
kJLLog(JLLOG_DEBUG, @"BLE Connecting... Name ---> %@", peripheral.name);
}
- (void)connectPeripheralWithUUID:(NSString*)uuid {
_connectByUUID = uuid;
[self startScanBLE:self.lastAddress filePath:self.lastFilePath];
}
-(void)findHid:(NSString *)uuid{
NSUUID *uuidNs = [[NSUUID alloc] initWithUUIDString:uuid];
NSArray *array = [self.bleManager retrievePeripheralsWithIdentifiers:@[uuidNs]];
for (CBPeripheral *cbp in array) {
if([cbp.identifier.UUIDString isEqualToString:uuid]){
kJLLog(JLLOG_DEBUG, @"reconnect:%@",cbp);
[self connectBLE:cbp];
break;
}
}
}
-(void)connectAction{
if(self.connectByUUID == nil) return;
NSArray *uuidArr = @[[[NSUUID alloc] initWithUUIDString:self.connectByUUID]];
NSArray *phArr = [_bleManager retrievePeripheralsWithIdentifiers:uuidArr];//serviceUUID就是你首次连接配对的蓝牙
if (phArr.count == 0) {
return;
}
CBPeripheral* peripheral = phArr[0];
if (phArr.firstObject && [phArr.firstObject state] != CBPeripheralStateConnected && [phArr.firstObject state] != CBPeripheralStateConnecting) {
NSString *ble_name = peripheral.name;
NSString *ble_uuid = peripheral.identifier.UUIDString;
kJLLog(JLLOG_DEBUG, @"FLT Connecting(Last)... Name ---> %@ UUID:%@",ble_name,ble_uuid);
_bleCurrentPeripheral = peripheral;
[_bleCurrentPeripheral setDelegate:self];
[_bleManager connectPeripheral:_bleCurrentPeripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
_connectByUUID = nil;
}
}
#pragma mark - CBCentralManagerDelegate
#pragma mark 蓝牙初始化 Callback
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
_mBleManagerState = central.state;
if (_mBleManagerState != CBManagerStatePoweredOn) {
self.mBlePeripheral = nil;
self.blePeripheralArr = [NSMutableArray array];
}
}
#pragma mark 发现设备
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
NSString *ble_name = advertisementData[@"kCBAdvDataLocalName"];
NSData *ble_AD = advertisementData[@"kCBAdvDataManufacturerData"];
if (ble_name.length == 0) return;
kJLLog(JLLOG_DEBUG, @"发现 ----> NAME:%@ RSSI:%@ AD:%@", ble_name,RSSI,ble_AD);
if (ble_AD.length >= 29) {
const uint8_t *bytes = ble_AD.bytes;
NSMutableString *macStr = [NSMutableString string];
for (int i = 7; i <= 12; i++) {
uint8_t macByte = bytes[i] ^ 0x5A;
[macStr appendFormat:@"%02X", macByte];
if (i < 12) [macStr appendString:@":"];
}
[self addPeripheral:peripheral Info:macStr];
}
[[NSNotificationCenter defaultCenter] postNotificationName:kFLT_BLE_FOUND object:_blePeripheralArr userInfo:nil];
// ota升级过程,回连使用
if ([JLAdvParse otaBleMacAddress:self.lastBleMacAddress isEqualToCBAdvDataManufacturerData:ble_AD]) {
[self connectBLE:peripheral];
}
}
- (void)addPeripheral:(CBPeripheral*)peripheral Info:(NSString*)macStr {
kJLLog(JLLOG_DEBUG, @"BLE addPeripheral ---> Device %@", peripheral.name);
if (self.lastAddress && [macStr isEqualToString:self.lastAddress]) {
[self stopScanBLE];
[self connectBLE:peripheral];
}
}
#pragma mark 设备连接回调
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
kJLLog(JLLOG_DEBUG, @"BLE Connected ---> Device %@", peripheral.name);
for (JLBleEntity *entity in self.blePeripheralArr) {
if([entity.mPeripheral.identifier.UUIDString isEqualToString:peripheral.identifier.UUIDString]){
self.currentEntity = entity;
break;
}
}
self.isConnected = YES;
_otaManager.mBLE_NAME = peripheral.name;
_otaManager.mBLE_UUID = peripheral.identifier.UUIDString;
[DFNotice post:kFLT_BLE_CONNECTED Object:peripheral];
// 连接成功后,查找服务
[peripheral discoverServices:nil];
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error {
kJLLog(JLLOG_DEBUG, @"Err:BLE Connect FAIL ---> Device:%@ Error:%@",peripheral.name,[error description]);
}
#pragma mark 设备断开连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error {
kJLLog(JLLOG_DEBUG, @"BLE Disconnect ---> Device %@ error:%d", peripheral.name, (int)error.code);
[_otaManager noteEntityDisconnected];
self.isConnected = NO;
self.pairStatus = NO;
/*--- UI刷新,设备断开 ---*/
[[NSNotificationCenter defaultCenter] postNotificationName:kFLT_BLE_DISCONNECTED object:peripheral];
}
#pragma mark - CBPeripheralDelegate
#pragma mark 设备服务回调
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error {
if (error) { kJLLog(JLLOG_DEBUG, @"Err: Discovered services fail."); return; }
_mBlePeripheral = peripheral;
for (CBService *service in peripheral.services) {
//如果我们知道要查询的特性的CBUUID,可以在参数一中传入CBUUID数组。
//if ([service.UUID.UUIDString isEqual:FLT_BLE_SERVICE]) {
kJLLog(JLLOG_DEBUG, @"BLE Service ---> %@", service.UUID.UUIDString);
[peripheral discoverCharacteristics:nil forService:service];
//break;
//}
}
}
#pragma mark 设备特征回调
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error {
if (error) { kJLLog(JLLOG_DEBUG, @"Err: Discovered Characteristics fail."); return; }
if ([service.UUID.UUIDString isEqual:FLT_BLE_SERVICE]) {
for (CBCharacteristic *character in service.characteristics) {
/*--- RCSP ---*/
if ([character.UUID.UUIDString isEqual:FLT_BLE_RCSP_W]) {
kJLLog(JLLOG_DEBUG, @"BLE Get Rcsp(Write) Channel ---> %@",character.UUID.UUIDString);
self.mRcspWrite = character;
}
if ([character.UUID.UUIDString isEqual:FLT_BLE_RCSP_R]) {
kJLLog(JLLOG_DEBUG, @"BLE Get Rcsp(Read) Channel ---> %@",character.UUID.UUIDString);
self.mRcspRead = character;
[peripheral setNotifyValue:YES forCharacteristic:character];
if(self.mRcspRead.properties == CBCharacteristicPropertyRead){
[peripheral readValueForCharacteristic:character];
kJLLog(JLLOG_DEBUG, @"BLE Rcsp(Read) Read Value For Characteristic.");
}
}
}
}
}
#pragma mark 更新通知特征的状态
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error {
if (error) { kJLLog(JLLOG_DEBUG, @"Err: Update NotificationState For Characteristic fail."); return; }
if ([characteristic.service.UUID.UUIDString isEqual:FLT_BLE_SERVICE] &&
[characteristic.UUID.UUIDString isEqual:FLT_BLE_RCSP_R] &&
characteristic.isNotifying == YES)
{
__weak typeof(self) weakSelf = self;
self.bleMtu = [peripheral maximumWriteValueLengthForType:CBCharacteristicWriteWithoutResponse];
kJLLog(JLLOG_DEBUG, @"BLE ---> MTU:%lu",(unsigned long)self.bleMtu);
if (self.isPaired == YES) {
[_pairHash hashResetPair];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//设备认证
[self->_pairHash bluetoothPairingKey:self.pairKey Result:^(BOOL ret) {
if(ret){
weakSelf.lastUUID = peripheral.identifier.UUIDString;
weakSelf.lastBleMacAddress = nil;
[self postBlePairedNotificationWithPeripheral:peripheral];
[weakSelf.otaManager noteEntityConnected];
weakSelf.pairStatus = YES;
}else{
kJLLog(JLLOG_DEBUG, @"JL_Assist Err: bluetooth pairing fail.");
[weakSelf.bleManager cancelPeripheralConnection:peripheral];
}
}];
});
}else{
self.lastUUID = peripheral.identifier.UUIDString;
self.lastBleMacAddress = nil;
[self postBlePairedNotificationWithPeripheral:peripheral];
[self.otaManager noteEntityConnected];
}
}
self.isConnected = YES;
}
- (void)postBlePairedNotificationWithPeripheral:(CBPeripheral *)peripheral {
[[NSNotificationCenter defaultCenter] postNotificationName:kFLT_BLE_PAIRED object:peripheral];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self getDeviceInfo:^(BOOL needForcedUpgrade) {
kJLLog(JLLOG_DEBUG, @"getDeviceInfo:%d",__LINE__);
if (needForcedUpgrade) {
kJLLog(JLLOG_DEBUG, @"设备需要强制升级,请到升级界面选择ota升级文件进行升级!");
}
[self otaFuncWithFilePath:self.lastFilePath];
}];
});
}
#pragma mark 设备返回的数据 GET
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (error) { kJLLog(JLLOG_DEBUG, @"Err: receive data fail."); return; }
if(_isPaired == YES && _pairStatus == NO){
//收到设备的认证交互数据
[_pairHash inputPairData:characteristic.value];
}else{
//收到的设备数据,正常通讯数据
[_otaManager cmdOtaDataReceive:characteristic.value];
}
}
- (void)peripheralIsReadyToSendWriteWithoutResponse:(CBPeripheral *)peripheral{
}
#pragma mark - 杰理蓝牙库OTA流程相关业务
/**
* 获取已连接的蓝牙设备信息,这里如果上次设备升级没有成功,会要求执行otaFuncWithFilePath:强制升级
*/
- (void)getDeviceInfo:(GET_DEVICE_CALLBACK _Nonnull)callback {
/*--- 获取设备信息 ---*/
_getCallback = callback;
[_otaManager cmdTargetFeature];
}
/**
* ota升级
* @param otaFilePath ota升级文件路径
*/
- (void)otaFuncWithFilePath:(NSString *)otaFilePath {
kJLLog(JLLOG_DEBUG, @"current otaFilePath ---> %@", otaFilePath);
if (self.flutterEventSink) {
self.flutterEventSink(@{
@"event": @"onStartOTA",
@"type": @0,
@"progress": @0.0,
@"code": @8,
@"message": @"开始升级"
});
}
self.selectedOtaFilePath = otaFilePath;
NSData *otaData = [[NSData alloc] initWithContentsOfFile:otaFilePath];
[_otaManager cmdOTAData:otaData Result:^(JL_OTAResult result, float progress) {
for (id<JLBleManagerOtaDelegate> objc in self.delegates) {
if([objc respondsToSelector:@selector(otaProgressWithOtaResult:withProgress:)]){
[objc otaProgressWithOtaResult:result withProgress:progress];
}
}
}];
}
- (void)otaFuncCancel:(CANCEL_CALLBACK _Nonnull)result{
[_otaManager cmdOTACancelResult:^(uint8_t status, uint8_t sn, NSData * _Nullable data) {
result(status);
}];
}
//MARK: - ota manager delegate callback
-(void)otaCancel{
//TODO: 取消OTA升级回调
}
-(void)otaUpgradeResult:(JL_OTAResult)result Progress:(float)progress{
//TODO: 设备升级过程回调,包括进度状态
kJLLog(JLLOG_DEBUG, @"otaUpgradeResult ---> %u", result);
if (result == JL_OTAResultPreparing) {
if (self.flutterEventSink) {
self.flutterEventSink(@{
@"event": @"onProgress",
@"type": @0,
@"progress": @(progress * 100),
@"code": @(result),
@"message": @"开始升级"
});
}
} else if (result == JL_OTAResultUpgrading) {
if (self.flutterEventSink) {
self.flutterEventSink(@{
@"event": @"onProgress",
@"type": @1,
@"progress": @(progress * 100),
@"code": @(result),
@"message": @"开始升级"
});
}
} else if (result == JL_OTAResultPrepared) {
} else if (result == JL_OTAResultReconnect) {
} else if (result == JL_OTAResultReconnectWithMacAddr) {
} else if (result == JL_OTAResultSuccess) {
if (self.flutterEventSink) {
self.flutterEventSink(@{
@"event": @"onStopOTA",
@"type": @0,
@"progress": @0.0,
@"code": @(result),
@"message": @"升级成功"
});
}
} else if (result == JL_OTAResultReboot) {
} else if (result == JL_OTAResultDisconnect) {
} else {
if (self.flutterEventSink) {
self.flutterEventSink(@{
@"event": @"onError",
@"type": @0,
@"progress": @0.0,
@"code": @(result),
@"message": @"升级失败"
});
}
}
}
-(void)otaDataSend:(NSData *)data{
[self writeDataByCbp:data];
}
-(void)otaFeatureResult:(JL_OTAManager *)manager{
kJLLog(JLLOG_DEBUG, @"getDeviceInfo:%d",__LINE__);
if (manager.otaStatus == JL_OtaStatusForce) {
kJLLog(JLLOG_DEBUG, @"---> 进入强制升级.");
if (self.selectedOtaFilePath) {
[self otaFuncWithFilePath:self.selectedOtaFilePath];
} else {
_getCallback(true);
}
return;
} else {
if (manager.otaHeadset == JL_OtaHeadsetYES) {
kJLLog(JLLOG_DEBUG, @"---> 进入强制升级: OTA另一只耳机.");
if (self.selectedOtaFilePath) {
[self otaFuncWithFilePath:self.selectedOtaFilePath];
} else {
_getCallback(true);
}
return;
}
}
kJLLog(JLLOG_DEBUG, @"---> 设备正常使用...");
dispatch_async(dispatch_get_main_queue(), ^{
/*--- 获取公共信息 ---*/
[self->_otaManager cmdSystemFunction];
self->_getCallback(false);
});
}
//MARK: - Hash pair delegate callback
-(void)hashOnPairOutputData:(NSData *)data{
[self writeDataByCbp:data];
}
//MARK: - data send manager
/// 需要分包发送
/// - Parameter data: 数据
-(void)writeDataByCbp:(NSData *)data{
// kJLLog(JLLOG_DEBUG, @"%s:data:%@",__func__,data);
if (_mBlePeripheral && self.mRcspWrite) {
if (data.length > 0 ) {
NSInteger len = data.length;
while (len>0) {
if (len <= _bleMtu) {
NSData *mtuData = [data subdataWithRange:NSMakeRange(0, data.length)];
[self selectSendAction:mtuData];
len -= data.length;
}else{
NSData *mtuData = [data subdataWithRange:NSMakeRange(0, _bleMtu)];
[self selectSendAction:mtuData];
len -= _bleMtu;
data = [data subdataWithRange:NSMakeRange(_bleMtu, len)];
}
}
}
}else{
//需要先赋值写特征的内容
kJLLog(JLLOG_DEBUG, @"need to init");
}
}
-(void)selectSendAction:(NSData *)data{
[_mBlePeripheral writeValue:data
forCharacteristic:self.mRcspWrite
type:CBCharacteristicWriteWithoutResponse];
}
//MARK: - 通过信号阀发送
- (void)singleDidSendData:(NSData *)data{
[_mBlePeripheral writeValue:data
forCharacteristic:self.mRcspWrite
type:CBCharacteristicWriteWithoutResponse];
}
- (void)releaseAllResources {
// 停止扫描
[self stopScanBLE];
// 断开蓝牙连接
[self disconnectBLE];
// 释放 delegate
self.bleManager.delegate = nil;
self.pairHash.delegate = nil;
self.otaManager.delegate = nil;
// 清空 eventSink
self.flutterEventSink = nil;
// 清空回调
self.getCallback = nil;
// 清空当前设备和属性
self.bleCurrentPeripheral = nil;
self.mService = nil;
self.mRcspWrite = nil;
self.mRcspRead = nil;
self.currentEntity = nil;
self.blePeripheralArr = nil;
self.selectedOtaFilePath = nil;
self.connectByUUID = nil;
self.lastAddress = nil;
self.lastFilePath = nil;
}
@end

60
local_plugins/ota/ios/Classes/OtaPlugin.swift

@ -1,60 +0,0 @@
import Flutter
public class OtaPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
var userManager: JLBleManager?
var eventSink: FlutterEventSink?
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "ota", binaryMessenger: registrar.messenger())
let eventChannel = FlutterEventChannel(name: "com.example.ota/events", binaryMessenger: registrar.messenger())
let instance = OtaPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
eventChannel.setStreamHandler(instance)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let arguments = call.arguments as? [String: Any]
switch call.method {
case "init":
userManager = JLBleManager.init()
result("")
case "startUpgrading":
let address = arguments?["address"] as? String
let filePath = arguments?["filePath"] as? String
startUpgrading(address: address, filePath: filePath)
result("")
case "onOtaClose":
onOtaClose()
result("")
default:
result(FlutterMethodNotImplemented)
}
}
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
eventSink = events
return nil
}
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
eventSink = nil
userManager?.flutterEventSink = nil
return nil
}
private func startUpgrading(address: String?, filePath: String?) {
if userManager?.mBleManagerState == CBManagerState.poweredOn {
userManager?.flutterEventSink = eventSink
userManager?.startScanBLE(address, filePath: filePath)
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
self.userManager?.stopScanBLE()
}
}
}
private func onOtaClose() {
userManager?.releaseAllResources()
userManager = nil
}
}

BIN
local_plugins/ota/ios/Frameworks/DFUnits.framework/DFUnits

Binary file not shown.

28
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/AESx.h

@ -1,28 +0,0 @@
//
// AES_DF.h
// WifiAudio
//
// Created by zhjl on 15-5-29.
// Copyright (c) 2015年 ZH-jl. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface AESx : NSObject
+(id)shared;
-(unsigned int)Dcs_EnCodeSrc:(char *)src
Des:(char *)des
Lenghts:(unsigned int)lengths
Key:(char *)key;
-(void)Dcs_DeCodeSrc:(char *)src
Des:(char *)des
Lengths:(unsigned int)lengths
Key:(char *)key;
-(unsigned int)ns_crc32Buffer:(const unsigned char *)buffer
Lenght:(unsigned int)len;
@end

82
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFAction.h

@ -1,82 +0,0 @@
//
// DFAction.h
// DFUnits
//
// Created by DFung on 16/1/25.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void(^Action)(void);
@interface DFAction : NSObject
/**
* @how:Execution block on Asynchronous thread.
*/
+(void)subTask:(Action)block;
/**
* @how:Execution block on Synchronization thread.
*/
+(void)mainTask:(Action)block;
/**
* @how:Execution some blocks asynchronousily and make a summary.
* @tasks block Array
* @block final block
*/
+(void)subTasks:(NSArray*)tasks Final:(Action)block;
/**
* @how:Execution block after a few seconds.
* @param sec Delay time
* @param block Code block
*/
+(void)delay:(double)sec Task:(Action)block;
/**
* @how:Execution block only once.
* @param block Code block
*/
+(void)taskOnce:(Action)block;
/**
* @how:Execution block N times.
* @param block Code block
* @param times N
*/
+(void)task:(Action)block Times:(int)times;
/**
* 设置执行代码的最小时间间隔gap。
* 返回 YES:大于gap,建议继续执行。
* 返回 NO: 小于gap,建议代码return。
*/
+(BOOL)setMinExecutionGap:(NSTimeInterval)gap;
/**
* @how:定时处理.
* @return NSTimer
*/
+(NSTimer*)timingStart:(SEL)sel target:(id)objc Time:(NSTimeInterval)sec;
/**
* @how:暂停定时处理.
* @return NSTimer
*/
+(void)timingPause:(__weak NSTimer*)timer;
/**
* @how:继续定时处理.
* @return NSTimer
*/
+(void)timingContinue:(__weak NSTimer*)timer;
/**
* @how:摧毁定时处理功能.
*/
+(void)timingStop:(__weak NSTimer*)timer;
@end

173
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFAudio.h

@ -1,173 +0,0 @@
//
// DFAudio.h
// DFUnits
//
// Created by DFung on 16/1/22.
// Copyright © 2016年 DFung. All rights reserved.
//
/**
* 科普: 数据量(字节/秒)= (采样频率(Hz) * 采样位数(bit) * 声道数) / 8
*/
#import <Foundation/Foundation.h>
#import <AudioUnit/AudioUnit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#include <stdio.h>
#include <stdlib.h>
/**
* 【DFAudio】状态回调
*/
#define kDFAudio_ST @"NOTE_DFAUDIO_ST"
/**
* 【DFAudio】播放进度(时间)
*/
#define kDFAudio_PG @"NOTE_DFAUDIO_PG"
/**
* 【DFAudio】录音数据
*/
#define kDFAudio_REC @"NOTE_DFAUDIO_REC"
typedef enum : NSUInteger {
DFAudio_ST_STOP, //停止状态
DFAudio_ST_PLAYING, //播放状态
DFAudio_ST_PENDING, //等待状态
DFAudio_ST_RECORDING, //录音状态
} DFAudio_ST;
struct DF_Data
{
int size;
unsigned char *data;
};
@class DFAudioFormat;
@interface DFAudio : NSObject
#pragma mark 播放
/**
* 用途:初始化【Player】
* @param size 缓存大小
* @param format (默认 采样率=8000,采样位数=16,声道数=1)
*/
-(void)setPlayerBufferSize:(int32_t)size
Format:(DFAudioFormat*)format;
/**
* 用途:输入音频数据。
* @param data 音频数据
*/
-(void)didPlayerInputBuffer:(NSData*)data;
/**
PCM缓存可用空间。
@return 大小
*/
-(uint32_t)didRingUsable;
/**
* 用途:运行【Player】
*/
-(void)didPlayerStart;
/**
* 用途:停止【Player】
*/
-(void)didPlayerStop;
/**
* 用途:关闭并释放【Player】
*/
-(void)didPlayerRelease;
#pragma mark 录音
/**
* 用途:初始化【Recorder】
* @param format (默认 采样率=8000,采样位数=16,声道数=1)
* @tips 用【kDFAudio_REC】通知回调录音数据。
*/
-(void)setRecorderFormat:(DFAudioFormat*)format;
/**
* 用途:运行【Recorder】
*/
-(void)didRecorderStart;
/**
* 用途:停止【Recorder】
*/
-(void)didRecorderStop;
/**
* 用途:完成【Recorder】
*/
-(void)didRecorderFinished;
/**
* 用途:关闭并释放【Recorder】
*/
-(void)didRecorderRelease;
#pragma mark PCM <-> WAV 互转
/**
* 用途:wav转换成pcm
*/
+(NSString*)wavToPcm:(NSString*)wavPath;
/**
* 用途:pcm转换成Wav
*/
+(NSString*)pcmToWav:(NSString*)pcmPath Format:(DFAudioFormat*)format;
#pragma mark 设置PCM参数
+(void)setPcmFormat:(DFAudioFormat *)format;
#pragma mark 检测PCM数据 音量分贝
+(double)checkPcmDB:(NSData*)pcmData;
#pragma mark super vad
/**
* return
* --> 0 : vad prepare.
* --> 1 : vad start.
* --> 2 : vad end.
*/
+(int)vadPcm:(NSData*)pcm MinDB:(float)db;
#pragma mark super vad + path
/**
* return
* --> 0 : vad prepare.
* --> 1 : vad start.
* --> 2 : vad end. (此时path为断句路径)
*/
+(int)vadPcm:(NSData*)pcm MinDB:(float)db Path:(NSString*)path;
/**
* clean vad cache
*/
+(void)vadClean;
@end
@interface DFAudioFormat : NSObject
@property(nonatomic,assign)Float64 mSampleRate;
@property(nonatomic,assign)UInt32 mBitsPerChannel;
@property(nonatomic,assign)UInt32 mChannelsPerFrame;
@property(nonatomic,assign)AudioFormatID mFormatID;
@end

123
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFCircleTextView.h

@ -1,123 +0,0 @@
//
// DFCircleTextView.h
//
// Created by DFung on 2017/6/15.
// Copyright © 2017年 DFung All rights reserved.
//
#import <UIKit/UIKit.h>
typedef enum {
DFCircleTextAlignOutside,
DFCircleTextAlignCenter,
DFCircleTextAlignInside
} DFCircleTextAlignment;
@interface DFCircleTextView : UIView
/**
* Set the text to display in the DFCircleTextView
*/
@property (strong, nonatomic) NSString *text;
/**
* Set the Text Attributes for the text.
* Refer to the Text Attributes documentation for more info.
*/
@property (strong, nonatomic) NSDictionary *textAttributes;
/**
* Align the text left, right or center reletive to the baseAngle.
*/
@property (nonatomic) NSTextAlignment textAlignment;
/**
* Align the text inside, outside or centered on the circle.
*/
@property (nonatomic) DFCircleTextAlignment circleTextAlignment;
/**
* Set the radius of the circle.
* When no radius is set, the maximum radius is calculated and used.
*/
@property (nonatomic) float radius;
/**
* Set the base angle. See textAlignment property for more information.
*/
@property (nonatomic) float baseAngle;
/**
* Adjust the spacing of the characters.
* 1 = default spacing, 0.5 = half spacing, 2 = double spacing, etc ...
*/
@property (nonatomic) float characterSpacing;
/**
* Disable the kerning cache.
*/
@property (nonatomic) BOOL disableKerningCache;
/**
* Clear the kerning cache.
* Note that this is automaticlly done when the app gives a memory warning.
*/
- (void)clearKerningCache;
/**
* Convenience function for quickly changing the textColor
* without the need of creating an NSDictionary *textAttributes
*/
- (void) setColor:(UIColor *)color;
/**
* text display from right side.
*/
-(void)showFromRight;
/**
* text display from left side.
*/
-(void)showFromLeft;
/**
* text display from outside.
*/
-(void)showFromOutside;
/**
* text display from inside.
*/
-(void)showFromInside;
/**
* text display from bothside.
*/
-(void)showFromBothSide;
/**
* text display from center.
*/
-(void)showFromCenter;
/**
* text will rotate.
*/
-(void)showRotateWise:(BOOL)wise;
@end

39
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFContacts.h

@ -1,39 +0,0 @@
//
// DFContacts.h
// DFUnits
//
// Created by DFung on 2018/4/19.
// Copyright © 2018年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
//#define JL_CONTACTS_ENABLE
#ifdef JL_CONTACTS_ENABLE
#import <Contacts/Contacts.h>
@interface DFContacts : NSObject
/**
* keys: @[CNContactPhoneNumbersKey, 手机号
* CNContactFamilyNameKey, 姓氏
* CNContactGivenNameKey 名字
* ...,nil ]; @see <Contacts/Contacts.h> 内有详情。
* 选择需要的信息。
*
* contacts:返回NSArray<CNContact>。
* flag:0=成功,-1=用户拒绝,-2=需在设置界面开启通讯录,-3=参数有误;
*/
+(void)scanContactsWithKeys:(NSArray*)keys
Result:(void(^)(NSArray*contacts,
int flag))result;
/**
* 简单解析 contacts
* {@"FamilyName":@"...",
* @"GivenName":@"...",
* @"Phones":@[@"iphone":@"110",@"home":@"456",...]}
*/
+(NSDictionary*)openContact:(CNContact*)contact;
@end
#endif

33
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFCrc16.h

@ -1,33 +0,0 @@
//
// DFCrc16.h
// DFUnits
//
// Created by DFung on 2017/3/6.
// Copyright © 2017年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
#include <unistd.h>
#include <_types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@interface DFCrc16 : NSObject
/**
* 单独Crc16值.
*/
+(uint16_t)didCrc16:(uint8_t*)pt
Length:(uint16_t)len;
/**
* 累加Crc16值.
*/
+(uint16_t)didCrc16All:(uint8_t*)pt
Length:(uint16_t)len
CrcValue:(uint16_t)value;
/**
* 清除Crc值.
*/
+(void)didResetCrc;
@end

32
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFFadeLabel.h

@ -1,32 +0,0 @@
//
// DFFadeLabel.h
// DFUnits
//
// Created by DFung on 2017/6/15.
// Copyright © 2017年 DFung. All rights reserved.
//
#import <UIKit/UIKit.h>
/**
DFFadeLabel is a UIView subclass adds a UILabel effect when the text of a label instance outgrows the available width. Instances of `DFLabel` can be configured
for label fading or unFading toward Right、Left、Up、Down.
*/
typedef enum : NSUInteger {
DFFadeLabel_TYPE_LEFT,
DFFadeLabel_TYPE_RIGHT,
DFFadeLabel_TYPE_UP,
DFFadeLabel_TYPE_DOWN,
DFFadeLabel_TYPE_CENTER,
DFFadeLabel_TYPE_BOTHSIDE
} DFFadeLabel_TYPE;
@interface DFFadeLabel : UIView
@property(nonatomic,strong)UILabel*label;
@property(nonatomic,strong)NSString *text;
-(void)showFromDirection:(DFFadeLabel_TYPE)type;
@end

125
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFFile.h

@ -1,125 +0,0 @@
//
// DFFile.h
// DVRunning
//
// Created by Mac on 15/11/13.
// Copyright (c) 2015年 DevinVon. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DFFile : NSObject
/**
* 用途:在存在的路径上,创建一个文件。
* @param path 你喜欢的路径
*/
+(BOOL)createPath:(NSString*)path;
/**
* 用途:【创建】一个文件,在你想要的路径下。
* @param sPath 系统路径
* @param mPath 中途路径 -->> @"test1/test2/test3" <<--
* @param file 文件名
*/
+(NSString*)createOn:(NSSearchPathDirectory)sPath
MiddlePath:(NSString*)mPath
File:(NSString*)file;
/**
* 用途:生成一个文件路径字符串。
* @param sPath 系统路径
* @param mPath 中途路径 -->> @"test1/test2/test3" <<--
* @param file 文件名
*/
+(NSString*)listPath:(NSSearchPathDirectory)sPath
MiddlePath:(NSString*)mPath
File:(NSString*)file;
/**
* 用途:【查找】一个文件,在你想要的路径下。
* @param sPath 系统路径
* @param mPath 中途路径 -->> @"test1/test2/test3" <<--
* @param file 文件名
*/
+(NSString*)findPath:(NSSearchPathDirectory)sPath
MiddlePath:(NSString*)mPath
File:(NSString*)file;
/**
* 用途:Byte单位转换成KB,MB,GB
* @param byte 多少bytes?
*/
+(NSString*)fileByte:(long long)byte;
/**
* 用途:重命名。
* @param oldName 旧的文件(路径) -->> @"test1/test2/test3" <<--
* @param NewName 新的文件(路径) -->> @"test1/test2/test3" <<--
*/
+(BOOL)renameOldName:(NSString*)oldName
NewName:(NSString*)newName;
/**
* 用途:删除文件。
* @param path 文件路径
*/
+(BOOL)removePath:(NSString*)path;
/**
* 用途:把数据写进文件(覆盖)。
* @param data 数据字节
* @param path 文件路径
*/
+(BOOL)writeData:(NSData*)data fillFile:(NSString*)path;
/**
* 用途:把数据写进文件(文件末尾)。
* @param data 数据字节
* @param path 文件路径
*/
+(void)writeData:(NSData*)data endFile:(NSString*)path;
/**
* 用途:从bundle里寻找文件。
* @param bundle @"*.bundle"
* @param file 文件名
*/
+(NSString*)find:(NSString*)bundle File:(NSString*)file;
/**
* 用途:从Project资源里寻找文件。
* (先把资源文件添加至工程内的Copy Bundle Resources内。)
* @param file 文件名
* @return 该文件的路径。
*/
+(NSString*)find:(NSString *)file;
/**
* 用途:解析JSON文件。
* @param path 文件路径
*/
+(id)JsonPath:(NSString*)path;
/**
* 用途:解析JSON数据。
* @param data jsonData
*/
+(id)JsonData:(NSData*)data;
/**
* 用途:读取文件字符串。
* @param path 文件路径
*/
+(NSString*)stringPath:(NSString*)path;
/**
* 用途:文件夹内文件元素。
* @param path 文件夹路径
*/
+(NSArray*)subPaths:(NSString*)path;
/**
* 用途:文件大小。
* @param path 文件夹路径
* @return 该文件的大小。
*/
+(long long)sizeOfFile:(NSString*)path;
@end

25
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFGzip.h

@ -1,25 +0,0 @@
//
// DFGzip.h
// DFUnits
//
// Created by DFung on 2016/12/13.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DFGzip : NSObject
/**
* Gzip 解压(Need Include => libz.1.2.8.tbd)
*/
+(NSData *)uncompressZippedData:(NSData *)compressedData;
/**
* Gzip 压缩(Need Include => libz.1.2.8.tbd)
*/
+(NSData *)gzipData:(NSData *)pUncompressedData;
@end

24
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFHmacMD5.h

@ -1,24 +0,0 @@
//
// DFHmacMD5.h
// DFUnits
//
// Created by DFung on 2016/12/13.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DFHmacMD5 : NSObject
/*
* MD5加密32位
*/
+ (NSString *)HmacMD5String:(NSString *)string;
/*
* HmacMD5加密
*/
+ (NSString *)HmacMD5String:(NSString *)string
Key:(NSString *)keyStr;
@end

70
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFHttp.h

@ -1,70 +0,0 @@
//
// DFHttp.h
// DFUnits
//
// Created by DFung on 16/1/22.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
@class DFHttp;
@protocol DFHttpDelegate <NSObject>
@optional
-(void)http:(DFHttp*)http didFail:(NSError*)error;
-(void)http:(DFHttp*)http didSuccess:(NSString*)path;
-(void)http:(DFHttp*)http progress:(float)rate;
@end
@interface DFHttp : NSObject
@property(assign,nonatomic)int tag;
@property(assign,nonatomic)id <DFHttpDelegate>delegate;
/*
* Set info[@"URL"];
* info[@"PATH"];
*/
-(void)down:(NSDictionary*)info;
-(void)cancelTask;
/*
Returns a new string made from the receiver by replacing
all characters not in the allowedCharacters set with percent
encoded characters. UTF-8 encoding is used to determine the
correct percent encoded characters. Entire URL strings cannot
be percent-encoded. This method is intended to percent-encode
an URL component or subcomponent string, NOT the entire URL
string. Any characters in allowedCharacters outside of the
7-bit ASCII range are ignored.
*/
+(NSString*)encodeURL:(NSString*)url;
/*
Returns a new string made from the receiver by replacing
all percent encoded sequences with the matching UTF-8 characters.
*/
+(NSString*)decodeURL:(NSString*)url;
/**
* 异步请求(GET)
*/
+(void)getWithUrl:(NSString*)url
Result:(void(^)(id ret, NSURLResponse *rps))block;
/**
* 异步请求(POST)
*/
+(void)postWithUrl:(NSString*)url
Body:(NSString*)body
Result:(void(^)(id ret, NSURLResponse *rps))block;
@end

29
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFHttp1.h

@ -1,29 +0,0 @@
//
// DFHttp1.h
// DFUnits
//
// Created by 杰理科技 on 2021/4/1.
// Copyright © 2021 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(UInt8, DF_HTTP1_Result) {
DF_HTTP1_ResultFail = 0x00, //下载失败
DF_HTTP1_ResultSuccess = 0x01, //下载成功
DF_HTTP1_ResultStart = 0x02, //开始下载
DF_HTTP1_ResultDownload = 0x03, //正在下载
DF_HTTP1_ResultCancel = 0x04, //正在取消
};
typedef void(^DF_HTTP1_BK)(float progress,NSData *__nullable data, DF_HTTP1_Result result);
@interface DFHttp1 : NSObject
-(void)httpDownload:(NSString*)url Result:(DF_HTTP1_BK __nullable)result;
-(void)httpCancelTask;
@end
NS_ASSUME_NONNULL_END

57
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFImage.h

@ -1,57 +0,0 @@
//
// DFImage.h
// DFUnits
//
// Created by DFung on 16/1/22.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface DFImage : NSObject
/**
* 用途:压缩图片。
* @param srcImage 待压缩的图片
* @param scale 压缩比
*/
+(NSData*)compressImage:(UIImage *)srcImage Scale:(double)scale;
/**
* 用途:从Project资源里寻找图片文件。
* @param image 图片名 -->> @"test@2x.png" <<--
*/
+(UIImage*)loadImage:(NSString*)image;
/**
* @use 图片模糊处理
* @param image 图片数据
* @param blur 模糊值,取值[0,1]
* @return 模糊后的图片
*/
+(UIImage*)blurImage:(UIImage*)image Blur:(CGFloat)blur;
/**
* @use 图片模糊处理
* @param image 图片数据
* @param blur 模糊值,取值[0,1]
* @param color 背景色调
* @return 模糊后的图片
*/
+(UIImage*)blurImage:(UIImage*)image Blur:(CGFloat)blur TintColor:(UIColor*)color;
/**
* @use 屏幕截图
* @param size 大小
* @param view 截取视图
* @return 截取后的图片
*/
+(UIImage*)screenshotSize:(CGSize)size OnView:(UIView*)view;
@end

534
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFLabel.h

@ -1,534 +0,0 @@
//
// DFLabel.h
// DFUnits
//
// Created by DFung on 2017/3/15.
// Copyright © 2017年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
/** An enum that defines the types of `DFLabel` scrolling */
typedef NS_ENUM(NSUInteger, DFLabelType) {
/** Scrolls left first, then back right to the original position. */
DFLeftRight = 0,
/** Scrolls right first, then back left to the original position. */
DFRightLeft = 1,
/** Continuously scrolls left (with a pause at the original position if animationDelay is set). See the `trailingBuffer` property to define a spacing between the repeating strings.*/
DFContinuous = 2,
/** Continuously scrolls right (with a pause at the original position if animationDelay is set). See the `trailingBuffer` property to define a spacing between the repeating strings.*/
DFContinuousReverse = 3
};
#ifndef IBInspectable
#define IBInspectable
#endif
/**
DFLabel is a UILabel subclass adds a scrolling DFLabel effect when the text of a label instance outgrows the available width. Instances of `DFLabel` can be configured
for label scrolling direction/looping, speed/rate, and other options.
*/
IB_DESIGNABLE
@interface DFLabel : UILabel
////////////////////////////////////////////////////////////////////////////////
/// @name Creating DFLabels
////////////////////////////////////////////////////////////////////////////////
/** Returns a newly initialized `DFLabel` instance.
The default scroll duration of 7.0 seconds and fade length of 0.0 are used.
@param frame A rectangle specifying the initial location and size of the view in its superview's coordinates. Text (for the given font, font size, etc.) that does not fit in this frame will automatically scroll.
@return An initialized `DFLabel` object or nil if the object couldn't be created.
*/
- (instancetype)initWithFrame:(CGRect)frame;
/** Returns a newly initialized `DFLabel` instance with the specified scroll rate and edge transparency fade length.
You must specify a non-zero rate, and you cannot thereafter modify the rate.
@param frame A rectangle specifying the initial location and size of the view in its superview's coordinates. Text (for the given font, font size, etc.) that does not fit in this frame will automatically scroll.
@param pixelsPerSec A rate of scroll for the label scroll animation. Must be non-zero. Note that this will be the maximum rate for ease-type animation.
@param fadeLength A length of transparency fade at the left and right edges of the `DFLabel` instance's frame.
@see fadeLength
@return An initialized `DFLabel` object or nil if the object couldn't be created.
*/
- (instancetype)initWithFrame:(CGRect)frame rate:(CGFloat)pixelsPerSec andFadeLength:(CGFloat)fadeLength;
/** Returns a newly initialized `DFLabel` instance with the specified scroll duration and edge transparency fade length.
You must specify a non-zero duration, and you cannot thereafter modify the duration.
@param frame A rectangle specifying the initial location and size of the view in its superview's coordinates. Text (for the given font, font size, etc.) that does not fit in this frame will automatically scroll.
@param scrollDuration A scroll duration the label scroll animation. Must be non-zero. This will be the duration that the animation takes for one-half of the scroll cycle in the case of left-right and right-left DFLabel types, and for one loop of a continuous DFLabel type.
@param fadeLength A length of transparency fade at the left and right edges of the `DFLabel` instance's frame.
@see fadeLength
@return An initialized `DFLabel` object or nil if the object couldn't be created.
*/
- (instancetype)initWithFrame:(CGRect)frame duration:(NSTimeInterval)scrollDuration andFadeLength:(CGFloat)fadeLength;
/** Resizes the view to the minimum size necessary to fully enclose the current text (i.e. without scrolling), up to the maximum size specified.
The current origin of the frame is retained.
@param maxSize The maximum size up to which the view should be resized. Passing `CGSizeZero` will result in no maximum size limit.
@param adjustHeight A boolean that can be used to indicate if the view's height should also be adjusted. Note that this has no impact on scrolling.
*/
- (void)minimizeLabelFrameWithMaximumSize:(CGSize)maxSize adjustHeight:(BOOL)adjustHeight;
////////////////////////////////////////////////////////////////////////////////
/// @name Configuration Options
////////////////////////////////////////////////////////////////////////////////
/** Specifies the animation curve used in the scrolling motion of the labels.
Allowable options:
- `UIViewAnimationOptionCurveEaseInOut`
- `UIViewAnimationOptionCurveEaseIn`
- `UIViewAnimationOptionCurveEaseOut`
- `UIViewAnimationOptionCurveLinear`
Defaults to `UIViewAnimationOptionCurveEaseInOut`.
*/
@property (nonatomic, assign) UIViewAnimationOptions animationCurve;
/** A boolean property that sets whether the `DFLabel` should behave like a normal UILabel.
When set to `YES` the `DFLabel` will behave like a normal UILabel, and will not begin scrolling when the text is
larger than the specified frame. The change takes effect immediately, removing any in-flight animation as well as any
current edge fade. Note that the `DFLabel` will respect the current values of the `lineBreakMode` and `textAlignment`
properties while labelized.
To simply prevent automatic scrolling, use the `holdScrolling` property.
Defaults to `NO`.
@see holdScrolling
@see lineBreakMode
@warning The label will not automatically scroll when this property is set to `YES`.
@warning The UILabel default setting for the `lineBreakMode` property is `NSLineBreakByTruncatingTail`, which truncates
the text adds an ellipsis glyph (...). Set the `lineBreakMode` property to `NSLineBreakByClipping` in order to avoid the
ellipsis, especially if using an edge transparency fade.
*/
@property (nonatomic, assign) IBInspectable BOOL labelize;
/** A boolean property that sets whether the `DFLabel` should hold (prevent) label scrolling.
When set to `YES`, the `DFLabel` will not automatically scroll even its text is larger than the specified frame,
although the specified edge fades will remain.
To set the `DFLabel` to act like a normal UILabel, use the `labelize` property.
Defaults to `NO`.
@see labelize
@warning The label will not automatically scroll when this property is set to `YES`.
*/
@property (nonatomic, assign) IBInspectable BOOL holdScrolling;
/** A boolean property that sets whether the `DFLabel` should only begin a scroll when tapped.
If this property is set to `YES`, the `DFLabel` will begin a scroll animation cycle only when tapped. The label will
not automatically being a scroll. This setting overrides the setting of the `holdScrolling` property.
Defaults to `NO` .
@warning The label will not automatically scroll when this property is set to `YES`.
@see holdScrolling
*/
@property (nonatomic, assign) IBInspectable BOOL tapToScroll;
/** Defines the direction and method in which the `DFLabel` instance scrolls.
`DFLabel` supports four types of scrolling: `DFLeftRight`, `DFRightLeft`, `DFContinuous`, and `DFContinuousReverse`.
Given the nature of how text direction works, the options for the `DFLabelType` property require specific text alignments
and will set the textAlignment property accordingly.
- `DFLeftRight` type is ONLY compatible with a label text alignment of `NSTextAlignmentLeft`.
- `DFRightLeft` type is ONLY compatible with a label text alignment of `NSTextAlignmentRight`.
- `DFContinuous` does not require a text alignment (it is effectively centered).
- `DFContinuousReverse` does not require a text alignment (it is effectively centered).
Defaults to `DFLeftRight`.
@see DFLabelType
@see textAlignment
*/
#if TARGET_INTERFACE_BUILDER
@property (nonatomic, assign) IBInspectable NSInteger labelType;
#else
@property (nonatomic, assign) DFLabelType labelType;
#endif
/** Defines the duration of the scrolling animation.
This property sets the amount of time it will take for the scrolling animation to complete a
scrolling cycle. Note that for `DFLeftRight` and `DFRightLeft`, a cycle consists of the animation away,
a pause (if a delay is specified), and the animation back to the original position.
Setting this property will automatically override any value previously set to the `rate` property, and the `rate`
property will be set to `0.0`.
@see rate
*/
@property (nonatomic, assign) IBInspectable CGFloat scrollDuration;
/** Defines the rate at which the label will scroll, in pixels per second.
Setting this property will automatically override any value previousy set to the `scrollDuration` property, and the
`scrollDuration` property will be set to `0.0`. Note that this is the rate at which the label would scroll if it
moved at a constant speed - with other animation curves the rate will be slightly different.
@see scrollDuration
*/
@property (nonatomic, assign) IBInspectable CGFloat rate;
/** A buffer (offset) between the leading edge of the label text and the label frame.
This property adds additional space between the leading edge of the label text and the label frame. The
leading edge is the edge of the label text facing the direction of scroll (i.e. the edge that animates
offscreen first during scrolling).
Defaults to `0`.
@note The value set to this property affects label positioning at all times (including when `labelize` is set to `YES`),
including when the text string length is short enough that the label does not need to scroll.
@note For `DFContinuous`-type labels, the smallest value of `leadingBuffer`, 'trailingBuffer`, and `fadeLength`
is used as spacing between the two label instances. Zero is an allowable value for all three properties.
@see trailingBuffer
@since Available in 2.1.0 and later.
*/
@property (nonatomic, assign) IBInspectable CGFloat leadingBuffer;
/** A buffer (offset) between the trailing edge of the label text and the label frame.
This property adds additional space (buffer) between the trailing edge of the label text and the label frame. The
trailing edge is the edge of the label text facing away from the direction of scroll (i.e. the edge that animates
offscreen last during scrolling).
Defaults to `0`.
@note For `DFContinuous`-type labels, the smallest value of `leadingBuffer`, 'trailingBuffer`, and `fadeLength`
is used as spacing between the two label instances. Zero is an allowable value for all three properties.
@note The value set to this property has no effect when the `labelize` property is set to `YES`.
@see leadingBuffer
@since Available in 2.1.0 and later.
*/
@property (nonatomic, assign) IBInspectable CGFloat trailingBuffer;
/**
@deprecated Use `trailingBuffer` instead. Values set to this property are simply forwarded to `trailingBuffer`.
*/
@property (nonatomic, assign) CGFloat continuousDFLabelExtraBuffer DEPRECATED_ATTRIBUTE;
/** The length of transparency fade at the left and right edges of the `DFLabel` instance's frame.
This propery sets the size (in points) of the view edge transparency fades on the left and right edges of a `DFLabel`. The
transparency fades from an alpha of 1.0 (fully visible) to 0.0 (fully transparent) over this distance. Values set to this property
will be sanitized to prevent a fade length greater than 1/2 of the frame width.
Defaults to `0`.
*/
@property (nonatomic, assign) IBInspectable CGFloat fadeLength;
/** The length of delay in seconds that the label pauses at the completion of a scroll. */
@property (nonatomic, assign) IBInspectable CGFloat animationDelay;
/** The read-only duration of the scroll animation (not including delay).
The value of this property is calculated when using the `scrollRate` property to set label animation speed. The value of this property
is equal to the value of `scrollDuration` property when using the `scrollDuration` property to set label animation speed.
@see scrollDuration
@see scrollRate
*/
@property (nonatomic, readonly) NSTimeInterval animationDuration;
////////////////////////////////////////////////////////////////////////////////
/// @name Animation control
////////////////////////////////////////////////////////////////////////////////
/** Immediately resets the label to the home position, cancelling any in-flight scroll animation, and restarts the scroll animation if the appropriate conditions are met.
@see resetLabel
@see triggerScrollStart
*/
- (void)restartLabel;
/** Immediately resets the label to the home position, cancelling any in-flight scroll animation.
The text is immediately returned to the home position. Scrolling will not resume automatically after a call to this method.
To re-initiate scrolling use a call to `restartLabel` or `triggerScrollStart`, or make a change to a UILabel property such as text, bounds/frame,
font, font size, etc.
@see restartLabel
@see triggerScrollStart
@since Available in 2.4.0 and later.
*/
- (void)shutdownLabel;
/** Resets the label text, recalculating the scroll animation.
The text is immediately returned to the home position, and the scroll animation positions are cleared. Scrolling will not resume automatically after
a call to this method. To re-initiate scrolling, use either a call to `restartLabel` or make a change to a UILabel property such as text, bounds/frame,
font, font size, etc.
@see restartLabel
*/
- (void)resetLabel;
/** Pauses the text scrolling animation, at any point during an in-progress animation.
@note This method has no effect if a scroll animation is NOT already in progress. To prevent automatic scrolling on a newly-initialized label prior to its presentation onscreen, see the `holdScrolling` property.
@see holdScrolling
@see unpauseLabel
*/
- (void)pauseLabel;
/** Un-pauses a previously paused text scrolling animation. This method has no effect if the label was not previously paused using `pauseLabel`.
@see pauseLabel
*/
- (void)unpauseLabel;
/** Overrides any non-size condition which is preventing the receiver from automatically scrolling, and begins a scroll animation.
Currently the only non-size conditions which can prevent a label from scrolling are the `tapToScroll` and `holdScrolling` properties. This
method will not force a label with a string that fits inside the label bounds (i.e. that would not automatically scroll) to begin a scroll
animation.
Upon the completion of the first forced scroll animation, the receiver will not automatically continue to scroll unless the conditions
preventing scrolling have been removed.
@note This method has no effect if called during an already in-flight scroll animation.
@see restartLabel
@since Available in 2.2.0 and later.
*/
- (void)triggerScrollStart;
////////////////////////////////////////////////////////////////////////////////
/// @name Animation Status
////////////////////////////////////////////////////////////////////////////////
/** Called when the label animation is about to begin.
The default implementation of this method does nothing. Subclasses may override this method in order to perform any custom actions just as
the label animation begins. This is only called in the event that the conditions for scrolling to begin are met.
@since Available in 1.5.0 and later.
*/
- (void)labelWillBeginScroll;
/** Called when the label animation has finished, and the label is at the home position.
The default implementation of this method does nothing. Subclasses may override this method in order to perform any custom actions jas as
the label animation completes, and before the next animation would begin (assuming the scroll conditions are met).
@param finished A Boolean that indicates whether or not the scroll animation actually finished before the completion handler was called.
@since Available in 1.5.0 and later.
@warning This method will be called, and the `finished` parameter will be `NO`, when any property changes are made that would cause the label
scrolling to be automatically reset. This includes changes to label text and font/font size changes.
*/
- (void)labelReturnedToHome:(BOOL)finished;
/** A boolean property that indicates if the label's scroll animation has been paused.
@see pauseLabel
@see unpauseLabel
*/
@property (nonatomic, assign, readonly) BOOL isPaused;
/** A boolean property that indicates if the label is currently away from the home location.
The "home" location is the traditional location of `UILabel` text. This property essentially reflects if a scroll animation is underway.
*/
@property (nonatomic, assign, readonly) BOOL awayFromHome;
////////////////////////////////////////////////////////////////////////////////
/// @name Bulk-manipulation Methods
////////////////////////////////////////////////////////////////////////////////
/** Convenience method to restart all `DFLabel` instances that have the specified view controller in their next responder chain.
This method sends a `NSNotification` to all `DFLabel` instances with the specified view controller in their next responder chain.
The scrolling animation of these instances will be automatically restarted. This is equivalent to calling `restartLabel` on all affected
instances.
There is currently no functional difference between this method and `controllerViewDidAppear:` or `controllerViewWillAppear:`. The methods may
be used interchangeably.
@warning View controllers that appear with animation (such as from underneath a modal-style controller) can cause some `DFLabel` text
position "jumping" when this method is used in `viewDidAppear` if scroll animations are already underway. Use this method inside `viewWillAppear:`
instead to avoid this problem.
@warning This method may not function properly if passed the parent view controller when using view controller containment.
@param controller The view controller that has appeared.
@see restartLabel
@see controllerViewDidAppear:
@see controllerViewWillAppear:
@since Available in 1.3.1 and later.
*/
+ (void)restartLabelsOfController:(UIViewController *)controller;
/** Convenience method to restart all `DFLabel` instances that have the specified view controller in their next responder chain.
Alternative to `restartLabelsOfController:`. This method is retained for backwards compatibility and future enhancements.
@param controller The view controller that has appeared.
@see restartLabel
@see controllerViewWillAppear:
@since Available in 1.2.7 and later.
*/
+ (void)controllerViewDidAppear:(UIViewController *)controller;
/** Convenience method to restart all `DFLabel` instances that have the specified view controller in their next responder chain.
Alternative to `restartLabelsOfController:`. This method is retained for backwards compatibility and future enhancements.
@param controller The view controller that has appeared.
@see restartLabel
@see controllerViewDidAppear:
@since Available in 1.2.8 and later.
*/
+ (void)controllerViewWillAppear:(UIViewController *)controller;
/**
@deprecated Use `controllerViewDidAppear:` instead.
*/
+ (void)controllerViewAppearing:(UIViewController *)controller DEPRECATED_ATTRIBUTE;
/** Labelizes all `DFLabel` instances that have the specified view controller in their next responder chain.
This method sends an `NSNotification` to all `DFLabel` instances with the specified view controller in their next
responder chain. The `labelize` property of these `DFLabel` instances will be set to `YES`.
@param controller The view controller for which all `DFLabel` instances should be labelized.
@see labelize
*/
+ (void)controllerLabelsShouldLabelize:(UIViewController *)controller;
/** De-Labelizes all `DFLabel` instances that have the specified view controller in their next responder chain.
This method sends an `NSNotification` to all `DFLabel` instances with the specified view controller in their next
responder chain. The `labelize` property of these `DFLabel` instances will be set to `NO` .
@param controller The view controller for which all `DFLabel` instances should be de-labelized.
@see labelize
*/
+ (void)controllerLabelsShouldAnimate:(UIViewController *)controller;
@end

51
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFNetPlayer.h

@ -1,51 +0,0 @@
//
// DFNetPlayer.h
// Test
//
// Created by DFung on 2018/2/2.
// Copyright © 2018年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>
typedef enum : NSUInteger {
DFNetPlayer_STATUS_PENDING,
DFNetPlayer_STATUS_PLAY,
DFNetPlayer_STATUS_PAUSE,
DFNetPlayer_STATUS_STOP,
} DFNetPlayer_STATUS;
@class DFNetPlayer;
@protocol DFNetPlayerDelegate <NSObject>
-(void)onDFNetPlayer:(DFNetPlayer*)player ChangeStatus:(DFNetPlayer_STATUS)status;
-(void)onDFNetPlayer:(DFNetPlayer*)player CachedProgress:(float)progress;
-(void)onDFNetPlayer:(DFNetPlayer*)player Speed:(float)speed TimeGap:(NSTimeInterval)timeGap;
-(void)onDFNetPlayer:(DFNetPlayer*)player PlayTime:(float)time;
-(void)onDFNetPlayer:(DFNetPlayer*)player PlayFinished:(float)ret;
@end
@interface DFNetPlayer : NSObject
@property (assign,nonatomic)id delegate;
@property (strong,nonatomic)AVPlayer *mPlayer;
@property (strong,nonatomic)AVPlayerItem *mSongItem;
@property (assign,nonatomic)DFNetPlayer_STATUS status;
@property (assign,nonatomic)float time_cached;
@property (assign,nonatomic)float time_total;
@property (assign,nonatomic)float time_play;
-(void)setVolume:(float)volume;
-(float)getVolume;
-(void)didPlayUrl:(NSString*)url;
-(void)didContinue;
-(void)didPause;
-(void)didStop;
-(void)clearObservers;
@end

56
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFNotice.h

@ -1,56 +0,0 @@
//
// DFNotice.h
// IPCamera
//
// Created by DFung on 16/5/27.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>
@interface DFNotice : NSObject
/**
* 发送通知
*
* @param name :通知名字
* @param object:传递的对象
*/
+(void)post:(NSString*)name Object:(id)object;
/**
* 监听通知
*
* @param name :通知名字
* @param action:实现方法
* @param own :监听者
*/
+(void)add:(NSString*)name Action:(SEL)action Own:(id)own;
/**
* 监听取消
*
* @param name:通知名字
* @param own :监听者
*/
+(void)remove:(NSString*)name Own:(id)own;
/** (iOS 10.0 以上有效。)
* 定时通知
*
* @param date:yyyyMMddHHmmss
* @param repeat:0 -->不重复
*/
+(void)pushLocalNoticeDate:(NSString*)date
ID:(NSString*)noteId
Txt_0:(NSString*)txt_0
Txt_1:(NSString*)txt_1
Txt_2:(NSString*)txt_2
Badge:(NSNumber*)badge
Repeat:(BOOL)repeat;
@end

312
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFPing.h

@ -1,312 +0,0 @@
//
// DFPing.h
// MusicTest
//
// Created by DFung on 2018/3/30.
// Copyright © 2018年 DFung. All rights reserved.
//
#import <UIKit/UIKit.h>
#include <AssertMacros.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#pragma once
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>
#include <fcntl.h>
#include <string.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/errno.h>
#include <pthread.h>
#define kNET_TIME_GAP 100
#define kDFPING_TIMEOUT @"DFPING_TIMEOUT"
struct net_ping_addr_t{
const char *name;
const char *host;
const int port;
};
typedef struct net_ping_addr_t n_ping_addr_t;
/**
* return 1:OK 0:Not good
*/
int do_net_ping(void);
int do_net_ping_1(n_ping_addr_t *paddrs);
NS_ASSUME_NONNULL_BEGIN
@protocol DFPingDelegate;
/*! Controls the IP address version used by DFPing instances.
*/
typedef NS_ENUM(NSInteger, DFPingAddressStyle) {
DFPingAddressStyleAny, ///< Use the first IPv4 or IPv6 address found; the default.
DFPingAddressStyleICMPv4, ///< Use the first IPv4 address found.
DFPingAddressStyleICMPv6 ///< Use the first IPv6 address found.
};
/*! An object wrapper around the low-level BSD Sockets ping function.
* \details To use the class create an instance, set the delegate and call `-start`
* to start the instance on the current run loop. If things go well you'll soon get the
* `-DFPing:didStartWithAddress:` delegate callback. From there you can can call
* `-sendPingWithData:` to send a ping and you'll receive the
* `-DFPing:didReceivePingResponsePacket:sequenceNumber:` and
* `-DFPing:didReceiveUnexpectedPacket:` delegate callbacks as ICMP packets arrive.
*
* The class can be used from any thread but the use of any single instance must be
* confined to a specific thread and that thread must run its run loop.
*/
@interface DFPing : NSObject
- (instancetype)init NS_UNAVAILABLE;
/*! Initialise the object to ping the specified host.
* \param hostName The DNS name of the host to ping; an IPv4 or IPv6 address in string form will
* work here.
* \returns The initialised object.
*/
- (instancetype)initWithHostName:(NSString *)hostName NS_DESIGNATED_INITIALIZER;
/*! A copy of the value passed to `-initWithHostName:`.
*/
@property (nonatomic, copy, readonly) NSString * hostName;
/*! The delegate for this object.
* \details Delegate callbacks are schedule in the default run loop mode of the run loop of the
* thread that calls `-start`.
*/
@property (nonatomic, weak, readwrite, nullable) id<DFPingDelegate> delegate;
/*! Controls the IP address version used by the object.
* \details You should set this value before starting the object.
*/
@property (nonatomic, assign, readwrite) DFPingAddressStyle addressStyle;
/*! The address being pinged.
* \details The contents of the NSData is a (struct sockaddr) of some form. The
* value is nil while the object is stopped and remains nil on start until
* `-DFPing:didStartWithAddress:` is called.
*/
@property (nonatomic, copy, readonly, nullable) NSData * hostAddress;
/*! The address family for `hostAddress`, or `AF_UNSPEC` if that's nil.
*/
@property (nonatomic, assign, readonly) sa_family_t hostAddressFamily;
/*! The identifier used by pings by this object.
* \details When you create an instance of this object it generates a random identifier
* that it uses to identify its own pings.
*/
@property (nonatomic, assign, readonly) uint16_t identifier;
/*! The next sequence number to be used by this object.
* \details This value starts at zero and increments each time you send a ping (safely
* wrapping back to zero if necessary). The sequence number is included in the ping,
* allowing you to match up requests and responses, and thus calculate ping times and
* so on.
*/
@property (nonatomic, assign, readonly) uint16_t nextSequenceNumber;
/*! Starts the object.
* \details You should set up the delegate and any ping parameters before calling this.
*
* If things go well you'll soon get the `-DFPing:didStartWithAddress:` delegate
* callback, at which point you can start sending pings (via `-sendPingWithData:`) and
* will start receiving ICMP packets (either ping responses, via the
* `-DFPing:didReceivePingResponsePacket:sequenceNumber:` delegate callback, or
* unsolicited ICMP packets, via the `-DFPing:didReceiveUnexpectedPacket:` delegate
* callback).
*
* If the object fails to start, typically because `hostName` doesn't resolve, you'll get
* the `-DFPing:didFailWithError:` delegate callback.
*
* It is not correct to start an already started object.
*/
- (void)start;
/*! Sends a ping packet containing the specified data.
* \details Sends an actual ping.
*
* The object must be started when you call this method and, on starting the object, you must
* wait for the `-DFPing:didStartWithAddress:` delegate callback before calling it.
* \param data Some data to include in the ping packet, after the ICMP header, or nil if you
* want the packet to include a standard 56 byte payload (resulting in a standard 64 byte
* ping).
*/
- (void)sendPingWithData:(nullable NSData *)data;
/*! Stops the object.
* \details You should call this when you're done pinging.
*
* It's safe to call this on an object that's stopped.
*/
- (void)stop;
@end
/*! A delegate protocol for the DFPing class.
*/
@protocol DFPingDelegate <NSObject>
@optional
/*! A DFPing delegate callback, called once the object has started up.
* \details This is called shortly after you start the object to tell you that the
* object has successfully started. On receiving this callback, you can call
* `-sendPingWithData:` to send pings.
*
* If the object didn't start, `-DFPing:didFailWithError:` is called instead.
* \param pinger The object issuing the callback.
* \param address The address that's being pinged; at the time this delegate callback
* is made, this will have the same value as the `hostAddress` property.
*/
- (void)DFPing:(DFPing *)pinger didStartWithAddress:(NSData *)address;
/*! A DFPing delegate callback, called if the object fails to start up.
* \details This is called shortly after you start the object to tell you that the
* object has failed to start. The most likely cause of failure is a problem
* resolving `hostName`.
*
* By the time this callback is called, the object has stopped (that is, you don't
* need to call `-stop` yourself).
* \param pinger The object issuing the callback.
* \param error Describes the failure.
*/
- (void)DFPing:(DFPing *)pinger didFailWithError:(NSError *)error;
/*! A DFPing delegate callback, called when the object has successfully sent a ping packet.
* \details Each call to `-sendPingWithData:` will result in either a
* `-DFPing:didSendPacket:sequenceNumber:` delegate callback or a
* `-DFPing:didFailToSendPacket:sequenceNumber:error:` delegate callback (unless you
* stop the object before you get the callback). These callbacks are currently delivered
* synchronously from within `-sendPingWithData:`, but this synchronous behaviour is not
* considered API.
* \param pinger The object issuing the callback.
* \param packet The packet that was sent; this includes the ICMP header (`ICMPHeader`) and the
* data you passed to `-sendPingWithData:` but does not include any IP-level headers.
* \param sequenceNumber The ICMP sequence number of that packet.
*/
- (void)DFPing:(DFPing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber;
/*! A DFPing delegate callback, called when the object fails to send a ping packet.
* \details Each call to `-sendPingWithData:` will result in either a
* `-DFPing:didSendPacket:sequenceNumber:` delegate callback or a
* `-DFPing:didFailToSendPacket:sequenceNumber:error:` delegate callback (unless you
* stop the object before you get the callback). These callbacks are currently delivered
* synchronously from within `-sendPingWithData:`, but this synchronous behaviour is not
* considered API.
* \param pinger The object issuing the callback.
* \param packet The packet that was not sent; see `-DFPing:didSendPacket:sequenceNumber:`
* for details.
* \param sequenceNumber The ICMP sequence number of that packet.
* \param error Describes the failure.
*/
- (void)DFPing:(DFPing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error;
/*! A DFPing delegate callback, called when the object receives a ping response.
* \details If the object receives an ping response that matches a ping request that it
* sent, it informs the delegate via this callback. Matching is primarily done based on
* the ICMP identifier, although other criteria are used as well.
* \param pinger The object issuing the callback.
* \param packet The packet received; this includes the ICMP header (`ICMPHeader`) and any data that
* follows that in the ICMP message but does not include any IP-level headers.
* \param sequenceNumber The ICMP sequence number of that packet.
*/
- (void)DFPing:(DFPing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber;
/*! A DFPing delegate callback, called when the object receives an unmatched ICMP message.
* \details If the object receives an ICMP message that does not match a ping request that it
* sent, it informs the delegate via this callback. The nature of ICMP handling in a
* BSD kernel makes this a common event because, when an ICMP message arrives, it is
* delivered to all ICMP sockets.
*
* IMPORTANT: This callback is especially common when using IPv6 because IPv6 uses ICMP
* for important network management functions. For example, IPv6 routers periodically
* send out Router Advertisement (RA) packets via Neighbor Discovery Protocol (NDP), which
* is implemented on top of ICMP.
*
* For more on matching, see the discussion associated with
* `-DFPing:didReceivePingResponsePacket:sequenceNumber:`.
* \param pinger The object issuing the callback.
* \param packet The packet received; this includes the ICMP header (`ICMPHeader`) and any data that
* follows that in the ICMP message but does not include any IP-level headers.
*/
- (void)DFPing:(DFPing *)pinger didReceiveUnexpectedPacket:(NSData *)packet;
@end
#pragma mark * ICMP On-The-Wire Format
/*! Describes the on-the-wire header format for an ICMP ping.
* \details This defines the header structure of ping packets on the wire. Both IPv4 and
* IPv6 use the same basic structure.
*
* This is declared in the header because clients of DFPing might want to use
* it parse received ping packets.
*/
struct DF_ICMPHeader {
uint8_t type;
uint8_t code;
uint16_t checksum;
uint16_t identifier;
uint16_t sequenceNumber;
};
typedef struct DF_ICMPHeader DF_ICMPHeader;
__Check_Compile_Time(sizeof(DF_ICMPHeader) == 8);
__Check_Compile_Time(offsetof(DF_ICMPHeader, type) == 0);
__Check_Compile_Time(offsetof(DF_ICMPHeader, code) == 1);
__Check_Compile_Time(offsetof(DF_ICMPHeader, checksum) == 2);
__Check_Compile_Time(offsetof(DF_ICMPHeader, identifier) == 4);
__Check_Compile_Time(offsetof(DF_ICMPHeader, sequenceNumber) == 6);
enum {
DF_ICMPv4TypeEchoRequest = 8, ///< The ICMP `type` for a ping request; in this case `code` is always 0.
DF_ICMPv4TypeEchoReply = 0 ///< The ICMP `type` for a ping response; in this case `code` is always 0.
};
enum {
DF_ICMPv6TypeEchoRequest = 128, ///< The ICMP `type` for a ping request; in this case `code` is always 0.
DF_ICMPv6TypeEchoReply = 129 ///< The ICMP `type` for a ping response; in this case `code` is always 0.
};
NS_ASSUME_NONNULL_END
typedef void(^DFPING_RET)(int ret);
@interface DFSimplePing : NSObject
+(id _Nullable )sharedMe;
-(void)pingNetWork:(DFPING_RET _Nullable )result;
@end

52
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFRing.h

@ -1,52 +0,0 @@
//
// DFRing.h
// libDVRunning
//
// Created by DFung on 2017/7/13.
// Copyright © 2017年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DFRing : NSObject
@property(assign,nonatomic)int32_t len_total;
/**
* 用途:【Ring Buffer】剩余容量
* @return uint32_t 容量大小
*/
-(uint32_t)ringUsable;
/**
* 用途:创建【Ring Buffer】
* @param size 循环buffer的大小
* @return BOOL 创建是否成功
*/
-(BOOL)ringMakeSize:(int32_t)size;
/**
* 用途:存入数据。
* @param buf 数据地址
* @param size 数据大小
*/
-(uint32_t)ringPut:(void*)buf Size:(uint32_t)size;
/**
* 用途:获取数据。
* @param buf 数据地址
* @param size 数据大小
*/
-(uint32_t)ringGet:(void*)buf Size:(uint32_t)size;
/**
* 用途:擦除【Ring Buffer】的数据。
*/
-(void)ringClean;
/**
* 用途:完全释放【Ring Buffer】
*/
-(void)ringRelease;
@end

32
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFSort.h

@ -1,32 +0,0 @@
//
// DFSort.h
// DFUnits
//
// Created by DFung on 16/1/29.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
#include <stdio.h>
@interface DFSort : NSObject
void DescendingSort(int* arr,int left, int right);
void AscendingSort(int* arr,int left, int right);
/**
* 打乱数组顺序。
* @param array
*/
+(NSArray*)arrayRandom:(NSArray*)array;
@end

115
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFTime.h

@ -1,115 +0,0 @@
//
// DFTime.h
//
//
// Created by Mac on 15/12/10.
//
//
#import <Foundation/Foundation.h>
@interface DFTime : NSObject
/**
返回时间戳(单位:秒)
*/
+(long)dateCurrent;
/**
* 获取iPhone时间(数组形式)。
* @return @"2016" @"2" @"18" @"11" @"26" @"00"
*/
+(NSArray*)dateMembers;
/**
* 获取iPhone时间(字符串形式)。
* @return @"20160218112600"
*/
+ (NSString*)dateString;
/**
* 编辑日期时间
*/
+(NSDate*)makeDateYear:(int)y
Month:(int)mo
Day:(int)d
Hour:(int)h
Min:(int)m
Sec:(int)s;
/**
* 将字符串日期分解时间成员,@"20160218112600" => @"2016" @"2" @"18" @"11" @"26" @"00"
* @param time @"20160218112600"
* @return @"2016" @"2" @"18" @"11" @"26" @"00"
*/
+ (NSArray*)divideDateMembers:(NSString*)time;
/**
* 时间值加“秒”值。
* @param sec 秒数
* @param date @"20160218112600"
*/
+ (NSString*)addSec:(NSTimeInterval)sec OnDate:(NSString *)date;
/**
* 求两个时间点差值。(timeA-timeB)
* @param timeA @"20160218112601"
* @param timeB @"20160218112600"
*/
+(NSTimeInterval)differenceOfDateA:(NSString*)timeA AndDateB:(NSString*)timeB;
/**
* 求两个时间点差值。(dateA-dateB)
* @param dateA
* @param dateB
*/
+(NSTimeInterval)gapOfDateA:(NSDate*)dateA DateB:(NSDate*)dateB;
/**
* 当前【天】
*/
+ (NSInteger)day:(NSDate *)date;
/**
* 当前【月】
*/
+ (NSInteger)month:(NSDate *)date;
/**
* 当前【年】
*/
+ (NSInteger)year:(NSDate *)date;
/**
* 当前【星期】
*/
+ (NSInteger)weekday:(NSDate *)date;
/**
* 这周是这个月的第几周?
*/
+ (NSInteger)firstWeekdayInThisMonth:(NSDate *)date;
/**
* 获取当前月天数
*/
+ (NSInteger)totaldaysInMonth:(NSDate *)date;
/**
* 上/下m个月后的时间。
*/
+ (NSDate *)changeMonth:(int)m onDate:(NSDate *)date;
/**
* 上/下d个天后的时间。
*/
+ (NSDate *)changeDay:(int)d onDate:(NSDate *)date;
/**
* 秒数换算
* 输入 :60秒 (uint32_t)
* 返回 :00:01:00 (NSString*)
*/
+(NSString*)stringFromSec:(uint32_t)sec;
@end

496
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFTips.h

@ -1,496 +0,0 @@
//
// DFTips.h
// JMAirKissDemo
//
// Created by DFung on 2016/12/9.
// Copyright © 2016年 com.DFung. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
@protocol DFTipsDelegate;
typedef NS_ENUM(NSInteger, DFTipsMode) {
/** Progress is shown using an UIActivityIndicatorView. This is the default. */
DFTipsModeIndeterminate,
/** Progress is shown using a round, pie-chart like, progress view. */
DFTipsModeDeterminate,
/** Progress is shown using a horizontal progress bar */
DFTipsModeDeterminateHorizontalBar,
/** Progress is shown using a ring-shaped progress view. */
DFTipsModeAnnularDeterminate,
/** Shows a custom view */
DFTipsModeCustomView,
/** Shows only labels */
DFTipsModeText
};
typedef NS_ENUM(NSInteger, DFTipsAnimation) {
/** Opacity animation */
DFTipsAnimationFade,
/** Opacity + scale animation */
DFTipsAnimationZoom,
DFTipsAnimationZoomOut = DFTipsAnimationZoom,
DFTipsAnimationZoomIn
};
#ifndef DF_MB_INSTANCETYPE
#if __has_feature(objc_instancetype)
#define DF_MB_INSTANCETYPE instancetype
#else
#define DF_MB_INSTANCETYPE id
#endif
#endif
#ifndef DF_MB_STRONG
#if __has_feature(objc_arc)
#define DF_MB_STRONG strong
#else
#define DF_MB_STRONG retain
#endif
#endif
#ifndef DF_MB_WEAK
#if __has_feature(objc_arc_weak)
#define DF_MB_WEAK weak
#elif __has_feature(objc_arc)
#define DF_MB_WEAK unsafe_unretained
#else
#define DF_MB_WEAK assign
#endif
#endif
#if NS_BLOCKS_AVAILABLE
typedef void (^DFTipsCompletionBlock)();
#endif
/**
* Displays a simple HUD window containing a progress indicator and two optional labels for short messages.
*
* This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class.
* The DFTips window spans over the entire space given to it by the initWithFrame constructor and catches all
* user input on this region, thereby preventing the user operations on components below the view. The HUD itself is
* drawn centered as a rounded semi-transparent view which resizes depending on the user specified content.
*
* This view supports four modes of operation:
* - DFTipsModeIndeterminate - shows a UIActivityIndicatorView
* - DFTipsModeDeterminate - shows a custom round progress indicator
* - DFTipsModeAnnularDeterminate - shows a custom annular progress indicator
* - DFTipsModeCustomView - shows an arbitrary, user specified view (@see customView)
*
* All three modes can have optional labels assigned:
* - If the labelText property is set and non-empty then a label containing the provided content is placed below the
* indicator view.
* - If also the detailsLabelText property is set then another label is placed below the first label.
*/
@interface DFTips : UIView
/**
* Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:.
*
* @param view The view that the HUD will be added to
* @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
* animations while appearing.
* @return A reference to the created HUD.
*
* @see hideHUDForView:animated:
* @see animationType
*/
+ (DF_MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated;
/**
* Finds the top-most HUD subview and hides it. The counterpart to this method is showHUDAddedTo:animated:.
*
* @param view The view that is going to be searched for a HUD subview.
* @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
* animations while disappearing.
* @return YES if a HUD was found and removed, NO otherwise.
*
* @see showHUDAddedTo:animated:
* @see animationType
*/
+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated;
/**
* Finds all the HUD subviews and hides them.
*
* @param view The view that is going to be searched for HUD subviews.
* @param animated If set to YES the HUDs will disappear using the current animationType. If set to NO the HUDs will not use
* animations while disappearing.
* @return the number of HUDs found and removed.
*
* @see hideHUDForView:animated:
* @see animationType
*/
+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated;
/**
* Finds the top-most HUD subview and returns it.
*
* @param view The view that is going to be searched.
* @return A reference to the last HUD subview discovered.
*/
+ (DF_MB_INSTANCETYPE)HUDForView:(UIView *)view;
/**
* Finds all HUD subviews and returns them.
*
* @param view The view that is going to be searched.
* @return All found HUD views (array of DFTips objects).
*/
+ (NSArray *)allHUDsForView:(UIView *)view;
/**
* A convenience constructor that initializes the HUD with the window's bounds. Calls the designated constructor with
* window.bounds as the parameter.
*
* @param window The window instance that will provide the bounds for the HUD. Should be the same instance as
* the HUD's superview (i.e., the window that the HUD will be added to).
*/
- (id)initWithWindow:(UIWindow *)window;
/**
* A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with
* view.bounds as the parameter
*
* @param view The view instance that will provide the bounds for the HUD. Should be the same instance as
* the HUD's superview (i.e., the view that the HUD will be added to).
*/
- (id)initWithView:(UIView *)view;
/**
* Display the HUD. You need to make sure that the main thread completes its run loop soon after this method call so
* the user interface can be updated. Call this method when your task is already set-up to be executed in a new thread
* (e.g., when using something like NSOperation or calling an asynchronous call like NSURLRequest).
*
* @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
* animations while appearing.
*
* @see animationType
*/
- (void)show:(BOOL)animated;
/**
* Hide the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
* hide the HUD when your task completes.
*
* @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
* animations while disappearing.
*
* @see animationType
*/
- (void)hide:(BOOL)animated;
/**
* Hide the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
* hide the HUD when your task completes.
*
* @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
* animations while disappearing.
* @param delay Delay in seconds until the HUD is hidden.
*
* @see animationType
*/
- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay;
/**
* Shows the HUD while a background task is executing in a new thread, then hides the HUD.
*
* This method also takes care of autorelease pools so your method does not have to be concerned with setting up a
* pool.
*
* @param method The method to be executed while the HUD is shown. This method will be executed in a new thread.
* @param target The object that the target method belongs to.
* @param object An optional object to be passed to the method.
* @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will not use
* animations while (dis)appearing.
*/
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated;
#if NS_BLOCKS_AVAILABLE
/**
* Shows the HUD while a block is executing on a background queue, then hides the HUD.
*
* @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block;
/**
* Shows the HUD while a block is executing on a background queue, then hides the HUD.
*
* @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(DFTipsCompletionBlock)completion;
/**
* Shows the HUD while a block is executing on the specified dispatch queue, then hides the HUD.
*
* @see showAnimated:whileExecutingBlock:onQueue:completionBlock:
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue;
/**
* Shows the HUD while a block is executing on the specified dispatch queue, executes completion block on the main queue, and then hides the HUD.
*
* @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will
* not use animations while (dis)appearing.
* @param block The block to be executed while the HUD is shown.
* @param queue The dispatch queue on which the block should be executed.
* @param completion The block to be executed on completion.
*
* @see completionBlock
*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
completionBlock:(DFTipsCompletionBlock)completion;
/**
* A block that gets called after the HUD was completely hidden.
*/
@property (copy) DFTipsCompletionBlock completionBlock;
#endif
/**
* DFTips operation mode. The default is DFTipsModeIndeterminate.
*
* @see DFTipsMode
*/
@property (assign) DFTipsMode mode;
/**
* The animation type that should be used when the HUD is shown and hidden.
*
* @see DFTipsAnimation
*/
@property (assign) DFTipsAnimation animationType;
/**
* The UIView (e.g., a UIImageView) to be shown when the HUD is in DFTipsModeCustomView.
* For best results use a 37 by 37 pixel view (so the bounds match the built in indicator bounds).
*/
@property (DF_MB_STRONG) UIView *customView;
/**
* The HUD delegate object.
*
* @see DFTipsDelegate
*/
@property (DF_MB_WEAK) id<DFTipsDelegate> delegate;
/**
* An optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit
* the entire text. If the text is too long it will get clipped by displaying "..." at the end. If left unchanged or
* set to @"", then no message is displayed.
*/
@property (copy) NSString *labelText;
/**
* An optional details message displayed below the labelText message. This message is displayed only if the labelText
* property is also set and is different from an empty string (@""). The details text can span multiple lines.
*/
@property (copy) NSString *detailsLabelText;
/**
* The opacity of the HUD window. Defaults to 0.8 (80% opacity).
*/
@property (assign) float opacity;
/**
* The color of the HUD window. Defaults to black. If this property is set, color is set using
* this UIColor and the opacity property is not used. using retain because performing copy on
* UIColor base colors (like [UIColor greenColor]) cause problems with the copyZone.
*/
@property (DF_MB_STRONG) UIColor *color;
/**
* The x-axis offset of the HUD relative to the centre of the superview.
*/
@property (assign) float xOffset;
/**
* The y-axis offset of the HUD relative to the centre of the superview.
*/
@property (assign) float yOffset;
/**
* The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views).
* Defaults to 20.0
*/
@property (assign) float margin;
/**
* The corner radius for the HUD
* Defaults to 10.0
*/
@property (assign) float cornerRadius;
/**
* Cover the HUD background view with a radial gradient.
*/
@property (assign) BOOL dimBackground;
/*
* Grace period is the time (in seconds) that the invoked method may be run without
* showing the HUD. If the task finishes before the grace time runs out, the HUD will
* not be shown at all.
* This may be used to prevent HUD display for very short tasks.
* Defaults to 0 (no grace time).
* Grace time functionality is only supported when the task status is known!
* @see taskInProgress
*/
@property (assign) float graceTime;
/**
* The minimum time (in seconds) that the HUD is shown.
* This avoids the problem of the HUD being shown and than instantly hidden.
* Defaults to 0 (no minimum show time).
*/
@property (assign) float minShowTime;
/**
* Indicates that the executed operation is in progress. Needed for correct graceTime operation.
* If you don't set a graceTime (different than 0.0) this does nothing.
* This property is automatically set when using showWhileExecuting:onTarget:withObject:animated:.
* When threading is done outside of the HUD (i.e., when the show: and hide: methods are used directly),
* you need to set this property when your task starts and completes in order to have normal graceTime
* functionality.
*/
@property (assign) BOOL taskInProgress;
/**
* Removes the HUD from its parent view when hidden.
* Defaults to NO.
*/
@property (assign) BOOL removeFromSuperViewOnHide;
/**
* Font to be used for the main label. Set this property if the default is not adequate.
*/
@property (DF_MB_STRONG) UIFont* labelFont;
/**
* Color to be used for the main label. Set this property if the default is not adequate.
*/
@property (DF_MB_STRONG) UIColor* labelColor;
/**
* Font to be used for the details label. Set this property if the default is not adequate.
*/
@property (DF_MB_STRONG) UIFont* detailsLabelFont;
/**
* Color to be used for the details label. Set this property if the default is not adequate.
*/
@property (DF_MB_STRONG) UIColor* detailsLabelColor;
/**
* The color of the activity indicator. Defaults to [UIColor whiteColor]
* Does nothing on pre iOS 5.
*/
@property (DF_MB_STRONG) UIColor *activityIndicatorColor;
/**
* The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0.
*/
@property (assign) float progress;
/**
* The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size).
*/
@property (assign) CGSize minSize;
/**
* The actual size of the HUD bezel.
* You can use this to limit touch handling on the bezel aria only.
* @see https://github.com/jdg/DFTips/pull/200
*/
@property (atomic, assign, readonly) CGSize size;
/**
* Force the HUD dimensions to be equal if possible.
*/
@property (assign, getter = isSquare) BOOL square;
@end
@protocol DFTipsDelegate <NSObject>
@optional
/**
* Called after the HUD was fully hidden from the screen.
*/
- (void)hudWasHidden:(DFTips *)hud;
@end
/**
* A progress view for showing definite progress by filling up a circle (pie chart).
*/
@interface DF_MBRoundProgressView : UIView
/**
* Progress (0.0 to 1.0)
*/
@property (nonatomic, assign) float progress;
/**
* Indicator progress color.
* Defaults to white [UIColor whiteColor]
*/
@property (nonatomic, DF_MB_STRONG) UIColor *progressTintColor;
/**
* Indicator background (non-progress) color.
* Defaults to translucent white (alpha 0.1)
*/
@property (nonatomic, DF_MB_STRONG) UIColor *backgroundTintColor;
/*
* Display mode - NO = round or YES = annular. Defaults to round.
*/
@property (nonatomic, assign, getter = isAnnular) BOOL annular;
@end
/**
* A flat bar progress view.
*/
@interface DF_MBBarProgressView : UIView
/**
* Progress (0.0 to 1.0)
*/
@property (nonatomic, assign) float progress;
/**
* Bar border line color.
* Defaults to white [UIColor whiteColor].
*/
@property (nonatomic, DF_MB_STRONG) UIColor *lineColor;
/**
* Bar background color.
* Defaults to clear [UIColor clearColor];
*/
@property (nonatomic, DF_MB_STRONG) UIColor *progressRemainingColor;
/**
* Bar progress color.
* Defaults to white [UIColor whiteColor].
*/
@property (nonatomic, DF_MB_STRONG) UIColor *progressColor;
@end

161
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFTools.h

@ -1,161 +0,0 @@
//
// DFTools.h
// DFUnits
//
// Created by DFung on 16/1/22.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DFTools : NSObject
/**
* NSString to NSMutableData
*
* @"ffff0000" => <ffff 0000>
*
* @param str:NSString
* @return NSMutableData
*/
+(NSMutableData*)HexToData:(NSString*)hex;
/**
* NSData to NSString
*
* <ffff 0000> => @"ffff0000"
*
* @param data:NSData
* @return NSString
*/
+(NSString*)dataToHex:(NSData*)data;
/**
* Alignment data in length you like.
* 将data按照指定的长度补齐
*/
+(NSData*)alignment:(NSData*)data length:(NSInteger)len;
/**
* NSData ==> NSDictory.
* 将 Json 字节码转换成 NSDictory。
*/
+(id)jsonWithData:(NSData*)data;
/**
* NSDictory ==> NSString.
*/
+(NSString*)dictionaryToJson:(NSDictionary *)dic;
/**
* NSDictory ==> NSData.
*/
+(NSData*)makeDataByDictionary:(NSDictionary *)dic;
/**
* NSData ==> NSDictory.
*/
+(NSDictionary*)makeDictionaryByData:(NSData *)data;
/**
* NSArray ==> NSString.
*/
+(NSString*)arrayToJson:(NSArray *)array;
/**
* 将 uint32_t 的4个字节转换成 NSData。
*/
+(NSData*)uInt32_data:(uint32_t)value;
/**
* 将 uint32_t 的4个字节转换成 NSData。
* @param endian:是否改变大小端
*/
+(NSData*)uInt32_data:(uint32_t)value Endian:(BOOL)endian;
/**
* 将 uint16_t 的2个字节转换成 NSData。
*/
+(NSData*)uInt16_data:(uint16_t)value;
/**
* 将 uint16_t 的2个字节转换成 NSData。
* @param endian:是否改变大小端
*/
+(NSData*)uInt16_data:(uint16_t)value Endian:(BOOL)endian;
+(NSData*)uInt8_data:(uint8_t)value;
/**
* Change Big Or Small Endian(改变NSData的大小端。)
* <000f> => <0f00>
*
* @param data:NSData
* @return NSData
*/
+(NSData*)changeBigOrSmall:(NSData*)data;
/**
* NSData to 10进制
*
* <000f> => 16
*
* @param data:NSData
* @return NSInteger
*/
+(NSInteger)dataToInt:(NSData*)data;
/**
* 求自然数:aByte ==> -1 0 1 2 3...
*/
+(int)getNaturalNumber:(NSData*)aByte;
/**
* 简写: [data subdataWithRange:NSMakeRange(index, length)];
*/
+(NSData*)data:(NSData*)data R:(NSInteger)index L:(NSInteger)length;
/**
* 简写: [[NSString alloc] initWithData:data encoding:encoding];
*/
+(NSString*)string:(NSData*)data Encode:(NSStringEncoding)encoding;
/**
* 简写: [NSString stringWithFormat:(NSString *)format, ...];
*/
+(NSString*)string:(NSArray*)array;
/**
* UNICODE 编码字符串
*/
+(NSString*)stringUnicode:(NSData*)data;
/**
* ANSI 编码字符串
*/
+(NSString*)stringANSI:(NSData*)data;
/**
* GBK 编码字符串
*/
+(NSString*)stringGBK:(NSData*)data;
/**
* 存入 NSUserDefaults
*/
+(void)setUser:(id)objc forKey:(NSString*)key;
/**
* 取出 NSUserDefaults
*/
+(id)getUserByKey:(NSString*)key;
/**
* 移除 NSUserDefaults
*/
+(void)removeUserByKey:(NSString*)key;
@end

21
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUIAnimation.h

@ -1,21 +0,0 @@
//
// DFUIAnimation.h
// DFUIBox
//
// Created by DFung on 16/5/18.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef enum : NSUInteger {
DFUIAnimation_TYPE_SPRING,
} DFUIAnimation_TYPE;
@interface DFUIAnimation : NSObject
+ (void)showView:(UIView*)view Type:(DFUIAnimation_TYPE)type Completed:(void(^)(BOOL finished))block;
+ (void)hideView:(UIView*)view Type:(DFUIAnimation_TYPE)type Completed:(void(^)(BOOL finished))block;
@end

46
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUIPullView.h

@ -1,46 +0,0 @@
//
// DFUIPullView.h
// RetainTest
//
// Created by DFung on 2016/12/7.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <UIKit/UIKit.h>
#define kPULLVIEW_IMAGE_SIZE 40.0
#define kPULLVIEW_TIME 1.5
typedef enum : NSUInteger {
PullView_TYPE_TABLEVIEW,
PullView_TYPE_COLLECTIONVIEW
} PullView_TYPE;
@protocol DFUIPullViewDelegate <NSObject>
@optional
-(void)onDFUIPullViewIsLoading;
-(void)onDFUIPullViewLoadFinished;
@end
@interface DFUIPullView : UIView
@property(nonatomic,weak) id<DFUIPullViewDelegate>delegate;
@property(nonatomic,strong) NSString *subText;
@property(nonatomic,weak) UIScrollView *outScrollView;
@property(nonatomic,weak) id outView;
- (instancetype)initWithScrollView:(UIScrollView*)scrollView
Type:(PullView_TYPE)type
OnView:(id)view;
- (void)setSubImage:(UIImage*)sImage;
@end

215
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUITools.h

@ -1,215 +0,0 @@
//
// DFUITools.h
// DFUnits
//
// Created by DFung on 2016/12/9.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef void (^TipsCompletion) (void);
@class DFTips;
@interface DFUITools : NSObject
#define kDF_SCR_W_0 (int)[DFUITools screen_W]
#define kDF_SCR_H_0 (int)[DFUITools screen_H]
#define kDF_SCR_W_1 (int)[DFUITools screen_1_W]
#define kDF_SCR_H_1 (int)[DFUITools screen_1_H]
#define kDF_RGBA(r,g,b,a) [UIColor colorWithRed:((r)/255.0) green:((g)/255.0) blue:((b)/255.0) alpha:(a)]
#pragma mark 屏幕尺寸
/**
* 设备屏幕的【宽】
*/
+(CGFloat)screen_W;
/**
* 设备屏幕的【长】
*/
+(CGFloat)screen_H;
/**
* 设备竖屏的【宽】
*/
+(float)screen_1_W;
/**
* 设备竖屏的【长】
*/
+(float)screen_1_H;
/**
* iPhone竖屏的【宽】
*/
+(float)screen_2_W;
/**
* iPhone竖屏的【长】
*/
+(float)screen_2_H;
/**
* 获取手机版本
*/
+(float)getVersion;
/**
* 获取当前设备UUID
*/
+(NSString*)getUUID;
/**
* 获取当前UIWindow
*/
+(UIWindow*)getWindow;
/**
* 多语言化:当前系统语言
*/
+(NSString*)systemLanguage;
/**
* 多语言化:选择
*/
+(void)languageSet:(NSString*)lan;
/**
* 多语言化:翻译
*/
+(NSString*)languageText:(NSString*)key Table:(NSString*)table;
/**
* 设置UIButton的图片
*/
+(void)setButton:(UIButton*)btn Image:(NSString*)image;
+(void)setButton:(UIButton*)btn Image_1:(UIImage*)image;
/**
* 设置UIButton的文字
*/
+(void)setButton:(UIButton*)btn Text:(NSString*)text;
/**
* 设置UIButton的字体颜色
*/
+(void)setButton:(UIButton*)btn Color:(UIColor*)color;
/**
* 获取【定宽Label】的【高】。
*/
+ (CGFloat)labelHeightByWidth:(CGFloat)width Text:(NSString *)text Font:(UIFont *)font;
/**
* 获取【定宽Label】的【宽】。
*/
+ (CGFloat)labelWidthByWidth:(CGFloat)width Text:(NSString *)text Font:(UIFont *)font;
/**
* 加载Nib文件的UI。
*/
+(id)loadNib:(NSString*)name;
/**
* 增加触摸事件。
*/
+(UITapGestureRecognizer*)addSingleTaps:(int)taps
View:(UIView*)view
Target:(id)target
Action:(SEL)action;
/**
* 弄个UIColor,【RGB值】和【透明度Alpha】
*/
+(UIColor*)colorR:(float)r G:(float)g B:(float)b AP:(float)ap;
#pragma mark >>> DFTips___APIs___
+ (DFTips *)showHUDWithLabel:(NSString *)labelText
onView:(UIView *)view;
+ (DFTips *)showHUDWithLabel_1:(NSString *)labelText
onView:(UIView *)view;
+ (DFTips *)showHUDWithDetailLabel:(NSString *)detailLabelText
onView:(UIView *)view;
+ (DFTips *)showHUDOnWindowWithLabel:(NSString *)labelText;
+ (DFTips *)showHUDWithLabel:(NSString *)labelText
onView:(UIView *)view
color:(UIColor *)color;
+ (DFTips *)showHUDWithLabel:(NSString *)labelText
onView:(UIView *)view
color:(UIColor *)color
labelTextColor:(UIColor *)textColor
activityIndicatorColor:(UIColor *)actIndicatorColor;
+ (DFTips *)showHUDWithLabel:(NSString *)labelText
onView:(UIView *)view
alpha:(float)alpha
color:(UIColor *)color
labelTextColor:(UIColor *)textColor
activityIndicatorColor:(UIColor *)actIndicatorColor;
+ (DFTips *)showHUDOnWindowWithLabel:(NSString *)labelText
color:(UIColor *)color;
+ (DFTips *)showTransparentHUDWithLabel:(NSString *)labelText
onView:(UIView *)view;
+ (DFTips *)showTransparentHUDOnWindowWithLabel:(NSString *)labelText
labelTextColor:(UIColor *)textColor;
+ (DFTips *)showTransparentHUDOnWindowWithLabel:(NSString *)labelText;
+ (DFTips *)changeLabelText:(NSString *)labelText;
+ (DFTips *)changeDetailLabelText:(NSString *)labelText;
+ (void)removeHUD;
+ (void)removeHUDWithDelay:(float)time;
+ (void)removeHUDWithDelay:(float)time
completion:(TipsCompletion)completion;
+ (void)showText:(NSString *)text
onView:(UIView *)view
delay:(float)time;
+ (void)showText:(NSString *)text
onView:(UIView *)view
delay:(float)time
completion:(TipsCompletion)completion;
+ (void)showText_1:(NSString *)text
onView:(UIView *)view
delay:(float)time;
+ (void)showDetailText:(NSString *)text
onView:(UIView *)view
delay:(float)time;
+ (void)showDetailText:(NSString *)text
onView:(UIView *)view
delay:(float)time
completion:(TipsCompletion)completion;
+(void)showClearLayer;
+(void)showClearLayerDelay:(NSTimeInterval)time;
+(void)openWaittting:(NSString*)text delay:(NSTimeInterval)time;
+(void)closeWaitting:(NSTimeInterval)time;
@end

51
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFUnits.h

@ -1,51 +0,0 @@
//
// DFUnits.h
// DFUnits
//
// Created by EzioChan on 2022/6/29.
//
#import <Foundation/Foundation.h>
//! Project version number for DFUnits.
FOUNDATION_EXPORT double DFUnitsVersionNumber;
//! Project version string for DFUnits.
FOUNDATION_EXPORT const unsigned char DFUnitsVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <DFUnits/PublicHeader.h>
//Using statements like #import <DFUnits/PublicHeader.h>
#import <DFUnits/DFTools.h>
#import <DFUnits/DFFile.h>
#import <DFUnits/DFTime.h>
#import <DFUnits/DFHttp.h>
#import <DFUnits/DFHttp1.h>
#import <DFUnits/DFImage.h>
#import <DFUnits/DFVideo.h>
#import <DFUnits/DFAudio.h>
#import <DFUnits/DFAction.h>
#import <DFUnits/DFSort.h>
#import <DFUnits/DFNotice.h>
#import <DFUnits/AESx.h>
#import <DFUnits/OpenALM.h>
#import <DFUnits/queue.h>
#import <DFUnits/tcp_client.h>
#import <DFUnits/tcp_server.h>
#import <DFUnits/DFGzip.h>
#import <DFUnits/DFHmacMD5.h>
#import <DFUnits/DFNetPlayer.h>
#import <DFUnits/DFCrc16.h>
#import <DFUnits/DFRing.h>
#import <DFUnits/DFPing.h>
#import <DFUnits/DFContacts.h>
#import <DFUnits/DFUIAnimation.h>
#import <DFUnits/DFUITools.h>
#import <DFUnits/DFTips.h>
#import <DFUnits/DFUIPullView.h>
#import <DFUnits/DFLabel.h>
#import <DFUnits/DFFadeLabel.h>
#import <DFUnits/DFCircleTextView.h>
#define DFLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

38
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/DFVideo.h

@ -1,38 +0,0 @@
//
// DFVideo.h
// DFUnits
//
// Created by DFung on 16/1/22.
// Copyright © 2016年 DFung. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DFVideo : NSObject
/**
* 用途:获得AVI视频的PreViewImage。
* @param path 文件路径
* @return @{@"IMG" : 图片Data,
* @"SIZE": 宽高,
* @"TIME": 时长}
*/
+(NSDictionary*)previewAVI:(NSString*)path;
/**
* 用途:获得AVI视频的PreViewImage。
* @param data 文件数据
* @return @{@"IMG" : 图片Data,
* @"SIZE": 宽高,
* @"TIME": 时长}
*/
+(NSDictionary *)previewData:(NSData*)data;
/**
* 用途:秒数换算成时间字符串。
* @param total 秒数(60s ==> 00:01:00)
* @return @"00:01:00"
*/
+(NSString *)timeTyping:(long)total;
@end

59
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/OPenALM.h

@ -1,59 +0,0 @@
//
// OPenALM.h
// OpenALForPCM
//
// Created by 陈冠杰 on 16/2/15.
// Copyright © 2016年 zh-JieLi. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AudioToolbox/ExtendedAudioFile.h>
#import <OpenAL/al.h>
#import <OpenAL/alc.h>
#include "queue.h"
struct AL_Data{
int size;
unsigned char *data;
};
/**
* 【OPenALM】播放停止
*/
#define kOPenALM_STOP @"OPenALM_STOP"
@interface OPenALM : NSObject
{
ALCcontext *mContext;
ALCdevice *mDevicde;
ALuint outSourceId;
ALuint buff;
}
@property(nonatomic)ALCcontext *mContext;
@property(nonatomic)ALCdevice *mDevice;
/**
* Need Import <OpenAL.frameworks>
* <AudioToolBox.frameworks>
*/
-(void)inputAudioBuffer:(struct AL_Data*)pkg;
-(BOOL)updataQueueBuffer;
-(void)playSound;
-(void)stopSound;
-(void)cleanUpOpenAL;
-(void)cleanMe;
@end

224
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/TPCircularBuffer.h

@ -1,224 +0,0 @@
//
// TPCircularBuffer.h
// Circular/Ring buffer implementation
//
// https://github.com/michaeltyson/TPCircularBuffer
//
// Created by Michael Tyson on 10/12/2011.
//
//
// This implementation makes use of a virtual memory mapping technique that inserts a virtual copy
// of the buffer memory directly after the buffer's end, negating the need for any buffer wrap-around
// logic. Clients can simply use the returned memory address as if it were contiguous space.
//
// The implementation is thread-safe in the case of a single producer and single consumer.
//
// Virtual memory technique originally proposed by Philip Howard (http://vrb.slashusr.org/), and
// adapted to Darwin by Kurt Revis (http://www.snoize.com,
// http://www.snoize.com/Code/PlayBufferedSoundFile.tar.gz)
//
//
// Copyright (C) 2012-2013 A Tasty Pixel
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
#ifndef TPCircularBuffer_h
#define TPCircularBuffer_h
#include <libkern/OSAtomic.h>
#include <string.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
void *buffer;
int32_t length;
int32_t tail;
int32_t head;
volatile int32_t fillCount;
bool atomic;
} TPCircularBuffer;
/*!
* Initialise buffer
*
* Note that the length is advisory only: Because of the way the
* memory mirroring technique works, the true buffer length will
* be multiples of the device page size (e.g. 4096 bytes)
*
* @param buffer Circular buffer
* @param length Length of buffer
*/
#define TPCircularBufferInit(buffer, length) \
_TPCircularBufferInit(buffer, length, sizeof(*buffer))
bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t structSize);
/*!
* Cleanup buffer
*
* Releases buffer resources.
*/
void TPCircularBufferCleanup(TPCircularBuffer *buffer);
/*!
* Clear buffer
*
* Resets buffer to original, empty state.
*
* This is safe for use by consumer while producer is accessing
* buffer.
*/
void TPCircularBufferClear(TPCircularBuffer *buffer);
/*!
* Set the atomicity
*
* If you set the atomiticy to false using this method, the buffer will
* not use atomic operations. This can be used to give the compiler a little
* more optimisation opportunities when the buffer is only used on one thread.
*
* Important note: Only set this to false if you know what you're doing!
*
* The default value is true (the buffer will use atomic operations)
*
* @param buffer Circular buffer
* @param atomic Whether the buffer is atomic (default true)
*/
void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic);
// Reading (consuming)
/*!
* Access end of buffer
*
* This gives you a pointer to the end of the buffer, ready
* for reading, and the number of available bytes to read.
*
* @param buffer Circular buffer
* @param availableBytes On output, the number of bytes ready for reading
* @return Pointer to the first bytes ready for reading, or NULL if buffer is empty
*/
static __inline__ __attribute__((always_inline)) void* TPCircularBufferTail(TPCircularBuffer *buffer, int32_t* availableBytes) {
*availableBytes = buffer->fillCount;
if ( *availableBytes == 0 ) return NULL;
return (void*)((char*)buffer->buffer + buffer->tail);
}
/*!
* Consume bytes in buffer
*
* This frees up the just-read bytes, ready for writing again.
*
* @param buffer Circular buffer
* @param amount Number of bytes to consume
*/
static __inline__ __attribute__((always_inline)) void TPCircularBufferConsume(TPCircularBuffer *buffer, int32_t amount) {
buffer->tail = (buffer->tail + amount) % buffer->length;
if ( buffer->atomic ) {
OSAtomicAdd32Barrier(-amount, &buffer->fillCount);
} else {
buffer->fillCount -= amount;
}
assert(buffer->fillCount >= 0);
}
/*!
* Access front of buffer
*
* This gives you a pointer to the front of the buffer, ready
* for writing, and the number of available bytes to write.
*
* @param buffer Circular buffer
* @param availableBytes On output, the number of bytes ready for writing
* @return Pointer to the first bytes ready for writing, or NULL if buffer is full
*/
static __inline__ __attribute__((always_inline)) void* TPCircularBufferHead(TPCircularBuffer *buffer, int32_t* availableBytes) {
*availableBytes = (buffer->length - buffer->fillCount);
if ( *availableBytes == 0 ) return NULL;
return (void*)((char*)buffer->buffer + buffer->head);
}
// Writing (producing)
/*!
* Produce bytes in buffer
*
* This marks the given section of the buffer ready for reading.
*
* @param buffer Circular buffer
* @param amount Number of bytes to produce
*/
static __inline__ __attribute__((always_inline)) void TPCircularBufferProduce(TPCircularBuffer *buffer, int32_t amount) {
buffer->head = (buffer->head + amount) % buffer->length;
if ( buffer->atomic ) {
OSAtomicAdd32Barrier(amount, &buffer->fillCount);
} else {
buffer->fillCount += amount;
}
assert(buffer->fillCount <= buffer->length);
}
/*!
* Helper routine to copy bytes to buffer
*
* This copies the given bytes to the buffer, and marks them ready for reading.
*
* @param buffer Circular buffer
* @param src Source buffer
* @param len Number of bytes in source buffer
* @return true if bytes copied, false if there was insufficient space
*/
static __inline__ __attribute__((always_inline)) bool TPCircularBufferProduceBytes(TPCircularBuffer *buffer, const void* src, int32_t len) {
int32_t space;
void *ptr = TPCircularBufferHead(buffer, &space);
if ( space < len ) return false;
memcpy(ptr, src, len);
TPCircularBufferProduce(buffer, len);
return true;
}
/*!
* Deprecated method
*/
static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferConsume instead")
void TPCircularBufferConsumeNoBarrier(TPCircularBuffer *buffer, int32_t amount) {
buffer->tail = (buffer->tail + amount) % buffer->length;
buffer->fillCount -= amount;
assert(buffer->fillCount >= 0);
}
/*!
* Deprecated method
*/
static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferProduce instead")
void TPCircularBufferProduceNoBarrier(TPCircularBuffer *buffer, int32_t amount) {
buffer->head = (buffer->head + amount) % buffer->length;
buffer->fillCount += amount;
assert(buffer->fillCount <= buffer->length);
}
#ifdef __cplusplus
}
#endif
#endif

317
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/queue.h

@ -1,317 +0,0 @@
#ifndef __QUEUE_H__
#define __QUEUE_H__
//
// Created by DFung on 16/1/25.
// Copyright © 2016年 DFung. All rights reserved.
//
/**
* Sample Used
*
* 1.Create Queue:
*
* queue_t *qt_video = queue_create_limited(100);
*
* 2.Put Data:
*
* Type_Data * p_data = (Type_Data *)p;
* int ret = queue_put(qt_video, p_data);
* if(ret != Q_OK){
* free(p_data);
* }
*
* 3.Get Data:
*
* Type_Data * get_frm_pkg = NULL;
* queue_get(qt_video, (void**)&get_frm_pkg);
*
* 4.Number of Data:
*
* int cache_counts = queue_elements(qt_video);
*
* 5.Destroy Queue:
*
* if (qt_video != NULL) {
* queue_destroy_complete(qt_video, queue_clean_video);
* qt_video = NULL;
* }
* static void queue_clean_video(void* tmp){
* Type_Data * qt_tmp = (Type_Data *)tmp;
* if (qt_tmp != NULL) {
* free(qt_tmp);
* }
* }
**/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> /* (u)intX_t */
#ifndef _WIN32
#include <unistd.h> /* usleep */
#else
#include <windows.h> /* Sleep */
#endif
#include <errno.h> /* EBUSY */
#include <pthread.h> /* pthread_mutex_t, pthread_cond_t */
#ifdef _WIN32
#define sleepmilli(x) Sleep(x)
#else
#define sleepmilli(x) usleep(x * 1000)
#endif
/**
* type which is used for counting the number of elements.
* needed for limited queues
*/
#ifndef UINTX_MAX
typedef uint16_t uintX_t;
#define UINTX_MAX UINT16_MAX
#endif
/**
* simple macros to reduce necessary casting to void *
* or function pointers
*/
#define DEFINE_Q_DESTROY(fname, type) int8_t fname(queue_t *q, void (*ff)(type *)) { return queue_destroy_complete(q, (void (*)(void *))ff); }
#define DEFINE_Q_FLUSH(fname, type) int8_t fname(queue_t *q, void (*ff)(type *)) { return queue_flush_complete(q, (void (*)(void *))ff); }
#define DEFINE_Q_GET(fname, type) int8_t fname(queue_t *q, type **e) { return queue_get(q, (void **)e); }
#define DEFINE_Q_GET_WAIT(fname, type) int8_t fname(queue_t *q, type **e) { return queue_get_wait(q, (void **)e); }
#define DEFINE_Q_PUT(fname, type) int8_t fname(queue_t *q, type *e) { return queue_put(q, (void *)e); }
#define DEFINE_Q_PUT_WAIT(fname, type) int8_t fname(queue_t *q, type *e) { return queue_put_wait(q, (void *)e); }
#define DEFINE_Q_FLUSH_PUT(fname, type) int8_t fname(queue_t *q, void (*ff)(type *), type *e) { return queue_flush_complete_put(q, (void (*)(void *))ff, (void *)e); }
/**
* returned error codes, everything except Q_OK should be < 0
*/
typedef enum queue_erros_e {
Q_OK = 0,
Q_ERR_INVALID = -1,
Q_ERR_LOCK = -2,
Q_ERR_MEM = -3,
Q_ERR_NONEWDATA = -4,
Q_ERR_INVALID_ELEMENT = -5,
Q_ERR_INVALID_CB = -6,
Q_ERR_NUM_ELEMENTS = -7
} queue_errors_t;
typedef struct queue_element_s {
void *data;
struct queue_element_s *next;
} queue_element_t;
typedef struct queue_s {
queue_element_t *first_el, *last_el;
// (max.) number of elements
uintX_t num_els;
uintX_t max_els;
// no new data allowed
uint8_t new_data;
// sorted queue
int8_t sort;
int8_t asc_order;
int (*cmp_el)(void *, void *);
// multithreaded
pthread_mutex_t *mutex;
pthread_cond_t *cond_get;
pthread_cond_t *cond_put;
} queue_t;
/**
* initializes and allocates a queue with unlimited elements
*
* returns NULL on error, or a pointer to the queue
*/
queue_t *queue_create(void);
/**
* initializes and allocates a queue
*
* max_elements - maximum number of elements which are allowed in the queue, == 0 for "unlimited"
*
* returns NULL on error, or a pointer to the queue
*/
queue_t *queue_create_limited(uintX_t max_elements);
/**
* just like queue_create()
* additionally you can specify a comparator function so that your elements are ordered in the queue
* elements will only be ordered if you create the queue with this method
* the compare function should return 0 if both elements are the same, < 0 if the first is smaller
* and > 0 if the second is smaller
*
* asc - sort in ascending order if not 0
* cmp - comparator function, NULL will create an error
*
* returns NULL on error, or a pointer to the queue
*/
queue_t *queue_create_sorted(int8_t asc, int (*cmp)(void *, void *));
/**
* see queue_create_limited() and queue_create_sorted()
*/
queue_t *queue_create_limited_sorted(uintX_t max_elements, int8_t asc, int (*cmp)(void *, void *));
/**
* releases the memory internally allocated and destroys the queue
* you have to release the memory the elements in the queue use
*
* q - the queue to be destroyed
*/
int8_t queue_destroy(queue_t *q);
/**
* in addition to queue_destroy(), this function will also free the memory of your elements
*
* q - the queue to be destroyed
* ff - the free function to be used for the elements (free() if NULL)
*/
int8_t queue_destroy_complete(queue_t *q, void (*ff)(void *));
/**
* deletes all the elements from the queue, but does not release their memory
*
* q - the queue
*/
int8_t queue_flush(queue_t *q);
/**
* just like queue_flush, but releases the memory of the elements
*
* q - the queue
* ff - the free function to be used for the elements (free() if NULL)
*/
int8_t queue_flush_complete(queue_t *q, void (*ff)(void *));
/**
* just like queue_flush, followed by an queue_put atomically
*
* q - the queue
* ff - the free function to be used for the elements (free() if NULL)
* e - the element
*/
int8_t queue_flush_put(queue_t *q, void (*ff)(void *), void *e);
/**
* just like queue_flush_complete, followed by an queue_put atomically
*
* q - the queue
* ff - the free function to be used for the elements (free() if NULL)
* e - the element
*/
int8_t queue_flush_complete_put(queue_t *q, void (*ff)(void *), void *e);
/**
* returns the number of elements in the queue
*
* q - the queue
*
* returns number of elements or UINTX_MAX if an error occured
*/
uintX_t queue_elements(queue_t *q);
/**
* returns wether the queue is empty
* returns empty if there was an error
*
* q - the queue
*
* returns zero if queue is NOT empty, < 0 => error
*/
int8_t queue_empty(queue_t *q);
/**
* put a new element at the end of the queue
* will produce an error if you called queue_no_new_data()
*
* q - the queue
* e - the element
*
* returns 0 if everything worked, > 0 if max_elements is reached, < 0 if error occured
*/
int8_t queue_put(queue_t *q, void *e);
/**
* the same as queue_put(), but will wait if max_elements is reached,
* until queue_set_new_data(, 0) is called or elements are removed
*
* q - the queue
* e - the element
*
* returns 0 if everything worked, < 0 if error occured
*/
int8_t queue_put_wait(queue_t *q, void *e);
/**
* preview the first element of the queue(预览一个元素,但没有抽取。)
*
* q - the queue
* e - pointer which will be set to the element
*
* returns 0 if everything worked, > 0 if no elements in queue, < 0 if error occured
*/
int8_t queue_get_pre(queue_t *q, void **e);
/**
* get the first element of the queue
*
* q - the queue
* e - pointer which will be set to the element
*
* returns 0 if everything worked, > 0 if no elements in queue, < 0 if error occured
*/
int8_t queue_get(queue_t *q, void **e);
/**
* the same as queue_get(), but will wait if no elements are in the queue,
* until queue_set_new_data(, 0) is called or new elements are added
*
* q - the queue
* e - pointer which will be set to the element
*
* returns 0 if everything worked, < 0 if error occured
*/
int8_t queue_get_wait(queue_t *q, void **e);
/**
* gets the first element for which the given compare function returns 0 (equal)
* does NOT wait if no elements in the queue
* the compare function should return 0 if both elements are the same, < 0 if the first is smaller
* and > 0 if the second is smaller
*
* q - the queue
* e - pointer which will be set to the element
* cmp - comparator function, NULL will create an error
* cmpel - element with which should be compared
*
* returns 0 if everything worked, < 0 => error, Q_ERR_NUM_ELEMENTS(<0) if no element fulfills the requirement
*/
int8_t queue_get_filtered(queue_t *q, void **e, int (*cmp)(void *, void *), void *cmpel);
/**
* sets wether the queue will accept new data
* defaults to 1 on creation
* you should use this function when you're done and queue_put_wait() and queue_get_wait() should return
* queue_put()/queue_put_wait() won't have any effect when new data isn't accepted.
*
* q - the queue
* v - 0 new data NOT accepted
*/
int8_t queue_set_new_data(queue_t *q, uint8_t v);
/**
* returns wether the queue will accept new data
* also returns 0, if there was an error
*
* q - the queue
*
* return 0 if new data is NOT accepted
*/
uint8_t queue_get_new_data(queue_t *q);
#endif /* __QUEUE_H__ */

97
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/queue_internal.h

@ -1,97 +0,0 @@
#ifndef __QUEUE_INTERNAL_H__
#define __QUEUE_INTERNAL_H__
/**
* Copyright (C) 2011 by Tobias Thiel
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <queue.h>
/**
* ATTENTION:
* these functions are internal and should not be used directly.
* they may _not_ lock properly, expecting the caller to do so
*/
/**
* locks the queue
* returns 0 on success, else not usable
*/
int8_t queue_lock_internal(queue_t *q);
/**
* unlocks the queue
* returns 0 on success, else not usable
*/
int8_t queue_unlock_internal(queue_t *q);
/**
* adds an element to the queue.
* when action is NULL the function returns with an error code.
* queue _has_ to be locked.
*
* q - the queue
* el - the element
* action - specifies what should be executed if max_elements is reached.
*
* returns < 0 => error, 0 okay
*/
int8_t queue_put_internal(queue_t *q, void *el, int (*action)(pthread_cond_t *, pthread_mutex_t *));
/**
* gets the first element in the queue.
* when action is NULL the function returns with an error code.
* queue _has_ to be locked.
*
* q - the queue
* e - element pointer
* action - specifies what should be executed if there are no elements in the queue
* cmp - comparator function, NULL will create an error
* cmpel - element with which should be compared
*
* returns < 0 => error, 0 okay
*/
int8_t queue_get_internal(queue_t *q, void **e, int (*action)(pthread_cond_t *, pthread_mutex_t *), int (*cmp)(void *, void *), void *cmpel);
/**
* destroys a queue.
* queue will be locked.
*
* q - the queue
* fd - should element data be freed? 0 => No, Otherwise => Yes
* ff - function to release the memory, NULL => free()
*/
int8_t queue_destroy_internal(queue_t *q, uint8_t fd, void (*ff)(void *));
/**
* flushes a queue.
* deletes all elements in the queue.
* queue _has_ to be locked.
*
* q - the queue
* fd - should element data be freed? 0 => No, Otherwise => Yes
* ff - function to release the memory, NULL => free()
*/
int8_t queue_flush_internal(queue_t *q, uint8_t fd, void (*ff)(void *));
#endif /* __QUEUE_INTERNAL_H__ */

26
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/tcp_client.h

@ -1,26 +0,0 @@
#ifndef __TCP_CLIENT_H__
#define __TCP_CLIENT_H__
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
struct tcp_client{
int fd;
};
int tcp_connect(const char *ip, const int port, struct tcp_client **tc);
int tcp_read(struct tcp_client *tc, unsigned char *buf, int size);
int tcp_write(struct tcp_client *tc, unsigned char *buf, int size);
int tcp_close(struct tcp_client *tc);
#endif

29
local_plugins/ota/ios/Frameworks/DFUnits.framework/Headers/tcp_server.h

@ -1,29 +0,0 @@
#ifndef __TCP_SERVER_H__
#define __TCP_SERVER_H__
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
struct tcp_server{
int fd;
};
#include "tcp_client.h"
int tcp_new_server(const int port ,struct tcp_server **ts);
int tcp_new_client(int fd, struct tcp_client **tc);
int tcp_listen(struct tcp_server *ts, const int max);
int tcp_accept(struct tcp_server *ts, struct sockaddr *addr, socklen_t *len);
int tcp_server_close(struct tcp_server *ts);
#endif

BIN
local_plugins/ota/ios/Frameworks/DFUnits.framework/Info.plist

Binary file not shown.

6
local_plugins/ota/ios/Frameworks/DFUnits.framework/Modules/module.modulemap

@ -1,6 +0,0 @@
framework module DFUnits {
umbrella header "DFUnits.h"
export *
module * { export * }
}

19
local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Headers/JLLogHelper.h

@ -1,19 +0,0 @@
//
// JLLogHelper.h
// JLLogHelper
//
// Created by EzioChan on 2024/5/8.
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
//
#import <Foundation/Foundation.h>
//! Project version number for JLLogHelper.
FOUNDATION_EXPORT double JLLogHelperVersionNumber;
//! Project version string for JLLogHelper.
FOUNDATION_EXPORT const unsigned char JLLogHelperVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <JLLogHelper/PublicHeader.h>
#import <JLLogHelper/JLLogManager.h>

75
local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Headers/JLLogManager.h

@ -1,75 +0,0 @@
//
// JLLogManager.h
// JLLogHelper
//
// Created by EzioChan on 2024/5/8.
// Copyright © 2024 www.zh-jieli.com. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// 打印宏
#define kJLLog(level,fmt...) [JLLogManager logLevel:level funcName:__FUNCTION__ line:__LINE__ format:fmt]
typedef NS_ENUM(NSInteger, JLLOG_LEVEL) {
JLLOG_COMPLETE = 0,
JLLOG_DEBUG = 1,
JLLOG_INFO = 2,
JLLOG_WARN = 3,
JLLOG_ERROR = 4,
};
/// 日志打印
@interface JLLogManager : NSObject
/// 打印SDK版本
+(void)sdkVersion;
///清理已存储的打印
+(void)clearLog;
/**
* 打印文本
*/
+(void)openLogTextFile;
/// 打印时间
/// @param isTimeStamp 是否打印 default is false
+(void)logWithTimestamp:(BOOL)isTimeStamp;
/// 把日志保存存储起来
/// @param isSave 是否保存 default is yes
+(void)saveLogAsFile:(BOOL)isSave;
///LOG使能与等级,默认开启且debug等级。
/// @param enable LOG使能
/// @param isMore 是否打印【函数名&行号】
/// @param level LOG等级
+(void)setLog:(BOOL)enable IsMore:(BOOL)isMore Level:(JLLOG_LEVEL)level;
/// 打印函数
/// @param level LOG等级
/// @param func 函数名
/// @param line 行号
/// @param format 内容
+(void)logLevel:(JLLOG_LEVEL)level funcName:(const char* _Nullable)func line:(const int)line format:(NSString * _Nonnull)format,...;
/// 打印
/// @param something 任意字符串内容
+(void)logSomething:(NSString *)something;
/// 打印
/// @param level LOG等级
/// @param content 内容
+(void)logLevel:(JLLOG_LEVEL)level content:(NSString *)content;
/// 保存日志信息到文件中
/// @param logContent 日志内容
+(void)saveLog:(NSString *)logContent;
@end
NS_ASSUME_NONNULL_END

BIN
local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Info.plist

Binary file not shown.

BIN
local_plugins/ota/ios/Frameworks/JLLogHelper.framework/JLLogHelper

Binary file not shown.

6
local_plugins/ota/ios/Frameworks/JLLogHelper.framework/Modules/module.modulemap

@ -1,6 +0,0 @@
framework module JLLogHelper {
umbrella header "JLLogHelper.h"
export *
module * { export * }
}

BIN
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Frameworks/JLLogHelper.framework/Info.plist

Binary file not shown.

BIN
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Frameworks/JLLogHelper.framework/JLLogHelper

Binary file not shown.

67
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLAdvParse.h

@ -1,67 +0,0 @@
//
// JLAdvParse.h
// JL_AdvParse
//
// Created by EzioChan on 2023/1/31.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <JLLogHelper/JLLogHelper.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(UInt8,JL_AdvType) {
JL_AdvTypeSoundBox = 0, //音箱类型
JL_AdvTypeChargingBin = 1, //充电仓类型
JL_AdvTypeTWS = 2, //TWS耳机类型
JL_AdvTypeHeadset = 3, //普通耳机类型
JL_AdvTypeSoundCard = 4, //声卡类型
JL_AdvTypeWatch = 5, //手表类型
JL_AdvTypeTradition = 6, //传统设备类型
};
typedef NS_ENUM(NSInteger,JL_DeviceType) {
JL_DeviceTypeSoundBox = 0, //AI音箱类型
JL_DeviceTypeChargingBin = 1, //充电仓类型
JL_DeviceTypeTWS = 2, //TWS耳机类型
JL_DeviceTypeHeadset = 3, //普通耳机类型
JL_DeviceTypeSoundCard = 4, //声卡类型
JL_DeviceTypeWatch = 5, //手表类型
JL_DeviceTypeTradition = -1, //传统设备类型
};
/// 广播包解析器
@interface JLAdvParse : NSObject
/// 打印当前SDK的版本
+(void)sdkVersion;
/// 解析设备广播包内容
/// @param key 过滤码(只针对传统设备生效,默认填空即可)
/// @param advertData 蓝牙广播字典
+(NSDictionary*)bluetoothAdvParse:(NSData *_Nullable)key AdvData:(NSDictionary*_Nonnull)advertData;
#pragma mark - 回连广播包信息
/**
* 获取广播包kCBAdvDataManufacturerData里面 'JLOTA' 标识的蓝牙地址
* @param kCBAdvDataManufacturerData 广播包
*/
+ (NSString * _Nullable)otaBleMacAddressFromCBAdvDataManufacturerData:(NSData *)kCBAdvDataManufacturerData;
/**
* 判断当前蓝牙地址是否等于广播包kCBAdvDataManufacturerData里面的蓝牙地址
* @param otaBleMacAddress ota升级中设备的蓝牙地址
* @param kCBAdvDataManufacturerData 广播包
*/
+ (Boolean)otaBleMacAddress:(NSString *)otaBleMacAddress isEqualToCBAdvDataManufacturerData:(NSData *)kCBAdvDataManufacturerData;
@end
NS_ASSUME_NONNULL_END

64
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLChargingBoxAdv.h

@ -1,64 +0,0 @@
//
// JLChargingBoxAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import "JLDevicesAdv.h"
NS_ASSUME_NONNULL_BEGIN
@interface JLChargingBoxAdv : JLDevicesAdv
/// 经典蓝牙地址
@property(nonatomic, strong) NSString *edrAddr;
/// 是否已配对
@property(nonatomic, assign) BOOL isParied;
/// 是否已开盖
@property(nonatomic, assign) BOOL isOpen;
/// 耳机状态
///0x00:不显示弹窗
///0x01:经典蓝牙未连接
///0x02:经典蓝牙已连接
///0x03:设备正在回连
///0x04:设备不可连接 (需要手动进入配对模式)
@property(nonatomic, assign) uint8_t status;
/// 左耳电量
@property(nonatomic, assign) uint8_t batteryLeft;
/// 右耳电量
@property(nonatomic, assign) uint8_t batteryRight;
/// 充电仓电量
@property(nonatomic, assign) uint8_t batteryBox;
///左耳是否在充电中
@property(nonatomic, assign) BOOL isChargingLeft;
///右耳是否在充电中
@property(nonatomic, assign) BOOL isChargingRight;
///充电仓是否在充电中
@property(nonatomic, assign) BOOL isChargingBox;
/// seq
/// 用于区分是否同一次开机。每次开机或者断开连接后 增加1
@property(nonatomic, assign) uint8_t seq;
///模式
/// 0x00:充电模式
/// 0x01:发射模式
@property(nonatomic, assign) uint8_t mode;
/// 加密 Hash 校验值
@property(nonatomic, copy) NSData *hashData;
@end
NS_ASSUME_NONNULL_END

54
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLDevicesAdv.h

@ -1,54 +0,0 @@
//
// JLDevicesAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "JLAdvParse.h"
NS_ASSUME_NONNULL_BEGIN
@interface JLDevicesAdv : NSObject
/// 客户唯一标识
@property(nonatomic,assign)uint16_t uid;
/// 产品唯一标识
@property(nonatomic,assign)uint16_t pid;
/// 设备类型
///JL_DeviceTypeSoundBox = 0, //AI音箱类型
///JL_DeviceTypeChargingBin = 1, //充电仓类型
///JL_DeviceTypeTWS = 2, //TWS耳机类型
///JL_DeviceTypeHeadset = 3, //普通耳机类型
///JL_DeviceTypeSoundCard = 4, //声卡类型
///JL_DeviceTypeWatch = 5, //手表类型
///JL_DeviceTypeTradition = -1, //传统设备类型
@property(nonatomic,assign)JL_DeviceType type;
/// 协议版本
@property(nonatomic,assign)uint8_t version;
/// 可变数据段
@property(nonatomic,copy)NSData *variableData;
- (instancetype)initWithData:(NSData *)data;
/// 转成model类型
/// @param basicData 蓝牙广播数据
+(JLDevicesAdv *__nullable)advertDataToModel:(NSData *)basicData;
/// 转成model类型
/// @param basicHexStr 蓝牙广播数据
+(JLDevicesAdv *__nullable)advertDataHexStrToModel:(NSString *)basicHexStr;
@end
NS_ASSUME_NONNULL_END

47
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLEarphoneAdv.h

@ -1,47 +0,0 @@
//
// JLEarphoneAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import "JLDevicesAdv.h"
NS_ASSUME_NONNULL_BEGIN
@interface JLEarphoneAdv : JLDevicesAdv
/// 左耳电量
@property(nonatomic, assign) uint8_t batteryLeft;
/// 右耳电量
@property(nonatomic, assign) uint8_t batteryRight;
///左耳是否在充电中
@property(nonatomic, assign) BOOL isChargingLeft;
///右耳是否在充电中
@property(nonatomic, assign) BOOL isChargingRight;
/// 是否已配对
@property(nonatomic, assign) BOOL isParied;
/// 是否主机
@property(nonatomic, assign) BOOL isMaster;
/// 是否允许连接
@property(nonatomic, assign) BOOL enableConnect;
/// 耳机状态
///0x00:不显示弹窗
///0x01:经典蓝牙未连接
///0x02:经典蓝牙已连接
///0x03:设备正在回连
///0x04:设备不可连接 (需要手动进入配对模式)
@property(nonatomic, assign) uint8_t status;
@end
NS_ASSUME_NONNULL_END

25
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLOtaAdv.h

@ -1,25 +0,0 @@
//
// JLOtaAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import <JL_AdvParse/JL_AdvParse.h>
NS_ASSUME_NONNULL_BEGIN
@interface JLOtaAdv : JLDevicesAdv
/// ble address before
@property(nonatomic,strong)NSString *BleAddrBefore;
//MARK: - Version 1
/// battery
@property(nonatomic,assign)uint8_t battery;
@end
NS_ASSUME_NONNULL_END

19
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLSoundBoxAdv.h

@ -1,19 +0,0 @@
//
// JLSoundBoxAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import "JLTwsAdv.h"
NS_ASSUME_NONNULL_BEGIN
@interface JLSoundBoxAdv : JLTwsAdv
@property(nonatomic,assign)uint8_t battery;
@end
NS_ASSUME_NONNULL_END

19
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLSoundCardAdv.h

@ -1,19 +0,0 @@
//
// JLSoundCardAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import "JLTwsAdv.h"
NS_ASSUME_NONNULL_BEGIN
@interface JLSoundCardAdv : JLTwsAdv
@property(nonatomic,assign)uint8_t battery;
@end
NS_ASSUME_NONNULL_END

70
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLTwsAdv.h

@ -1,70 +0,0 @@
//
// JLTwsAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import "JLDevicesAdv.h"
NS_ASSUME_NONNULL_BEGIN
@interface JLTwsAdv : JLDevicesAdv
//MARK: - Version 0
/// 经典蓝牙地址
@property(nonatomic, strong) NSString *edrAddr;
/// 耳机状态
///0x00:不显示弹窗
///0x01:经典蓝牙未连接
///0x02:经典蓝牙已连接
///0x03:设备正在回连
///0x04:设备不可连接 (需要手动进入配对模式)
@property(nonatomic, assign) uint8_t status;
/// 左耳电量
@property(nonatomic, assign) uint8_t batteryLeft;
/// 右耳电量
@property(nonatomic, assign) uint8_t batteryRight;
/// 充电仓电量
@property(nonatomic, assign) uint8_t batteryBox;
///左耳是否在充电中
@property(nonatomic, assign) BOOL isChargingLeft;
///右耳是否在充电中
@property(nonatomic, assign) BOOL isChargingRight;
///充电仓是否在充电中
@property(nonatomic, assign) BOOL isChargingBox;
/// seq
/// 用于区分是否同一次开机。每次开机或者断开连接后 增加1
@property(nonatomic, assign) uint8_t seq;
/// 加密 Hash 校验值
@property(nonatomic, copy) NSData *hashData;
//MARK: - Version 1
/// BLE连接属性(enableConnect)
@property(nonatomic, assign) BOOL bleEnable;
//MARK: - Version 2
/// 连接方式
/// 0x00 BLE 通迅
/// 0x01 SPP 通迅
@property(nonatomic, assign) uint8_t connectWay;
/// 是否支持智能充电仓
@property(nonatomic, assign) BOOL isSupportChargBox;
//MARK: - Version 3
/// 左耳电量为挂脖耳机电量!!!,其他耳机电量使用
@end
NS_ASSUME_NONNULL_END

35
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JLWatchAdv.h

@ -1,35 +0,0 @@
//
// JLWatchAdv.h
// JL_AdvParse
//
// Created by EzioChan on 2023/12/12.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import <JL_AdvParse/JLDevicesAdv.h>
NS_ASSUME_NONNULL_BEGIN
@interface JLWatchAdv : JLDevicesAdv
/// 经典蓝牙地址
@property(nonatomic, strong) NSString *edrAddr;
/// 连接方式
/// 0x00 ble
/// 0x01 spp
@property(nonatomic, assign) int8_t connectWay;
/// 手表状态
/// 0x00:经典蓝牙未连接
/// 0x01:经典蓝牙已连接 0x02:设备正在回连
/// 0x03:设备不可连接 (需要手动进入配对模式)
@property(nonatomic, assign) int8_t connectState;
/// 是否需要先连上 ble
@property(nonatomic, assign) BOOL priorityConnection;
@end
NS_ASSUME_NONNULL_END

27
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Headers/JL_AdvParse.h

@ -1,27 +0,0 @@
//
// JL_AdvParse.h
// JL_AdvParse
//
// Created by EzioChan on 2023/1/31.
// Copyright © 2023 www.zh-jieli.com. All rights reserved.
//
#import <Foundation/Foundation.h>
//! Project version number for JL_AdvParse.
FOUNDATION_EXPORT double JL_AdvParseVersionNumber;
//! Project version string for JL_AdvParse.
FOUNDATION_EXPORT const unsigned char JL_AdvParseVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <JL_AdvParse/PublicHeader.h>
#import <JL_AdvParse/JLAdvParse.h>
#import <JL_AdvParse/JLDevicesAdv.h>
#import <JL_AdvParse/JLTwsAdv.h>
#import <JL_AdvParse/JLSoundBoxAdv.h>
#import <JL_AdvParse/JLSoundCardAdv.h>
#import <JL_AdvParse/JLChargingBoxAdv.h>
#import <JL_AdvParse/JLEarphoneAdv.h>
#import <JL_AdvParse/JLWatchAdv.h>
#import <JL_AdvParse/JLOtaAdv.h>

BIN
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Info.plist

Binary file not shown.

BIN
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/JL_AdvParse

Binary file not shown.

6
local_plugins/ota/ios/Frameworks/JL_AdvParse.framework/Modules/module.modulemap

@ -1,6 +0,0 @@
framework module JL_AdvParse {
umbrella header "JL_AdvParse.h"
export *
module * { export * }
}

BIN
local_plugins/ota/ios/Frameworks/JL_HashPair.framework/Frameworks/JLLogHelper.framework/Info.plist

Binary file not shown.

BIN
local_plugins/ota/ios/Frameworks/JL_HashPair.framework/Frameworks/JLLogHelper.framework/JLLogHelper

Binary file not shown.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save