FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
+ "$(PROJECT_DIR)/ShenYin/UI/Mine/Update/SDKBleManager",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = ShenYin/Info.plist;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
+ "$(PROJECT_DIR)/ShenYin/UI/Mine/Update/SDKBleManager",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = ShenYin/Info.plist;
// static let wxSecret = "751582916ca3779b7b99356609e30e55"
// static let wxUniversalLink = "https://www.thisiot.com/flychat"
//
- static let wxAppID = "wxf19317f23b00d8ab"
+ static let wxAppID = "wxd9d677e0024caa90"
static let wxUniversalLink = "https://dc-cloud-pub.tos-cn-guangzhou.volces.com/app/"
static let wxSecret = "SECRET"
/// 通用链接
case updatePwd(param:[String:Any])
/// 检查令牌
case token
+ /// 绑定手机号码
+ case bindPhone(param:[String:Any])
/// 更新手机号码
case updatePhone(param:[String:Any])
/// 更新邮箱
return "/uc/token"
case .updatePhone(let param):
return "/uc/phone?smsCode=\(param["smsCode"]!)&phone=\(param["phone"]!)"
+ case .bindPhone(let param):
+ return "/uc/phone/bind?smsCode=\(param["smsCode"]!)&phone=\(param["phone"]!)"
case .updateEmail(let param):
return "/uc/email?emailCode=\(param["emailCode"]!)&email=\(param["email"]!)"
case .updateUserInfo(let param):
switch self {
case .register(_),.phoneCodeLogin(_),.emailCodeLogin(_),.appleLogin(_),.login(_),.commitFeedback(_),.voiceRecord(_),.voiceRecordText(_):
return .post
- case .updatePwd(_),.updateUserInfo(_),.updatePhone(_),.updateEmail(_),.bindDevice(_),.otaUpdateVersion(_),.voiceRecordCollection(_),.updateVoiceRecord(_):
+ case .updatePwd(_),.updateUserInfo(_),.updatePhone(_),.bindPhone(_),.updateEmail(_),.bindDevice(_),.otaUpdateVersion(_),.voiceRecordCollection(_),.updateVoiceRecord(_):
return .put
case .deleteLoginRecord(_),.unbind(_),.deleteVoiceRecord(_):
return .delete
private let userDefaults = UserDefaults.standard
private let key = "UserCacheInfo"
+ func remove(){
+ userDefaults.removeObject(forKey: key)
+ userDefaults.synchronize()
+ }
+
func save(_ info: UserInfo) {
let cache = UserCacheInfo.infoToCache(info)
let encoder = NSKeyedArchiver.archivedData(withRootObject: cache)
}
func logout(){
self.token = nil
+ self.info = UserInfo()
+ UserCache.shared.remove()
NotificationManager.post(type: .logout, objtect: nil)
App.shared.goToLogin()
}
UserCache.shared.save(self.info)
}
else{
- if let dict = YLToos.stringToJson(res),let code = dict["code"] as? Int,code == 50000{
- logout()
+ if let dict = YLToos.stringToJson(res),let code = dict["code"] as? Int{
+ if code == 50000{
+ logout()
+ }
+ else if code == 50022{
+ if let vc = App.shared.topVC() as? BindingPhoneVC{
+
+ }
+ else{
+ App.shared.goToPage(BindingPhoneVC())
+ }
+ }
}
}
finished?()
#import "YLTimerButton.h"
#import "PcmSound.h"
#import <zlib.h>
+#import "YLOtaManager2.h"
</array>
<key>com.apple.developer.associated-domains</key>
<array>
- <string>applinks:https://dc-cloud-pub.tos-cn-guangzhou.volces.com</string>
+ <string>applinks:dc-cloud-pub.tos-cn-guangzhou.volces.com</string>
</array>
</dict>
</plist>
var roleList:[JoyGemSpeaker] = []
-
deinit {
PcmSound.sharedInstance().stopAudioUnit()
PcmSound.sharedInstance().cleanup()
class DialogTranslateCell:BaseTableViewCell{
let bgView = UIView()
- let line = BrokenLineView()
+// let line = BrokenLineView()
+ let line = UIView()
let originalLabel = UILabel()
let translationLabel = UILabel()
let playIcon = UIImageView()
--- /dev/null
+//
+// BindingPhoneVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/11/17.
+//
+
+import UIKit
+
+class BindingPhoneVC:BaseVC{
+
+ let titleLabel = UILabel()
+ let phoneView = CustomInputView()
+ let loginBtn = CustomButton()
+
+ var isBingding:Bool = false
+
+ init(binding:Bool = false) {
+ self.isBingding = binding
+ super.init()
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+ override func setupViews(){
+ self.navBar.leftView.isHidden = true
+ self.navBar.title = "绑定安全手机".l10n
+ view.backgroundColor = .color(.bgColor)
+
+
+ titleLabel.do { v in
+ v.text = "请输入手机号码".l10n
+ v.font = .medium(18)
+ v.textColor = .hexString("#121212")
+ }
+ phoneView.do { v in
+
+ }
+ loginBtn.set(title: "下一步".l10n,style: .theme1, target: self, action: #selector(loginAction))
+ view.addSubviews([titleLabel,phoneView,loginBtn])
+
+ }
+ override func setupLayout(){
+
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().offset(kNavBtm + 30)
+ make.left.right.equalToSuperview().inset(36)
+ }
+ phoneView.snp.makeConstraints { make in
+ make.top.equalTo(titleLabel.snp.bottom).offset(16)
+ make.left.right.equalToSuperview().inset(36)
+ }
+
+ loginBtn.snp.makeConstraints { make in
+ make.top.equalTo(phoneView.snp.bottom).offset(40)
+ make.left.right.equalToSuperview().inset(51)
+ make.height.equalTo(55)
+ }
+
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ if isBingding{
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+ }
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ if isBingding{
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ }
+ }
+// override func navRightViewTapped() {
+// super.navRightViewTapped()
+//
+// CacheManager.shared.user.logout()
+// }
+}
+
+extension BindingPhoneVC{
+ @objc func loginAction(){
+ guard let phone = phoneView.textField.value else{
+ YLprogressHUD.showAutoHiden("请输入手机号码".l10n)
+ return
+ }
+ App.shared.goToPage(VarifyBindingVC(phone: phone))
+ }
+}
--- /dev/null
+//
+// VarifyBindingVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/11/17.
+//
+
+
+import UIKit
+class VarifyBindingVC:BaseVC{
+
+ let titleLabel = UILabel()
+ let codeView = CodeView()
+ let loginBtn = CustomButton()
+
+ var phone:String = ""
+
+ init(phone:String) {
+ self.phone = phone
+ super.init()
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+ override func setupViews(){
+ self.navBar.title = "账号设置".l10n
+ view.backgroundColor = .color(.bgColor)
+
+ titleLabel.do { v in
+
+ v.font = .medium(18)
+ v.textColor = .hexString("#121212")
+ v.numberOfLines = 0
+ }
+ codeView.do { v in
+ v.codeButton.addTarget(self, action: #selector(codeButtonAction), for: .touchUpInside)
+ }
+ loginBtn.set(title: "确定".l10n,style: .theme1, target: self, action: #selector(loginAction))
+ view.addSubviews([titleLabel,codeView,loginBtn])
+
+ titleLabel.text = "请使用安全手机".l10n + phone + "获取验证码短信".l10n
+ }
+ override func setupLayout(){
+
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().offset(kNavBtm + 30)
+ make.left.right.equalToSuperview().inset(36)
+ }
+ codeView.snp.makeConstraints { make in
+ make.top.equalTo(titleLabel.snp.bottom).offset(16)
+ make.left.right.equalToSuperview().inset(36)
+ }
+
+ loginBtn.snp.makeConstraints { make in
+ make.top.equalTo(codeView.snp.bottom).offset(40)
+ make.left.right.equalToSuperview().inset(51)
+ make.height.equalTo(55)
+ }
+ }
+ override func setupData() {
+ codeButtonAction()
+ }
+}
+
+extension VarifyBindingVC{
+ @objc func codeButtonAction(){
+ YLprogressHUD.showLoading()
+ HttpClient.request(CommomApi.sms(account: self.phone,type: .bind)) {[weak self] (model:ResponseBaseModel, res) in
+ if model.isSuccess{
+ YLprogressHUD.hidden()
+ self?.codeView.codeButton.start()
+ }
+ else{
+ YLprogressHUD.showAutoHiden(model.msg)
+ }
+ }
+ }
+ @objc func loginAction(){
+ guard let code = codeView.textField.value else{
+ YLprogressHUD.showAutoHiden("请输入验证码".l10n)
+ return
+ }
+ YLprogressHUD.showLoading()
+ var params:[String:Any] = [:]
+ params["phone"] = phone
+ params["smsCode"] = code
+
+ let api = CommomApi.bindPhone(param: params)
+ HttpClient.request(api) { (result:ResponseBaseModel,res) in
+ if result.isSuccess{
+ YLprogressHUD.showSuccess {
+ App.shared.didLogin()
+ }
+ }
+ else{
+ YLprogressHUD.showAutoHiden(result.msg)
+ }
+ }
+ }
+}
loginBtn.set(title: "确定".l10n,style: .theme1, target: self, action: #selector(loginAction))
view.addSubviews([titleLabel,codeView,loginBtn])
- titleLabel.text = "请使用安全邮箱\(email)获取验证码短信".l10n
+ titleLabel.text = "请使用安全邮箱".l10n + email + "获取验证码短信".l10n
}
override func setupLayout(){
loginBtn.set(title: "确定".l10n,style: .theme1, target: self, action: #selector(loginAction))
view.addSubviews([titleLabel,codeView,loginBtn])
- titleLabel.text = "请使用安全手机\(phone)获取验证码短信".l10n
+ titleLabel.text = "请使用安全手机".l10n + phone + "获取验证码短信".l10n
}
override func setupLayout(){
}
}
@objc func wechatAction(){
- Logger.debug("wechat action")
- return
+// Logger.debug("wechat action")
+// return
guard IASignWithWeChat.shared.isInstalled else { return }
// guard agreeAgreementBtn.isSelected else { return "请同意《App隐私政策》".asToastShow() }
case forget
case update
case login
+ case bind
var value:String{
switch self {
return "update"
case .login:
return "login"
+ case .bind:
+ return "bind"
}
}
}
if CacheManager.shared.user.info.phone.isNotEmpty{
- titleLabel.text = "请使用安全手机\(CacheManager.shared.user.info.phone)获取验证码短信".l10n
+ titleLabel.text = "请使用安全手机".l10n + CacheManager.shared.user.info.phone + "获取验证码短信".l10n
}
else{
- titleLabel.text = "请使用安全邮箱\(CacheManager.shared.user.info.email)获取验证码短信".l10n
+ titleLabel.text = "请使用安全邮箱".l10n + CacheManager.shared.user.info.email + "获取验证码短信".l10n
}
}
override func setupLayout(){
--- /dev/null
+//
+// 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>
--- /dev/null
+//
+// 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 \ 5yes
++(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
--- /dev/null
+framework module JLLogHelper {
+ umbrella header "JLLogHelper.h"
+ export *
+
+ module * { export * }
+}
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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>
+
--- /dev/null
+framework module JL_AdvParse {
+ umbrella header "JL_AdvParse.h"
+ export *
+
+ module * { export * }
+}
--- /dev/null
+//
+// ECBDTManager.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/11/20.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <JL_BLEKit/JL_BLEKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+
+@protocol ECBDTManagerProtocol <NSObject>
+
+/// 大数据传输错误
+/// - Parameters:
+/// - manager: 设备
+/// - type: 类型
+/// - error: 错误
+-(void)ecBDTManagerError:(JL_ManagerM *)manager Type:(uint8_t) type Error:(NSError *)error;
+
+/// 获取到设备端推送/ SDK 端读取的大数据内容
+/// - Parameters:
+/// - manager: 设备
+/// - type: 类型
+/// - data: 数据块
+/// - progress: 进度
+-(void)ecBDTManager:(JL_ManagerM *)manager Type:(uint8_t) type GetBigData:(NSData *)data Progress:(float) progress;
+
+/// 获取到设备端推送/ SDK 端读取的大数据内容 结束
+/// - Parameters:
+/// - manager: 设备
+/// - type: 类型
+/// - saveFilePath: 数据存放位置
+-(void)ecBDTManager:(JL_ManagerM *)manager Type:(uint8_t) type FinishBigData:(NSString *)saveFilePath;
+
+
+@optional
+
+/// App 端主动发起的向写入数据进度
+/// - Parameters:
+/// - manager: 设备
+/// - progress: 数据
+/// - finish: 是否完成
+-(void)ecBDTManager:(JL_ManagerM *)manager SendBigDataPresent:(float )progress Finish:(BOOL)finish;
+
+/// 设备端发起大数据写操作
+/// 设备端主动发起的向 App 端写入数据
+/// - Parameters:
+/// - manager: 设备
+/// - type: 类型
+/// - req: 请求写入的内容
+-(void)ecBDTManager:(JL_ManagerM *)manager StartBigData:(ECBDTWriteReq *)req Type:(uint8_t) type;
+
+
+/// 设备端发起大数据读取操作
+/// 开发者在这里需要对设备主动过来请求的内容进行回复
+/// -(void)responseDev:(JL_ManagerM *)manager resp:(ECBDTReadReq *)req Data:(NSData *)data
+/// - Parameters:
+/// - manager: 设备
+/// - type: 类型
+/// - req: 请求内容
+-(void)ecBDTManager:(JL_ManagerM *)manager ReadBigData:(ECBDTReadReq *)req Type:(uint8_t) type;
+
+/// 发送大数据完毕
+/// - Parameter manager: 设备
+/// - Parameter type: 类型
+-(void)ecBDTManagerSendFinish:(JL_ManagerM *)manager Type:(uint8_t) type;
+
+@end
+
+@interface ECBDTManager : ECOneToMorePtl
+
++(instancetype)share;
+
+/// APP 读取设备数据
+/// - Parameters:
+/// - manager: 设备
+/// - type: 数据类型
+/// * 0 :原始数据
+/// * 1 : 阿里云数据
+/// * 2:RTC数据
+/// * 3:AI云
+/// * 4:TTS语音合成
+/// * 5:平台接口认证信息
+/// * 6:esim 卡信息
+/// * 7:4G 模块升级数据
+/// * 8:提示音文件数据
+-(void)readData:(JL_ManagerM *)manager Type:(uint8_t)type;
+
+/// APP 写入设备数据
+/// - Parameters:
+/// - manager: 设备
+/// - type: 数据类型
+/// * 0 :原始数据
+/// * 1 : 阿里云数据
+/// * 2:RTC数据
+/// * 3:AI云
+/// * 4:TTS语音合成
+/// * 5:平台接口认证信息
+/// * 6:esim 卡信息
+/// * 7:4G 模块升级数据
+/// * 8:提示音文件数据
+/// - data: 大数据内容
+-(void)writeData:(JL_ManagerM *)manager Type:(uint8_t) type Data:(NSData*)data;
+
+/// 回应设备主动读取内容
+/// 此方法需要配合使用
+/// -(void)ecBDTManager:(JL_ManagerM *)manager ReadBigData:(ECBDTReadReq *)req
+/// - Parameters:
+/// - manager: 设备
+/// - req: 设备端请求的对象
+/// - data: 需要下发的数据内容
+-(void)responseDev:(JL_ManagerM *)manager resp:(ECBDTReadReq *)req Data:(NSData *)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// ECBDTObjc.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/11/21.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ECBDTObjc : NSObject
+
+@end
+
+/// 设备传输参数回复数据
+@interface ECBDTBasic : NSObject
+/// 操作类型
+/// 0:设备传输参数
+/// 1:传输数据
+@property (nonatomic, assign) uint8_t op;
+
+/// 方式
+/// 0:读取数据
+/// 1:发送数据
+@property (nonatomic, assign) uint8_t way;
+
+/// 数据类型
+/// * 0 :原始数据
+/// * 1 : 阿里云数据
+/// * 2:RTC数据
+/// * 3:AI云
+/// * 4:TTS语音合成
+/// * 5:平台接口认证信息
+/// * 6:esim 卡信息
+/// * 7:4G 模块升级数据
+@property (nonatomic, assign) uint8_t type;
+
+/// 版本
+@property (nonatomic, assign) uint8_t version;
+
+/// 数据
+@property (nonatomic, copy)NSData *paramData;
+
+-(instancetype)initData:(NSData *)data;
+
+@end
+
+
+//MARK: - 回复大数据数据解析(设备回复)
+
+/// 设备传输参数(读取回复)
+@interface ECBDTReadResp : ECBDTBasic
+/// 结果码
+@property (nonatomic, assign) uint8_t result;
+
+/// 数据长度
+@property (nonatomic, assign) uint32_t dtLen;
+
+/// 数据总 CRC
+@property (nonatomic, assign) uint16_t crc;
+
+/// 发送 MTU 协商值
+@property (nonatomic, assign) uint16_t sendMtu;
+
+/// 接收 MTU 协商值
+@property (nonatomic, assign) uint16_t receiveMtu;
+
+@end
+
+/// 设备传输参数(发送回复)
+@interface ECBDTWriteResp : ECBDTBasic
+/// 结果码
+@property (nonatomic, assign) uint8_t result;
+
+/// 发送 MTU 协商值
+@property (nonatomic, assign) uint16_t sendMtu;
+
+/// 接收 MTU 协商值
+@property (nonatomic, assign) uint16_t receiveMtu;
+
+@end
+
+//MARK: - 请求大数据数据解析(设备请求)
+
+/// 设备传输参数(读取请求)
+@interface ECBDTReadReq: ECBDTBasic
+
+/// 发送 MTU 协商值
+@property (nonatomic, assign) uint16_t sendMtu;
+
+/// 接收 MTU 协商值
+@property (nonatomic, assign) uint16_t receiveMtu;
+
+@end
+
+
+/// 设备传输参数(发送请求)
+@interface ECBDTWriteReq : ECBDTBasic
+
+/// 数据长度
+@property (nonatomic, assign) uint32_t dtLen;
+
+/// 数据总 CRC
+@property (nonatomic, assign) uint16_t crc;
+
+/// 发送 MTU 协商值
+@property (nonatomic, assign) uint16_t sendMtu;
+
+/// 接收 MTU 协商值
+@property (nonatomic, assign) uint16_t receiveMtu;
+
+@end
+
+
+//传输数据命令参数
+@interface ECBDTCmdData : NSObject<NSCopying>
+/// 数据类型
+/// * 0 :原始数据
+/// * 1 : 阿里云数据
+/// * 2:RTC数据
+/// * 3:AI云
+/// * 4:TTS语音合成
+/// * 5:平台接口认证信息
+/// * 6:esim 卡信息
+/// * 7:4G 模块升级数据
+@property (nonatomic, assign) uint8_t type;
+
+
+/// 标识位
+/// YES:结束
+/// NO:继续
+@property (nonatomic, assign) BOOL isEnd;
+
+///序号
+@property (nonatomic, assign) uint32_t seq;
+
+/// crc
+@property (nonatomic, assign) uint16_t crc;
+
+/// 数据偏移
+@property (nonatomic, assign) uint32_t offset;
+
+/// 数据长度
+@property (nonatomic, assign) uint16_t len;
+
+/// 数据
+@property (nonatomic, copy)NSData *data;
+
+
+-(instancetype)initData:(NSData *)data;
+
+-(NSData *)beData;
+
+/// 切块分包数据
+/// - Parameters:
+/// - mtu: 发送的 mtu
+/// - type: 数据类型
+/// - dt: 文件数据
++(NSArray<ECBDTCmdData *>*)makeWithMtu:(uint16_t)mtu Type:(uint8_t) type Data:(NSData *)dt;
+
+@end
+
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// ECOneToMorePtl.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/27.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "NSData+ToUnit.h"
+#import "JL_ManagerM.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ECOneToMorePtl : NSObject
+
+@property(nonatomic,strong,readonly)NSHashTable *delegates;
+@property(nonatomic,strong)NSLock *delegateLock;
+
+-(void)addDelegate:(id)delegate;
+-(void)removeDelegate:(id)delegate;
+-(void)removeAll;
+-(void)inputPKG:(JL_PKG*)pkg;
+-(void)inputPKG:(JL_PKG *)pkg Manager:(JL_ManagerM *)mgr;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// ECThreadHelper.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/11/20.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol ECThreadHelperPtl <NSObject>
+
+-(void)startAction:(id)objc;
+-(void)finishThreadTaskAction;
+
+@end
+
+typedef void(^EcThreadAction)(id objc);
+
+@interface ECThreadHelper : NSObject
+
+
+@property (nonatomic, weak) id<ECThreadHelperPtl> delegate;
+
+@property (nonatomic, copy) EcThreadAction action;
+
++(instancetype)share;
+
+-(instancetype)init;
+
+-(void)addTask:(id<NSCopying>)any;
+
+-(void)nextTask;
+
+-(void)clean;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL4GUpgradeManager.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/12/18.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JLPublicSettingBlocks.h"
+
+NS_ASSUME_NONNULL_BEGIN
+/// 4G 升级状态枚举
+typedef NS_ENUM(uint8_t, JL4GUpgradeStatus) {
+ /// 完成
+ JL4GUpgradeStatusFinish = 0x00,
+ /// 开始
+ JL4GUpgradeStatusStart = 0x01,
+ /// 传输中
+ JL4GUpgradeStatusTransporting = 0x02,
+ /// 设备处理中
+ JL4GUpgradeStatusDeviceProcessing = 0xff
+};
+
+@class JL4GUpgradeManager;
+
+/// 4G 升级代理回调
+@protocol JL4GUpgradeDelegate <NSObject>
+
+/// 升级结果
+/// - Parameters:
+/// - mgr:4G升级管理对象
+/// - status: 升级状态
+/// - progress: 升级进度
+/// - code: 结果码
+/// 0x00 升级成功
+/// 0x01 升级失败
+/// 0x02 升级超时
+/// - error: 错误信息
+-(void)jl4GUpgradeResult:(JL4GUpgradeManager *)mgr Status:(JL4GUpgradeStatus) status Progress:(float)progress Code:(uint8_t)code error:(NSError * _Nullable)error;
+
+/// 设备 4G 信息更新
+/// - Parameter g4Model: 4G信息
+-(void)jl4GGetDeviceInfo:(JLPublic4GModel *)g4Model;
+
+@end
+
+@class JL_ManagerM;
+
+/// 4G模块升级管理对象
+@interface JL4GUpgradeManager : NSObject
+
+/// 单例
++(instancetype)share;
+
+/// 4G 升级信息
+/// ⚠️需要先执行获取模块信息后获得值
+@property(nonatomic,strong)JLPublic4GModel *g4Model;
+
+/// 4G升级代理回调
+@property(nonatomic,weak) id<JL4GUpgradeDelegate> delegate;
+
+/// 获取4G模块信息
+/// - Parameters:
+/// - manager: 设备
+/// - result: 回调结果
+-(void)cmdGetDevice4GInfo:(JL_ManagerM *)manager result:(JLPSSource4GCbk)result;
+
+
+/// 开始4G升级
+/// - Parameters:
+/// - manager: 设备
+/// - data: 升级数据
+-(void)cmdStartUpgrade4G:(JL_ManagerM *)manager Data:(NSData *)data;
+
+/// 取消4G升级
+/// - Parameter manager: 设备
+-(void)cmdCancel4GUpgrade:(JL_ManagerM *)manager;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLAIDialManager.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/10/12.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_FileManager.h>
+
+NS_ASSUME_NONNULL_BEGIN
+@class JL_ManagerM;
+@class JLAIDialManager;
+
+@protocol JLAIDialManagerDelegate <NSObject>
+
+/// 设备通知App AI表盘界面变化
+/// - Parameters:
+/// - manager: ai dial manager
+/// - status:0x00: 退出AI表盘功能 0x01: 进入AI表盘功能
+-(void)aiDialManager:(JLAIDialManager *)manager didAiDialStatusChange:(uint8_t)status;
+
+/// 开始AI生成表盘
+/// - Parameter manager: ai dial manager
+-(void)aiDialdidStartCreateManager:(JLAIDialManager *)manager;
+
+/// 重新录音
+/// - Parameter manager: ai dial manager
+-(void)aiDialdidRestartRecordManager:(JLAIDialManager *)manager;
+
+/// AI表盘开始安装
+/// - Parameter manager: ai dial manager
+-(void)aiDialdidStartInstallManager:(JLAIDialManager *)manager;
+
+
+/// 重新生成表盘
+/// - Parameter manager: ai dial manager
+-(void)aiDialdidReCreateManager:(JLAIDialManager *)manager;
+
+@end
+
+
+
+/// ai dial manager
+@interface JLAIDialManager : NSObject
+
+/// 进入/退出AI表盘
+@property (nonatomic, assign) BOOL isCreateing;
+
+/// 缩略图尺寸 默认 200*200
+/// scale zoom size default 200*200
+@property (nonatomic,assign) CGSize scaleZoomSize;
+
+
+/// 代理
+@property (nonatomic, weak) id<JLAIDialManagerDelegate> delegate;
+
+
+/// AI 表盘风格显示设置
+/// - Parameter manager: 设备对象
+/// - Parameter style: 风格类型
+/// - Parameter result: 回调对象
+-(void)aiDialSetManager:(JL_ManagerM *)manager AiStyle:(NSString *)style Result:(JL_CMD_RESPOND)result;
+
+
+/// AI表盘告诉设备缩略图发送完毕
+/// - Parameter manager: 设备对象
+/// - Parameter path: 目标缩略图路径(设备端的位置)默认 "/VIE_THUMB"
+/// - Parameter result: 回调对象
+-(void)aiDialSendThumbAiImageTo:(JL_ManagerM *)manager withPath:(NSString *)path Result:(JL_CMD_RESPOND)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLAiManager.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/8/9.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+//MARK: - JLOpenPlatformInfo
+/// 平台接口认证信息
+@interface JLOpenPlatformInfo : NSObject
+/// 版本号
+@property(nonatomic,assign)uint8_t version;
+/// 平台 ID
+@property(nonatomic,copy)NSString *appID;
+/// app key
+@property(nonatomic,copy)NSString *appKey;
+/// app 的密钥
+@property(nonatomic,copy)NSString *appSecret;
+/// 原始数据
+@property(nonatomic,copy)NSData *basicData;
+
+-(instancetype)initData:(NSData *)data;
+
+@end
+
+/// 平台接口认证信息
+@interface JLOpenPlatformMessage : NSObject
+/// 版本号
+@property(nonatomic,assign)uint8_t version;
+/// 支持平台信息
+@property(nonatomic,copy)NSArray <JLOpenPlatformInfo *>* infoArray;
+
+-(instancetype)initData:(NSData *)dt;
+
+@end
+
+//MARK: - JLAiManager
+@class JL_ManagerM;
+@class JLAiManager;
+
+@protocol JLAIManagerDelegate <NSObject>
+
+/// 设备回调/推送结果
+/// - Parameter mgr: JLAiManager
+-(void)jlaiUpdateStatus:(JLAiManager *)mgr;
+
+@optional
+/// 设备主动推送JLOpenPlatformInfo信息
+/// - Parameters:
+/// - mgr: 设备
+/// - infoArray: [JLOpenPlatformInfo]
+-(void)jlaiUpdateDevAiOpenPlatforms:(JLAiManager *)mgr Info:(JLOpenPlatformMessage *)info;
+
+
+@end
+
+typedef void(^JLOpenPFBlock)(JLOpenPlatformMessage *message,JL_CMDStatus result);
+
+/// AI状态 管理类
+/// 当前接口适用于一些支持设备对讲的设备,在使用时需要先初始化当前类并接受代理:JLAIManagerDelegate
+/// 在初始化后需要主动获取状态才可以获得首次的状态内容
+///
+@interface JLAiManager : NSObject
+
+/// 版本号
+@property(assign,nonatomic)uint8_t version;
+
+/// 0x00:默认状态
+/// 0x01:进入AI界面
+/// 0x02:退出AI界面
+@property(assign,nonatomic)uint8_t status;
+
+/// 回调代理
+@property(weak,nonatomic)id<JLAIManagerDelegate> delegate;
+
+/// 获取AI 的状态
+///- Parameters:
+/// - manager: 设备对象
+-(void)getStatus:(JL_ManagerM *)manager;
+
+/// 设置设备的状态
+/// - Parameters:
+/// - manager: 设备对象
+/// - result: 回调结果
+-(void)setToDevice:(JL_ManagerM *)manager result:(JL_CMD_RESPOND _Nullable)result;
+
+
+/// 获取平台接口认证信息,此信息需要先获取 JLDeviceConfig
+/// 根据JLDeviceConfigModel 的 exportFunc 属性的
+/// spOpenInfo 判断是否支持平台开放接口信息获得
+/// - Parameters:
+/// - manager: 设备对象
+/// - result: 回调结果
+-(void)getOpenPlatformInfo:(JL_ManagerM *)manager result:(JLOpenPFBlock _Nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLAutoConfigAnc.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/10/28.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+
+#import "ECOneToMorePtl.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+
+typedef void(^AutoConfigResult)(BOOL status);
+
+@protocol JLAutoConfigAncPtl <NSObject>
+
+
+/// 设备正在重新检测自适应降噪
+-(void)autoConfigDidConfiging;
+///设置自适应降噪失败了
+-(void)autoConfigDidFailed;
+///设置自适应降噪成功了
+-(void)autoConfigDidSucceed;
+///关闭自适应降噪
+-(void)autoConfigDidClose;
+
+@end
+
+
+/// 自适应降噪处理类
+@interface JLAutoConfigAnc : ECOneToMorePtl
+
+/// 设备开启/关闭自适应降噪的状态
+@property (assign,nonatomic)BOOL status;
+
+/// 开启设备自适应降噪
+/// 这里只是进入了设备开始适配降噪的命令过程
+/// 适配成功与否需要添加协议JLAutoConfigAncPtl进行监听
+/**
+ interface testView : UIView<JLAutoConfigAncPtl>
+
+ @end
+
+ -(void)initData{
+ JLAutoConfigAnc *anc = [[JLAutoConfigAnc alloc] init];
+ [anc addDelegate:self];
+ }
+
+ -(void)autoConfigDidFailed{
+ //设置自适应降噪失败了
+ }
+ -(void)autoConfigDidSucceed{
+ //设置自适应降噪成功了
+ }
+ -(void)autoConfigDidClose{
+ //关闭自适应降噪
+ }
+*/
+/// - Parameter manager: manager
+-(void)atAncStartAutoConfigWithManager:(JL_ManagerM*)manager;
+
+
+/// 打开设备自适应降噪
+/// 设备默认有一套已在运行的降噪算法
+/// 打开后设备会进入降噪模式,不会经历检测启动自适应的时间,相当于是即时生效
+/// - Parameter result: 这里回调的是一个设备命令处理的结果
+/// - Parameter manager: manager
+-(void)atAncOpenAutoConfigResult:(JL_CMD_RESPOND)result Manager:(JL_ManagerM*)manager;
+
+/// 用户关闭设备的自适应降噪模式算法
+/// - Parameter result: 命令处理结果,不代表命令处理成功
+/// - Parameter manager: manager
+-(void)atAncCloseAutoConfigResult:(JL_CMD_RESPOND)result Manager:(JL_ManagerM*)manager;
+
+/// 获取设备是否开启了自适应降噪
+/// - Parameter result: 这里处理的结果是,设备实际是否开启了的结果,无需从代理中获得结果
+/// - Parameter manager: manager
+-(void)atAncGetAutoConfigResult:(AutoConfigResult)result Manager:(JL_ManagerM*)manager;
+
+
+@end
+
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLAutoPressureModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+///压力自动检测模式
+typedef NS_ENUM(UInt8, WatchAPLeveType) {
+ ///放松
+ WatchAPLeve_Relex = 0x00,
+ /// 正常
+ WatchAPLeve_Normal = 0x01,
+ /// 中等
+ WatchAPLeve_Middle = 0x02,
+ /// 偏高
+ WatchAPLeve_Hight = 0x03
+};
+
+@interface JLAutoPressureModel : JLwSettingModel
+
+///开关
+@property(nonatomic,assign)BOOL status;
+/// 模式
+@property(nonatomic,assign)WatchAPLeveType model;
+
+-(instancetype)initWithData:(NSData *)data;
+
+-(instancetype)initWithModel:(WatchAPLeveType)model switchStatus:(BOOL)status;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLCmdBasic.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/9/13.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_ManagerM.h>
+#import <JL_BLEKit/NSData+ToUnit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLCmdBasic : NSObject
+
+-(void)inputPKG:(JL_PKG *)pkg;
+
+-(void)makeCommandAction:(NSData *)targetData withManager:(JL_ManagerM *)manager Result:(JL_CMD_RESPOND _Nullable)result;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLConsequentHeartRateModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 测量心率传感器设置
+@interface JLConsequentHeartRateModel : JLwSettingModel
+///开关
+@property(nonatomic,assign)BOOL status;
+/// 测量模式
+@property(nonatomic,assign)WatchConsequentType rType;
+
+/// 上限心率
+@property(nonatomic,assign)UInt8 maxHeartRate;
+
+/// 下限心率
+@property(nonatomic,assign)UInt8 minHeartRate;
+
+/// 是否包含上下心率区间
+@property(nonatomic,assign)BOOL hasRange;
+
+-(instancetype)initWithData:(NSData *)data;
+
+/// 创建一个新的传感器设置对象
+/// @param type 测量类型
+/// @param status 开团状态
+- (instancetype)initWithModel:(WatchConsequentType)type Status:(BOOL)status;
+
+/// 创建一个新的传感器设置对象
+/// 携带心率上下限的
+/// @param type 测量类型
+/// @param status 开关状态
+/// @param min 心率下限
+/// @param max 心率上限
+- (instancetype)initWithModel:(WatchConsequentType)type Status:(BOOL)status Min:(UInt8) min Max:(UInt8)max;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDevPlayerCtrl.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/9/25.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <JL_BLEKit/JL_BLEKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+@class JLDevPlayerCtrl;
+
+/// 播放器回调
+@protocol JLDevPlayerCtrlDelegate<NSObject>
+
+/// 播放状态
+/// - Parameters:
+/// - ctrl: 播放器
+/// - status: 播放模式
+-(void)jlDevPlayerCtrl:(JLDevPlayerCtrl *)ctrl playMode:(uint8_t)playMode;
+
+/// 播放状态回调
+/// - Parameters:
+/// - ctrl: 播放器
+/// - status: 播放状态
+/// - card: 当前播放的设备
+/// - time: 当前播放的时间
+/// - total: 总时长
+-(void)jlDevPlayerCtrl:(JLDevPlayerCtrl *)ctrl playStatus:(uint8_t)status currentCard:(uint8_t)card currentTime:(uint32_t)time tolalTime:(uint32_t)total;
+
+/// 播放文件回调
+/// - Parameters:
+/// - ctrl: 播放器
+/// - name: 文件名
+/// - clus: 文件簇号
+-(void)jlDevPlayerCtrl:(JLDevPlayerCtrl *)ctrl fileName:(NSString *)name currentClus:(uint32_t)clus;
+
+@end
+
+
+/// 设备播放器管理类
+@interface JLDevPlayerCtrl : JLCmdBasic
+
+/// 播放状态
+@property(nonatomic,assign)uint8_t playStatus;
+
+/// 当前播放的设备
+/// 0x00 : USB
+/// 0x01 : SD_0
+/// 0x02 : SD_1
+/// 0x03 : FLASH
+/// 0x04 : LineIn
+/// 0x05 : FLASH2
+@property(nonatomic,assign)uint8_t currentCard;
+
+/// 当前播放时间
+@property(nonatomic,assign)uint32_t currentTime;
+
+/// 歌曲总时长
+@property(nonatomic,assign)uint32_t tolalTime;
+
+/// 当前播放文件名
+@property(nonatomic,strong)NSString *fileName;
+
+/// 当前播放文件的簇号
+@property(nonatomic,assign)uint32_t currentClus;
+
+/// 当前播放模式
+/// 0x01:全部循环;
+/// 0x02:设备循环;
+/// 0x03:单曲循环;
+/// 0x04:随机播放;
+/// 0x05:文件夹循环
+@property (nonatomic,assign)uint8_t playMode;
+
+/// 代理
+@property(nonatomic,weak)id<JLDevPlayerCtrlDelegate> delegate;
+
+/// 操控设备播放器设置
+/// - Parameters:
+/// - cmd: 操作命令
+/// 0x01:PP按钮
+/// 0x02:上一曲
+/// 0x03:下一曲
+/// 0x04:切换播放模式(当前播放模式:不可指定,设备播放模式自增)
+/// 0x05:EQ
+/// 0x06:快退
+/// 0x07:快进
+/// - sec: 时间(当快进/快退时需要,其他功能时值为0)
+/// - manager: 设备对象
+/// - result: 返回结果
+-(void)cmdPlayerCtrl:(uint8_t)cmd
+ Second:(uint16_t)sec
+ Manager:(JL_ManagerM *)manager
+ Result:(JL_CMD_RESPOND __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDeviceConfig.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/10/31.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class ECOneToMorePtl;
+@class JLDeviceConfigTws;
+@class JLDeviceConfigModel;
+
+NS_ASSUME_NONNULL_BEGIN
+typedef void(^JLConfigRsp)(JL_CMDStatus status, uint8_t sn, JLDeviceConfigModel* __nullable config);
+
+typedef void(^JLConfigTwsRsp)(JL_CMDStatus status, uint8_t sn, JLDeviceConfigTws* __nullable config);
+
+
+/// 固件设置配置回调协议
+/// 遵循时,可通过父类的- (void)addDelegate:(id)delegate方法添加遵循
+@protocol JLConfigPtl <NSObject>
+
+@optional
+/// 监听回调协议
+/// - Parameter configModel: 固件设置配置回调
+-(void)deviceConfigWith:(JLDeviceConfigModel *)configModel;
+
+/// TWS监听回调协议
+/// - Parameter configModel: 固件设置配置回调
+-(void)deviceTwsConfigWith:(JLDeviceConfigTws *)configModel;
+
+@end
+
+@interface JLDeviceConfig : ECOneToMorePtl
+
++(instancetype)share;
+
+/// 手表查询设备当前固件配置内容
+/// - Parameters:
+/// - manager: manager
+/// - result: 回调功能配置内容
+-(void)deviceGetConfig:(JL_ManagerM *)manager result:(JLConfigRsp)result;
+
+/// 手表多设备管理时,可通过对应的设备UUID 获取相关的设备配置
+/// - Parameter entity: 设备uuidStr
+-(JLDeviceConfigModel *_Nullable)deviceGetConfigWithUUID:(NSString *)uuidStr;
+
+/// TWS查询设备当前固件配置内容
+/// - Parameters:
+/// - manager: manager
+/// - result: 回调功能配置内容
+-(void)deviceTwsGetConfig:(JL_ManagerM *)manager result:(JLConfigTwsRsp)result;
+
+/// Tws多设备管理时,可通过对应的设备UUID 获取相关的设备配置
+/// - Parameter entity: 设备uuidStr
+-(JLDeviceConfigTws *)deviceGetTwsConfigWithUUID:(NSString *)uuidStr;
+
+
+/// 私有测试接口请勿使用
+/// - Parameter data: 用于测试数据
+/// - Parameter st: 是否开启测试模式
+-(void)pDeviceTest:(NSData *)data Status:(BOOL)st;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDeviceConfigFuncModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/10/31.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import "ECOneToMorePtl.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+//MARK: - 必须功能
+
+/// 必须功能
+@interface JLDeviceBasicFuncModel : NSObject
+
+/// 支持OTA
+@property(nonatomic,assign)BOOL spOTA;
+
+/// 支持资源更新
+@property(nonatomic,assign)BOOL spSourceUpdate;
+
+/// 支持表盘增加/删除/查询
+@property(nonatomic,assign)BOOL spDialOperation;
+
+/// 支持表盘切换
+@property(nonatomic,assign)BOOL spDialSwitch;
+
+/// 支持表盘预览
+@property(nonatomic,assign)BOOL spDialPreview;
+
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+//MARK: - 系统功能
+/// 系统功能
+@interface JLDeviceSystemFuncModel : NSObject
+
+/// 支持屏幕设置
+@property(nonatomic,assign)BOOL spScreenSetting;
+/// 支持震动强度
+@property(nonatomic,assign)BOOL spVibrationIntensity;
+/// 支持勿扰模式
+@property(nonatomic,assign)BOOL spDoNotDisturb;
+/// 支持锻炼设置
+@property(nonatomic,assign)BOOL spExerciseSettings;
+/// 支持断开提醒
+@property(nonatomic,assign)BOOL spDisconnectReminder;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+//MARK: - 功能选项
+/// 功能选项
+@interface JLDeviceExportFuncModel : NSObject
+/// 支持常用联系人
+@property(nonatomic,assign)BOOL spTopContacts;
+/// 支持音乐文件浏览
+@property(nonatomic,assign)BOOL spMusicFileBrows;
+/// 音乐文件删除、传输
+@property(nonatomic,assign)BOOL spMusicFileOp;
+/// 支持闹钟设置
+@property(nonatomic,assign)BOOL spAlarmSettings;
+/// 支持信息同步
+@property(nonatomic,assign)BOOL spSyncInfo;
+/// 支持天气同步
+@property(nonatomic,assign)BOOL spSyncWeather;
+/// 支持找手机/设备
+@property(nonatomic,assign)BOOL spFindPhoneOrDevice;
+/// Ai 云功能
+@property(nonatomic,assign)BOOL spAiCloud;
+/// Ai 表盘
+@property(nonatomic,assign)BOOL spAiDial;
+/// 平台接口信息获取
+@property(nonatomic,assign)BOOL spOpenInfo;
+/// 支持4G模块
+@property(nonatomic,assign)BOOL sp4GModel;
+
+/// 支持表盘信息拓展
+@property(nonatomic,assign)BOOL spDialInfoExtend;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+//MARK: - 运动健康
+
+/// 手表综合功能支持
+@interface JLHealthFuncComprehensive : NSObject
+
+/// 支持健康监控
+@property(nonatomic,assign)BOOL spHealthMonitor;
+/// 支持个人信息
+@property(nonatomic,assign)BOOL spPersonInfo;
+/// 支持睡眠检测
+@property(nonatomic,assign)BOOL spSleepMonitor;
+/// 支持运动心率提醒
+@property(nonatomic,assign)BOOL spSportHeartRateRemind;
+/// 支持久坐提醒
+@property(nonatomic,assign)BOOL spSedentaryRemind;
+/// 支持压力自动检测
+@property(nonatomic,assign)BOOL spStressDetection;
+/// 支持跌倒检测
+@property(nonatomic,assign)BOOL spFallDetection;
+/// 支持传感器设置
+@property(nonatomic,assign)BOOL spSensorSetup;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+/// 手表运动模式支持功能
+@interface JLHealthFuncSportModel : NSObject
+/// 支持运动记录
+@property(nonatomic,assign)BOOL spRecord;
+/// 支持运动统计
+@property(nonatomic,assign)BOOL spStatistics;
+/// 支持室外运动
+@property(nonatomic,assign)BOOL spOutdoor;
+/// 支持室内运动
+@property(nonatomic,assign)BOOL spIndoor;
+
+-(instancetype)init:(NSData *)data;
+@end
+
+/// 手表计步功能支持功能
+@interface JLHealthFuncGSensorModel : NSObject
+/// 是否存在该传感器
+@property(nonatomic,assign)BOOL spExist;
+/// 支持运动步数
+@property(nonatomic,assign)BOOL spStep;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+
+/// 手表心率功能支持功能
+@interface JLHealthFuncHeartRateModel : NSObject
+/// 是否存在该传感器
+@property(nonatomic,assign)BOOL spExist;
+/// 支持连续测试
+@property(nonatomic,assign)BOOL spSerialTest;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+/// 手表血氧功能支持功能
+@interface JLHealthFuncBloodOxygenModel : NSObject
+/// 是否存在该传感器
+@property(nonatomic,assign)BOOL spExist;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+
+/// 手表海拔功能支持功能
+@interface JLHealthFuncAltitudeModel : NSObject
+/// 是否存在该传感器
+@property(nonatomic,assign)BOOL spExist;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+/// 手表GPS功能支持功能
+@interface JLHealthFuncGPSModel : NSObject
+/// 是否存在该传感器
+@property(nonatomic,assign)BOOL spExist;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+
+
+@interface JLDeviceHealthFuncModel : NSObject
+
+/// 手表综合功能支持
+@property(nonatomic,strong)JLHealthFuncComprehensive *spComprehensive;
+/// 手表运动模式支持功能
+@property(nonatomic,strong)JLHealthFuncSportModel *spSportModel;
+/// 手表计步功能支持功能
+@property(nonatomic,strong)JLHealthFuncGSensorModel *spGSensor;
+/// 手表心率功能支持功能
+@property(nonatomic,strong)JLHealthFuncHeartRateModel *spHeartRate;
+/// 手表血氧功能支持功能
+@property(nonatomic,strong)JLHealthFuncBloodOxygenModel *spBloodOxygen;
+/// 手表海拔功能支持功能
+@property(nonatomic,strong)JLHealthFuncAltitudeModel *spAltitude;
+/// 手表GPS功能支持功能
+@property(nonatomic,strong)JLHealthFuncGPSModel *spGPS;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+//MARK: - 设备配置信息
+
+/// 设备配置信息
+@interface JLDeviceConfigBasic:NSObject
+/// 产品标志类型
+/// 0 - 手表
+/// 1 - TWS耳机
+@property(nonatomic,assign)int deviceType;
+/// 版本
+@property(nonatomic,assign)int version;
+
+/// 数据
+@property(nonatomic,copy)NSData *basicData;
+
+/// 功能配置所属设备的UUID
+@property(nonatomic,strong)NSString * _Nullable mbleIdentifyStr;
+
+-(instancetype)init:(NSData *)data;
+
+@end
+
+//MARK: - 手表配置信息数据结构解析
+
+/// 手表配置信息数据结构
+@interface JLDeviceConfigModel:JLDeviceConfigBasic
+/// - 必须功能
+@property(nonatomic,strong)JLDeviceBasicFuncModel *basicFunc;
+/// - 系统功能
+@property(nonatomic,strong)JLDeviceSystemFuncModel *systemFunc;
+/// - 功能选项
+@property(nonatomic,strong)JLDeviceExportFuncModel * exportFunc;
+/// - 运动健康
+@property(nonatomic,strong)JLDeviceHealthFuncModel *healthFunc;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDeviceConfigTws.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2024/1/23.
+// Copyright © 2024 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JLDeviceConfigFuncModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLDeviceConfigTws : JLDeviceConfigBasic
+
+/// 是否支持替换提示音
+@property(nonatomic, assign)BOOL isSupportReplaceTipsVoice;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDhaFitting.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/6/28.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+
+@class JL_ManagerM;
+
+/// 左右声道类型
+typedef NS_ENUM(UInt8, DhaChannel) {
+ ///左声道
+ DhaChannel_left = 0x00,
+ ///右声道
+ DhaChannel_right = 0x01
+};
+
+/// 左右耳验配类型
+typedef NS_ENUM(UInt8, DhaFittingType) {
+ ///验配左耳
+ DhaFittingType_left = 0x00,
+ ///验配右耳
+ DhaFittingType_right = 0x00,
+ ///验配左右耳
+ DhaFittingType_All = 0x00,
+};
+
+
+/// 辅听耳机的信息
+@interface DhaFittingInfo : NSObject
+/// /*版本号:DHA_FITTING_VERSION*/
+@property(nonatomic,assign)uint8_t version;
+/// /*通道数:DHA_FITTING_CHANNEL_MAX*/
+@property(nonatomic,assign)uint8_t ch_num;
+/// /*通道频率组:获取通道对应的freq*/
+@property(nonatomic,strong)NSArray *ch_freq;
+
+- (instancetype)initWithData:(NSData *)basicData;
+
+@end
+
+@interface DhaFittingSwitch : NSObject
+
+@property(nonatomic,assign)BOOL leftOn;
+
+@property(nonatomic,assign)BOOL rightOn;
+
+@end
+
+
+/// 辅听验配对象
+@interface DhaFittingData : NSObject<NSCopying>
+/// 左右声道
+@property(nonatomic,assign)DhaChannel channel;
+
+/// 左开关
+@property(nonatomic,assign)BOOL leftOn;
+/// 右开关
+@property(nonatomic,assign)BOOL rightOn;
+
+/// 保留位
+@property(nonatomic,assign)uint8_t reserved;
+/// 通道频率
+@property(nonatomic,assign)uint16_t freq;
+/// 通道增益
+@property(nonatomic,assign)float gain;
+
+-(NSData*)beData;
+
+@end
+
+
+typedef void(^DhaInfoBlock)(DhaFittingInfo *info,NSArray <NSNumber *>*gains);
+
+
+@interface JLDhaFitting : NSObject
+
+/// 获取设备当前辅听的基础信息
+/// @param result 辅听耳机信息
+/// @param manager manager
++(void)auxiGetInfo:(DhaInfoBlock)result Manager:(JL_ManagerM*)manager;
+
+/// 进行辅听验配
+/// @param dhaFit 辅听设置对象
+/// @param manager manager
+/// @param result 设备工作状态回调
+-(void)auxiCheckByStep:(DhaFittingData *)dhaFit Manager:(JL_ManagerM*)manager Result:(JL_CMD_RESPOND __nullable)result;
+
+/// 退出辅听验配
+/// @param manager 命令对象
+/// @param result 设备工作状态回调
+-(void)auxiCloseManager:(JL_ManagerM*)manager Result:(JL_CMD_RESPOND __nullable)result;
+
+/// 保存验配设置
+/// @param gains 验配的增益数组
+/// @param manager manager
+/// @param type 左右耳类型
+/// @param result 回调结果
+-(void)auxiSaveGainsList:(NSArray <DhaFittingData *>*) gains Manager:(JL_ManagerM*)manager Type:(DhaFittingType)type Result:(JL_CMD_RESPOND __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDialInfoExtentManager.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2024/2/20.
+// Copyright © 2024 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_TypeEnum.h"
+
+@class JLDialInfoExtentedModel;
+@class JL_ManagerM;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 表盘信息扩展内容回调
+/// Dial information extended content block
+typedef void(^JLDialInfoExtentedBlock)(JL_CMDStatus status,JLDialInfoExtentedModel *_Nullable op);
+
+/// 请求设备表盘信息扩展内容类
+/// Request device dial information extended content class
+@interface JLDialInfoExtentManager : NSObject
+
+/// 单例
+/// Single
++(instancetype)share;
+
+/// 开始请求表盘信息扩展内容
+/// Start request dial information extended content
+/// - Parameters:
+/// - manager: 设备 - Device manager
+/// - block: 状态回调 - Dial information extended content block
+-(void)getDialInfoExtented:(JL_ManagerM *)manager result:(JLDialInfoExtentedBlock)block;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDialInfoExtentedModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2024/2/20.
+// Copyright © 2024 www.zh-jieli.com. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+
+/// 设备表盘拓展信息
+/// device dial information extended model
+@interface JLDialInfoExtentedModel : NSObject
+
+
+/// 屏幕形状
+/// shape of screen
+/// 默认形状 0x01
+/// default 0x01 circular
+/// 0x01 - 圆形 circular
+/// 0x02 - 矩形 rectangle
+/// 0x03 - 圆角矩形 rounded rectangle
+@property(nonatomic, assign) uint8_t shape;
+
+
+/// 圆形半径
+/// radius of circle
+@property(nonatomic, assign) CGFloat radius;
+
+/// 背景颜色
+/// background color
+/// default is clean color
+@property(nonatomic, strong) UIColor *backgroundColor;
+
+/// 屏幕尺寸
+/// 此项默认值为(240 * 240)
+/// default is (240 * 240)
+/// device screen sice
+@property(nonatomic, assign) CGSize size;
+
+
+/// 初始化
+/// initialize
+/// - Parameter data: 数据 data
+/// - Returns: 实例
+-(instancetype)initWithData:(NSData *)data Manager:(JL_ManagerM*)manager;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLDisconnectRemindModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 手表蓝牙断开提醒设置
+@interface JLDisconnectRemindModel : JLwSettingModel
+//开关
+@property(nonatomic,assign)BOOL status;
+/// 提醒模式
+@property(nonatomic,assign)WatchRemindType rType;
+
+-(instancetype)initWithData:(NSData *)data;
+
+- (instancetype)initWithModel:(WatchRemindType)type Status:(BOOL)status;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLEmergencyContactModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/2/17.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 紧急联系人设置
+@interface JLEmergencyContactModel : JLwSettingModel
+
+/// 联系电话
+@property(nonatomic,strong)NSString *phoneNumber;
+
+-(instancetype)initWithData:(NSData *)data;
+
+-(instancetype)initWithPhoneNumber:(NSString *)phoneNumber;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLExerciseHeartRateRemindModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+#import "JLWatchEnum.h"
+NS_ASSUME_NONNULL_BEGIN
+
+/// 运动心率提醒设置
+@interface JLExerciseHeartRateRemindModel : JLwSettingModel
+///开关
+@property(nonatomic,assign)BOOL status;
+/// 上限心率0~255
+@property(nonatomic,assign)uint8_t maxRate;
+
+/// 心率区间划分方式:
+/// 0x00:最大心率百分比
+/// 0x01:存储心率百分比s
+@property(nonatomic,assign)WatchHeartRateType way;
+
+-(instancetype)initWithWay:(WatchHeartRateType)way maxRate:(uint8_t)max switchStatus:(BOOL)status;
+
+-(instancetype)initWithData:(NSData *)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLFallDetectionModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 跌到监测设置
+@interface JLFallDetectionModel : JLwSettingModel
+///开关
+@property(nonatomic,assign)BOOL status;
+/// 提醒模式
+@property(nonatomic,assign)WatchRemindType rType;
+/// 电话号码
+@property(nonatomic,strong,readonly)NSString *phoneNumber;
+
+-(instancetype)initWithData:(NSData *)data;
+
+/// 构建一个跌倒监测的设置对象
+/// @param type 提醒类型
+/// @param status 开关
+/// @param pn 电话号码
+- (instancetype)initWithModel:(WatchRemindType)type Status:(BOOL)status phoneNumber:(NSString * _Nullable)pn;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// HttpHelper.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/7/2.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef void(^JLHttpDataCbk)(NSData * _Nullable data);
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLHttpHelper : NSObject
+
++(instancetype)share;
+
+-(void)dataTask:(NSURL *)url Result:(JLHttpDataCbk)result;
+
+-(NSData *)dataTaskSync:(NSURL *)url;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModelCardInfo.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/11/30.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLCardInfo : NSObject
+
+/// 存储类型
+/// 0x00 USB
+/// 0x01 SD0
+/// 0x02 SD1
+/// 0x03 flash
+/// 0x04 lineIn
+/// 0x05 flash2
+/// 0x06 flash3
+@property(nonatomic,assign)uint8_t type;
+
+/// 是否在线
+@property(nonatomic,assign)BOOL isOnline;
+
+/// 文件句柄
+@property(nonatomic,copy)NSData *handle;
+
+@end
+
+/// 存储卡信息
+@interface JLModelCardInfo:NSObject
+
+/// 版本信息
+@property(nonatomic,assign)uint8_t version;
+
+/// 存储卡在线数组
+@property(nonatomic,strong,readonly)NSArray *cardArray;
+
+/// USB 在线状态
+@property (nonatomic, assign) BOOL usbOnline;
+
+/// SD0 在线状态
+@property (nonatomic, assign) BOOL sd0Online;
+
+/// SD1 在线状态
+@property (nonatomic, assign) BOOL sd1Online;
+
+/// lineIn 在线状态
+@property (nonatomic, assign) BOOL lineInOnline;
+
+/// flash 在线状态
+@property (nonatomic, assign) BOOL flashOnline;
+
+/// flash 2 在线状态
+@property (nonatomic, assign) BOOL flash2Online;
+
+/// flash 3 在线状态
+@property (nonatomic, assign) BOOL flash3Online;
+
+/// 是否处于设备复用状态
+@property (nonatomic, assign) BOOL isComplex;
+
+/// USB 句柄
+@property (nonatomic, copy)NSData *usbHandle;
+
+/// SD0 句柄
+@property (nonatomic, copy)NSData *sd0Handle;
+
+/// SD1 句柄
+@property (nonatomic, copy)NSData *sd1Handle;
+
+/// flash 句柄
+@property (nonatomic, copy)NSData *flashHandle;
+
+/// flash2 句柄
+@property (nonatomic, copy)NSData *flash2Handle;
+
+/// flash3 句柄
+@property (nonatomic, copy)NSData *flash3Handle;
+
+/// 卡在线数组信息
+@property (nonatomic, strong)NSArray <JLCardInfo *> *cardInfos;
+
+-(instancetype)initData:(NSData *)data;
+
+/// 是否具备存储卡在线
+-(BOOL)hasStorageCard;
+
+@end
+
+
+
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModelDevFunc.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/11/29.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLModelDevFunc : NSObject
+
+/// 当前模式
+/// 0x16代表低功耗模式)
+@property (nonatomic, assign) uint8_t currentModel;
+
+/// 设备是否支持蓝牙(EDR)
+@property (nonatomic, assign) BOOL isSupportEDR;
+
+/// 设备是否支持音乐模式
+@property (nonatomic, assign) BOOL isSupportDevMusic;
+
+/// 设备是否支持 RTC
+@property (nonatomic, assign) BOOL isSupportDevRTC;
+
+/// 设备是否支持 LineIn
+@property (nonatomic, assign) BOOL isSupportDevLineIn;
+
+/// 设备是否支持 FM
+@property (nonatomic, assign) BOOL isSupportDevFm;
+
+/// 设备是否支持氛围灯
+@property (nonatomic, assign) BOOL isSupportDevLight;
+
+/// 设备是否支持 FMTX
+@property (nonatomic, assign) BOOL isSupportDevFMTX;
+
+/// 设备是否支持 EQ
+@property (nonatomic, assign) BOOL isSupportDevEQ;
+
+/// 是否显示不在线的usb 、sd、linein功能
+@property (nonatomic, assign) BOOL isShowOfflineFunc;
+
+/// 设备是否持有 USB
+@property (nonatomic, assign) BOOL isSupportUSB;
+
+/// 设备是否持有 SD0
+@property (nonatomic, assign) BOOL isSupportSD0;
+
+/// 设备是否持有 SD1
+@property (nonatomic, assign) BOOL isSupportSD1;
+
+/// 设备是否支持网络电台
+@property (nonatomic, assign) BOOL isSupportNetRadio;
+
+-(instancetype)initWithData:(NSData *)data;
+
+@end
+
+
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModelNoiseDetection.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/9/13.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <JL_BLEKit/JL_BLEKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+@class JLModelNoiseDetection;
+
+@protocol JLModelNoiseDetectionDelegate <NSObject>
+
+-(void)noiseDetectionGetInfo:(JLModelNoiseDetection *)model;
+
+@end
+
+typedef void(^JLModelNoiseDetectionBlock)(JLModelNoiseDetection *model);
+
+/// TWS风噪检测
+@interface JLModelNoiseDetection : JLCmdBasic
+
+/// 版本号
+@property(nonatomic,assign)uint8_t version;
+
+/// 风噪检测:
+/// 0x00:关闭
+/// 0x01:开启
+@property(nonatomic,assign)uint8_t status;
+
+@property(nonatomic,weak)id<JLModelNoiseDetectionDelegate> delegate;
+
+/// 获取设备风噪检测
+/// - Parameter manager: 设备对象
+-(void)noiseDetectionStatusGet:(JL_ManagerM *)manager Result:(JLModelNoiseDetectionBlock)block;
+
+/// 设置设备风噪检测
+/// - Parameters:
+/// - manager: 设备对象
+/// - status: 开关
+/// - result:回调
+-(void)noiseDetectionStatusSet:(JL_ManagerM *)manager Status:(uint8_t)status Result:(JL_CMD_RESPOND)result;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModelSceneNoiseReduction.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/9/13.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <JL_BLEKit/JLCmdBasic.h>
+
+NS_ASSUME_NONNULL_BEGIN
+@class JLModelSceneNoiseReduction;
+
+@protocol JLModelSceneNoiseReductionDelegate <NSObject>
+
+-(void)sceneNoiseReductionGetInfo:(JLModelSceneNoiseReduction *)model;
+
+@end
+
+typedef void(^JLSceneNoiseReductionBlock)(JLModelSceneNoiseReduction *model);
+
+/// TWS场景降噪
+@interface JLModelSceneNoiseReduction : JLCmdBasic
+
+/// 版本号
+@property(nonatomic,assign)uint8_t version;
+
+/// 场景降噪模式:
+/// 0x00:智能
+/// 0x01:轻度
+/// 0x02:均衡
+/// 0x03:深度
+@property(nonatomic,assign)uint8_t scene;
+
+@property(nonatomic,weak)id<JLModelSceneNoiseReductionDelegate> delegate;
+
+/// 获取设备场景降噪
+/// - Parameter manager: 设备对象
+-(void)sceneNoiseStatusGet:(JL_ManagerM *)manager Result:(JLSceneNoiseReductionBlock)block;
+
+/// 设置设备场景降噪
+/// - Parameters:
+/// - manager: 设备对象
+/// - scene: 场景降噪
+/// - result:回调
+-(void)sceneNoiseStatusSet:(JL_ManagerM *)manager Scene:(uint8_t)scene Result:(JL_CMD_RESPOND)result;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModelSmartPickFree.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/9/12.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+@class JLModelSmartPickFree;
+
+@protocol JLModelSmartPickFreeDelegate <NSObject>
+
+-(void)smartPickFreeGetInfo:(JLModelSmartPickFree *)model;
+
+@end
+
+/// 智能免摘的耳机管理类
+@interface JLModelSmartPickFree : NSObject
+
+/// 版本号
+@property(nonatomic,assign)uint8_t version;
+
+/// 功能类型
+/// 0x00:仅设置开关
+/// 0x01:仅设置灵敏度
+/// 0x02:仅设置启动后关闭时间
+/// 0xff:仅获取全部参数
+@property(nonatomic,assign)uint8_t funcType;
+
+/// 功能开关
+/// 当功能类型 funcType 为 0x00 时此属性需要对应设置
+/// 当功能类型 funcType 为 0xFF 时此属性为设备端功能开关状态
+@property(nonatomic,assign)BOOL funcStatus;
+
+/// 灵敏度
+/// 当功能类型 funcType 为 0x01 时此属性需要对应设置
+/// 当功能类型 funcType 为 0xFF 时此属性为设备端灵敏度
+/// 0x00:高灵敏度
+/// 0x01:低灵敏度
+@property(nonatomic,assign)uint8_t senivitiy;
+
+///启动后关闭时间
+///当功能类型 funcType 为 0x02 时此属性需要对应设置的时间
+///当功能类型 funcType 为 0xFF 时此属性为设备端启动后关闭时间
+///0x00:不自动关闭;
+///0x01:短(5s);
+///0x02:标准(15s);
+///0x03:长(30s);
+@property(nonatomic,assign)uint8_t autoInterval;
+
+
+@property(nonatomic,weak)id<JLModelSmartPickFreeDelegate> delegate;
+
+/// 设置智能免摘功能开关
+/// - Parameters:
+/// - manager: 设备对象
+/// - status: 开关
+/// - result: 结果回调
+-(void)smartPickFreeSetOn:(JL_ManagerM *)manager st:(BOOL)status Result:(JL_CMD_RESPOND)result;
+
+/// 设置智能免摘灵敏度
+/// - Parameters:
+/// - manager: 设备对象
+/// - senivitiy: 灵敏度
+/// 0x00:高灵敏度
+/// 0x01:低灵敏度
+/// - result: 结果回调
+-(void)smartPickFreeSetSenivitiy:(JL_ManagerM *)manager Senivitiy:(uint8_t)senivitiy Result:(JL_CMD_RESPOND)result;
+
+/// 设置智能免摘启动后关闭时间
+/// - Parameters:
+/// - manager: 设备对象
+/// - interval: 启动后关闭时间
+/// 0x01:短(5s);
+/// 0x02:标准(15s);
+/// 0x03:长(30s);
+/// - result: 结果回调
+-(void)smartPickFreeSetAutoInterval:(JL_ManagerM *)manager Interval:(uint8_t)interval Result:(JL_CMD_RESPOND)result;
+
+
+/// 查询设备状态
+/// - Parameter manager: 设备对象
+-(void)smartPickFreeGet:(JL_ManagerM *)manager;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModelVocalBoost.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/9/13.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <JL_BLEKit/JL_BLEKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+@class JLModelVocalBoost;
+
+@protocol JLModelVocalBoostDelegate <NSObject>
+
+-(void)vocalBoostGetInfo:(JLModelVocalBoost *)model;
+
+@end
+
+typedef void(^JLModelVocalBoostBlock)(JLModelVocalBoost *model);
+
+
+/// TWS人声增强
+@interface JLModelVocalBoost : JLCmdBasic
+
+/// 版本号
+@property(nonatomic,assign)uint8_t version;
+
+/// 人声增强:
+/// 0x00: 关闭人声增强模式;
+/// 0x01: 开启人声增强模式
+@property(nonatomic,assign)uint8_t status;
+
+@property(nonatomic,weak)id<JLModelVocalBoostDelegate> delegate;
+
+/// 获取设备人声增强
+/// - Parameter manager: 设备对象
+-(void)vocalBoostStatusGet:(JL_ManagerM *)manager Result:(JLModelVocalBoostBlock)block;
+
+/// 设置设备人声增强
+/// - Parameters:
+/// - manager: 设备对象
+/// - status: 开关
+/// 0x00: 关闭人声增强模式;
+/// 0x01: 开启人声增强模式
+/// - result:回调
+-(void)vocalBoostStatusSet:(JL_ManagerM *)manager Status:(uint8_t)status Result:(JL_CMD_RESPOND)result;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_ANC.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8,JL_AncMode) {
+ JL_AncMode_Normal = 0, //普通模式
+ JL_AncMode_NoiseReduction = 1, //降噪模式
+ JL_AncMode_Transparent = 2, //通透模式
+};
+
+@interface JLModel_ANC : NSObject
+@property(assign,nonatomic)JL_AncMode mAncMode; //耳机降噪模式
+@property(assign,nonatomic) uint16_t mAncMax_L; //左耳最大增益
+@property(assign,nonatomic) uint16_t mAncCurrent_L; //左耳当前增益
+@property(assign,nonatomic) uint16_t mAncMax_R; //右耳最大增益
+@property(assign,nonatomic) uint16_t mAncCurrent_R; //右耳当前增益
+-(NSData*)dataModel;
+@end
+
+
+
+/// 手机名/经典蓝牙地址信息
+@interface JLTWSAddrNameInfo : NSObject
+
+/// 是否被绑定
+@property(nonatomic,assign)uint8_t isBind;
+
+/// 手机蓝牙地址
+@property(nonatomic,strong)NSData *phoneEdrAddr;
+
+/// 手机名称
+@property(nonatomic,strong)NSString *phoneName;
+
+/// 初始化数据成对象
+/// - Parameter data: 数据内容
++(NSArray<JLTWSAddrNameInfo *>*)dataBeObjc:(NSData *)data;
+
+@end
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_AlarmSetting.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLModel_AlarmSetting : NSObject
+@property(assign,nonatomic)uint8_t index; //闹钟索引
+@property(assign,nonatomic)uint8_t isCount; //是否可以设置【闹铃次数】
+@property(assign,nonatomic)uint8_t count; //闹铃次数
+@property(assign,nonatomic)uint8_t isInterval; //是否可以设置【时间间隔】
+@property(assign,nonatomic)uint8_t interval; //时间间隔
+@property(assign,nonatomic)uint8_t isTime; //是否可以设置【时间长度】
+@property(assign,nonatomic)uint8_t time; //时间长度
+-(NSData*)dataModel;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_BT.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLModel_BT : NSObject
+@property(assign,nonatomic)uint32_t mBtType;
+@property(strong,nonatomic)NSData *__nullable mBtAddress;
+@property(assign,nonatomic)uint8_t mBtRssi;
+@property(strong,nonatomic)NSString *__nullable mBtName;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_Device.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Modify by EzioChan on 2023/03/16
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JLModel_Flash.h>
+#import <JL_BLEKit/JLModel_ANC.h>
+#import <JL_BLEKit/JLModel_RTC.h>
+#import <JL_BLEKit/JLModel_FM.h>
+#import <JL_BLEKit/JLModel_File.h>
+#import <JL_BLEKit/JLModel_EQ.h>
+#import <JL_BLEKit/JLDhaFitting.h>
+#import <JL_OTALib/JL_OTALib.h>
+#import <JL_BLEKit/JLModelCardInfo.h>
+#import <JL_BLEKit/JLModelDevFunc.h>
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_DevicePlatform) {
+ JL_DevicePlatformTuring = 0, //适用于【图灵】
+ JL_DevicePlatformDeepbrain = 1, //适用于【Deepbrain】
+ JL_DevicePlatformUnknown,
+};
+typedef NS_ENUM(UInt8, JL_SDKType) {
+ JL_SDKTypeAI = 0x0, //AI SDK AC692x
+ JL_SDKTypeST = 0x1, //标准 SDK AC692x
+ JL_SDKType693xTWS = 0x2, //TWS
+ JL_SDKType695xSDK = 0x3, //
+ JL_SDKType697xTWS = 0x4, //TWS
+ JL_SDKType696xSB = 0x5, //696x_soundbox
+ JL_SDKType696xTWS = 0x6, //TWS
+ JL_SDKType695xSC = 0x7, //695x_sound_card
+ JL_SDKType695xWATCH = 0x8, //BR23 Watch
+ JL_SDKType701xWATCH = 0x9, //BR28 Watch
+ JL_SDKTypeManifestEarphone = 0x0A, //ManifestEarphone
+ JL_SDKTypeManifestSoundbox = 0x0B, //ManifestSoundbox
+ JL_SDKTypeChargingCase = 0x0C, //ChargingCase 彩屏充电仓
+ JL_SDKType707nWATCH = 0x0D, //707N Watch
+ JL_SDKTypeUnknown,
+};
+typedef NS_ENUM(UInt8, JL_FunctionCode) {
+ JL_FunctionCodeBT = 0, //BT
+ JL_FunctionCodeMUSIC = 1, //音乐
+ JL_FunctionCodeRTC = 2, //闹钟
+ JL_FunctionCodeLINEIN = 3, //LineIn
+ JL_FunctionCodeFM = 4, //FM
+ JL_FunctionCodeLIGHT = 5, //LIGHT
+ JL_FunctionCodeFMTX = 6, //发射频点
+ JL_FunctionCodeCOMMON = 0xff, //通用
+};
+
+typedef NS_ENUM(UInt8, JL_FCmdMusic) {
+ JL_FCmdMusicPP = 0x01, //PP按钮
+ JL_FCmdMusicPREV = 0x02, //上一曲
+ JL_FCmdMusicNEXT = 0x03, //下一曲
+ JL_FCmdMusicMODE = 0x04, //切换播放模式
+ JL_FCmdMusicEQ = 0x05, //EQ
+ JL_FCmdMusicFastBack = 0x06, //快退
+ JL_FCmdMusicFastPlay = 0x07, //快进
+};
+
+typedef NS_ENUM(UInt8, JL_OtaBleAllowConnect) {
+ JL_OtaBleAllowConnectYES = 0, //OTA 允许BLE连接
+ JL_OtaBleAllowConnectNO = 1, //OTA 禁止BLE连接
+ JL_OtaBleAllowConnectUnknow = 2, //未定义
+};
+typedef NS_ENUM(UInt8, JL_BLEOnly) { //是否仅仅支持BLE
+ JL_BLEOnlyNO = 0, //否
+ JL_BLEOnlyYES = 1, //是
+};
+typedef NS_ENUM(UInt8, JL_FasheEnable) { //是否发射模式
+ JL_FasheEnableNO = 0, //否
+ JL_FasheEnableYES = 1, //是
+};
+typedef NS_ENUM(UInt8, JL_FasheType) { //当前是否为发射模式
+ JL_FasheTypeNO = 0, //否
+ JL_FasheTypeYES = 1, //是
+};
+typedef NS_ENUM(UInt8, JL_MD5Type) { //是否支持MD5校验
+ JL_MD5TypeNO = 0, //否
+ JL_MD5TypeYES = 1, //是
+};
+typedef NS_ENUM(UInt8, JL_GameType) { //是否为游戏模式
+ JL_GameTypeNO = 0, //否
+ JL_GameTypeYES = 1, //是
+};
+typedef NS_ENUM(UInt8, JL_SearchType) { //是否支持查找设备
+ JL_SearchTypeNO = 0, //否
+ JL_SearchTypeYES = 1, //是
+};
+typedef NS_ENUM(UInt8, JL_KaraokeType) { //是否支持卡拉OK
+ JL_KaraokeTypeNO = 0, //否
+ JL_KaraokeTypeYES = 1, //是
+};
+typedef NS_ENUM(UInt8,JL_KaraokeEQType){ //是否禁止app调节设备音效
+ JL_KaraokeEQTypeNO = 0, //不禁止
+ JL_KaraokeEQTypeYES = 1, //禁止
+};
+typedef NS_ENUM(UInt8,JL_FlashType){ //是否支持外挂Flash
+ JL_FlashTypeNO = 0, //不支持
+ JL_FlashTypeYES = 1, //支持
+};
+typedef NS_ENUM(UInt8,JL_AncType){ //是否支持ANC
+ JL_AncTypeNO = 0, //不支持
+ JL_AncTypeYES = 1, //支持
+};
+typedef NS_ENUM(UInt8, JL_AudioFileType) { //是否支持音频文件传输
+ JL_AudioFileTypeNO = 0, //否
+ JL_AudioFileTypeYES = 1, //是
+};
+typedef NS_ENUM(UInt8, JL_FileSubcontractTransferCrc16Type){//文件分包传输是否支持crc16方式
+ JL_FileSubcontractTransferCrc16TypeNO = 0, //不支持
+ JL_FileSubcontractTransferCrc16TypeYES = 1, //支持
+};
+typedef NS_ENUM(UInt8, JL_ReadFileInNewWayType){ //是否以新的方式读取固件文件
+ JL_ReadFileInNewWayTypeNO = 0, //不支持
+ JL_ReadFileInNewWayTypeYES = 1, //支持
+};
+
+typedef NS_ENUM(UInt8, JL_SmallFileWayType){ //是否支持小文件传输
+ JL_SmallFileWayTypeNO = 0, //不支持
+ JL_SmallFileWayTypeYES = 1, //支持
+};
+
+typedef NS_ENUM(UInt8,JL_CALLType) {
+ JL_CALLType_OFF = 0, //空闲
+ JL_CALLType_ON = 1, //通话中
+};
+
+typedef NS_ENUM(UInt8, JL_LightState) {
+ JL_LightStateClose = 0x00, //关闭
+ JL_LightStateOpen = 0x01, //开启
+ JL_LightStateSetting = 0x02, //设置模式
+};
+typedef NS_ENUM(UInt8, JL_LightMode) {
+ JL_LightModeNormal = 0x00, //彩色模式
+ JL_LightModeFlash = 0x01, //闪烁模式
+ JL_LightModeScene = 0x02, //情景模式
+};
+typedef NS_ENUM(UInt8, JL_LightFlashModeIndex) {
+ JL_LightModeIndexColorfulFlash = 0x00, //七彩闪烁
+ JL_LightModeIndexRedFlash = 0x01, //红色闪烁
+ JL_LightModeIndexOrangeFlash = 0x02, //橙色闪烁
+ JL_LightModeIndexYeallowFlash = 0x03, //黄色闪烁
+ JL_LightModeIndexGreenFlash = 0x04, //绿色闪烁
+ JL_LightModeIndexCyanFlash = 0x05, //青色闪烁
+ JL_LightModeIndexBlueFlash = 0x06, //蓝色闪烁
+ JL_LightModeIndexPurpleFlash = 0x07, //紫色闪烁
+};
+
+typedef NS_ENUM(UInt8, JL_LightFlashModeFrequency) {
+ JL_LightFlashModeFrequencyFast = 0x00, //快闪
+ JL_LightFlashModeFrequencySlow = 0x01, //慢闪
+ JL_LightFlashModeFrequencyNormal = 0x02, //缓闪
+ JL_LightFlashModeFrequencyMusic = 0x03, //音乐闪烁
+};
+
+typedef NS_ENUM(UInt8, JL_LightSceneMode) {
+ JL_LightSceneModeRainbow = 0x00, //彩虹
+ JL_LightSceneModeHeartbeat = 0x01, //心跳
+ JL_LightSceneModeCandlelight = 0x02, //烛火
+ JL_LightSceneModeNightLight = 0x03, //夜灯
+ JL_LightSceneModeStage = 0x04, //舞台
+ JL_LightSceneModeDiffuseColourBreathing = 0x05, //漫彩呼吸
+ JL_LightSceneModeDiffuseRedBreathing = 0x06, //漫红呼吸
+ JL_LightSceneModeDiffuseGreenBreathing = 0x07, //漫绿呼吸
+ JL_LightSceneModeDiffuseBlueBreathing = 0x08, //漫蓝呼吸
+ JL_LightSceneModeGreenMood = 0x09, //绿色心情
+ JL_LightSceneModeSettingSunView = 0x10, //夕阳美景
+ JL_LightSceneModeMusicRhythm = 0x11, //音乐律动
+};
+
+typedef NS_ENUM(UInt8, JL_FileHandleType) { //文件句柄
+ JL_FileHandleTypeSD_0 = 0, //SD_0
+ JL_FileHandleTypeSD_1 = 1, //SD_1
+ JL_FileHandleTypeFLASH = 2, //FLASH
+ JL_FileHandleTypeUSB = 3, //USB
+ JL_FileHandleTypeLineIn = 4, //LineIn
+ JL_FileHandleTypeFLASH2 = 5, //FLASH2
+ JL_FileHandleTypeFLASH3 = 6, //FLASH3
+};
+
+typedef NS_ENUM(UInt8, JL_MusicMode) {
+ JL_MusicModeLoopAll = 0x01, //全部循环
+ JL_MusicModeLoopDevice = 0x02, //单设备循环
+ JL_MusicModeLoopOne = 0x03, //单曲循环
+ JL_MusicModeRandomDevice = 0x04, //单设备随机
+ JL_MusicModeLoopFolder = 0x05, //文件夹循环
+};
+
+typedef NS_ENUM(UInt8, JL_MusicStatus) {
+ JL_MusicStatusPlay = 0x01, //播放
+ JL_MusicStatusPause = 0x00, //暂停
+};
+
+typedef NS_ENUM(UInt8, JL_EQType) { //EQ段数类型
+ JL_EQType10 = 0, //固定10段式
+ JL_EQTypeMutable = 1, //动态EQ段
+};
+
+//---------------------------------------------------------//
+#pragma mark - RTC
+typedef NS_ENUM(UInt8, JL_RTCAlarmType) { //是否支持闹铃设置
+ JL_RTCAlarmTypeNO = 0, //不支持
+ JL_RTCAlarmTypeYES = 1, //支持
+};
+//---------------------------------------------------------//
+#pragma mark - LINEIN
+typedef NS_ENUM(UInt8, JL_LineInStatus) {
+ JL_LineInStatusPause = 0x00, //暂停
+ JL_LineInStatusPlay = 0x01, //播放
+ JL_LineInStatusUnknown,
+};
+//---------------------------------------------------------//
+#pragma mark - FM
+typedef NS_ENUM(UInt8, JL_FMStatus) {
+ JL_FMStatusPause = 0x01, //播放
+ JL_FMStatusPlay = 0x02, //暂停
+ JL_FMStatusSearching = 0x03, //搜索中
+ JL_FMStatusUnknown,
+};
+typedef NS_ENUM(UInt8, JL_FMMode) {
+ JL_FMMode875Mhz = 0x00, //87.5-108.0Mhz
+ JL_FMMode760Mhz = 0x01, //76.5-108.0Mhz
+ JL_FMModeUnknown,
+};
+
+typedef NS_ENUM(UInt8,JL_ReverberationType) {
+ JL_ReverberationTypeNormal = 0, //混响
+ JL_ReverberationTypeDynamic = 1, //限幅器
+};
+
+
+@interface JLModel_Device : NSObject<NSCopying>
+
+///设备UUID
+@property (copy, nonatomic) NSString *mBLE_UUID;
+
+///协议版本
+@property (copy, nonatomic) NSString *versionProtocol;
+
+///固件版本
+@property (copy, nonatomic) NSString *versionFirmware;
+
+/// 单包固件最大发送值,APP单次能收到最大的值
+@property (assign,nonatomic) NSInteger getMtu;
+
+/// 单包固件最大接收值(MaxMtu)APP单次可发送最大值
+@property (assign,nonatomic) NSInteger sendMtu;
+
+///SDK类型
+@property (assign,nonatomic) JL_SDKType sdkType;
+
+///电量0~9
+@property (assign,nonatomic) NSUInteger battery;
+
+/// 是否支持音量同步
+@property (assign,nonatomic) BOOL isSyncVoice;
+
+/// 最低允许升级资源/OTA电量
+@property (assign,nonatomic) NSInteger lowBattery;
+
+///当前音量
+@property (assign,nonatomic) NSUInteger currentVol;
+
+///最大音量
+@property (assign,nonatomic) NSUInteger maxVol;
+
+///经典蓝牙地址
+@property (copy, nonatomic) NSString *btAddr;
+
+///平台序列号
+@property (copy, nonatomic) NSString *license;
+
+///平台类型(图灵,Deepbrain)
+@property (assign,nonatomic) JL_DevicePlatform platform;
+
+///经典蓝牙状态
+@property (assign,nonatomic) JL_DeviceBTStatus btStatus;
+
+///BIT(0):BT BIT(1):MUSIC BIT(2):RTC
+@property (assign,nonatomic) uint32_t function;
+
+///当前处于的模式
+@property (assign,nonatomic) JL_FunctionCode currentFunc;
+
+///USb,SD,LineIn,网络电台是否在线
+@property (assign,nonatomic) uint8_t funcOnlineStatus;
+
+/// 设备功能模式支持
+@property (strong,nonatomic) JLModelDevFunc *deviceFuncs;
+
+///uboot版本
+@property (copy, nonatomic) NSString *versionUBoot;
+
+///设备单、双备份
+@property (assign,nonatomic) JL_Partition partitionType;
+
+///OTA状态
+@property (assign,nonatomic) JL_OtaStatus otaStatus;
+
+///耳机单备份 是否需要强制升级
+@property (assign,nonatomic) JL_OtaHeadset otaHeadset;
+
+///手表资源 是否需要强制升级
+@property (assign,nonatomic) JL_OtaWatch otaWatch;
+
+///厂商ID
+@property (copy, nonatomic) NSString *pidvid;
+
+///授权Key
+@property (copy, nonatomic) NSString *authKey;
+
+///授权Code
+@property (copy, nonatomic) NSString *proCode;
+
+///是否下载BootLoader
+@property (assign,nonatomic) JL_BootLoader bootLoaderType;
+
+///OTA是否允许BLE连接
+@property (assign,nonatomic) JL_OtaBleAllowConnect otaBleAllowConnect;
+
+///是否仅仅支持BLE
+@property (assign,nonatomic) JL_BLEOnly bleOnly;
+
+///ble蓝牙地址
+@property (copy, nonatomic) NSString *bleAddr;
+
+///是否支持发射模式
+@property (assign,nonatomic) JL_FasheEnable fasheEnable;
+
+///当前是否为发射模式
+@property (assign,nonatomic) JL_FasheType fasheType;
+
+///是否支持MD5固件校验
+@property (assign,nonatomic) JL_MD5Type md5Type;
+
+///是否为游戏模式
+@property (assign,nonatomic) JL_GameType gameType;
+
+///是否支持游戏模式
+@property (assign,nonatomic) BOOL isSupportGameModel;
+
+///是否支持查找设备
+@property (assign,nonatomic) JL_SearchType searchType;
+
+///是否支持卡拉OK
+@property (assign,nonatomic) JL_KaraokeType karaokeType;
+
+///是否禁止app调节设备音效
+@property (assign,nonatomic) JL_KaraokeEQType karaokeEQType;
+
+///是否外挂flash
+@property (assign,nonatomic) JL_FlashType flashType;
+
+///是否支持ANC
+@property (assign,nonatomic) JL_AncType ancType;
+
+///是否支持音频文件传输功能
+@property (assign,nonatomic) JL_AudioFileType audioFileType;
+
+/// 是否支持日志获取
+@property (assign,nonatomic) BOOL isSupportLog;
+
+/// 是否支持辅听设置
+@property (assign,nonatomic) BOOL isSupportDhaFitting;
+
+///验配信息交互:版本、通道数、通道频率
+///Fitting information interaction: version, channel number, channel frequency
+@property (strong,nonatomic) DhaFittingInfo *dhaFitInfo;
+
+/// 验配中断/开启的对象,仅限于监听
+/// Fitting interrupted/opened object, only for listening
+@property (strong,nonatomic) DhaFittingSwitch *dhaFitSwitch;
+
+/// 通道增益值数组,先左耳后右耳,个数和验配信息中返回的一致
+/// Array of channel gain values, first left ear then right ear, the number is the same as the one returned in the fitting information
+@property (strong,nonatomic) NSArray<NSNumber *> *dhaFittingList;
+
+/// 是否支持获取设备配置信息
+@property (assign,nonatomic) BOOL isSupportDevConfigInfo;
+
+/// 是否支持自适应ANC
+@property (assign,nonatomic) BOOL isSupportAutoANC;
+
+///低音
+@property (assign,nonatomic) int pitchLow;
+
+///高音
+@property (assign,nonatomic) int pitchHigh;
+
+///外挂flash信息
+@property (copy, nonatomic) JLModel_Flash *flashInfo;
+
+/// 设备信息中指明,外部SD卡/U盘引脚是否被复用
+/// Specify in the device information, whether the external SD card/U disk pins are multiplexed
+@property (assign,nonatomic) BOOL devPinMultiplex;
+
+
+/*--- File INFO ---*/
+///当前文件传输句柄
+@property (assign,nonatomic) JL_FileHandleType currentFileHandleType;
+///文件分包传输是否支持crc16方式
+@property (assign,nonatomic) JL_FileSubcontractTransferCrc16Type fileSubcontractTransferCrc16Type;
+///是否以新的方式读取固件文件
+@property (assign,nonatomic) JL_ReadFileInNewWayType readFileInNewWayType;
+///是否小文件方式传输
+@property (assign,nonatomic) JL_SmallFileWayType smallFileWayType;
+
+/*--- 公用INFO ---*/
+//MARK: - 存储信息
+///卡的数组
+@property (copy, nonatomic) NSArray *cardArray __attribute__((deprecated ( "Use the instance property cardArray of the JLModelCardInfo class instead, this property is about to become invalid")));
+///USB handle
+@property (copy, nonatomic) NSString *handleUSB __attribute__((deprecated ( "Use the instance property usbHandle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///SD_0 handle
+@property (copy, nonatomic) NSString *handleSD_0 __attribute__((deprecated ( "Use the instance property sd0Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///SD_1 handle
+@property (copy, nonatomic) NSString *handleSD_1 __attribute__((deprecated ( "Use the instance property sd1Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///Flash handle
+@property (copy, nonatomic) NSString *handleFlash __attribute__((deprecated ( "Use the instance property flashHandle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///Flash2 handle
+@property (copy, nonatomic) NSString *handleFlash2 __attribute__((deprecated ( "Use the instance property flash2Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+
+///Flash3 handle
+@property (copy, nonatomic) NSString *handleFlash3 __attribute__((deprecated ( "Use the instance property flash3Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+
+///USB handle Data
+@property (copy, nonatomic) NSData *handleUSBData __attribute__((deprecated ( "Use the instance property usbHandle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///SD_0 handle Data
+@property (copy, nonatomic) NSData *handleSD_0Data __attribute__((deprecated ( "Use the instance property sd0Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///SD_1 handle Data
+@property (copy, nonatomic) NSData *handleSD_1Data __attribute__((deprecated ( "Use the instance property sd1Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///Flash handle Data
+@property (copy, nonatomic) NSData *handleFlashData __attribute__((deprecated ( "Use the instance property flashHandle of the JLModelCardInfo class instead, this property is about to become invalid")));
+///Flash2 handle Data
+@property (copy, nonatomic) NSData *handleFlash2Data __attribute__((deprecated ( "Use the instance property flash2Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+
+///Flash3 handle Data
+@property (copy, nonatomic) NSData *handleFlash3Data __attribute__((deprecated ( "Use the instance property flash3Handle of the JLModelCardInfo class instead, this property is about to become invalid")));
+
+/// 设备存储信息(卡信息)
+@property (strong, nonatomic)JLModelCardInfo *cardInfo;
+
+/// 错误原因
+@property (copy, nonatomic) NSString *errReason;
+
+/// 发射频点
+@property (assign,nonatomic) uint16_t fmtxPoint;
+/// 0x00:普通模式 0x01:发射模式
+@property (assign,nonatomic) uint8_t mTWS_Mode;
+/// 0x00:未连接 0x01:已连接
+@property (assign,nonatomic) uint8_t mTWS_Status;
+/// 发射模式中,连接的外设地址
+@property (copy ,nonatomic) NSString *mTWS_Addr;
+/// 当前ANC的模式
+@property (copy ,nonatomic) JLModel_ANC *mAncModeCurrent;
+/// ANC模式数组
+@property (copy ,nonatomic) NSMutableArray *mAncModeArray;
+///通话状态
+@property (assign,nonatomic) JL_CALLType mCallType;
+
+/// 混响所支持的类型
+@property (strong,nonatomic) NSArray *reverberationTypes;
+/// 混响的开关
+@property (assign,nonatomic) int reverberationSwitchState;
+/// 深度值
+@property (assign,nonatomic) int depthValue;
+/// 混响度值
+@property (assign,nonatomic) int intensityValue;
+/// 混响幅值
+@property (assign,nonatomic) int dynamicLimiterValue;
+
+//MARK: - 卡拉OK
+///卡拉OK 固件返回的掩码
+@property (assign,nonatomic)uint64_t kalaokMask __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SoundCardManager class instead, this property is about to become invalid")));
+
+///卡拉OK 频率数组
+@property (strong,nonatomic)NSArray *mKaraokeMicFrequencyArray __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SoundCardManager class instead, this property is about to become invalid")));
+
+///卡拉OK EQ数组
+@property (strong,nonatomic)NSArray *mKaraokeMicEQArray __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SoundCardManager class instead, this property is about to become invalid")));
+
+//MARK: - EQ 属性列表
+/// EQ模式
+@property (assign,nonatomic) JL_EQMode eqMode __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SystemEQ class instead, this property is about to become invalid")));;
+/// EQ参数值(只适用于EQ Mode == CUSTOM情况)
+@property (copy, nonatomic) NSArray *eqArray __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SystemEQ class instead, this property is about to become invalid")));;
+///自定义EQ
+@property (copy, nonatomic) NSArray *eqCustomArray __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SystemEQ class instead, this property is about to become invalid")));;
+
+///EQ频率
+@property (copy, nonatomic) NSArray *eqFrequencyArray __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SystemEQ class instead, this property is about to become invalid")));;
+///EQ段数类型
+@property (assign,nonatomic) JL_EQType eqType __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SystemEQ class instead, this property is about to become invalid")));;
+
+///EQ的预设值数组 数组元素类型-->【JLEQModel】
+@property (strong,nonatomic) NSArray *eqDefaultArray __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_SystemEQ class instead, this property is about to become invalid")));;
+
+//MARK: - 灯光属性列表
+/// 0:关闭 1:打开 2:设置模式(彩色/闪烁/情景)
+@property (assign,nonatomic) JL_LightState lightState __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 0:彩色 1:闪烁 2: 情景
+@property (assign,nonatomic) JL_LightMode lightMode __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 灯光红色
+@property (assign,nonatomic) uint8_t lightRed __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 灯光绿色
+@property (assign,nonatomic) uint8_t lightGreen __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 灯光蓝色
+@property (assign,nonatomic) uint8_t lightBlue __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 闪烁模式Index
+@property (assign,nonatomic) JL_LightFlashModeIndex lightFlashIndex __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 闪烁频率Index
+@property (assign,nonatomic) JL_LightFlashModeFrequency lightFrequencyIndex __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 情景模式Index
+@property (assign,nonatomic) JL_LightSceneMode lightSceneIndex __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 色调,范围0-360
+@property (assign,nonatomic) uint16_t lightHue __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 饱和度,0-100
+@property (assign,nonatomic) uint8_t lightSat __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+/// 亮度,0-100
+@property (assign,nonatomic) uint8_t lightLightness __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_LightManager class instead, this property is about to become invalid")));
+
+
+//MARK: - BT INFO
+@property (strong,nonatomic) NSString *ID3_Title;
+@property (strong,nonatomic) NSString *ID3_Artist;
+@property (strong,nonatomic) NSString *ID3_AlBum;
+@property (assign,nonatomic) uint8_t ID3_Number;
+@property (assign,nonatomic) uint16_t ID3_Total;
+@property (strong,nonatomic) NSString *ID3_Genre;
+@property (assign,nonatomic) uint32_t ID3_Time;
+/// 0x01:播放 0x00:暂停
+@property (assign,nonatomic) uint8_t ID3_Status;
+
+@property (assign,nonatomic) uint32_t ID3_CurrentTime;
+
+//MARK: - Music INFO
+///播放状态
+@property (assign,nonatomic) JL_MusicStatus playStatus __attribute__((deprecated ( "Use the instance property rtcVersion of the JLDevPlayerCtrl class instead, this property is about to become invalid")));
+
+///播放模式
+@property (assign,nonatomic) JL_MusicMode playMode __attribute__((deprecated ( "Use the instance property rtcVersion of the JLDevPlayerCtrl class instead, this property is about to become invalid")));
+
+///当前播放文件的簇号
+@property (assign,nonatomic) uint32_t currentClus __attribute__((deprecated ( "Use the instance property rtcVersion of the JLDevPlayerCtrl class instead, this property is about to become invalid")));
+
+///当前时间
+@property (assign,nonatomic) uint32_t currentTime __attribute__((deprecated ( "Use the instance property rtcVersion of the JLDevPlayerCtrl class instead, this property is about to become invalid")));
+
+///总时长
+@property (assign,nonatomic) uint32_t tolalTime __attribute__((deprecated ( "Use the instance property rtcVersion of the JLDevPlayerCtrl class instead, this property is about to become invalid")));
+
+///当前卡
+@property (assign,nonatomic) JL_CardType currentCard __attribute__((deprecated ( "Use the instance property rtcVersion of the JLDevPlayerCtrl class instead, this property is about to become invalid")));
+
+///名字
+@property (copy, nonatomic) NSString *fileName __attribute__((deprecated ( "Use the instance property rtcVersion of the JLDevPlayerCtrl class instead, this property is about to become invalid")));
+
+///目录浏览文件类型(所支持解码音频格式)
+@property (copy, nonatomic) NSString *typeSupport;
+
+//MARK: - RTC INFO
+
+///RTC 版本
+@property (assign,nonatomic) uint8_t rtcVersion __attribute__((deprecated ( "Use the instance property rtcVersion of the JL_AlarmClockManager class instead, this property is about to become invalid")));
+
+///是否支持闹铃设置
+@property (assign,nonatomic) JL_RTCAlarmType rtcAlarmType __attribute__((deprecated ( "Use the instance property rtcAlarmType of the JL_AlarmClockManager class instead, this property is about to become invalid")));
+
+///设备当前时间
+@property (strong,nonatomic) JLModel_RTC *rtcModel __attribute__((deprecated ( "Use the instance property rtcModel of the JL_AlarmClockManager class instead, this property is about to become invalid")));
+
+///设备闹钟数组
+@property (strong,nonatomic) NSMutableArray *rtcAlarms __attribute__((deprecated ( "Use the instance property rtcAlarms of the JL_AlarmClockManager class instead, this property is about to become invalid")));
+
+///默认铃声
+@property (strong,nonatomic) NSMutableArray *rtcDfRings __attribute__((deprecated ( "Use the instance property rtcDfRings of the JL_AlarmClockManager class instead, this property is about to become invalid")));
+
+//MARK: - LineIn INFO
+
+///LineIn状态
+@property (assign,nonatomic) JL_LineInStatus lineInStatus;
+
+
+//MARK: - Fm 模式
+///Fm状态
+@property (assign,nonatomic) JL_FMStatus fmStatus;
+
+///Fm 频段范围
+///76.5-108.0Mhz
+///87.5-108.0Mhz
+@property (assign,nonatomic) JL_FMMode fmMode;
+
+///当前fm
+@property (strong,nonatomic) JLModel_FM *currentFm;
+
+///Fm列表
+@property (strong,nonatomic) NSArray *fmArray;
+
+//MARK: - custom version info
+/// 自定义版本信息
+@property(strong,nonatomic) NSData *customizeInfo;
+
+
+-(void)cleanMe;
++(void)observeModelProperty:(NSString*)prty Action:(SEL)action Own:(id)own;
++(void)removeModelProperty:(NSString*)prty Own:(id)own;
+
+#pragma mark ---> 设备信息
+-(void)deviceInfoData:(NSData*)infoData;
+
+#pragma mark ---> 各个模式信息
+-(void)deviceModeInfoData:(NSData*)infoData;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_EQ.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_EQMode) {
+ JL_EQModeNORMAL = 0, //自然
+ JL_EQModeROCK = 1, //摇滚
+ JL_EQModePOP = 2, //流行
+ JL_EQModeCLASSIC = 3, //经典
+ JL_EQModeJAZZ = 4, //爵士
+ JL_EQModeCOUNTRY = 5, //乡村
+ JL_EQModeCUSTOM = 6, //用户自定义
+ JL_EQModeLATIN = 7, //拉丁
+ JL_EQModeDANCE = 8, //舞蹈
+};
+
+@interface JLModel_EQ : NSObject
+@property(assign,nonatomic)JL_EQMode mMode;
+@property(strong,nonatomic)NSArray *__nullable mEqArray;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_FM.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLModel_FM : NSObject<NSCoding>
+@property (assign,nonatomic) uint8_t fmChannel;
+@property (assign,nonatomic) uint16_t fmFrequency;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_File.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_BrowseType) {
+ JL_BrowseTypeFolder = 0, //文件夹
+ JL_BrowseTypeFile = 1, //文件
+};
+typedef NS_ENUM(UInt8, JL_CardType) {
+ JL_CardTypeUSB = 0, //USB
+ JL_CardTypeSD_0 = 1, //SD_0
+ JL_CardTypeSD_1 = 2, //SD_1
+ JL_CardTypeFLASH = 3, //FLASH
+ JL_CardTypeLineIn = 4, //LineIn
+ JL_CardTypeFLASH2 = 5, //FLASH2
+ JL_CardTypeFLASH3 = 6, //FLASH3
+};
+
+@interface JLModel_File : NSObject<NSCopying,NSCoding>
+@property (assign,nonatomic) JL_BrowseType fileType;
+@property (assign,nonatomic) JL_CardType cardType;
+@property (assign,nonatomic) uint32_t fileClus;
+@property (assign,nonatomic) uint16_t fileIndex;
+@property (copy, nonatomic) NSString *fileHandle;
+@property (copy, nonatomic) NSString *fileName;
+@property (copy, nonatomic) NSString *folderName;
+@property (copy, nonatomic) NSData *__nullable pathData;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_Flash.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_FlashSystemType) {
+ JL_FlashSystemType_FATFS = 0,
+ JL_FlashSystemType_RCSP = 1,
+};
+
+@interface JLModel_Flash : NSObject
+
+/// flash大小
+@property(assign,nonatomic)uint32_t mFlashSize;
+
+/// FAT系统大小
+@property(assign,nonatomic)uint32_t mFatfsSize;
+
+/// 系统类型 0:FATFS,1:RCSP
+@property(assign,nonatomic)JL_FlashSystemType mFlashType;
+
+/// 系统当前状态,0x00正常,0x01异常
+@property(assign,nonatomic)uint8_t mFlashStatus;
+
+/// Flash版本
+@property(assign,nonatomic)uint16_t mFlashVersion;
+
+/// 读数MTU
+@property(assign,nonatomic)uint16_t mFlashReadMtu;
+
+/// 扇区大小
+@property(assign,nonatomic)uint16_t mFlashCluster;
+
+/// 手表兼容列表"W001,W002,W003"
+@property(strong,nonatomic)NSString *mFlashMatchVersion;
+
+/// 写数MTU
+@property(assign,nonatomic)uint16_t mFlashWriteMtu;
+
+/// 屏幕宽度
+@property(assign,nonatomic)uint16_t mScreenWidth;
+
+/// 屏幕高度
+@property(assign,nonatomic)uint16_t mScreenHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_Headset.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLModel_Headset : NSObject
+@property(assign,nonatomic)BOOL mCharging_L;
+@property(assign,nonatomic)BOOL mCharging_R;
+@property(assign,nonatomic)BOOL mCharging_C;
+@property(assign,nonatomic)uint8_t mPower;
+@property(assign,nonatomic)uint8_t mPower_L;
+@property(assign,nonatomic)uint8_t mPower_R;
+@property(assign,nonatomic)uint8_t mPower_C;
+@property(assign,nonatomic)uint8_t mLedScene;
+@property(assign,nonatomic)uint8_t mLedEffect;
+@property(assign,nonatomic)uint8_t mKeyLR;
+@property(assign,nonatomic)uint8_t mKeyAction;
+@property(assign,nonatomic)uint8_t mKeyFunction;
+@property(assign,nonatomic)uint8_t mMicMode;
+@property(assign,nonatomic)uint8_t mWorkMode;
+@property(strong,nonatomic)NSString *mEdr;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_RTC.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/RTC_RingInfo.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLModel_RTC : NSObject
+
+/// 年
+@property (assign,nonatomic) uint16_t rtcYear;
+
+/// 月
+@property (assign,nonatomic) uint8_t rtcMonth;
+
+/// 日
+@property (assign,nonatomic) uint8_t rtcDay;
+
+/// 时
+@property (assign,nonatomic) uint8_t rtcHour;
+
+/// 分
+@property (assign,nonatomic) uint8_t rtcMin;
+
+/// 秒
+@property (assign,nonatomic) uint8_t rtcSec;
+
+/// RTC使能
+@property (assign,nonatomic) BOOL rtcEnable;
+
+/// RTC循环模式
+/// mode: 值为 0 时只响一次
+/// bit0: 每天
+/// bit1: 周一
+/// bit2: 周二
+/// bit3: 周三
+/// bit4: 周四
+/// bit5: 周五
+/// bit6: 周六
+/// bit7: 周日
+@property (assign,nonatomic) uint8_t rtcMode;
+
+
+/// RTC索引
+@property (assign,nonatomic) uint8_t rtcIndex;
+
+/// 名称
+@property (copy ,nonatomic) NSString *rtcName;
+
+/// 自定义闹铃内容
+/// 这部分内容取自设备音乐浏览所获得的句柄以及簇号
+@property (strong,nonatomic) RTC_RingInfo *ringInfo;
+
+/// 闹铃数据
+@property (strong,nonatomic) NSData *RingData;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_Ring.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLModel_Ring : NSObject
+
+/// 默认铃声序号
+/// alarm default rings index
+@property(assign,nonatomic) uint8_t index;
+
+/// 默认铃声名称
+/// alarm default rings name
+@property(strong,nonatomic) NSString *name;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_SPEEX.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Modify By EzioChan on 2023/03/27.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_SpeakType) {
+ JL_SpeakTypeDo = 0, //开始录音
+ JL_SpeakTypeDone = 1, //结束录音
+ JL_SpeakTypeDoing = 2, //正在录音
+ JL_SpeakTypeDoneFail = 0x0f, //结束失败
+};
+typedef NS_ENUM(UInt8, JL_SpeakDataType) {
+ JL_SpeakDataTypePCM = 0, //PCM数据
+ JL_SpeakDataTypeSPEEX = 1, //SPEEX数据
+ JL_SpeakDataTypeOPUS = 2, //OPUS数据
+};
+
+/// 结束原因
+typedef NS_ENUM(UInt8, JLSpeakDownReason) {
+ ///正常
+ JLSpeakDownNormal = 0x00,
+ ///取消
+ JLSpeakDownByDevice = 0x01
+};
+
+/// SampleRate
+typedef NS_ENUM(UInt8, JLRecordSampleRate) {
+ ///8000
+ JLRecordSampleRate8K = 0x08,
+ ///16000
+ JLRecordSampleRate16K = 0x10
+};
+
+
+
+
+
+
+@interface JLModel_SPEEX : NSObject
+@property(assign,nonatomic)JL_SpeakType mSpeakType;
+@property(assign,nonatomic)JL_SpeakDataType mDataType;
+@property(assign,nonatomic)JLSpeakDownReason mDownReason;
+@property(assign,nonatomic)uint8_t mSampleRate; //0x08=8k,0x10=16k
+@property(assign,nonatomic)uint8_t mVad; //断句方: 0:固件 1:APP
+@end
+
+
+///语音助手配置参数
+@interface JLSpeechRecognition:NSObject
+
+///是否下发识别文本,0:否 1:是
+@property(assign,nonatomic)BOOL sendText;
+
+/// 是否下发AI文本,0:否 1:是
+@property(assign,nonatomic)BOOL sendAIText;
+
+/// 是否播放AI TTS语音,0:否 1:是
+@property(assign,nonatomic)BOOL needPlayTTS;
+
++(JLSpeechRecognition *)beObjc:(NSData *)data;
+
+-(NSData *)beData;
+
+@end
+
+
+/// 录音参数对象
+@interface JLRecordParams : NSObject
+
+/// 音频类型
+@property(nonatomic,assign)JL_SpeakDataType mDataType;
+
+/// VAD方式
+@property(assign,nonatomic)JLSpeakDownReason mVadWay;
+
+/// 采样率
+@property(assign,nonatomic)JLRecordSampleRate mSampleRate;
+
+/// 语音助手配置参数
+@property(strong,nonatomic)JLSpeechRecognition *speechRecognit;
+
+@end
+
+
+/// speech 语音:AI云数据格式
+@interface JLSpeechAiCloud : NSObject
+
+/// 版本信息
+@property(nonatomic,assign)uint8_t version;
+
+/// 文本类型
+/// 0 : 手表本地文本(语音识别)
+/// 1 : AI应答文本
+/// 2 : 错误提示文本
+@property(nonatomic,assign)uint8_t type;
+
+/// 供应商
+/// 0 : 杰理
+/// 1 : 科大讯飞
+@property(nonatomic,assign)uint8_t vendorID;
+
+/// 有效数据长度
+@property(nonatomic,assign)uint16_t lenght;
+
+/// 数据内容
+@property(nonatomic,strong)NSData *playload;
+
++(JLSpeechAiCloud *)beObject:(NSData *)data;
+
+-(NSData *)beData;
+
+@end
+
+/// TTS语音合成数据格式
+@interface JLSpeechTTSSynthesis : NSObject
+
+/// 版本信息
+@property(nonatomic,assign)uint8_t version;
+
+/// 有效数据长度
+@property(nonatomic,assign)uint16_t lenght;
+
+/// 数据内容
+@property(nonatomic,strong)NSData *playload;
+
+-(NSData *)beData;
+
++(JLSpeechTTSSynthesis *)beObject:(NSData *)data;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLModel_SmallFile.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/14.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+typedef NS_ENUM(UInt8, JL_SmallFileType) {
+ JL_SmallFileTypeContacts = 0x01, //联系人
+ JL_SmallFileTypeMotionRecord = 0x02, //运动记录
+ JL_SmallFileTypeHeartRate = 0x03, //心率数据
+ JL_SmallFileTypeSpoData = 0x04, //血氧数据
+ JL_SmallFileTypeSleepData = 0x05, //睡眠数据
+ JL_SmallFileTypeMassage = 0x06, //消息数据
+ JL_SmallFileTypeWeather = 0x07, //天气数据
+ JL_SmallFileTypeCallLog = 0x08, //通话记录
+ JL_SmallFileTypeStepCount = 0x09, //步数数据
+ JL_SmallFileTypeWeight = 0xFF, //体重数据
+};
+
+@interface JLModel_SmallFile : NSObject
+@property(nonatomic,assign)JL_SmallFileType file_type;
+@property(nonatomic,assign)uint8_t file_ver;
+@property(nonatomic,assign)uint16_t file_id;
+@property(nonatomic,assign)uint16_t file_size;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLOxygenSturationRemindModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/2/17.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 血氧检测控制
+@interface JLOxygenSturationRemindModel : JLwSettingModel
+///开关
+@property(nonatomic,assign)BOOL status;
+/// 测量模式
+@property(nonatomic,assign)WatchOxygenMsmType rType;
+
+
+-(instancetype)initWithData:(NSData *)data;
+
+/// 创建一个新的传感器设置对象
+/// @param type 测量类型
+/// @param status 开闭状态
+- (instancetype)initWithModel:(WatchOxygenMsmType)type Status:(BOOL)status;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLPersonInfoModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 个人信息设置
+@interface JLPersonInfoModel : JLwSettingModel
+
+/// 身高,cm
+@property(nonatomic,assign)uint16_t height;
+/// 体重,kg
+@property(nonatomic,assign)uint16_t weight;
+/// 生日
+@property(nonatomic,strong)NSDate *birthDay;
+/// 性别
+/// 女性:0x00
+/// 男性:0x01
+@property(nonatomic,assign)uint8_t gender;
+
+-(instancetype)initWith:(NSDate *)birthDay height:(uint16_t)h weight:(uint16_t)w gener:(uint8_t)gender;
+
+-(instancetype)initWithData:(NSData *)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLPublicSetting.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/12/1.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JLPublicSettingBlocks.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+@class JL_ManagerM;
+
+/// 公共 设置/通知/读取 交互类 0x33 回调协议
+@protocol JLPublicSettingProtocol <NSObject>
+@optional
+
+/// 屏幕亮度设置回调/通知
+/// - Parameters:
+/// - manager: 设备
+/// - light: 亮度
+-(void)publicSettingScreenLight:(JL_ManagerM *)manager Value:(uint8_t)light;
+
+/// 手电筒设置回调/通知
+/// - Parameters:
+/// - manager: 设备
+/// - isOn: 是否打开
+-(void)publicSettingFlashLight:(JL_ManagerM *)manager Value:(BOOL)isOn;
+
+/// 设备绑定状态回调/通知
+/// - Parameters:
+/// - manager: 设备
+/// - model: 绑定信息
+-(void)publicSettingBindStatus:(JL_ManagerM *)manager Model:(JLPublicBindDeviceModel *)model;
+
+/// 功能使用资源通知/回调
+/// - Parameters:
+/// - manager: 设备
+/// - model: 资源信息
+-(void)publicSettingFuncSource:(JL_ManagerM *)manager Model:(JLPublicSourceInfoModel *)model;
+
+/// 功能使用资源通知/回调
+/// - Parameters:
+/// - manager: 设备
+/// - model:
+/// 0x00 结束
+/// 0x01 开始推送
+-(void)publicSettingReplaceTipsVoiceStatus:(JL_ManagerM *)manager Model:(uint8_t )model Reason:(NSError *_Nullable)err;
+
+@end
+
+
+/// 公共 设置/通知/读取 交互类 0x33
+@interface JLPublicSetting : NSObject
+
+/// 代理
+@property(nonatomic,assign)id<JLPublicSettingProtocol> delegate;
+
+/// 读取设备当前屏幕亮度
+/// - Parameters:
+/// - manager: 设备
+/// - block: 回调
+-(void)cmdScreenLightGet:(JL_ManagerM *)manager result:(JLPSScreenLightCbk)block;
+
+/// 设置设备的屏幕亮度
+/// - Parameters:
+/// - manager: 设备
+/// - value: 亮度值 0~100
+/// - block: 回调
+-(void)cmdScreenLightSet:(JL_ManagerM *)manager Value:(uint8_t)value result:(JLPSScreenLightCbk)block;
+
+/// 读取手电筒开关
+/// - Parameters:
+/// - manager: 设备
+/// - block: 回调
+-(void)cmdFlashLightGet:(JL_ManagerM *)manager result:(JLPSFlashLightCbk)block;
+
+/// 设置手电筒开关
+/// - Parameters:
+/// - manager: 设备
+/// - isOn: 开关
+/// - block: 回调
+-(void)cmdFlashLightSet:(JL_ManagerM *)manager Status:(BOOL)isOn result:(JLPSFlashLightCbk)block;
+
+
+/// 获取绑定设备状态
+/// - Parameters:
+/// - manager: 设备
+/// - block: 回调
+-(void)cmdDeviceBindStatusGet:(JL_ManagerM *)manager result:(JLPSBindStatusCbk)block;
+
+
+/// 获取功能使用资源设置(彩屏舱)
+/// - Parameters:
+/// - manager: 设备
+/// - funcType: 功能码
+/// 0x01 屏幕保护程序
+/// 0x02 开机动画
+/// - block: 回调
+-(void)cmdDeviceFuncUsedSourceGet:(JL_ManagerM *)manager Type:(uint8_t)funcType result:(JLPSSourceInfoCbk)block;
+
+/// 设置功能使用资源(彩屏舱)
+/// - Parameters:
+/// - manager: 设备
+/// - info: 设置内容对象
+/// - block: 回调
+-(void)cmdDeviceFuncUseSourceSet:(JL_ManagerM *)manager Info:(JLPublicSourceInfoModel *)info result:(JLPSSourceInfoCbk)block;
+
+
+/// 开始发起替换提示音
+/// - Parameters:
+/// - manager: 设备
+/// - info: 提示音包 tone.cfg 信息
+/// - block: 状态回调
+-(void)cmdDeviceReplaceTipsVoiceStart:(JL_ManagerM *)manager Info:(JLPublicTipsVoiceRpInfo *)info result:(JLPSTipsVoiceRpCbk)block;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLPublicSettingBlocks.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/12/1.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_TypeEnum.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+#define PUBLIC_SCREEN_LIGHT 0x0001 //屏幕亮度
+#define PUBLIC_FLASH_LIGHT 0x0002 //手电筒
+#define PUBLIC_DEVICE_BIND_STATUS 0x0003 //设备绑定
+#define PUBLIC_FUNC_SOURCE 0x0004 //功能使用资源(彩屏舱)
+#define PUBLIC_FUNC_4G 0x0005 //4G功能升级功能
+#define PUBLIC_TIPS_VOICE 0x0006 //替换提示音
+
+@class JLPublicBindDeviceModel;
+@class JLPublicSourceInfoModel;
+@class JLPublic4GModel;
+
+/// 屏幕亮度回调
+typedef void(^JLPSScreenLightCbk)(JL_CMDStatus status,uint8_t value);
+
+/// 手电筒开关
+typedef void(^JLPSFlashLightCbk)(JL_CMDStatus status,BOOL isOn);
+
+/// 绑定状态
+typedef void(^JLPSBindStatusCbk)(JL_CMDStatus status,JLPublicBindDeviceModel *_Nullable model);
+/// 彩屏舱资源
+typedef void (^JLPSSourceInfoCbk)(JL_CMDStatus status,JLPublicSourceInfoModel *_Nullable model);
+
+/// 4G模块升级回调
+typedef void (^JLPSSource4GCbk)(JL_CMDStatus status,JLPublic4GModel *_Nullable model);
+
+/// 替换提示音回调
+typedef void(^JLPSTipsVoiceRpCbk)(JL_CMDStatus status,uint8_t op);
+
+//MARK: - 绑定设备状态(彩屏舱)
+/// 绑定设备状态
+@interface JLPublicBindDeviceModel : NSObject
+
+/// 设备类型
+/// 1 耳机
+/// 2 充电仓
+@property(nonatomic,assign)uint8_t type;
+
+/// 经典蓝牙地址
+/// 若不支持经典蓝牙,此值为 0
+@property(nonatomic,copy)NSString *edrAddr;
+
+/// ble 蓝牙地址
+/// 若不支持 ble 蓝牙,此值为 0
+@property(nonatomic,copy)NSString *bleAddr;
+
+/// 连接状态
+/// 0 未连接
+/// 1 已连接
+/// 2 正在回连
+/// 0xff 不可连接
+@property(nonatomic,assign)uint8_t status;
+
+/// 连接方式
+/// 0 BLE
+/// 1 SPP
+@property(nonatomic,assign)uint8_t way;
+
++(JLPublicBindDeviceModel *)initData:(NSData *)data;
+@end
+
+//MARK: -公有设置的资源信息(彩屏舱)
+/// 公有设置的资源信息
+@interface JLPublicSourceInfoModel:NSObject
+
+/// 功能码
+/// 0x01 屏幕保护程序
+/// 0x02 开机动画
+@property(nonatomic,assign)uint8_t type;
+
+/// 存储器的句柄
+@property(nonatomic,copy)NSData *fileHandle;
+
+/// 文件簇号
+/// 设置时当前字段设为 0
+@property(nonatomic,assign)uint32_t cluster;
+
+/// 文件内容 CRC
+/// 设置时当前字段为 0
+@property(nonatomic,assign)uint16_t crc;
+
+/// 文件路径数据
+@property(nonatomic,strong)NSString *filePath;
+
+-(NSData *)beData;
+
++(JLPublicSourceInfoModel *)initData:(NSData *)data;
+
+@end
+
+//MARK: - 4G 模块基本信息
+
+/// 4G 模块基本信息
+@interface JLPublic4GModel:NSObject
+
+/// 供应商信息
+/// 0x01:紫光展锐
+/// 0x02:归芯科技
+@property(nonatomic,assign)uint8_t vendor;
+
+/// 强制升级标识位
+/// 0x00:不强制
+/// 0x01:强制升级
+@property(nonatomic,assign)uint8_t updateStatus;
+
+/// 版本
+@property(nonatomic,copy)NSString *version;
+
+/// 开始 OTA 等待时间
+@property(nonatomic,assign)NSTimeInterval startOtaMaxTimeout;
+
+/// 结束 OTA 等待时间
+@property(nonatomic,assign)NSTimeInterval endOtaMaxTimeout;
+
+
++(JLPublic4GModel *)initData:(NSData *)data;
+
+@end
+
+//MARK: - 替换提示音参数
+@interface JLPublicTipsVoiceRpInfo : NSObject
+
+/// 目标存储器句柄
+/// 这个要从 JLModel_Device 中获得
+/// JLModelCardInfo *cardInfo;
+@property(nonatomic,copy)NSData *devHandle;
+
+/// 下发的文件名
+@property(nonatomic,strong)NSString *fileName;
+
+/// 下发的文件内容
+@property(nonatomic,copy)NSData *sendData;
+
+-(NSData *)createData;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLSedentaryRmdModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 久坐提醒
+@interface JLSedentaryRmdModel : JLwSettingModel
+
+///开关
+@property(nonatomic,assign)BOOL status;
+
+/// 提醒模式
+@property(nonatomic,assign)WatchRemindType rType;
+
+/// 午休免打扰:关闭/打开(午休时段为12:00-14:00)
+@property(nonatomic,assign)BOOL doNotDisturb;
+
+/// 开始时间
+@property(nonatomic,strong)WatchTimer *begin;
+
+/// 结束时间
+@property(nonatomic,strong)WatchTimer *end;
+
+- (instancetype)initWithData:(NSData *)data;
+
+/// 创建一个设置久坐提醒的位置
+/// @param type 提醒模式
+/// @param status 开关
+/// @param dnd 午休免打扰
+/// @param start 开始时间
+/// @param ed 结束时间
+- (instancetype)initWithModel:(WatchRemindType)type Status:(BOOL)status DoNotDisturb:(BOOL)dnd Begin:(WatchTimer *)start End:(WatchTimer *)ed;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLSensorFuncModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+#import "JLWatchEnum.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+/// 传感器开关设置
+@interface JLSensorFuncModel : JLwSettingModel
+
+/// 计步器开关
+@property(nonatomic,assign)BOOL pedometerStatus;
+/// 计步器记录开关
+@property(nonatomic,assign)BOOL pedometerRecordStatus;
+/// 心率传感器开关
+@property(nonatomic,assign)BOOL heartRateStatus;
+/// 心率传感器记录开关
+@property(nonatomic,assign)BOOL heartRateRecordStatus;
+/// 血氧传感器开关
+@property(nonatomic,assign)BOOL bloodOxygenStatus;
+/// 血氧传感器记录开关
+@property(nonatomic,assign)BOOL bloodOxygenRecordStatus;
+///海拔气压传感器开关
+@property(nonatomic,assign)BOOL AltitudeAirPressureStatus;
+///海拔气压传感器记录开关
+@property(nonatomic,assign)BOOL AltitudeAirPressureRecordStatus;
+
+
+/// 传感器功能
+/// @param status 功能的开关状态
+-(void)setFuncBy:(JL_SENSOR_FUNC_SWITCH)status;
+
+/// @param funcByte 功能的开关状态
+-(instancetype)initWhthFuncByte:(JL_SENSOR_FUNC_SWITCH)funcByte;
+
+-(instancetype)initWithData:(NSData *)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLSleepMonitorModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 睡眠监测设置
+@interface JLSleepMonitorModel : JLwSettingModel
+///开关类型
+@property(nonatomic,assign)WatchSwitchType status;
+///开始时间
+@property(nonatomic,strong)WatchTimer *start;
+/// 结束时间
+@property(nonatomic,strong)WatchTimer *end;
+
+-(instancetype)initWithData:(NSData *)data;
+
+/// 构建一个睡眠监测设置
+/// @param status 状态开关
+/// @param begin 开始时间
+/// @param end 结束时间
+-(instancetype)initWithSwitchStatus:(WatchSwitchType)status Begin:(WatchTimer *)begin End:(WatchTimer *)end;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLSportDataModel.h
+// Test
+//
+// Created by EzioChan on 2021/4/6.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLSportDataModel : NSObject
+
+/// 设备的UUID
+@property(nonatomic,strong)NSString *dev_uuid;
+
+/// 请求内容数据
+@property(nonatomic,strong)NSData *rqData;
+
+/// 功能掩码
+@property(nonatomic,assign)uint32_t funcMask;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWatchEnum.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/8/2.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+extern NSString *_Nonnull const JL_Watch_HeartRate;
+extern NSString *_Nonnull const JL_Watch_AirPressure;
+extern NSString *_Nonnull const JL_Watch_Altitude;
+extern NSString *_Nonnull const JL_Watch_MoveSteps;
+extern NSString *_Nonnull const JL_Watch_Stress;
+extern NSString *_Nonnull const JL_Watch_Oxsaturation;
+extern NSString *_Nonnull const JL_Watch_MaxOxg;
+extern NSString *_Nonnull const JL_Watch_RecTime;
+extern NSString *_Nonnull const JL_Watch_SportMsg;
+extern NSString *_Nonnull const JL_Watch_WatchLog;
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_WATCH_LOG_MASK) {
+ /// 加速度
+ JL_WATCH_LOG_MASK_Acceleration = 0x80000000 >> 31,
+ /// 心率和血氧
+ JL_WATCH_LOG_MASK_HeartRate_BloodOxy = 0x80000000 >> 30,
+};
+
+typedef NS_ENUM(UInt8, JL_WATCH_LOG_TYPE) {
+ ///设备回的加速度
+ JL_WATCH_LOG_TYPE_Res_Acceleration = 0x00,
+ /// 设备回的心率血氧
+ JL_WATCH_LOG_TYPE_Res_HeartRate_BloodOxy = 0x01,
+};
+
+/// 运动记录标记包类型
+typedef NS_ENUM(UInt8, JL_SRMDataType) {
+ ///开始包
+ JL_SRM_Start = 0x00,
+ ///基础包
+ JL_SRM_Basic = 0x01,
+ ///暂停包
+ JL_SRM_Pause = 0x02,
+ ///每公里配速包
+ JL_SRM_Pace = 0x03,
+ ///结束包
+ JL_SRM_End = 0xff,
+};
+
+// 实时健康数据类型
+typedef NS_ENUM(UInt8, JL_SportDataType) {
+ ///心率
+ JL_SportDataTypeHeartRate = 0,
+ ///空气压强
+ JL_SportDataTypeAirPressure = 1,
+ ///海拔高度
+ JL_SportDataTypeAltitude = 2,
+ ///运动步数
+ JL_SportDataTypeMovementSteps = 3,
+ ///压力
+ JL_SportDataTypeStress = 4,
+ ///血氧饱和度
+ JL_SportDataTypeOxygenSaturation = 5,
+ ///训练负荷
+ JL_SportDataTypeTrainingLoad = 6,
+ ///最大摄氧量
+ JL_SportDataTypeMaxOxygenUptake = 7,
+ ///运动恢复时间
+ JL_SportDataTypeRecoveryTime = 8,
+ ///运动信息
+ JL_SportDataTypeSportMessage = 9,
+};
+
+// 运动模式
+typedef NS_ENUM(UInt8, JL_SportPattern) {
+ JL_SportPatternRun = 0, ///跑步
+ JL_SportPatternClimb = 1, ///爬山
+ JL_SportPatternSwim = 2, ///游泳
+};
+
+// 运动数据格式
+typedef NS_ENUM(UInt8, JL_SportDataFormat) {
+ JL_SportDataFormatBeUint8 = 1,
+ JL_SportDataFormatBeBigendUint16 = 2,
+ JL_SportDataFormatBeBigendUint32 = 4,
+};
+
+typedef NS_ENUM(UInt8, JL_WATCH_SETTING_MASK) {
+ JL_WATCH_SETTING_MASK_READ_INFO = 0x00,///App读取设备信息
+ JL_WATCH_SETTING_MASK_SET_INFO = 0x01,///向设备写入设置信 息
+ JL_WATCH_SETTING_MASK_RECIVE_INFO = 0x02,///收到设备推送设置信息
+};
+
+/// 查询读取设备信息
+///使用示例:
+/// 如查询:传感器、连续测量心率、跌到监察
+/// 则对应的uint32_t 为:0x0000008A
+/// 即对应的Bit位指示为:0000 0000 0000 0000 0000 0000 1000 1010
+/// Bit0:保留(考虑是否用于做功能支持位)------ 0
+/// Bit1:传感器功能
+/// Bit2:久坐提醒
+/// Bit3:连续测量心率
+/// Bit4:运动心率提醒
+/// Bit5:压力自动检测
+/// Bit6:睡眠检测
+/// Bit7:跌到监察
+/// Bit8:抬腕监察
+/// Bit9:个人信息
+/// Bit10:蓝牙断开提醒
+/// Bit11:血氧测量提醒
+/// Bit12:紧急联系人
+typedef NS_ENUM(uint32_t, JL_WATCH_SETTING) {
+ JL_WATCH_SETTING_SENSOR_FUNC = 0x0002, // Bit1:传感器功能
+ JL_WATCH_SETTING_SEDENTARY_REMIND = 0x0004, // Bit2:久坐提醒
+ JL_WATCH_SETTING_CONTINUOUS_HEARTRATE_MEASUREMENT = 0x0008, // Bit3:连续测量心率
+ JL_WATCH_SETTING_EXERCISE_HEARTRATE_REMINDER = 0x0010, // Bit4:运动心率提醒
+ JL_WATCH_SETTING_AUTOMATIC_PRESSURE_DETECTION = 0x0020, // Bit5:压力自动检测
+ JL_WATCH_SETTING_SLEEP_DETECTION = 0x0040, // Bit6:睡眠检测
+ JL_WATCH_SETTING_FALL_DETECTION = 0x0080, // Bit7:跌到监察
+ JL_WATCH_SETTING_LIFTWRIST_DETECTION = 0x0100, // Bit8:抬腕监察
+ JL_WATCH_SETTING_PERSONAL_INFO = 0x0200, // Bit9:个人信息
+ JL_WATCH_SETTING_BLUETOOTH_DISCONECTED_REMINDER = 0x0400, // Bit10:蓝牙断开提醒
+ JL_WATCH_SETTING_OXIMETRY = 0x0800, //Bit11:血氧测量提醒
+ JL_WATCH_SETTING_EMERGENCY_CONTACT = 0x1000, //Bit12:紧急联系人
+};
+
+/// 传感器功能开关
+/// ///使用示例:
+/// 如设置打开:计步器、计步器记录、血氧、血氧记录、海拔
+/// 则对应的uint16_t 为:0x73
+/// 即对应的Bit位指示为: 0111 0011
+/// Bit0:计步器开关
+/// Bit1:计步器记录开关
+/// Bit2:心率传感器开关
+/// Bit3:心率传感器记录开关
+/// Bit4:血氧传感器开关
+/// Bit5:血氧传感器记录开关
+/// Bit6:海拔气压传感器开关
+/// Bit7:海拔气压传感器记录开关
+typedef NS_ENUM(uint16_t, JL_SENSOR_FUNC_SWITCH) {
+ JL_SENSOR_FUNC_SWITCH_PEDOMETER = 0x01, // Bit0:计步器开关
+ JL_SENSOR_FUNC_SWITCH_PEDOMETER_RECORD = 0x02, // Bit1:计步器记录开关
+ JL_SENSOR_FUNC_SWITCH_HEARTRATE = 0x04, // Bit2:心率传感器开关
+ JL_SENSOR_FUNC_SWITCH_HEARTRATE_RECORD = 0x08, // Bit3:心率传感器记录开关
+ JL_SENSOR_FUNC_SWITCH_BLOODOXYGEN = 0x10, // Bit4:血氧传感器开关
+ JL_SENSOR_FUNC_SWITCH_BLOODOXYGEN_RECORD = 0x20, // Bit5:血氧传感器记录开关
+ JL_SENSOR_FUNC_SWITCH_ALTITUDE_AIRPRESSURE = 0x40, // Bit6:海拔气压传感器开关
+ JL_SENSOR_FUNC_SWITCH_ALTITUDE_AIRPRESSURE_RECORD = 0x80, // Bit7:海拔气压传感器记录开关
+};
+
+///运动状态同步相关命令
+typedef NS_ENUM(UInt8, JL_WearSyncStatus) {
+ /// 读取运动信息
+ JL_WearSyncStatus_ReadInfo = 0x00,
+ /// 开始运动
+ JL_WearSyncStatus_Start = 0x01,
+ /// APP结束运动
+ JL_WearSyncStatus_EndByApp = 0x02,
+ /// 固件结束运动
+ JL_WearSyncStatus_EndByDevice = 0x03,
+ /// 暂停运动
+ JL_WearSyncStatus_Pause = 0x04,
+ /// 继续运动
+ JL_WearSyncStatus_Continue = 0x05,
+ /// 请求运动实时数据
+ JL_WearSyncStatus_RealTimeInfoRequire = 0x06,
+};
+
+
+///运动状态
+typedef NS_ENUM(UInt8, WatchSportStatus) {
+ /// 暂停
+ WatchSportStatus_Pause = 0x00,
+ /// 运动中
+ WatchSportStatus_Motion = 0x01
+};
+
+///心率模式
+typedef NS_ENUM(UInt8, WatchHeartRateType) {
+ ///最大心率模式
+ WatchHeartRate_Max = 0x00,
+ ///存储心率模式
+ WatchHeartRate_Save = 0x01
+};
+/// 运动强度类型
+typedef NS_ENUM(UInt8, WatchExerciseIntensityType) {
+ ///非运动模式
+ WatchExercise_Not = 0x00,
+ ///最大心率模式:热身 储备心率模式:有氧基础
+ WatchExercise_Level1 = 0x01,
+ ///最大心率模式:燃脂 储备心率模式:有氧进阶
+ WatchExercise_Level2 = 0x02,
+ ///最大心率模式:有氧耐力 储备心率模式:乳酸阈值
+ WatchExercise_Level3 = 0x03,
+ ///最大心率模式:无氧耐力 储备心率模式:无氧基础
+ WatchExercise_Level4 = 0x04,
+ ///最大心率模式:极限 储备心率模式:无氧进阶
+ WatchExercise_Level5 = 0x05
+};
+///睡眠类型
+typedef NS_ENUM(UInt8, WatchSleepType) {
+ ///清醒
+ WatchSleep_WideAwake = 0xFF,
+ /// 浅睡
+ WatchSleep_Light = 0x01,
+ /// 深睡
+ WatchSleep_Deep = 0x02,
+ /// 快速眼动
+ WatchSleep_RapidEyeMovement = 0x03,
+ /// 零星小睡
+ WatchSleep_SporadicNaps = 0x04
+};
+
+
+@interface JLWatchEnum : NSObject
+
+/**
+ * 运动数据类型转换为运动数据格式
+ * @param sportDataType 运动数据类型
+ * @return JL_SportDataFormat 运动数据格式
+ */
++ (JL_SportDataFormat)sportDataFormatFromSportDataType:(JL_SportDataType)sportDataType;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWearSync.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/26.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_RCSP.h"
+#import "JLWatchEnum.h"
+#import "JL_EntityM.h"
+#import "JL_SDM_Header.h"
+#import "JL_WatchSyncProtocol.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 穿戴设备状态同步指令
+@interface JLWearSync : NSObject
+
++(instancetype)share;
+
+/// 加入协议响应
+/// @param delegate 对象
+-(void)addProtocol:(id<JLWearSyncProtocol>)delegate;
+
+/// 移除协议响应
+/// @param delegate 对象
+-(void)removeProtocol:(id<JLWearSyncProtocol>)delegate;
+
+/// 读取运动信息
+/// @param entity 设备entity
+/// @param block JLWearSyncInfoModel 回调
+/// 本条命令的回调通过JLWearSyncProtocol协议
+///-(void)jlWearSyncSportInfo:(JLWearSyncInfoModel *_Nonnull)model;
+-(void)w_requireSportInfoWith:(JL_EntityM *)entity Block:(JL_CB_SyncSportInfo _Nullable)block;
+
+///开始运动命令
+/// @param type 运动类型
+/// 0x00 :非运动模式
+/// 0x01 :室外跑步
+/// 0x02 :室内跑步
+/// @param entity 设备entity
+/// @param block 命令成功与否回调
+-(void)w_SportStart:(uint8_t)type With:(JL_EntityM *)entity Block:(JL_CB_Status _Nullable)block;
+
+/// 结束运动命令
+/// @param entity 设备entity
+///本条命令的回调通过JLWearSyncProtocol协议
+///-(void)jlWearSyncStopMotion:(JLWearSyncFinishModel *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+-(void)w_SportFinishWith:(JL_EntityM*)entity;
+
+///暂停运动命令
+/// @param entity 设备entity
+/// @param block 命令成功与否回调
+-(void)w_SportPauseWith:(JL_EntityM*)entity Block:(JL_CB_Status _Nullable)block;
+
+///继续运动命令
+/// @param entity 设备entity
+/// @param block 命令成功与否回调
+-(void)w_SportContinueWith:(JL_EntityM*)entity Block:(JL_CB_Status _Nullable)block;
+
+/// 读取运动实时数据
+/// @param entity 设备entity
+///本条命令的回调通过JLWearSyncProtocol协议
+-(void)w_requireRealTimeSportInfoWith:(JL_EntityM *)entity;
+
+/// 实时数据获取时间间隔设置
+/// @param interval 时间间隔,单位:ms
+/// @param entity 设备entity
+-(void)pr_setTimeInterval:(UInt16)interval With:(JL_EntityM *)entity;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWearSyncCustom.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/4/13.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_RCSP.h"
+#import "JL_EntityM.h"
+#import "JL_SDM_Header.h"
+
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol JLWearSyncCustomPtl <NSObject>
+
+/// 运动信息返回
+/// @param model 运动信息对象
+/// @param entity 设备entity
+-(void)jlWearSyncSportInfo:(JLWearSyncDataModel *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+
+/// 结束运动返回内容
+/// @param model 结束时间相隔信息对象
+/// @param entity 设备entity
+-(void)jlWearSyncStopMotion:(JLWearSyncFinishDataModel *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+
+/// 开始运动返回消息
+/// @param entity 设备entity
+-(void)jlWearSyncStartMotionWith:(JL_EntityM *_Nonnull)entity;
+
+/// 暂停运动
+/// @param entity 设备entity
+-(void)jlWearSyncStatusPauseWith:(JL_EntityM *_Nonnull)entity;
+
+/// 继续运动
+/// @param entity 设备entity
+-(void)jlWearSyncStatusContiuneWith:(JL_EntityM *_Nonnull)entity;
+
+/// 实时数据回调
+/// @param model 实时数据模型
+/// @param entity 设备entity
+-(void)jlWearSyncRealTimeData:(JLWearSyncRealTimeData *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+
+@end
+
+
+
+@interface JLWearSyncCustom : NSObject
+
+@property(nonatomic,weak)id<JLWearSyncCustomPtl> delegate;
+
+/// 读取运动信息
+/// @param entity 设备entity
+/// @param block JLWearSyncInfoModel 回调
+/// 本条命令的回调通过JLWearSyncProtocol协议
+///-(void)jlWearSyncSportInfo:(JLWearSyncInfoModel *_Nonnull)model;
+-(void)w_requireSportInfoWith:(JL_EntityM *)entity Block:(JL_CB_SyncSportDataInfo _Nullable)block;
+
+///开始运动命令
+/// @param type 运动类型
+/// @param entity 设备entity
+/// @param block 命令成功与否回调
+-(void)w_SportStart:(UInt8)type With:(JL_EntityM *)entity Block:(JL_CB_Status _Nullable)block;
+
+/// 结束运动命令
+/// @param entity 设备entity
+///本条命令的回调通过JLWearSyncProtocol协议
+///-(void)jlWearSyncStopMotion:(JLWearSyncFinishModel *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+-(void)w_SportFinishWith:(JL_EntityM*)entity;
+
+///暂停运动命令
+/// @param entity 设备entity
+/// @param block 命令成功与否回调
+-(void)w_SportPauseWith:(JL_EntityM*)entity Block:(JL_CB_Status _Nullable)block;
+
+///继续运动命令
+/// @param entity 设备entity
+/// @param block 命令成功与否回调
+-(void)w_SportContinueWith:(JL_EntityM*)entity Block:(JL_CB_Status _Nullable)block;
+
+/// 读取运动实时数据
+/// @param entity 设备entity
+///本条命令的回调通过JLWearSyncProtocol协议
+-(void)w_requireRealTimeSportInfoWith:(JL_EntityM *)entity;
+
+/// 实时数据获取时间间隔设置
+/// @param interval 时间间隔,单位:ms
+/// @param entity 设备entity
+-(void)pr_setTimeInterval:(UInt16)interval With:(JL_EntityM *)entity;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWearSyncFinishModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/27.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JLWatchEnum.h"
+NS_ASSUME_NONNULL_BEGIN
+
+
+@interface JLWearSyncFinishDataModel:NSObject
+
+@property(nonatomic,strong)NSData *basicData;
+
+@end
+
+
+@interface JLWatchExerciseIntens:NSObject
+
+/// 运动强度类型
+@property(nonatomic,assign)WatchExerciseIntensityType type;
+
+/// 持续时间
+@property(nonatomic,assign)UInt32 duration;
+
+@end
+
+@interface JLWearSyncFinishModel : JLWearSyncFinishDataModel
+
+/// 结束时间
+@property(nonatomic,strong)NSDate *endTime;
+
+/// 运动恢复时间
+/// 格式 :hour : min
+@property(nonatomic,strong)NSString *recyleTime;
+
+/// 运动记录文件ID
+@property(nonatomic,assign)UInt16 sportId;
+
+/// 运动记录文件大小
+@property(nonatomic,assign)UInt16 fileSize;
+
+/// 运动强度类型数组
+@property(nonatomic,strong)NSArray <JLWatchExerciseIntens *> *durationArray;
+
+
++(JLWearSyncFinishModel *)initWithData:(NSData*)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWearSyncInfoModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/27.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JLWatchEnum.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLWearSyncDataModel : NSObject
+
+/// 基础返回对象
+@property(nonatomic,strong)NSData *basicData;
+
+@end
+
+
+@interface JLWearSyncInfoModel : JLWearSyncDataModel
+
+///运动模式类型
+/// 0x00 非运动模式
+/// 0x01 户外跑步
+/// 0x02 室内跑步
+@property(nonatomic,assign)uint8_t sportType;
+
+/// 运动状态
+@property(nonatomic,assign)WatchSportStatus status;
+
+///运动Id
+@property(nonatomic,assign)double sportID;
+
+///设备是否包含GPS
+@property(nonatomic,assign)BOOL hasGPS;
+
+///心率模式
+@property(nonatomic,assign)WatchHeartRateType heartRateType;
+
+///建议实时数据读取时间间隔,单位:ms
+@property(nonatomic,assign)UInt16 interval;
+
+/// 利用设备返回的数据初始化一个运动信息对象
+/// @param data 设备返回数据
++(JLWearSyncInfoModel *)initWithData:(NSData *)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWearSyncRealTimeModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/27.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JLWatchEnum.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+@interface JLWearSyncRealTimeData : NSObject
+
+@property(nonatomic,strong)NSData *basicData;
+
+@end
+
+@interface JLWearSyncRealTimeModel : JLWearSyncRealTimeData
+
+/// 类型
+@property(nonatomic,assign)UInt8 type;
+
+/// 运动步数
+@property(nonatomic,assign)UInt32 sportStep;
+
+/// 运动距离,单位:0.01公里
+@property(nonatomic,assign)UInt16 distance;
+
+/// 运动时长:单位:秒
+@property(nonatomic,assign)UInt32 exerciseTime;
+
+/// 速度,单位0:0.01公里/小时,(倒数为配速,单位:秒/公里)
+@property(nonatomic,assign)UInt16 speed;
+
+/// 热量,单位:千卡
+@property(nonatomic,assign)UInt16 calories;
+
+/// 步频,单位:步/分钟
+@property(nonatomic,assign)UInt16 cadence;
+
+///步幅,单位:厘米
+@property(nonatomic,assign)UInt16 stride;
+
+///实时运动强度状态
+@property(nonatomic,assign)WatchExerciseIntensityType statusType;
+
+///运动实时心率
+@property(nonatomic,assign)UInt8 heartRate;
+
++(JLWearSyncRealTimeModel *)initWithData:(NSData *)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWearable.h
+// Test
+//
+// Created by EzioChan on 2021/4/6.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_RCSP.h"
+#import "JL_EntityM.h"
+#import "JL_SDM_Header.h"
+#import "JL_WatchProtocol.h"
+#import "JLWearSync.h"
+#import "JLWearSyncCustom.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+#define JL_RECIVED_DATA @"JL_RECIVED_DATA"
+
+
+/// 穿戴设备基础命令控制
+@interface JLWearable : NSObject
+
+@property(nonatomic,assign,readonly)uint8_t version;
+@property(nonatomic,strong)JL_CB_HeartRate heartRate;
+@property(nonatomic,strong)JL_CB_AirPressure airPressure;
+@property(nonatomic,strong)JL_CB_Altitude alititude;
+@property(nonatomic,strong)JL_CB_MoveSteps moveStep;
+@property(nonatomic,strong)JL_CB_Stress stress;
+@property(nonatomic,strong)JL_CB_Oxsaturation oxStaturation;
+@property(nonatomic,strong)JL_CB_TrainLoad trainLoad;
+@property(nonatomic,strong)JL_CB_MaxOxg maxOxg;
+@property(nonatomic,strong)JL_CB_RecTime rectime;
+@property(nonatomic,strong)JL_CB_SportMsg sportMsg;
+@property(nonatomic,strong)JL_CB_WatchLog logMsg;
+@property(nonatomic,strong,readonly)JL_EntityM* responseEntity;
+
++(instancetype)sharedInstance;
+
+/// 把对象加入协议
+/// @param delegate 对象
+-(void)w_addDelegate:(id<JL_WatchProtocol>)delegate;
+
+/// 移除对象的协议
+/// @param delegate 对象
+-(void)w_removeDelegate:(id<JL_WatchProtocol>)delegate;
+
+/// 移除所有对象的协议
+-(void)w_removeAll;
+
+/// 请求穿戴设备的数据
+/// 使用例子:
+/**
+ JLWearable *w = [JLWearable sharedInstance];
+ NSMutableArray *array = [NSMutableArray new];
+ [array addObject:[JL_SDM_HeartRate requireRealTime:YES Resting:YES Max:YES]];
+ [array addObject:[JL_SDM_Altitude requireRealTime:YES min:NO Max:NO]];
+ [array addObject:[JL_SDM_MoveSteps require]];
+ w.heartRate = ^(JL_SDM_HeartRate *heartRate) {
+ //心率信息
+ };
+ w.alititude = ^(JL_SDM_Altitude *altitude) {
+ //海拔信息
+ };
+ JL_EntityM *entity = [[JL_EntityM alloc] init];
+ [w requestSportData:array withEntity:entity];
+*/
+/// @param reqModels 数据模型,可参考JL_SDM_相关的类型请求,这是个父类,这里是通过多态的方式来实现选择性的请求
+/// @param entity 当前设备的entity
+///
+-(void)w_requestSportData:(NSMutableArray<JLSportDataModel *>*)reqModels withEntity:(JL_EntityM *)entity;
+
+/// 私有测试接口
+/// @param data 数据
+/// @param entity 当前设备entity
+/// @param opcode 操作
+-(void)pr_requestSportDataMask:(NSData *)data withEntity:(JL_EntityM *)entity opCode:(uint16_t)opcode;
+
+
+/// 收到数据解析
+/// @param pkg 收到的数据包
+/// @param entity 当前的entity
+-(void)w_inputPKG:(JL_PKG*)pkg withEntity:(JL_EntityM *)entity;
+
+/// 推送天气到手表
+/// @param weather 天气内容
+/// @param entity 服务对象
+/// @param block 推送回调
+-(void)w_syncWeather:(JL_MSG_Weather *)weather withEntity:(JL_EntityM *)entity result:(JL_CB_Status)block;
+
+
+/**
+ 请求设备传感器的log
+ 使用示例
+ [[JLWearable shareInstance] w_transportLog:Log_Acceleration | Log_HeartRate_BloodOxy withEntity:entity];
+ */
+/// 请求设备传感器的log
+/// @param model 请求类型(Log_Acceleration | Log_HeartRate_BloodOxy)
+/// @param entity 当前的entity
+-(void)w_transportLog:(JL_WATCH_LOG_MASK)model withEntity:(JL_EntityM *)entity;
+
+
+//MARK: - 设备设置命令
+
+/// 查询读取设备信息
+/// @param target JL_WATCH_SETTING枚举,支持|运算同时设置多个设备类型信息
+/// @param entity 当前的entity
+/// /// 本方法的返回结果,需要接收对应的协议:JL_WatchProtocol ,并把遵循协议的对象加入到本单例中
+/// -(void)w_addDelegate:(id<JL_WatchProtocol>)delegate;
+-(void)w_InquireDeviceFuncWith:(JL_WATCH_SETTING)target withEntity:(JL_EntityM *)entity;
+
+/// 向设备写入设置信息
+/// @param models 设置对应的功能模型
+/// @param entity 当前的entity
+/// @param block 回复设置的状态
+/// 使用示例:
+/// 如设置:传感器、久坐提醒、蓝牙断开提醒
+/// NSMutableArray <JLwSettingModel *>* models = [NSMutableArray new];
+/// /*计步相关传感器*/
+/// JLSensorFuncModel *model = [[JLSensorFuncModel alloc] initWhthFuncByte:0x0073];//详情设置可参考相关接口
+/// [models addObject:model];
+/// /*久坐设置*/
+/// JLSedentaryRmdModel *model1 = [[JLSedentaryRmdModel alloc] initWithModel:s_Shake Status:true];
+/// [models addObject:model1];
+/// /*蓝牙断开提醒*/
+/// JLDisconnectRemindModel *model2 = [[JLDisconnectRemindModel alloc] initWithModel:s_BrightScreen Status:true];
+/// [models addObject:model2];
+/// [[JLWearable sharedInstance] w_SettingDeviceFuncWith:models withEntity:requestEntity]
+/// 本方法的返回结果,需要接收对应的协议:JL_WatchProtocol ,并把遵循协议的对象加入到本单例中
+/// -(void)w_addDelegate:(id<JL_WatchProtocol>)delegate;
+-(void)w_SettingDeviceFuncWith:(NSArray <JLwSettingModel *> *)models withEntity:(JL_EntityM *)entity result:(JL_CB_Status)block;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JLWristLiftDetectionModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLwSettingModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 抬腕监测设置
+@interface JLWristLiftDetectionModel : JLwSettingModel
+///开关
+@property(nonatomic,assign)WatchSwitchType status;
+/// 提醒模式
+@property(nonatomic,assign)WatchRemindType rType;
+/// 开始时间
+@property(nonatomic,strong)WatchTimer *start;
+
+/// 结束时间
+@property(nonatomic,strong)WatchTimer *end;
+
+
+-(instancetype)initWithData:(NSData *)data;
+
+/// 构建一个抬腕提醒设置对象
+/// @param type 提醒类型
+/// @param status 开关类型
+/// @param begin 开始时间
+/// @param ed 结束时间
+- (instancetype)initWithModel:(WatchRemindType)type Status:(WatchSwitchType )status Begin:(WatchTimer *)begin End:(WatchTimer *)ed;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_AlarmClockManager.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/12/16.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JLModel_AlarmSetting.h>
+#import <JL_BLEKit/RTC_RingInfo.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JLModel_RTC.h>
+#import <JL_BLEKit/JLModel_Ring.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_RtcOperate) {
+ JL_FlashOperateFlagRead = 0x00, //读取
+ JL_FlashOperateFlagWrite = 0x01, //设置
+};
+
+typedef void(^JL_RTC_ALARM_BK)(NSArray <JLModel_AlarmSetting *>* __nullable array, uint8_t flag);
+
+typedef void(^JL_RTC_GET_ALARM_BK)(NSArray <JLModel_RTC *>* __nullable alarms,NSError * __nullable error);
+
+#pragma mark ---> 闹钟响与停止
+///闹钟正在响
+extern NSString *kJL_MANAGER_RTC_RINGING;
+
+///闹钟停止响
+extern NSString *kJL_MANAGER_RTC_RINGSTOP;
+
+//闹钟铃声试听
+extern NSString *kJL_MANAGER_RTC_AUDITION;
+
+
+/// RTC闹钟管理者
+@interface JL_AlarmClockManager : JL_FunctionBaseManager
+
+///RTC 版本
+@property (assign,nonatomic) uint8_t rtcVersion;
+///是否支持闹铃设置
+@property (assign,nonatomic) JL_RTCAlarmType rtcAlarmType;
+///设备当前时间
+@property (strong,nonatomic) JLModel_RTC *rtcModel;
+///设备闹钟数组
+@property (strong,nonatomic) NSMutableArray<JLModel_RTC *> *rtcAlarms;
+///默认铃声
+@property (strong,nonatomic) NSMutableArray<JLModel_Ring *> *rtcDfRings;
+
+
+/// 查询设备闹钟
+/// - Parameter result: 设备回调
+-(void)cmdRtcGetAlarms:(JL_RTC_GET_ALARM_BK)result;
+
+
+/// 设置/增加闹钟
+/// - Parameters:
+/// - array: array 闹钟模型数组
+/// - result: 结果回调
+-(void)cmdRtcSetArray:(NSArray<JLModel_RTC *>*)array Result:(JL_CMD_RESPOND __nullable)result;
+
+
+/// 删除闹钟
+/// - Parameters:
+/// - array: 闹钟序号数组
+/// - result: 设备回复
+-(void)cmdRtcDeleteIndexArray:(NSArray<NSNumber *>*)array Result:(JL_CMD_RESPOND __nullable)result;
+
+
+/// 停止闹钟响声
+/// - Parameter result: 设备回复
+-(void)cmdRtcStopResult:(JL_CMD_RESPOND __nullable)result;
+
+
+/// 闹钟试听响铃
+/// - Parameters:
+/// - rtc: 闹钟模型
+/// - option: 启停标记
+/// - result: 设备回复
+-(void)cmdRtcAudition:(JLModel_RTC *)rtc Option:(BOOL)option result:(JL_CMD_RESPOND __nullable)result;
+
+
+/// 闹铃设置
+/// @param operate 0x00:读取 0x01:设置
+/// @param index 掩码 (0x01设置第1个闹钟,0x03设置第一个和第二个闹钟)
+/// @param setting 设置选项,读取时无需传入
+/// @param result 设备回复
+-(void)cmdRtcOperate:(JL_RtcOperate)operate
+ Index:(uint8_t)index
+ Setting:(JLModel_AlarmSetting* __nullable)setting
+ Result:(JL_RTC_ALARM_BK __nullable)result;
+
+
+/// 解析闹钟数据内容
+/// @param infoData 数据内容
+/// @param ltvVersion LTV的版本
+-(void)parseData:(NSData *)infoData WithLtyType:(uint8_t)ltvVersion;
+
+/// 【闹钟信息】解析
+/// - Parameters:
+/// - data: 需要解析的数据
+/// - rtcType: RTC类型
++(NSMutableArray<JLModel_RTC*> *)makeOutRtc:(NSData*)data RtcType:(uint8_t)rtcType;
+
+
+/// [默认闹钟铃声]解析
+/// - Parameter data: [默认闹钟铃声]数据
++(NSMutableArray<JLModel_Ring*> *)makeOutRtcDefaultRing:(NSData *)data;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_Assist.h
+// QCY_Demo
+//
+// Created by 杰理科技 on 2021/8/12.
+// Copyright © 2021 杰理科技. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <CoreBluetooth/CoreBluetooth.h>
+
+NS_ASSUME_NONNULL_BEGIN
+typedef void(^JL_Assist_BK)(BOOL isPaired);
+
+@class JL_ManagerM;
+
+@interface JL_Assist : NSObject
+@property(strong,nonatomic)JL_ManagerM *mCmdManager; //命令中心
+@property(strong,nonatomic)NSString *mService; //服务号
+@property(strong,nonatomic)NSString *mRcsp_W; //特征:RCSP写
+@property(strong,nonatomic)NSString *mRcsp_R; //特征:RCSP读
+@property(strong,nonatomic)NSData *__nullable mPairKey; //握手(配对)秘钥
+@property(assign,nonatomic)BOOL mNeedPaired; //是否需要配对
+@property(assign,nonatomic)BOOL mLogData; //是否打印裸数据
+@property(assign,nonatomic)NSInteger mLimitMtu; //(默认40)在最大的MTU基础上减少数据量
+
+/// Execute in a method 「- (void)centralManagerDidUpdateState:」
+/// @param state CBManagerState
+-(void)assistUpdateState:(CBManagerState)state;
+
+/// Execute in a method 「- (void)centralManager:didDisconnectPeripheral:error:」
+/// @param peripheral CBPeripheral
+-(void)assistDisconnectPeripheral:(CBPeripheral *)peripheral;
+
+
+/// Execute in a method 「- (void)peripheral:didDiscoverServices:」
+/// @param service CBService
+/// @param peripheral CBPeripheral
+-(void)assistDiscoverCharacteristicsForService:(CBService*)service
+ Peripheral:(CBPeripheral*)peripheral;
+
+/// Execute in a method 「- (void)peripheral:didUpdateNotificationStateForCharacteristic:error:」
+/// @param characteristic CBCharacteristic
+/// @param peripheral CBPeripheral
+/// @param result JL_Assist_BK (YES:配对成功 NO:配对失败)
+-(void)assistUpdateCharacteristic:(nonnull CBCharacteristic *)characteristic
+ Peripheral:(CBPeripheral*)peripheral
+ Result:(JL_Assist_BK)result;
+
+/// Execute in a method 「- (void)peripheral:didUpdateValueForCharacteristic:error:」
+/// @param characteristic CBCharacteristic
+-(void)assistUpdateValueForCharacteristic:(CBCharacteristic *)characteristic;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_BLEAction.h
+// JL_BLEKit
+//
+// Created by zhihui liang on 2018/11/10.
+// Copyright © 2018 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * BLE数据通知
+ */
+extern NSString *kJL_RCSP_RECEIVE; //Rcsp数据【接收】
+extern NSString *kJL_RCSP_SEND; //Rcsp数据【发送】
+
+
+typedef void(^ATC_Block)(BOOL ret);
+@protocol JL_BLEActionDelegate <NSObject>
+@optional
+-(void)onPairOutputData:(NSData*)data;
+
+@end
+
+@interface JL_BLEAction : NSObject
+@property(nonatomic,weak)id<JL_BLEActionDelegate>delegate;
+
++(id)sharedMe;
+
+/**
+ 过滤其余蓝牙设备
+ @param key 过滤码
+ @param advertData 蓝牙广播字典
+ @return NSDictionary 广播包含信息字典
+ */
++(NSDictionary*)bluetoothKey_1:(NSData*)key Filter:(NSDictionary*)advertData;
+
+/**
+ 蓝牙设备配对
+ @param pKey 配对码
+ @param bk 配对回调YES:成功 NO:失败
+ */
+-(void)bluetoothPairingKey:(NSData *__nullable)pKey Result:(ATC_Block)bk;
+-(void)inputPairData:(NSData*)rData;
+
+#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
--- /dev/null
+//
+// JL_BLEKit.h
+// JL_BLEKit
+//
+// Created by zhihui liang on 2018/11/9.
+// Copyright © 2018 www.zh-jieli.com. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import <Foundation/Foundation.h>
+//! Project version number for JL_BLEKit.
+FOUNDATION_EXPORT double JL_BLEKitVersionNumber;
+
+//! Project version string for JL_BLEKit.
+FOUNDATION_EXPORT const unsigned char JL_BLEKitVersionString[];
+
+#import <JL_BLEKit/JL_Tools.h>
+#import <JL_BLEKit/JL_RCSP.h>
+#import <JL_BLEKit/JL_OpCode.h>
+#import <JL_BLEKit/JL_Handle.h>
+#import <JL_BLEKit/JL_BLEAction.h>
+#import <JL_BLEKit/JL_vad.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+
+#import <JL_BLEKit/JLModel_Device.h>
+#import <JL_BLEKit/JLModel_RTC.h>
+#import <JL_BLEKit/JLModel_Ring.h>
+#import <JL_BLEKit/JLModel_File.h>
+#import <JL_BLEKit/JLModel_FM.h>
+#import <JL_BLEKit/JLModel_Headset.h>
+#import <JL_BLEKit/JLModel_BT.h>
+#import <JL_BLEKit/JLModel_EQ.h>
+#import <JL_BLEKit/JLModel_SPEEX.h>
+#import <JL_BLEKit/JLModel_Flash.h>
+#import <JL_BLEKit/JLModel_ANC.h>
+#import <JL_BLEKit/JLModel_AlarmSetting.h>
+#import <JL_BLEKit/RTC_RingInfo.h>
+#import <JL_BLEKit/JLModel_SmallFile.h>
+#import <JL_BLEKit/JLCmdBasic.h>
+#import <JL_BLEKit/JLModelVocalBoost.h>
+#import <JL_BLEKit/JLModelNoiseDetection.h>
+#import <JL_BLEKit/JLModelSceneNoiseReduction.h>
+#import <JL_BLEKit/JLModelSmartPickFree.h>
+
+#import <JL_BLEKit/JL_BLEMultiple.h>
+#import <JL_BLEKit/JL_EntityM.h>
+#import <JL_BLEKit/JL_ManagerM.h>
+#import <JL_BLEKit/JL_Assist.h>
+
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_FileManager.h>
+#import <JL_BLEKit/JL_SmallFileManager.h>
+#import <JL_BLEKit/JL_FlashOperateManager.h>
+#import <JL_BLEKit/JL_BinChargeManager.h>
+#import <JL_BLEKit/JL_CallManager.h>
+#import <JL_BLEKit/JL_AlarmClockManager.h>
+#import <JL_BLEKit/JL_LightManager.h>
+#import <JL_BLEKit/JL_TwsManager.h>
+#import <JL_BLEKit/JL_SoundCardManager.h>
+#import <JL_BLEKit/JL_LrcManager.h>
+#import <JL_BLEKit/JL_SpeexManager.h>
+#import <JL_BLEKit/JL_SpeechAIttsHandler.h>
+#import <JL_BLEKit/JL_FindDeviceManager.h>
+#import <JL_BLEKit/JL_MusicControlManager.h>
+#import <JL_BLEKit/JLDevPlayerCtrl.h>
+#import <JL_BLEKit/JL_FmManager.h>
+#import <JL_BLEKit/JL_SystemEQ.h>
+#import <JL_BLEKit/JL_SystemTime.h>
+#import <JL_BLEKit/JL_SystemVolume.h>
+#import <JL_BLEKit/JL_CustomManager.h>
+#import <JL_BLEKit/JL_BatchManger.h>
+#import <JL_BLEKit/JL_DeviceLogs.h>
+#import <JL_BLEKit/JLDhaFitting.h>
+#import <JL_BLEKit/JLAutoConfigAnc.h>
+#import <JL_BLEKit/JLDeviceConfig.h>
+#import <JL_BLEKit/JL_BigDataManager.h>
+#import <JL_BLEKit/JLAiManager.h>
+#import <JL_BLEKit/JLAIDialManager.h>
+
+
+#import <JL_BLEKit/JLWearable.h>
+#import <JL_BLEKit/JLSportDataModel.h>
+#import <JL_BLEKit/JL_SDM_Stress.h>
+#import <JL_BLEKit/JL_SDM_Altitude.h>
+#import <JL_BLEKit/JL_SDM_MaxOxg.h>
+#import <JL_BLEKit/JL_SDM_RecTime.h>
+#import <JL_BLEKit/JL_SDM_HeartRate.h>
+#import <JL_BLEKit/JL_SDM_MoveSteps.h>
+#import <JL_BLEKit/JL_SDM_TrainLoad.h>
+#import <JL_BLEKit/JL_SDM_AirPressure.h>
+#import <JL_BLEKit/JL_SDM_OxSaturation.h>
+#import <JL_BLEKit/JL_SDM_SportMessage.h>
+#import <JL_BLEKit/JL_SDM_Header.h>
+#import <JL_BLEKit/NSData+ToUnit.h>
+#import <JL_BLEKit/JL_MSG_Weather.h>
+#import <JL_BlEKit/JL_MSG_Func.h>
+#import <JL_BLEKit/JL_NFC.h>
+#import <JL_BLEKit/JLWatchEnum.h>
+#import <JL_BLEKit/JL_WatchProtocol.h>
+
+#import <JL_BLEKit/ECThreadHelper.h>
+#import <JL_BLEKit/JLHttpHelper.h>
+#import <JL_BLEKit/ECBDTObjc.h>
+#import <JL_BLEKit/ECBDTManager.h>
+#import <JL_BLEKit/JLModelDevFunc.h>
+#import <JL_BLEKit/JLModelCardInfo.h>
+#import <JL_BLEKit/JLPublicSetting.h>
+#import <JL_BLEKit/JL4GUpgradeManager.h>
+#import <JL_BLEKit/JLDeviceConfigTws.h>
+#import <JL_BLEKit/JLDialInfoExtentedModel.h>
+#import <JL_BLEKit/JLDialInfoExtentManager.h>
+
+
--- /dev/null
+//
+// JL_BLEMultiple.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2020/9/1.
+// Copyright © 2020 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <AVFoundation/AVFoundation.h>
+#import <CoreBluetooth/CoreBluetooth.h>
+#import <UIKit/UIKit.h>
+
+#import <JL_BLEKit/JL_EntityM.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * BLE状态通知
+ */
+extern NSString *kJL_BLE_M_FOUND; //发现设备
+extern NSString *kJL_BLE_M_FOUND_SINGLE; //发现单个设备
+extern NSString *kJL_BLE_M_ENTITY_CONNECTED; //连接有更新
+extern NSString *kJL_BLE_M_ENTITY_DISCONNECTED; //断开连接
+extern NSString *kJL_BLE_M_ON; //BLE开启
+extern NSString *kJL_BLE_M_OFF; //BLE关闭
+extern NSString *kJL_BLE_M_EDR_CHANGE; //经典蓝牙输出通道变化
+extern NSString *kJL_BLE_M_SAVE_BLEADDR; //存储EDR地址
+extern NSString *kJL_BLE_M_ANCS_UPDATE; //设备ANCS权限变更
+
+
+@interface JL_BLEMultiple : NSObject
+@property (strong, nonatomic) NSData *__nullable filterKey; //过滤码
+@property (strong, nonatomic) NSData *__nullable pairKey; //配对码
+@property (assign, nonatomic) BOOL BLE_IS_CONNECTING; //是否有设备正在连接
+@property (assign, nonatomic) BOOL BLE_FILTER_ENABLE; //是否【开启过滤】
+@property (assign, nonatomic) BOOL BLE_PAIR_ENABLE; //是否【开启配对】
+@property (assign, nonatomic) int BLE_TIMEOUT; //连接超时时间
+
+@property (strong, nonatomic) NSMutableArray<JL_EntityM *> *blePeripheralArr; //发现的设备
+@property (strong, nonatomic) NSMutableArray<JL_EntityM *> *bleConnectedArr; //已连接的设备
+@property (assign, nonatomic) CBManagerState bleManagerState; //蓝牙状态
+@property (strong, nonatomic) NSArray<NSNumber *> *__nullable bleDeviceTypeArr; //选择的设备类型<@(JL_DeviceType)>
+@property (strong, nonatomic) NSArray<NSNumber *> *__nullable managerClassArr; //实例化的业务逻辑<@(JL_CLASS)>
+
+
+@property (strong, nonatomic) NSString *JL_BLE_SERVICE; //服务号
+@property (strong, nonatomic) NSString *JL_BLE_RCSP_W; //命令【写】通道
+@property (strong, nonatomic) NSString *JL_BLE_RCSP_R; //命令【读】通道
+
++(NSString*)versionOfSDK;
+
+/**
+ 开始搜索
+ */
+-(void)scanStart;
+
+/**
+ 继续搜索
+ */
+-(void)scanContinue;
+
+/**
+ 停止搜索
+ */
+-(void)scanStop;
+
+
+/// 蓝牙中心管理器
+-(CBCentralManager *)getCenterManaer;
+
+/**
+ 通过UUID生成Entity。
+ */
+-(JL_EntityM *_Nullable)makeEntityWithUUID:(NSString*)uuid;
+
+/// 通过UUID获得一个已连接过的entity
+/// @param uuid uuid
+/// @param status 获取后是否继续蓝牙搜索
+/// @param result 结果
+-(void)getEntityWithSearchUUID:(NSString *)uuid SearchStatus:(BOOL)status Result:(void(^)(JL_EntityM *_Nullable entity))result;
+/**
+ 连接设备
+ @param entity 蓝牙设备类
+ */
+-(void)connectEntity:(JL_EntityM*)entity Result:(JL_EntityM_STATUS_BK)result;
+
+/// 根据设备Mac去回连
+/// @param mac Mac地址
+/// @param result 回调
+-(void)connectEntityForMac:(NSString *)mac Result:(JL_EntityM_STATUS_BK)result;
+
+/**
+ 断开连接
+ */
+-(void)disconnectEntity:(JL_EntityM*)entity Result:(JL_EntityM_STATUS_BK)result;
+
+/**
+ 更新名字信息
+*/
+-(void)updateHistoryRename:(NSString*)name withUuid:(NSString*)uuid;
+
+/// 获取当前正在连接的entity
+-(JL_EntityM *__nullable)connectingEntity;
+
+/**
+ 返回经典蓝牙信息
+ @return @{@"ADDRESS":@"7c9a1da7330e",
+ @"TYPE" :@"BluetoothA2DPOutput",
+ @"NAME" :@"earphone"}
+ */
++(NSDictionary*)outputEdrInfo;
+
+/**
+ 返回经典蓝牙edr列表
+ @return 蓝牙edr列表
+ */
++(NSArray<NSString *>*)outputEdrList;
+
+
+#pragma mark - ota升级
+/**
+ * ota升级功能
+ * @param mBleEntityM 当前ota升级的蓝牙设备(JL_EntityM)
+ * @param otaFilePath ota升级文件路径
+ * @param result ota升级过程回调
+ */
+- (void)otaFuncWithEntityM:(JL_EntityM *)mBleEntityM
+ withFilePath:(NSString *)otaFilePath
+ Result:(JL_OTA_RT __nullable)result;
+- (void)setOtaReconnectBleAddr:(NSString* __nullable)addr;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_BatchManger.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/21.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_BatchType) {
+ ///开始
+ BatchType_Begin = 0x00,
+ ///结束
+ BatchType_Finish = 0x80,
+ ///取消
+ BatchType_Cancel = 0x81,
+};
+
+typedef NS_ENUM(NSUInteger, JL_BatchOptionType) {
+ /// 格式化操作
+ BatchOption_Format = 0x00,
+ /// 未知操作
+ BatchOption_unKnow = 0xFF,
+};
+
+@interface JL_BatchManger : JL_FunctionBaseManager
+
+#pragma mark ---> 批操作命令
+typedef void(^JL_BATCH_BK)(uint8_t flag);
+/**
+ @param type 0x00:开始 0x80:结束 0x81:结束
+ @param array @[@(JL_BatchOptionType)],0x00代表格式化操作。
+ @param result 操作回调 0x00:成功 0x01:失败
+ */
+-(void)cmdBatchType:(JL_BatchType)type
+ Operations:(NSArray<NSNumber *>*)array
+ Result:(JL_BATCH_BK __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_BigDataManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2022/12/7.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+@class JL_BigData;
+
+typedef NS_ENUM(UInt8, JL_BigDataStatus) {
+ JL_BigDataStatusSendSuccess = 0, //成功
+ JL_BigDataStatusSendFailCRC = 1, //CRC校验失败
+ JL_BigDataStatusSendFailSEQ = 2, //SEQ不对
+ JL_BigDataStatusSendFailFormat = 3, //数据类型不支持
+ JL_BigDataStatusSendFailWay = 4, //传输方式不支持
+ JL_BigDataStatusSendFailOutOfRange = 5, //数据长度超范围
+ JL_BigDataStatusSendFailWrite = 6, //写入数据失败
+ JL_BigDataStatusSendFailMissingParameter = 7, //缺少配置参数
+ JL_BigDataStatusSendFailCmd = 8, //命令错误
+ JL_BigDataStatusSendFailTimeout = 9, //超时
+ JL_BigDataStatusGet = 10, //收到数据
+ JL_BigDataStatusSendFailUnknown = 0xff, //未知错误
+};
+typedef void(^JL_BIGDATA_RT)(JL_BigData *bigData);
+
+@interface JL_BigDataManager : JL_FunctionBaseManager
+
+//设立大数据监听(接收阿里数据,必须放在单利类中!!!)
+-(void)cmdBigDataMonitor:(JL_BIGDATA_RT)result;
+
+//发送大数据
+-(void)cmdInputBigData:(JL_BigData*)data;
+
+@end
+
+@interface JL_BigData : NSObject
+@property(nonatomic,assign)JL_BigDataStatus mResult;
+@property(nonatomic,assign)NSInteger mIndex;
+
+///0:原始数据
+///1:阿里云数据
+///2:RTC数据
+///3: AI云
+///4:TTS语音合成
+///5: 平台接口认证信息
+@property(nonatomic,assign)uint8_t mType;
+@property(nonatomic,assign)uint8_t mVersion;
+@property(nonatomic,strong)NSData *mData;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_BinCharge.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/12/16.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_ScanSetting) {
+ JL_ScanTimeout = 0x00, //超时结束
+ JL_ScanInterrupt = 0x01, //打断结束
+ JL_ScanFail = 0x02, //开启扫描失败
+ JL_Scaning = 0x03, //正在扫描
+};
+
+typedef NS_ENUM(UInt8, JL_ReverberationFunType) {
+ JL_ReverberationAndDynamicType = 0x00, //支持混响和动态限幅器
+ JL_OnlyReverberationType = 0x01, //仅支持混响
+ JL_OnlyDynamicLimiterType = 0x02, //仅支持动态限幅器
+};
+
+typedef void(^JL_CMD_VALUE_BK)(uint32_t value);
+typedef void(^JL_LOW_DELAY_BK)(uint16_t mtu, uint32_t delay);
+
+@interface JL_BinChargeManager : JL_FunctionBaseManager
+
+#pragma mark ---> 通知固件App的信息
+// @param flag 未知
+-(void)cmdSetAppInfo:(uint8_t)flag;
+
+#pragma mark ---> 设置通讯MTU
+// @param mtu app请求mtu⼤⼩
+// @param result 实际设置的Mtu⼤⼩
+-(void)cmdSetMTU:(uint16_t)mtu Result:(JL_CMD_VALUE_BK __nullable)result;
+
+#pragma mark ---> 开启蓝⽛扫描
+// @param timeout 超时时间
+// @param result 0:成功 1:失败
+-(void)cmdBTScanStartTimeout:(uint16_t)timeout Result:(JL_CMD_VALUE_BK __nullable)result;
+
+#pragma mark ---> 推送蓝⽛扫描结果
+// 返回【蓝⽛数据结构】数组
+// @see JLBTModel
+extern NSString *kJL_MANAGER_BT_LIST_RESULT;
+
+#pragma mark ---> 停⽌蓝⽛扫描(APP-->固件)
+// @param reason 0:超时结束 1:打断结束 2:开启扫描失败 3:正在扫描
+// @param result 0:成功 1:失败
+-(void)cmdBTScanStopReason:(JL_ScanSetting)reason Result:(JL_CMD_VALUE_BK __nullable)result;
+
+#pragma mark ---> 停⽌蓝⽛扫描(固件-->APP)
+// 0:超时结束 1:打断结束 2:开启扫描失败 3:正在扫描
+extern NSString *kJL_MANAGER_BT_SCAN_STOP_NOTE;
+
+#pragma mark ---> 通知固件连接指定的蓝⽛设备
+// @param addr 蓝⽛设备地址【设置0x00 00 00 00 00 00 则是断开外设的连接】
+// @param result 0:成功 1:失败
+-(void)cmdBTConnectAddress:(NSData*)addr Result:(JL_CMD_VALUE_BK __nullable)result;
+
+extern NSString *kJL_MANAGER_ID3_Title;
+extern NSString *kJL_MANAGER_ID3_Artist;
+extern NSString *kJL_MANAGER_ID3_Album;
+extern NSString *kJL_MANAGER_ID3_Time;
+extern NSString *kJL_MANAGER_ID3_Current;
+extern NSString *kJL_MANAGER_ID3_PlayPush;
+
+#pragma mark ---> 主动设置ID3播放状态
+-(void)setID3_Status:(uint8_t)st;
+
+#pragma mark ---> ID3 播放/暂停
+-(void)cmdID3_PP;
+
+#pragma mark ---> ID3 上一曲
+-(void)cmdID3_Before;
+
+#pragma mark ---> ID3 下一曲
+-(void)cmdID3_Next;
+
+#pragma mark ---> ID3 开启/暂停 音乐信息推送
+-(void)cmdID3_PushEnable:(BOOL)enable;
+
+#pragma mark ---> 设置高低音 [-12,+12]
+-(void)cmdSetLowPitch:(int)p_low HighPitch:(int)p_high;
+
+#pragma mark ---> 设置混响值[深度和强度][0,100]、限幅值[-60,0]
+/// 设置混响值
+/// @param depthValue 深度 0-100
+/// @param intensityValue 强度 0-100
+/// @param dynamicLimiterValue 动态限幅值 -60 - 0
+/// @param reverOn 是否开启
+/// @param type 混响类型
+-(void)cmdSetReverberation:(int)depthValue
+ IntensityValue:(int)intensityValue
+ DynamicLimiterValue:(int)dynamicLimiterValue
+ SwtichReverState:(int)reverOn
+ FunType:(JL_ReverberationFunType)type;
+
+#pragma mark ---> 获取低延时参数
+-(void)cmdGetLowDelay:(JL_LOW_DELAY_BK __nullable)result;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_CallManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/12/16.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_CallManager : JL_FunctionBaseManager
+
+#pragma mark ---> 拨打电话
+/**
+ @param number 电话号码
+ @param result 回复
+ */
+-(void)cmdPhoneCall:(NSString*)number Result:(JL_CMD_RESPOND __nullable)result;
+
+#pragma mark ---> 设备通话状态
+extern NSString *kJL_MANAGER_CALL_STATUS;
+
+#pragma mark - 案子API
+#pragma mark ---> 通知设备播放来电号码的方式
+/**
+ 通知设备播放来电号码的方式
+ @param way 正常模式:0x00 播放文件模式:0x01
+ */
+-(void)cmdPhoneNumberOnWay:(uint8_t)way;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_CustomManager.h
+// JL_BLEKit
+// Created by 李放 on 2021/12/21.
+// Modify by EzioChan on 2023/03/16.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_FunctionBaseManager.h"
+#import "JL_TypeEnum.h"
+#import "JL_Tools.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+///设备返回的自定义数据
+extern NSString *kJL_MANAGER_CUSTOM_DATA;
+/// 设备返回的自定义数据(回复包)
+extern NSString *kJL_MANAGER_CUSTOM_DATA_RSP;
+
+
+@protocol JLCustomCmdPtl <NSObject>
+
+/// 设备回复自定义数据内容
+/// - Parameters:
+/// - device: 设备句柄
+/// - data: 回复数据内容
+-(void)customCmdResponse:(JL_ManagerM *)manager Status:(uint8_t)status WithData:(NSData *)data;
+
+/// 设备主动请求
+/// - Parameters:
+/// - device: 设备
+/// - data: 请求数据内容
+-(void)customCmdRequire:(JL_ManagerM *)manager WithData:(NSData *)data;
+
+
+@end
+
+@interface JL_CustomManager : JL_FunctionBaseManager
+
+/// 数据回调委托
+@property(nonatomic,weak)id<JLCustomCmdPtl> delegate;
+
+#pragma mark ---> 用户自定义数据
+/**
+ @param data 数据
+ @param result 回复
+ */
+-(void)cmdCustomData:(NSData* __nullable)data
+ Result:(JL_CMD_RESPOND __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_DeviceLogs.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2022/5/12.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JL_FunctionBaseManager.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef enum : UInt8 {
+ LogTypeDownloading = 0x00,
+ LogTypeFailed = 0x01,
+ LogTypeSucceed = 0x02,
+ LogTypeNoLog = 0x03
+} DeviceLogType;
+
+typedef void(^JLDeviceLogBK)(DeviceLogType type,float progress,NSString *_Nullable tempSavePath);
+
+@interface JL_DeviceLogs : JL_FunctionBaseManager
+
+
+/// 检查获取设备log日志
+/// @param block 回调结果
+-(void)deviceLogDownload:(JLDeviceLogBK)block;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_EntityM.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2020/9/1.
+// Copyright © 2020 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <AVFoundation/AVFoundation.h>
+#import <CoreBluetooth/CoreBluetooth.h>
+#import <UIKit/UIKit.h>
+#import <JL_BLEKit/JL_Tools.h>
+#import <JL_BLEKit/JL_ManagerM.h>
+#import <JL_AdvParse/JLAdvParse.h>
+
+NS_ASSUME_NONNULL_BEGIN
+//@class JL_EntityM;
+typedef NS_ENUM(NSInteger, JL_EntityM_Status) {
+ JL_EntityM_StatusBleOFF = 0, //BLE蓝牙未开启
+ JL_EntityM_StatusConnectFail = 1, //BLE连接失败
+ JL_EntityM_StatusConnecting = 2, //BLE正在连接
+ JL_EntityM_StatusConnectRepeat = 3, //BLE重复连接
+ JL_EntityM_StatusConnectTimeout = 4, //BLE连接超时
+ JL_EntityM_StatusConnectRefuse = 5, //BLE被拒绝
+ JL_EntityM_StatusPairFail = 6, //配对失败
+ JL_EntityM_StatusPairTimeout = 7, //配对超时
+ JL_EntityM_StatusPaired = 8, //已配对
+ JL_EntityM_StatusMasterChanging = 9, //正在主从切换
+ JL_EntityM_StatusDisconnectOk = 10, //已断开成功
+ JL_EntityM_StatusNull = 11, //Entity为空
+};
+typedef void(^JL_EntityM_STATUS_BK)(JL_EntityM_Status status);
+
+@interface JL_EntityM : NSObject<NSCopying>
+
+///命令中心
+@property(nonatomic,strong) JL_ManagerM *mCmdManager;
+
+/// BLE外设备
+@property(nonatomic,readonly,copy) CBPeripheral *mPeripheral;
+///服务号AE00
+@property(nonatomic,strong) NSString *mSERVICE;
+///命令【写】通道AE01
+@property(nonatomic,strong) NSString *mRCSP_W;
+///命令【读】通道AE02
+@property(nonatomic,strong) NSString *mRCSP_R;
+///过滤码
+@property(nonatomic,strong) NSData *__nullable mFilterKey;
+///配对码
+@property(nonatomic,strong) NSData *__nullable mPairKey;
+///广播数据
+@property(strong,nonatomic) NSData *mAdvData;
+
+///连接超时时间
+@property(nonatomic,assign) int mBLE_TIMEOUT;
+///是否【开启过滤】
+@property(nonatomic,assign) BOOL mBLE_FILTER_ENABLE;
+///是否【开启配对】
+@property(nonatomic,assign) BOOL mBLE_PAIR_ENABLE;
+///是否完成配对
+@property(nonatomic,assign) BOOL mBLE_IS_PAIRED;
+///是否需要OTA
+@property(nonatomic,assign) BOOL mBLE_NEED_OTA;
+@property(nonatomic,assign) BOOL isFrom_HISTROY;
+@property(nonatomic,assign) BOOL isBLE_CHANGE;
+@property(nonatomic,assign) BOOL isCMD_PREPARED;
+
+@property(strong,nonatomic) NSString *mUUID;
+@property(strong,nonatomic) NSNumber *mRSSI;
+@property(readonly,copy,nonatomic)NSString *mItem;
+/**
+ * mType值说明:
+ * -1:传统设备
+ * 0:AI音箱
+ * 1:TWS
+ * 2:数码充电仓
+ * 3:普通耳机
+ * 4:声卡类型
+ * 5:手表类型
+ */
+@property(assign,nonatomic) JL_DeviceType mType;
+@property(assign,nonatomic) BOOL isExclusive;
+@property(assign,nonatomic) BOOL isBound;
+@property(assign,nonatomic) BOOL isEdrLinked;
+@property(assign,nonatomic) BOOL isCharging;
+@property(assign,nonatomic) BOOL isCharging_L;
+@property(assign,nonatomic) BOOL isCharging_R;
+@property(assign,nonatomic) BOOL isCharging_C;
+@property(assign,nonatomic) uint8_t mPower;
+@property(assign,nonatomic) uint8_t mPower_L;
+@property(assign,nonatomic) uint8_t mPower_R;
+@property(assign,nonatomic) uint8_t mPower_C;
+@property(strong,nonatomic) NSString *mVID;
+@property(strong,nonatomic) NSString *mPID;
+@property(strong,nonatomic) NSString *mEdr;
+@property(strong,nonatomic) NSString *mBleAddr; //OTA设备需要
+@property(assign,nonatomic) uint8_t mChipType; //0:690x 1:692x 2:693x
+@property(assign,nonatomic) uint8_t mProtocolType; //默认0x00
+/**
+ 0x00 - dismiss 不显示弹窗
+ 0x01 - unconnected 经典蓝牙未连接
+ iOS : 不显示电量,请手动连接XXX
+ Android:不显示电量,显示连接按钮
+ 0x02 - connected 经典蓝牙已连接
+ iOS:判断已连接的经典蓝牙名是否一致,若未连接或蓝牙名不一致,
+ 显示“设备已被占用”。若一致,显示电量等信息。
+ Android:判断已连接的经典蓝牙Mac是否一致,若未连接或蓝牙Mac不一致,
+ 显示“设备已被占用”。若一致,显示电量等信息。
+ 0x03 - connecting 设备正在自动回连
+ Android 和 iOS 显示“设备正在自动回连 ”
+ 0x04 - connectionless 设备不可连接(需要按下配对按键)
+ Android 和 iOS 显示配对操作方式
+ */
+@property(assign,nonatomic) int8_t mScene;
+
+///Seq 每次开机会加 1,用于app区分是否同一次开机
+@property(assign,nonatomic) uint8_t mSeq;
+
+///TWS配对标识,0:未配对 1:已配对
+@property(assign,nonatomic) uint8_t mTWS_Paired;
+
+///0:关盖 1:开盖
+@property(assign,nonatomic) uint8_t mTWS_Cap;
+
+///0:充电模式 1:发射模式
+@property(assign,nonatomic) uint8_t mTWS_Mode;
+///主从标识 (0:从机, 1:主机)
+@property(assign,nonatomic) uint8_t mHeadsetMaster;
+
+///连接标识 (0:可以连接 1:不可连接)
+@property(assign,nonatomic) uint8_t mHeadsetLinkEnable;
+/**
+ * mWatchScene值说明:
+ * 0x00:经典蓝牙未连接
+ * 0x01:经典蓝牙已连接
+ * 0x02:设备正在回连
+ * 0x03:设备不可连接 (需要手动进入配对模式)
+ */
+///连接标识 (0:可以连接 1:不可连接)
+@property(assign,nonatomic) uint8_t mWatchScene;
+
+///连接方式 0:ble 1:spp
+@property(assign,nonatomic) uint8_t mWatchWay;
+
+/// 设备特殊类型
+@property(assign,nonatomic) JLDevSpecialType mSpecialType;
+
+-(void)setBlePeripheral:(CBPeripheral *)mPeripheral;
+-(void)setBleItem:(NSString *)mItem;
+
+/**
+ 更新代理
+*/
+-(void)updateDelegate;
+
+/**
+ 释放定时器
+*/
+-(void)releaseEntityTimer;
+
+/**
+ 发送RCSP数据
+ @param data 数据
+ @return 是否已发送
+ */
+-(BOOL)writeRcspData:(NSData*)data;
+
+/**
+调整发数参数
+@param isGame 是否为游戏模式
+@param mtu 每包发数字节数
+@param delay 延时时间 (毫秒)
+*/
+-(void)setGameMode:(BOOL)isGame MTU:(NSUInteger)mtu Delay:(int)delay;
+
+
+-(void)flashFinishedAction;
+
+
+#pragma mark - 连接超时管理
+-(void)startTimeout:(int)code;
+-(void)stopTimeout;
+
+#pragma mark - EntityM 模型转换
+-(void)updateEntity:(NSDictionary*)dic;
++(JL_EntityM*)changeToEntity:(NSDictionary*)dic;
++(NSArray*)turnToEntityArray:(NSArray*)array;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_FileManager.h
+// JL_BLEKit
+//
+// Created by 凌煊峰 on 2021/12/13.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JLModel_File.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+//MARK: - 枚举
+typedef NS_ENUM(UInt8, JL_FileOperationEnvironmentType) {
+ JL_FileOperationEnvironmentTypeBigFileTransmission = 0x00, //大文件传输
+ JL_FileOperationEnvironmentTypeDeleteFile = 0x01, //删除文件
+ JL_FileOperationEnvironmentTypeFormatting = 0x02, //格式化
+ JL_FileOperationEnvironmentTypeFatfsTransmission = 0x03, //FAT文件传输
+};
+typedef NS_ENUM(UInt8, JL_DeleteFileLastType) {
+ JL_DeleteFileLastTypeIsNotLast = 0x00, //不是最后一个文件
+ JL_DeleteFileLastTypeIsLast = 0x01, //是最后一个文件
+};
+typedef NS_ENUM(UInt8, JL_BrowseReason) {
+ JL_BrowseReasonCommandEnd = 0, //读取完当前命令请求的文件
+ JL_BrowseReasonFolderEnd = 1, //读取完当前目录的文件
+ JL_BrowseReasonPlaySuccess = 2, //点播成功
+ JL_BrowseReasonBusy = 3, //设备繁忙
+ JL_BrowseReasonDataFail = 4, //目录数据发送失败
+ JL_BrowseReasonReading = 0x0f, //正在读取中
+ JL_BrowseReasonUnknown, //未知原因
+};
+typedef NS_ENUM(UInt8, JL_FileContentResult) {
+ JL_FileContentResultStart = 0x00, //开始传输
+ JL_FileContentResultReading = 0x01, //正在读取
+ JL_FileContentResultEnd = 0x02, //读取结束
+ JL_FileContentResultCancel = 0x03, //取消读取
+ JL_FileContentResultFail = 0x04, //读取失败
+ JL_FileContentResultNull = 0x05, //文件不存在
+ JL_FileContentResultDataError = 0x06, //数据错误
+ JL_FileContentResultCrcFail = 0x07, //crc校验失败
+};
+typedef NS_ENUM(UInt8, JL_FileDataType) {
+ JL_FileDataTypeDo = 0, //开始传输文件数据
+ JL_FileDataTypeDone = 1, //结束传输文件数据
+ JL_FileDataTypeDoing = 2, //正在传输文件数据
+ JL_FileDataTypeCancel = 3, //取消传输文件数据
+ JL_FileDataTypeError = 4, //传输文件数据出错
+ JL_FileDataTypeUnknown,
+};
+typedef NS_ENUM(UInt8, JL_BigFileTransferCode) {
+ JL_BigFileTransferCodeSuccess = 0x00, //成功
+ JL_BigFileTransferCodeFail = 0x01, //写失败
+ JL_BigFileTransferCodeOutOfRange = 0x02, //数据超出范围
+ JL_BigFileTransferCodeCrcFail = 0x03, //crc校验失败
+ JL_BigFileTransferCodeOutOfMemory = 0x04, //内存不足
+};
+typedef NS_ENUM(UInt8, JL_BigFileResult) {
+ JL_BigFileTransferStart = 0x00, //开始大文件数据传输
+ JL_BigFileTransferDownload = 0x01, //传输大文件有效数据
+ JL_BigFileTransferEnd = 0x02, //结束大文件数据传输
+ JL_BigFileTransferOutOfRange = 0x03, //大文件传输数据超范围
+ JL_BigFileTransferFail = 0x04, //大文件传输失败
+ JL_BigFileCrcError = 0x05, //大文件校验失败
+ JL_BigFileOutOfMemory = 0x06, //空间不足
+ JL_BigFileTransferCancel = 0x07, //取消传输
+ JL_BigFileTransferNoResponse = 0xF1, //设备没有响应
+};
+
+//MARK: - 回调
+
+typedef void(^JL_FILE_BK)(NSArray* __nullable array,JL_BrowseReason reason);
+typedef void(^JL_FILE_CONTENT_BK)(JL_FileContentResult result, uint32_t size, NSData* __nullable data, float progress);
+typedef void(^JL_FILE_DATA_BK)(NSData* __nullable data, NSString* __nullable path, uint16_t size, JL_FileDataType type);
+typedef void(^JL_BIGFILE_BK)(NSArray* __nullable array);
+typedef void(^JL_BIGFILE_RT)(JL_BigFileResult result, float progress);
+
+
+/// 文件浏览与下载、上载、删除等相关的操作类
+@interface JL_FileManager : JL_FunctionBaseManager
+
+/// 超时时间
+@property(nonatomic,assign)NSInteger maxTimeout;
+
+///大文件名是否使用其他编码
+///Default:false
+///短文件名:GBK CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000)
+///长文件名:Unicode16L (NSUTF16LittleEndianStringEncoding)
+///Other: true
+///需要设置encodeType属性的值,默认为Unicode16L
+@property(nonatomic,assign)BOOL isOtherEncode;
+
+/// 大文件名使用的编码
+/// default :NSUTF16LittleEndianStringEncoding
+@property(nonatomic,assign)NSStringEncoding encodeType;
+
+/// 停止超时计算
+- (void)closeTimer;
+
+
+//MARK: - 浏览目录
+
+/// 发起文件目录浏览
+/// - Parameters:
+/// - model: 文件Model
+/// - number: 读取的数量 单次请求建议 < 20 条
+/// - result: 回调操作结果
+-(void)cmdBrowseModel:(JLModel_File*)model
+ Number:(uint8_t)number
+ Result:(JL_CMD_RESPOND __nullable)result;
+
+/// 监听目录数据回调
+/// - Parameter result: 回调内容
+-(void)cmdBrowseMonitorResult:(JL_FILE_BK __nullable)result;
+
+
+
+//MARK: - 删除文件
+
+/// 删除文件(必须异步执行)
+/// @param array 文件Model数组
+-(BOOL)cmdDeleteFileModels:(NSArray*)array;
+
+/// 删除单个JLModel_File文件
+/// @param model 文件对象 JLModel_File
+/// @param last 是否最后一个文件
+/// @param result 删除成功回调
+-(void)cmdDeleteFile:(JLModel_File*)model
+ IsLast:(JL_DeleteFileLastType)last
+ Result:(JL_CMD_RESPOND __nullable)result;
+
+/// 通过名字删除文件
+/// 仅部分设备支持(设备要求支持文件系统支持唯一文件名)
+/// - Parameters:
+/// - name: 文件名
+/// - result: 回调结果
+-(void)cmdFileDeleteWithName:(NSString*)name Result:(JL_CMD_RESPOND __nullable)result;
+
+
+
+/// 设备格式化
+/// @param handle 设备句柄
+/// @param result 格式化回调
+-(void)cmdDeviceFormat:(NSString*)handle Result:(JL_CMD_RESPOND __nullable)result;
+
+/// 清除设备音乐缓存记录
+/// @param type 卡的类型
+-(void)cmdCleanCacheType:(JL_CardType)type;
+
+
+//MARK: - 通讯文件句柄相关
+
+/// 设置文件传输句柄
+/// 大文件传输,设置当前传输句柄
+/// - Parameter currentFileHandleType: 传输句柄
+- (void)setCurrentFileHandleType:(JL_FileHandleType)currentFileHandleType;
+
+/// 获取当前的传输文件句柄
+- (JL_FileHandleType)getCurrentFileHandleType;
+
+/// 文件传输的句柄数据
+- (NSData *)currentDeviceHandleData;
+
+/// 设置当前使用的存储设备
+/// @param devHandle 存储设备句柄
+/// 可参考JLModel_Device 中获取到的设备句柄内容
+/// @param result 命令回调结果
+-(void)cmdSetDeviceStorage:(NSData *)devHandle Result:(JL_CMD_RESPOND)result;
+
+
+//MARK: - 文件传输 固件-->APP
+
+/// 监听文件数据 固件-->APP
+/// - Parameter result: 数据内容监听回调
+-(void)cmdFileDataMonitorResult:(JL_FILE_DATA_BK __nullable)result __attribute__((deprecated("This method is deprecated. Use newMethod cmdFileReadContentWithName:(NSString*)name Result:(JL_FILE_CONTENT_BK __nullable)result")));
+
+/// app 端回复设备的请求文件传输 固件-->APP
+/// 允许传输文件数据
+-(void)cmdAllowFileData __attribute__((deprecated("This method is deprecated. Use newMethod cmdFileReadContentWithName:(NSString*)name Result:(JL_FILE_CONTENT_BK __nullable)result")));
+
+/// app 端回复设备的请求文件传输 固件-->APP
+/// 拒绝传输文件数据
+-(void)cmdRejectFileData __attribute__((deprecated("This method is deprecated. Use newMethod cmdFileReadContentWithName:(NSString*)name Result:(JL_FILE_CONTENT_BK __nullable)result")));
+
+/// 传输文件数据 固件-->APP
+/// 停止传输文件数据
+-(void)cmdStopFileData __attribute__((deprecated("This method is deprecated. Use newMethod cmdFileReadContentCancel")));
+
+/// 读取外置卡的文件内容 固件-->APP
+/// 此方法针对部分设备(要求设备文件系统支持唯一文件名)
+/// - Parameters:
+/// - name: 文件名
+/// - result: 回调结果
+-(void)cmdFileReadContentWithName:(NSString*)name Result:(JL_FILE_CONTENT_BK __nullable)result;
+
+/// 簇号方式读取外置卡的文件内容 固件-->APP
+/// - Parameters:
+/// - fileClus: 文件簇号
+/// - result: 回调
+- (void)cmdFileReadContentWithFileClus:(uint32_t)fileClus Result:(JL_FILE_CONTENT_BK __nullable)result;
+
+/// 取消读取外置卡的文件内容
+-(void)cmdFileReadContentCancel;
+
+
+//MARK: - 文件传输 APP-->固件
+
+/// 请求传输文件给设备
+/// - Parameters:
+/// - size: 文件大小
+/// - path: 存放路径
+-(void)cmdFileDataSize:(uint8_t)size
+ SavePath:(NSString*)path __attribute__((deprecated("This method is deprecated. Use newMethod cmdBigFileData:(NSString *)path WithFileName:(NSString *)fileName Result:(JL_BIGFILE_RT __nullable)result")));
+
+
+/// 推送文件数据给设备
+/// - Parameter data:文件数据
+-(void)cmdPushFileData:(NSData*)data __attribute__((deprecated("This method is deprecated. Use newMethod cmdBigFileData:(NSString *)path WithFileName:(NSString *)fileName Result:(JL_BIGFILE_RT __nullable)result")));
+
+
+/// 大文件传输 App-->固件
+/// - Parameters:
+/// - path: 本地大文件下载文件路径
+/// - fileName: 目标文件路径
+/// 如想指定文件夹路径,可以使用 Download/abc/def.txt
+/// 否则可以直接添加 def.txt 由系统存放到默认的文件夹下
+/// - result: 回调结果
+-(void)cmdBigFileData:(NSString *)path WithFileName:(NSString *)fileName
+ Result:(JL_BIGFILE_RT __nullable)result;
+
+/// 取消文件传输 App-->固件
+-(void)cmdStopBigFileData;
+
+/// 通知固件进行环境准备
+/// - Parameters:
+/// - environment:
+/// 0:大文件传输
+/// 1:删除文件
+/// 2:格式化
+/// - result: 回调结果
+-(void)cmdPreEnvironment:(JL_FileOperationEnvironmentType)environment Result:(JL_CMD_RESPOND __nullable)result;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_FindDeviceManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/12/17.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+/// 查找设备参数
+@interface JLFindDeviceOperation : NSObject
+
+/// 播放方式 way:
+/// 0. 全部播放
+/// 1.左侧播放
+/// 2.右侧播放
+/// 3.全部暂停
+@property(nonatomic,assign)uint8_t playWay;
+
+/// 超时时间
+/// 0 表示不限制时间
+/// 默认时间 60
+@property(nonatomic,assign)uint16_t timeout;
+
+/// 铃声操作
+/// 0x00: 关闭铃声
+/// 0x01: 播放铃声
+@property(nonatomic,assign)uint8_t sound;
+
+
+@end
+
+
+/// 查找手机参数
+@interface JLFindPhoneModel : NSObject
+
+/// 铃声操作
+/// 0x00: 关闭铃声
+/// 0x01: 播放铃声
+@property(nonatomic,assign)uint8_t sound;
+
+/// 超时时间
+/// 0 表示不限制时间
+/// 默认时间 10
+@property(nonatomic,assign)uint16_t timeout;
+
+@end
+
+
+
+@protocol JL_FindDeviceDelegate <NSObject>
+
+
+/// 设备查找手机回调
+/// - Parameter model:JLFindPhoneModel
+-(void)findDeviceStartFindMyPhone:(JLFindPhoneModel *)model;
+
+/// 查询设备当前状态
+/// 当前回调需要先查询设备状态cmdFindDeviceCheckStatus
+/// - Parameter model: JLFindDeviceOperation
+-(void)findDeviceCheckStatus:(JLFindDeviceOperation *)model;
+
+@end
+
+/// 查找设备类
+/// 查找设备/设备查找手机
+@interface JL_FindDeviceManager : JL_FunctionBaseManager
+
+#pragma mark ---> 查找设备
+// 设备查找手机的通知
+// 携带了响铃时长🔔
+// dict = @{@"op":@(操作类型),@"timeout":@(超时时间)};
+extern NSString *kJL_MANAGER_FIND_PHONE;
+
+// 手机查找设备
+// 携带是否停止响铃
+// dict = @{@"op":@(操作类型),@"timeout":@(超时时间)};
+extern NSString *kJL_MANAGER_FIND_DEVICE;
+
+/// 查询固件设备查找状态回调
+/// JLFindDeviceOperation 作为回调对象
+extern NSString *kJL_MANAGER_FIND_DEVICE_STATUS;
+
+
+typedef void(^JL_FIND_DEVICE_CHECK_RESPOND)(JL_CMDStatus status, JLFindDeviceOperation * _Nullable model);
+
+/// 代理
+@property(nonatomic,weak)id<JL_FindDeviceDelegate> delegate;
+
+// 查找设备命令
+// @param isVoice 是否发声
+// @param timeout 超时时间
+// @param isIphone 是否设备查找手机(默认是手机找设备)
+// @param opDict 这是一个可选项,若tws未连接,则该值无效,默认是全部播放
+// 字典键值对说明:
+// 播放方式 way: 0 全部播放
+// 1 左侧播放
+// 2 右侧播放
+// 播放源 player: 0 APP端播放
+// 1 设备端播放
+// etc.全部播放&APP播放音效
+// opDict:{@"way":@"0",@"player":@"0"}
+-(void)cmdFindDevice:(BOOL)isVoice
+ timeOut:(uint16_t)timeout
+ findIphone:(BOOL)isIphone
+ Operation:( NSDictionary * _Nullable )opDict __attribute__((deprecated ( "This method will be replaced with subcommands cmdFindDeviceWith and proxy etc.")));
+
+
+
+/// 查找设备命令
+/// - Parameter operation: 查找设备对象
+-(void)cmdFindDeviceWith:(JLFindDeviceOperation *)operation;
+
+
+
+/// 查询一次固件查找设备的状态
+/// - Parameter result: 状态回调
+-(void)cmdFindDeviceCheckStatus:(JL_FIND_DEVICE_CHECK_RESPOND _Nullable)result;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_FlashOperateManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/12/13.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+#pragma mark - 外挂FLASH操作命令
+typedef NS_ENUM(UInt8, JL_FlashOperationOPType) {
+ JL_FlashOperationOPTypeWriteData = 0x00, //写数据
+ JL_FlashOperationOPTypeReadData = 0x01, //读数据
+ JL_FlashOperationOPTypeInsertFile = 0x02, //插入文件
+ JL_FlashOperationOPTypeDialOperation = 0x03, //表盘操作
+ JL_FlashOperationOPTypeEraseData = 0x04, //擦除数据
+ JL_FlashOperationOPTypeDeleteFile = 0x05, //删除文件
+ JL_FlashOperationOPTypeWriteFileProtection = 0x06, //写文件保护
+ JL_FlashOperationOPTypeUpdateDialResource = 0x07, //更新表盘资源
+ JL_FlashOperationOPTypeCheckWriteDataSuccess = 0x08, //查询写数据是否成功
+ JL_FlashOperationOPTypeUpdateResourceFlag = 0x09, //升级资源标志操作
+ JL_FlashOperationOPTypeRestoreSystem = 0x0A, //还原系统
+ JL_FlashOperationOPTypeGetFileInfo = 0x0B, //获取文件信息
+ JL_FlashOperationOPTypeGetRemainingSpace = 0x0C, //获取剩余空间
+};
+
+typedef NS_ENUM(UInt8, JL_DialSetting) {
+ JL_DialSettingReadCurrentDial = 0x00, //读取当前表盘
+ JL_DialSettingSetDial = 0x01, //设置表盘
+ JL_DialSettingVersion = 0x03, //获取表盘额外信息,如版本
+ JL_DialSettingActivateCustomDial = 0x04, //激活自定义表盘
+ JL_DialSettingGetDialName = 0x05, //获取对应的自定义表盘名字
+};
+typedef NS_ENUM(UInt8, JL_FlashOperateFlag) {
+ JL_FlashOperateFlagFinish = 0x00, //结束
+ JL_FlashOperateFlagStart = 0x01, //开始
+};
+
+@interface JL_FlashOperateManager : JL_FunctionBaseManager
+
+typedef void(^JL_FlashInfo_BK)(JLModel_Flash* __nullable model);
+typedef void(^JL_FlashWrite_BK)(uint8_t flag);
+typedef void(^JL_FlashWriteStatus_BK)(uint8_t flag,uint16_t leftSize);
+typedef void(^JL_FlashWriteSize_BK)(uint8_t flag,uint32_t size);
+typedef void(^JL_FlashRead_BK)(uint8_t flag,NSData *__nullable data);
+typedef void(^JL_FlashAddOrDel_BK)(uint8_t flag);
+typedef void(^JL_FlashWatch_BK)(uint8_t flag, uint32_t size,
+ NSString *__nullable path,
+ NSString *__nullable describe);
+typedef void(^JL_FlashClean_BK)(uint8_t flag);
+typedef void(^JL_FlashProtect_BK)(uint8_t flag);
+typedef void(^JL_FlashUpdate_BK)(uint8_t flag);
+typedef void(^JL_FlashFileInfo_BK)(uint32_t size,uint16_t crc16);
+typedef void(^JL_FlashLeftSize_BK)(uint32_t leftSize);
+
+/// Flash Info
+@property(nonatomic,strong)JLModel_Flash *flashInfo;
+
+#pragma mark ---> 获取外置Flash信息
+/**
+ 获取外置Flash信息
+ @param result 回复
+ */
+-(void)cmdGetFlashInfoResult:(JL_FlashInfo_BK __nullable)result;
+
+#pragma mark ---> 写数据到Flash
+/**
+ 写数据到Flash
+ @param data 数据
+ @param offset 偏移
+ @param mtu 每包大小
+ @param result 回复
+ */
+-(void)cmdWriteToFlashAllData:(NSData*)data
+ Offset:(uint32_t)offset
+ Mtu:(uint16_t)mtu
+ Result:(JL_FlashWriteSize_BK __nullable)result;
+
+#pragma mark ---> 读数据从Flash
+/**
+ 读数据从Flash
+ @param offset 偏移
+ @param size 大小
+ @param mtu 每包大小
+ @param result 回复
+ */
+-(void)cmdReadFromFlashAllDataOffset:(uint32_t)offset
+ Size:(uint16_t)size
+ Mtu:(uint16_t)mtu
+ Result:(JL_FlashRead_BK __nullable)result;
+
+#pragma mark ---> [开始/结束]增加表盘(文件)
+/**
+ 开始/结束 插入文件
+ @param path 路径
+ @param size 大小
+ @param flag 开始:0x01 结束:0x00
+ @param result 回复
+ */
+-(void)cmdInsertFlashPath:(NSString* __nullable)path
+ Size:(uint32_t)size
+ Flag:(JL_FlashOperateFlag)flag
+ Result:(JL_FlashAddOrDel_BK __nullable)result;
+
+#pragma mark ---> 设置表盘(文件)
+
+/**
+ 表盘操作
+ @param path 路径
+ @param flag 0x00:读取当前表盘
+ 0x01:设置表盘
+ 0x03:获取表盘额外信息,如版本
+ 0x04:激活自定义表盘
+ 0x05:获取对应的自定义表盘名字
+ @param result 回复
+ */
+-(void)cmdWatchFlashPath:(NSString*__nullable)path
+ Flag:(JL_DialSetting)flag
+ Result:(JL_FlashWatch_BK __nullable)result;
+
+#pragma mark ---> 设备更新表盘(文件) 【kJL_MANAGER_WATCH_FACE】?// 返回 字符串
+extern NSString *kJL_MANAGER_WATCH_FACE;
+
+#pragma mark ---> [开始/结束]删除表盘(文件)
+/**
+ 开始/结束 删除文件
+ @param path 路径
+ @param flag 开始:0x01 结束:0x00
+ @param result 回复
+ */
+-(void)cmdDeleteFlashPath:(NSString* __nullable)path
+ Flag:(JL_FlashOperateFlag)flag
+ Result:(JL_FlashAddOrDel_BK __nullable)result;
+
+#pragma mark ---> 外挂Flash【写保护】操作
+/**
+ 开始/结束
+ @param flag 开始:0x01 结束:0x00
+ */
+-(void)cmdWriteProtectFlashFlag:(JL_FlashOperateFlag)flag Result:(JL_FlashProtect_BK __nullable)result;
+
+#pragma mark ---> 外挂Flash【资源更新】操作
+/**
+ 开始/结束 更新UI
+ @param flag 开始:0x01 结束:0x00
+ */
+-(void)cmdUpdateResourceFlashFlag:(JL_FlashOperateFlag)flag Result:(JL_FlashUpdate_BK __nullable)result __attribute__((deprecated ( "The current interface is about to be canceled in version 2.0.0, please use cmdUpdateResourceFlashFlagAsync:Result: instead")));
+-(void)cmdUpdateResourceFlashFlag:(JL_FlashOperateFlag)flag;
+/// 外挂Flash(资源更新)操作
+/// 异步回调
+/// - Parameters:
+/// - flag: flag
+/// - result: 操作结果
+-(void)cmdUpdateResourceFlashFlagAsync:(JL_FlashOperateFlag)flag Result:(JL_FlashUpdate_BK __nullable)result;
+
+#pragma mark ---> 断开连接,对FATFS处理。
+-(void)cmdFlashActionDisconnect;
+
+#pragma mark ---> 外挂Flash 手表资源更新标志位
+-(void)cmdWatchUpdateResource __attribute__((deprecated ( "The current interface is about to be canceled in version 2.0.0, please use cmdWatchUpdateResourceWith:(JL_CMD_RESPOND __nullable)result instead")));
+
+/// 打开设备升级资源标记操作
+/// - Parameter result: 设备回复结果
+/// 当设备回复的cmd代号为非 0 时,属于异常结束,不可继续升级
+-(void)cmdWatchUpdateResourceWith:(JL_CMD_RESPOND __nullable)result;
+
+#pragma mark ---> 外挂Flash 还原系统
+-(void)cmdFlashRecovery;
+
+#pragma mark ---> 外挂Flash 获取文件信息
+-(void)cmdFlashInformationOfFile:(NSString*)file Result:(JL_FlashFileInfo_BK)result;
+
+#pragma mark ---> 外挂Flash 剩余空间
+-(void)cmdFlashLeftSizeResult:(JL_FlashLeftSize_BK)result;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_FmManager.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/20.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+
+typedef NS_ENUM(UInt8, JL_FCmdFM) {
+ JL_FCmdFMPP = 0x01, //FM 暂停/播放
+ JL_FCmdFMPonitBefore = 0x02, //上一个频点
+ JL_FCmdFMPonitNext = 0x03, //下一个频点
+ JL_FCmdFMChannelBefore = 0x04, //上一个频道
+ JL_FCmdFMChannelNext = 0x05, //下一个频道
+ JL_FCmdFMSearch = 0x06, //扫描
+ JL_FCmdFMChannelSelect = 0x07, //选择频道
+ JL_FCmdFMChannelDelete = 0x08, //删除频道
+ JL_FCmdFMFrequencySelect = 0x09, //选择频点
+ JL_FCmdFMFrequencyDelete = 0x0a, //删除频点
+};
+
+typedef NS_ENUM(UInt8, JL_FMSearch) {
+ JL_FMSearchALL = 0x00, //FM 暂停/播放
+ JL_FMSearchForward = 0x01, //向前搜索
+ JL_FMSearchBackward = 0x02, //向后搜索
+ JL_FMSearchStop = 0x03, //停止搜索
+};
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_FmManager : JL_FunctionBaseManager
+
+///Fm状态
+@property (assign,nonatomic) JL_FMStatus fmStatus;
+
+///Fm 频段范围
+///76.5-108.0Mhz
+///87.5-108.0Mhz
+@property (assign,nonatomic) JL_FMMode fmMode;
+
+///当前fm
+@property (strong,nonatomic) JLModel_FM *currentFm;
+
+///Fm列表
+@property (strong,nonatomic) NSArray *fmArray;
+
+#pragma mark ---> FM相关操作
+/**
+ @param cmd FM功能
+ @param search FM搜索
+ @param channel FM频道
+ @param frequency FM频点
+ @param result 返回结果
+ */
+-(void)cmdFm:(JL_FCmdFM)cmd
+ Saerch:(JL_FMSearch)search
+ Channel:(uint8_t)channel
+ Frequency:(uint16_t)frequency
+ Result:(JL_CMD_RESPOND __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
--- /dev/null
+//
+// JL_FunctionBaseManager.h
+// JL_BLEKit
+//
+// Created by 凌煊峰 on 2021/12/13.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JLModel_Device.h>
+#import <JL_BLEKit/JL_RCSP.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+@interface JL_FunctionBaseManager : NSObject
+
+@property (assign, nonatomic) uint8_t mCmdSN;
+@property (strong, nonatomic) NSString *mBLE_UUID;
+@property (strong, nonatomic) NSString *mBLE_NAME;
+@property (weak , nonatomic) JLModel_Device *deviceModel;
+@property (weak , nonatomic) JL_ManagerM *centerManagerM;
+
+- (void)inputPKG:(JL_PKG *)pkg;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_Handle.h
+// JL_BLEKit
+//
+// Created by zhihui liang on 2018/11/10.
+// Copyright © 2018 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FlashOperateManager.h>
+#import <JL_BLEKit/JL_BLEAction.h>
+#import <JL_BLEKit/JL_RCSP.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * 收到设备返回的XM_PKG的回调。
+ */
+extern NSString *kJL_CMD_RECEIVE; //XM_RCSP【接收】
+
+@protocol JL_HandleDelegate <NSObject>
+@optional
+-(void)onHandleOutputPKG:(JL_PKG*)pkg;
+@end
+
+@interface JL_Handle : NSObject
+@property(nonatomic,weak)id<JL_HandleDelegate>delegate;
+
+/**
+输入BLE数据
+@param data 设备过来的数据
+*/
+-(void)inputHandleData:(NSData*)data;
+
+/**[实例]
+向设备发送JL_PKG数据包。
+@param pkg JL_PKG数据模型
+@param name 设备名字
+*/
+-(NSData*)sendPackage:(JL_PKG*)pkg WithName:(NSString*)name;
+
++(void)logPackage:(JL_PKG*)pkg WithName:(NSString *__nullable)name IsSend:(BOOL)isSend;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_LRCManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/12/17.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_LRCType) {
+ JL_LRCTypeDone = 1, //LRC已传输完
+ JL_LRCTypeBusy = 2, //设备忙碌
+ JL_LRCTypeDoneFail = 0x0e, //传输失败
+};
+typedef void(^JL_LRC_BK)(NSString* __nullable lrc, JL_LRCType type);
+typedef void(^JL_LRC_BK_1)(NSData* __nullable lrc, JL_LRCType type);
+
+@interface JL_LRCManager : JL_FunctionBaseManager
+
+#pragma mark ---> 获取LRC歌词
+/**
+ @param result 返回LRC数据
+ */
+-(void)cmdLrcMonitorResult:(JL_LRC_BK __nullable)result;
+-(void)cmdLrcMonitorResult_1:(JL_LRC_BK_1 __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_LightManager.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/16.
+// Modify by EzioChan on 2023/03/16
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_LightManager;
+
+@protocol JLLightStatusPtl <NSObject>
+
+-(void)jlLightStatus:(JL_LightManager *)lightManager;
+
+@end
+
+
+@interface JL_LightManager : JL_FunctionBaseManager
+
+/// 当前设备是否支持灯光设置
+@property(nonatomic,assign)BOOL isSupportLight;
+
+/// 0:关闭 1:打开 2:设置模式(彩色/闪烁/情景)
+@property (assign,nonatomic) JL_LightState lightState;
+
+// 0:彩色 1:闪烁 2: 情景
+@property (assign,nonatomic) JL_LightMode lightMode;
+
+/// 灯光红色
+@property (assign,nonatomic) uint8_t lightRed;
+
+/// 灯光绿色
+@property (assign,nonatomic) uint8_t lightGreen;
+
+/// 灯光蓝色
+@property (assign,nonatomic) uint8_t lightBlue;
+
+/// 闪烁模式Index
+@property (assign,nonatomic) JL_LightFlashModeIndex lightFlashIndex;
+
+/// 闪烁频率Index
+@property (assign,nonatomic) JL_LightFlashModeFrequency lightFrequencyIndex;
+
+/// 情景模式Index
+@property (assign,nonatomic) JL_LightSceneMode lightSceneIndex;
+
+// 色调,范围0-360
+@property (assign,nonatomic) uint16_t lightHue;
+
+// 饱和度,0-100
+@property (assign,nonatomic) uint8_t lightSat;
+
+// 亮度,0-100
+@property (assign,nonatomic) uint8_t lightLightness;
+
+/// 状态更新代理委托
+@property (weak,nonatomic)id<JLLightStatusPtl> delegate;
+
+
+/// 获取灯光设置,通过代理返回
+-(void)cmdGetLightStatus;
+/**
+ * 设置灯光
+ * @param lightState 灯光状态
+ * @param lightMode 灯光模式
+ * @param red 红色色值
+ * @param green 绿色色值
+ * @param blue 蓝色色值
+ * @param flashIndex 闪烁模式index
+ * @param flashFreqIndex 闪烁频率
+ * @param sceneIndex 情景模式
+ * @param hue 色调,范围0-360
+ * @param saturation 饱和度,0-100
+ * @param lightness 亮度,0-100
+ */
+-(void)cmdSetState:(JL_LightState)lightState
+ Mode:(JL_LightMode)lightMode
+ Red:(uint8_t)red
+ Green:(uint8_t)green
+ Blue:(uint8_t)blue
+ FlashInex:(JL_LightFlashModeIndex)flashIndex
+ FlashFreq:(JL_LightFlashModeFrequency)flashFreqIndex
+ SceneIndex:(JL_LightSceneMode)sceneIndex
+ Hue:(uint16_t)hue
+ Saturation:(uint8_t)saturation
+ Lightness:(uint8_t)lightness;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_MSG_Func.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/5/13.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+typedef enum : uint8_t {
+ Func_Location,
+ Func_Weather,
+ Func_Notify,
+} FuncMsgType;
+
+@interface JL_MSG_Func : NSObject
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_MSG_Weather.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/5/13.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+typedef NS_ENUM(UInt8, JLWeatherType) {
+ ///晴
+ JLWeatherTypeSunny = 0x00,
+ ///少云
+ JLWeatherTypeCloudLess,
+ ///晴间多云
+ JLWeatherTypePartlyCloudy,
+ ///多云
+ JLWeatherTypeCloudiness,
+ ///阴
+ JLWeatherTypeOvercastSky,
+ ///有风/和风/清风/微风
+ JLWeatherTypeBreeze,
+ ///平静
+ JLWeatherTypeCalmWind,
+ ///大风/强风/劲风/疾风
+ JLWeatherTypeHighWind,
+ ///飓风/狂爆风
+ JLWeatherTypeHurricane,
+ ///热带风暴/风暴
+ JLWeatherTypeTropicalStorm,
+ ///霾/中度霾/重度霾/严重霾
+ JLWeatherTypeHaze,
+ ///阵雨
+ JLWeatherTypeShower,
+ ///雷阵雨
+ JLWeatherTypeThunderShower,
+ ///雷阵雨并伴有冰雹
+ JLWeatherTypeHallThunderShower,
+ ///雨/小雨/毛毛雨/细雨/小雨-中雨
+ JLWeatherTypeLightRain,
+ ///中雨/中雨-大雨
+ JLWeatherTypeModerateRain,
+ ///大雨/大雨-暴雨
+ JLWeatherTypeHeavyRain,
+ ///暴雨/暴雨-大暴雨
+ JLWeatherTypeDownpour,
+ ///大暴雨/大暴雨-特大暴雨
+ JLWeatherTypeExtraordinaryRainstorm,
+ ///特大暴雨
+ JLWeatherTypeHeavyDownpour,
+ ///强阵雨
+ JLWeatherTypeStrongRainShower,
+ ///强雷阵雨
+ JLWeatherTypeStrongThunderShower,
+ ///极端降雨
+ JLWeatherTypeExtremeRainfall,
+ ///雨夹雪/阵雨夹雪/冻雨/雨雪天气
+ JLWeatherTypeRainySnowy,
+ ///雪
+ JLWeatherTypeSnowy,
+ ///阵雪
+ JLWeatherTypeSnowShower,
+ ///小雪/小雪-中雪
+ JLWeatherTypeLightSnow,
+ ///中雪/中雪-大雪
+ JLWeatherTypeModerateSnow,
+ ///大雪/大雪-暴雪
+ JLWeatherTypeHeavySnow,
+ ///暴雪
+ JLWeatherTypeSnowstorm,
+ ///浮尘
+ JLWeatherTypeDust,
+ ///扬沙
+ JLWeatherTypeblowingSand,
+ ///沙尘暴
+ JLWeatherTypedustStorm,
+ ///强沙尘暴
+ JLWeatherTypeSevereSandstorm,
+ ///龙卷风
+ JLWeatherTypeTornado,
+ ///雾/轻雾/浓雾/强浓雾/特强浓雾
+ JLWeatherTypeFog,
+ ///未知
+ JLWeatherTypeUnknow,
+ ///冷
+ JLWeatherTypeCold,
+ ///未知2
+ JLWeatherTypeUnknown1,
+
+};
+
+typedef NS_ENUM(UInt8, JLWindDirectionType) {
+ ///无风向
+ JLWindDirectionTypeNone = 0x00,
+ ///东
+ JLWindDirectionTypeEast,
+ ///南
+ JLWindDirectionTypeSouth,
+ ///西
+ JLWindDirectionTypeWest,
+ ///北
+ JLWindDirectionTypeNorth,
+ ///东南
+ JLWindDirectionTypeEastSouth,
+ ///东北
+ JLWindDirectionTypeEastNorth,
+ ///西北
+ JLWindDirectionTypeWestNorth,
+ ///西南
+ JLWindDirectionTypeWestSouth,
+ ///旋转不定
+ JLWindDirectionTypeUnknow
+};
+
+@interface JL_MSG_Weather : NSObject
+
+/// 省份
+@property(nonatomic,strong)NSString *province;
+///城市
+@property(nonatomic,strong)NSString *city;
+///天气编码
+@property(nonatomic,assign)JLWeatherType code;
+///温度
+@property(nonatomic,assign)NSInteger temperature;
+///湿度
+@property(nonatomic,assign)NSInteger humidity;
+///风向编码
+@property(nonatomic,assign)JLWindDirectionType direction;
+///风力
+@property(nonatomic,assign)NSInteger wind;
+/// 时间
+@property(nonatomic,strong)NSDate *date;
+
+
+-(NSData *)beData;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_ManagerM.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2020/9/4.
+// Modify By EzioChan on 2023/03/27.
+// Copyright © 2020 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_RCSP.h>
+
+#import <JL_BLEKit/JLModel_Device.h>
+#import <JL_BLEKit/JLModel_RTC.h>
+#import <JL_BLEKit/JLModel_Ring.h>
+#import <JL_BLEKit/JLModel_File.h>
+#import <JL_BLEKit/JLModel_FM.h>
+#import <JL_BLEKit/JLModel_Headset.h>
+#import <JL_BLEKit/JLModel_BT.h>
+#import <JL_BLEKit/JLModel_EQ.h>
+#import <JL_BLEKit/JLModel_SPEEX.h>
+#import <JL_BLEKit/JLModel_Flash.h>
+#import <JL_BLEKit/JLModel_ANC.h>
+#import <JL_BLEKit/JLModel_AlarmSetting.h>
+#import <JL_BLEKit/RTC_RingInfo.h>
+
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_SmallFileManager.h>
+#import <JL_BLEKit/JL_FileManager.h>
+#import <JL_BLEKit/JL_FlashOperateManager.h>
+#import <JL_BLEKit/JL_BinChargeManager.h>
+#import <JL_BLEKit/JL_AlarmClockManager.h>
+#import <JL_BLEKit/JL_CallManager.h>
+#import <JL_BLEKit/JL_LightManager.h>
+#import <JL_BLEKit/JL_TwsManager.h>
+#import <JL_BLEKit/JL_SoundCardManager.h>
+#import <JL_BLEKit/JL_LrcManager.h>
+#import <JL_BLEKit/JL_SpeexManager.h>
+#import <JL_BLEKit/JL_FindDeviceManager.h>
+#import <JL_BLEKit/JL_MusicControlManager.h>
+#import <JL_BLEKit/JL_FmManager.h>
+#import <JL_BLEKit/JL_SystemEQ.h>
+#import <JL_BLEKit/JL_SystemTime.h>
+#import <JL_BLEKit/JL_SystemVolume.h>
+#import <JL_BLEKit/JL_CustomManager.h>
+#import <JL_BLEKit/JL_BigDataManager.h>
+#import <JL_BLEKit/JL_DeviceLogs.h>
+#import <JL_BLEKit/JL_BatchManger.h>
+#import <JL_OTALib/JL_OTALib.h>
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+/*
+ * 从JL_ManagerM发出去的通知都是字典,如下所示:
+ *
+ * @{ kJL_MANAGER_KEY_UUID :当前设备的UUID,
+ * kJL_MANAGER_KEY_OBJECT:外抛的对象 }
+ */
+extern NSString *kJL_MANAGER_KEY_UUID; //KEY --> UUID
+extern NSString *kJL_MANAGER_KEY_OBJECT; //KEY --> 对象
+
+
+@protocol JL_ManagerMDelegate <NSObject>
+@optional
+-(void)onManagerSendPackage:(JL_PKG*)pkg;
+@end
+
+@class JL_EntityM;
+@interface JL_ManagerM : NSObject
+@property(nonatomic,weak)id<JL_ManagerMDelegate>delegate;
+@property(nonatomic,readonly,copy)NSString *mBLE_UUID;
+@property(nonatomic,readonly,copy)NSString *mBLE_NAME;
+@property(nonatomic,readonly,assign)uint8_t mCmdSN;
+@property(nonatomic,weak)JL_EntityM *mEntity;
+
+@property(nonatomic,strong)JL_SmallFileManager *mSmallFileManager;
+@property(nonatomic,strong)JL_FileManager *mFileManager;
+@property(nonatomic,strong)JL_OTAManager *mOTAManager;
+@property(nonatomic,strong)JL_FlashOperateManager *mFlashManager;
+@property(nonatomic,strong)JL_BinChargeManager *mChargingBinManager;
+@property(nonatomic,strong)JL_CallManager *mCallManager;
+@property(nonatomic,strong)JL_AlarmClockManager *mAlarmClockManager;
+@property(nonatomic,strong)JL_LightManager *mLightManager;
+@property(nonatomic,strong)JL_TwsManager *mTwsManager;
+@property(nonatomic,strong)JL_SpeexManager *mSpeexManager;
+@property(nonatomic,strong)JL_LRCManager *mLrcManager;
+@property(nonatomic,strong)JL_FindDeviceManager *mFindDeviceManager;
+@property(nonatomic,strong)JL_MusicControlManager *mMusicControlManager;
+@property(nonatomic,strong)JL_FmManager *mFmManager;
+@property(nonatomic,strong)JL_SystemEQ *mSystemEQ;
+@property(nonatomic,strong)JL_SystemTime *mSystemTime;
+@property(nonatomic,strong)JL_SystemVolume *mSystemVolume;
+@property(nonatomic,strong)JL_CustomManager *mCustomManager;
+@property(nonatomic,strong)JL_BatchManger *mBatchManger;
+
+@property(nonatomic,strong)JL_SoundCardManager *mSoundCardManager;
+@property(nonatomic,strong)JL_DeviceLogs *mDeviceLogs;
+
+@property(nonatomic,strong)JL_BigDataManager *mBigDataManager;
+
+
+-(void)setPropertyUpdate:(BOOL)isUpdate;
+-(void)setBleUuid:(NSString*)uuid;
+-(void)setBleName:(NSString*)name;
+-(void)inputPKG:(JL_PKG*)pkg;
+
+-(void)noteEntityConnected;
+-(void)noteEntityDisconnected;
+-(void)noteEntityBleOff;
+
+/**
+ 发送【命令包】
+ @param cmdCode 具体要发送的命令
+ @param needResponse 是否需要回复
+ @param sendData 具体要发送的数据
+ @discussion 只有isCommand是YES时needResponse才有意义,即只有命令才需要回复
+ */
+-(void)xmCommandCode:(uint8_t)cmdCode
+ needRep:(BOOL)needResponse
+ data:(NSData *)sendData;
+
+/**
+ 发送【回复包】
+ @param code 命令号
+ @param sn 序号
+ @param st 状态码
+ @param data 回复的命令的内容
+ */
+-(void)cmdResponseCode:(uint8_t)code
+ OpSN:(UInt8)sn
+ Status:(JL_CMDStatus)st
+ Data:(NSData* __nullable)data;
+
+/**
+ 发送【通知命令】
+ @param name 通知名字
+ @param obj 携带对象
+ */
+-(void)managerPost:(NSString*)name Object:(id __nullable)obj;
+
+/**
+ 获取当前命令序号
+ */
+-(uint8_t)xmCommandSN;
+
+#pragma mark ---> 取出设备信息
+
+/// copy出来的原值
+-(JLModel_Device *)outputDeviceModel;
+
+/// 取出原本的值
+-(JLModel_Device *)getDeviceModel;
+
+#pragma mark ---> 获取设备信息
+extern NSString *kJL_MANAGER_TARGET_INFO;
+-(void)cmdTargetFeatureResult:(JL_CMD_RESPOND __nullable)result;
+-(void)cmdTargetFeature:(uint32_t)feature Result:(JL_CMD_RESPOND __nullable)result;
+
+#pragma mark ---> 断开经典蓝牙
+-(void)cmdDisconnectEdrResult:(JL_CMD_RESPOND __nullable)result;
+
+#pragma mark ---> 重置配对流程标志(使适配连接ANCS设备)
+-(void)cmdResetPairingResult:(JL_CMD_RESPOND __nullable)result;
+
+#pragma mark ---> 获取系统信息(全获取)
+/**
+ @param function JL_FunctionCode
+ @param result 回复
+ */
+-(void)cmdGetSystemInfo:(JL_FunctionCode)function
+ Result:(JL_CMD_RESPOND __nullable)result;
+-(void)cmdGetSystemInfoResult;
+
+#pragma mark ---> 获取系统信息(选择性获取)
+/**
+ @param function JL_FunctionCode
+ @param result 回复
+ */
+-(void)cmdGetSystemInfo:(JL_FunctionCode)function
+ SelectionBit:(uint32_t)bits
+ Result:(JL_CMD_RESPOND __nullable)result;
+-(void)cmdGetSystemInfoResult_1;
+
+#pragma mark ---> 设备主动返回的系统信息
+extern NSString *kJL_MANAGER_SYSTEM_INFO;
+
+#pragma mark ---> 通用、BT、Music、RTC、Aux
+/**
+ @param function 功能类型
+ @param cmd 操作命令
+ @param ext 扩展数据
+ @param result 回复
+ */
+-(void)cmdFunction:(JL_FunctionCode)function
+ Command:(UInt8)cmd
+ Extend:(UInt8)ext
+ Result:(JL_CMD_RESPOND __nullable)result;
+
+typedef void(^JL_IMAGE_RT)(NSMutableDictionary* __nullable dict);
+#pragma mark ---> 获取设备的图片
+/**
+ @param vid 设备vid
+ @param pid 设备pid
+ @param result 图片数据
+ */
+-(void)cmdRequestDeviceImageVid:(NSString*)vid
+ Pid:(NSString*)pid
+ Result:(JL_IMAGE_RT __nullable)result;
+
+-(void)cmdRequestDeviceImageVid:(NSString*)vid
+ Pid:(NSString*)pid
+ ItemArray:(NSArray *__nullable)itemArray
+ Result:(JL_IMAGE_RT __nullable)result;
+
+-(NSDictionary*)localDeviceImage:(NSString*)jsonFile;
+
+#pragma mark ---> 通知固件开始播放TTS内容
+
+/// 通知固件SDK播放tts
+/// @param status 0:开始播放,1:播放结束
+-(void)cmdStartTTSNote:(uint8_t)status;
+
+
+/// 获取MD5信息
+/// @param result 回调
+-(void)cmdGetMD5_Result:(JL_CMD_RESPOND)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_MusicControlManager.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/20.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+__attribute__((deprecated("已废弃,请使用JLDevPlayerCtrl类")))
+
+@interface JL_MusicControlManager : JL_FunctionBaseManager
+
+
+#pragma mark ---> 设置播放模式
+/**
+ @param mode 模式
+ 0x01:全部循环; 0x02:设备循环; 0x03:单曲循环; 0x04:随机播放; 0x05:文件夹循环
+ */
+-(void)cmdSetSystemPlayMode:(JL_MusicMode)mode __attribute__((deprecated("cmdSetPlayMode:已废弃")));
+
+#pragma mark ---> 快进快退
+/**
+ @param cmd 快进或者快退枚举
+ @param sec 时间
+ @param result 返回结果
+ */
+-(void)cmdFastPlay:(JL_FCmdMusic)cmd
+ Second:(uint16_t)sec
+ Result:(JL_CMD_RESPOND __nullable)result __attribute__((deprecated("cmdFastPlay:已废弃,需要使用JLDevPlayerCtrl类里的方法设置")));
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_NFC.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/8/2.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_TypeEnum.h"
+#import "JL_ManagerM.h"
+
+@class JL_RCSP;
+@class JL_EntityM;
+@class NfcFileModel;
+@class NfcModel;
+NS_ASSUME_NONNULL_BEGIN
+
+typedef void(^NfcSyncResult)(UInt8 result,NSArray<NfcModel *> * _Nullable models);
+
+typedef void(^NfcIDResult)(UInt16 result);
+
+typedef void(^NfcDefaultResult)(BOOL result);
+
+typedef void(^NfcBeginAddResult)(JL_EntityM *entity);
+
+
+@interface JL_NFC : NSObject
+
+-(instancetype)initWith:(JL_EntityM *)entity FileHandler:(JL_FileHandleType)handler;
+
+
+/// 同步NFC信息开始
+-(void)w_syncNfcStart:(NfcSyncResult)result;
+
+
+/// 修改NFC的信息
+/// @param dict 修改的内容
+/**
+ dict 的内容
+ {
+ @"timestamp" : NSDate()
+ @"nickname" : @"我的家"
+ }
+ 如果key值找不到对应的value,那就说明该项值不参与被修改
+ */
+-(void)w_modifyNfc:(NSDictionary *)dict WithID:(UInt16)nfcID;
+
+
+/// 删除NFC信息
+/// @param model nfc头部model
+-(void)w_deleteNfc:(NfcModel *)model;
+
+
+/// 获取当前正在使用着的默认NFC卡ID
+/// @param result NFC卡id
+-(void)w_getNfcDefaultCard:(NfcIDResult)result;
+
+
+/// 设置默认的NFC信息
+/// @param model NFC头部model
+-(void)w_setNfcDefalutCard:(NfcModel *)model result:(NfcDefaultResult)result;
+
+
+/// 通知默认NFC改变
+/// @param model NFC信息头部
+-(void)w_NfcDefaultNotify:(NfcModel *)model;
+
+/// 添加NFC文件
+/// @param model NFC文件模型
+/// @param result 开始传输操作
+/** examp.
+ NfcFileModel *fm = [[NfcFileModel alloc] init];
+// fm.idCard = ...
+// fm.nfcFileName = ...
+ JL_NFC *mgr = [[JL_NFC alloc] init];
+ [mgr w_NfcAddCard:fm BeginAdd:^(JL_EntityM * _Nonnull entity) {
+ //大文件传输开始
+ [entity.mCmdManager cmdBigFileData:#path WithFileName:#fileName Result:^(JL_BigFileResult result, float progress) {
+ if (result == JL_BigFileTransferEnd) {
+ //结束NFC文件添加
+ [mgr w_NfcEndAdd:fm];
+ }
+
+ }];
+ }];
+ */
+-(void)w_NfcAddCard:(NfcFileModel *)model BeginAdd:(NfcBeginAddResult)result;
+
+/// 添加NFC文件结束
+/// @param model NFC文件模型
+-(void)w_NfcEndAdd:(NfcFileModel *)model;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_OpCode.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2022/12/28.
+// Copyright © 2022 www.zh-jieli.com. All rights reserved.
+//
+
+#ifndef JL_OpCode_h
+#define JL_OpCode_h
+
+#define kJL_DATA_CMD 0x0001
+#define kJL_GET_TARGET_FEATURE_MAP 0x0002 //保留
+#define kJL_GET_TARGET_FEATURE 0x0003
+#define kJL_VOICE_START 0x0004
+#define kJL_VOICE_STOP 0x0005
+#define kJL_VOICE_DISCONNECT_EDR 0x0006
+#define kJL_SYS_INFO_GET 0x0007
+#define kJL_SYS_INFO_SET 0x0008
+#define kJL_SYS_INFO_AUTO_UPDATE 0x0009
+#define kJL_PHONE_CALL_REQUEST 0x000a
+#define kJL_FILE_BROWSE_START 0x000c
+#define kJL_FILE_BROWSE_STOP 0x000d
+#define kJL_FILE_STRUCT_CHANGE 0x00f2 //通知文件结构变化
+#define kJL_FUNCTION_CMD 0x000e
+#define kJL_LRC_GET_START 0x000f
+#define kJL_LRC_GET_STOP 0x0010
+#define kJL_A2F_TTS_START 0x0011
+#define kJL_BT_SCAN_START 0x0012
+#define kJL_BT_SCAN_RESULT 0x0013
+#define kJL_BT_SCAN_STOP 0x0014
+//#define kJL_BT_CONNECT 0x0015
+#define kJL_FILE_START 0x0016
+#define kJL_FILE_STOP 0x0017
+#define kJL_FIND_DEVICE 0x0019
+#define kJL_CUSTOMER_USER 0x00ff
+
+#define kJL_OTA_INFO_OFFSET 0x00e1
+#define kJL_OTA_CAN_UPDATE 0x00e2
+#define kJL_OTA_ENTER_UPDATE 0x00e3
+#define kJL_OTA_EXIT_UPDATE 0x00e4
+#define kJL_OTA_GET_DATA 0x00e5
+#define kJL_OTA_STATUS_UPDATE 0x00e6
+#define kJL_OTA_REBOOT 0x00e7
+#define kJL_OTA_BLE_SPP 0x000b
+#define kJL_OTA_LENGTH 0x00e8
+
+#define kJL_SET_ADV 0x00C0
+#define kJL_GET_ADV 0x00C1
+#define kJL_ADV_NOTIFY_DEVICE 0x00C2
+#define kJL_ADV_NOTIFY_ENABLE 0x00C3
+#define kJL_ADV_NOTIFY_TIPS 0x00C4 //主要用于ADV设置同步后需要主机操作的行为。
+
+#define kJL_SET_APP_INFO 0x00D0
+#define kJL_SET_MTU 0x00D1
+#define kJL_GET_MD5 0x00D4
+#define kJL_GET_LOW_DELAY 0x00D5
+#define kJL_GET_FLASH_INFO 0x00D6
+#define kJL_SET_DEV_STORAGE 0x00D8 //设置当前使用的存储设备
+#define kJL_GET_DEV_CONFIG 0x00D9 //获取设备配置信息
+#define kJL_GET_FLASH_W_R 0x001A
+
+#define kJL_BIGFILE_START 0x001B
+#define kJL_BIGFILE_END 0x001C
+#define kJL_BIGFILE_GET_FILE 0x001D
+#define kJL_BIGFILE_STOP 0x001E
+#define kJL_FILE_DELETE 0x001F
+#define kJL_GET_FILENAME 0x0020
+#define kJL_PRE_ENVIRONMENT 0x0021
+#define kJL_FILE_FORMAT 0x0022
+#define kJL_FILE_NAME_DEL 0x0023
+#define kJL_FILE_READ_CONTENT 0x0024
+
+#define kJL_RTC_PLUS 0x0025
+#define kJL_BATCH_OPERATE 0x0026
+#define kJL_FILE_GET_CRC 0x0027
+#define kJL_SMALL_FILE 0x0028
+
+#define kJL_DEVICE_LOG 0x0029
+#define kJL_BIG_DATA 0x0030
+#define kJL_TWS_NAME_LIST 0x0031 //一拖二/获取设备已连接手机名
+#define kJL_AI_CONTROL 0x0032 //AI控制命令
+#define kJL_PUBLIC_SET 0x0033 //公共设置命令
+
+
+#define kJL_WEAR_REQ_OPCODE 0x00A0 //获取运动信息
+#define kJL_WEAR_SET_OPCODE 0x00A1 //设置运动信息
+#define kJL_WEAR_RES_OPCODE 0x00A2 //设备主动推的运动信息
+#define kJL_WEAR_CMD_LOG 0x00A3 //传感器log传输命令
+#define kJL_WEAR_CMD_SETTING 0x00A5 //健康设备设置命令
+#define kJL_WEAR_SYNC_SPORT 0x00A6 //运动模式相关命令(同步数据)
+
+#define kJL_PHONE_NUMBER_WAY 0x00F1
+
+#endif /* JL_OpCode_h */
--- /dev/null
+//
+// JL_RCSP.h
+// JL_BLEKit
+//
+// Created by zhihui liang on 2018/11/9.
+// Copyright © 2018 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_OpCode.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+
+@class JL_PKG;
+@interface JL_RCSP : NSObject
+
+/**
+ 解析JL数据包
+
+ @param data 把数据转成JL_PKG模型。
+ @return JL_PKG数据模型
+ */
++(JL_PKG*)rcspAnalysisData:(NSData*)data;
+
+/**
+ 生成XM数据包
+
+ @param pkg 把JL_PKG模型转成data。
+ @return 数据
+ */
++(NSData*)rcspMakePackage:(JL_PKG*)pkg;
+
+/**
+ 分析JL_PKG参数
+
+ @param pkg 把JL_PKG的xmData参数部分解析成一列数组。
+ @return 参数数组
+ */
++(NSArray*)rcspAnalysisParams:(JL_PKG*)pkg;
+
+/**
+ 分解dJL_PKG信息
+
+ @param data JL_PKG中的信息数据
+ @return 参数c数组
+ */
++(NSArray*)rcspInfoArrFromData:(NSData*)data;
+
+/// 拆分LTV数据
+/// 当前方法针对的是 L 长度为 2Byte
+/// @param data LTV数据
++(NSArray*)rcspInfoFromData2ByteSize:(NSData*)data;
+
+/**
+ 生成JL_PKG参数
+
+ @param array 把参数数组变成data(注意:数组元素必须是NSData类型)。
+ @return 数据
+ */
++(NSData*)rcspMakeParams:(NSArray*)array;
+@end
+
+@interface JL_PKG : NSObject
+@property(assign,nonatomic) uint16_t pkgIsCommand; //1Bit
+@property(assign,nonatomic) uint16_t pkgNeedResponse; //1Bit
+@property(assign,nonatomic) uint16_t pkgUnused; //6Bits
+@property(assign,nonatomic) uint16_t pkgOpCode; //8Bits
+@property(assign,nonatomic) uint16_t pkgLength; //参数长度(本身不计)
+@property(strong,nonatomic) NSData *pkgData; //参数数据
+@end
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_AirPressure.h
+// Test
+//
+// Created by EzioChan on 2021/4/6.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 压力实时
+@interface JL_SDM_AirPressure : JLSportDataModel
+/// 实时
+@property(nonatomic,assign)int realTime;
+/// 最高
+@property(nonatomic,assign)int max;
+/// 最低
+@property(nonatomic,assign)int min;
+
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_AirPressure*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求内容设置
+/// @param rt 是否需要实时气压
+/// @param min 是否需要最小气压
+/// @param max 是否需要最大气压
++(JL_SDM_AirPressure*)requireRealTime:(BOOL)rt min:(BOOL)min Max:(BOOL)max;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_Altitude.h
+// Test
+//
+// Created by EzioChan on 2021/4/6.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+///海拔高度相关
+@interface JL_SDM_Altitude : JLSportDataModel
+
+/// 最大值
+@property(nonatomic,assign)float max;
+/// 最小值
+@property(nonatomic,assign)float min;
+/// 实时的
+@property(nonatomic,assign)float realTime;
+
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_Altitude*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求海拔内容设置
+/// @param rt 是否需要实时海拔
+/// @param min 是否需要最小海拔
+/// @param max 是否需要最大海拔
++(JL_SDM_Altitude*)requireRealTime:(BOOL)rt min:(BOOL)min Max:(BOOL)max;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_Header.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/4/8.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#ifndef JL_SDM_Header_h
+#define JL_SDM_Header_h
+
+#import <Foundation/Foundation.h>
+#import "JL_SDM_Stress.h"
+#import "JL_SDM_Altitude.h"
+#import "JL_SDM_MaxOxg.h"
+#import "JL_SDM_RecTime.h"
+#import "JL_SDM_HeartRate.h"
+#import "JL_SDM_MoveSteps.h"
+#import "JL_SDM_TrainLoad.h"
+#import "JL_SDM_AirPressure.h"
+#import "JL_SDM_OxSaturation.h"
+#import "JL_SDM_SportMessage.h"
+#import "JL_MSG_Weather.h"
+#import "JL_MSG_Func.h"
+#import "JLWatchEnum.h"
+#import "NfcModel.h"
+#import "JLwSettingModel.h"
+#import "JLSensorFuncModel.h"
+#import "JLSedentaryRmdModel.h"
+#import "JLConsequentHeartRateModel.h"
+#import "JLExerciseHeartRateRemindModel.h"
+#import "JLAutoPressureModel.h"
+#import "JLSleepMonitorModel.h"
+#import "JLFallDetectionModel.h"
+#import "JLEmergencyContactModel.h"
+#import "JLOxygenSturationRemindModel.h"
+#import "JLWristLiftDetectionModel.h"
+#import "JLPersonInfoModel.h"
+#import "JLDisconnectRemindModel.h"
+#import "JLWearSyncInfoModel.h"
+#import "JLWearSyncFinishModel.h"
+#import "JLWearSyncRealTimeModel.h"
+#import "JLeSimManager.h"
+
+
+#include <syslog.h>
+#ifndef JL_IOS
+#define JL_IOS
+#endif
+
+#pragma - Please select your log mode and log level
+
+// Note: Only debug mode will print log. You could also set mode for log level.
+#define kJLDebugMode
+// JLLogLevelFatal , JLLogLevelError , JLLogLevelWarn , JLLogLevelInfo , JLLogLevelDebug
+#define JLLogLevelError
+//Note: print method name
+#define kModuleName __func__
+
+#pragma ----------------------------------
+
+#ifdef kJLDebugMode
+
+static const int JL_IOS_FLAG_FATAL = 0x10;
+static const int JL_IOS_FLAG_ERROR = 0x08;
+static const int JL_IOS_FLAG_WARN = 0x04;
+static const int JL_IOS_FLAG_INFO = 0x02;
+static const int JL_IOS_FLAG_DEBUG = 0x01;
+
+#ifdef JLLogLevelFatal
+static const int JL_IOS_LOG_LEVEL = JL_IOS_FLAG_FATAL;
+#elif defined(JLLogLevelError)
+static const int JL_IOS_LOG_LEVEL = (JL_IOS_FLAG_FATAL | JL_IOS_FLAG_ERROR);
+#elif defined(JLLogLevelWarn)
+static const int JL_IOS_LOG_LEVEL = (JL_IOS_FLAG_FATAL | JL_IOS_FLAG_ERROR | JL_IOS_FLAG_WARN);
+#elif defined(JLLogLevelInfo)
+static const int JL_IOS_LOG_LEVEL = (JL_IOS_FLAG_FATAL | JL_IOS_FLAG_ERROR | JL_IOS_FLAG_WARN | JL_IOS_FLAG_INFO);
+#elif defined(JLLogLevelDebug)
+static const int JL_IOS_LOG_LEVEL = (JL_IOS_FLAG_FATAL | JL_IOS_FLAG_ERROR | JL_IOS_FLAG_WARN | JL_IOS_FLAG_INFO | JL_IOS_FLAG_DEBUG);
+#endif
+
+
+
+#define log4cplus_fatal(category, logFmt, ...) \
+if(JL_IOS_LOG_LEVEL & JL_IOS_FLAG_FATAL) \
+syslog(LOG_CRIT, "%s:" logFmt, category,##__VA_ARGS__); \
+
+#define log4cplus_error(category, logFmt, ...) \
+if(JL_IOS_LOG_LEVEL & JL_IOS_FLAG_ERROR) \
+syslog(LOG_ERR, "%s:" logFmt, category,##__VA_ARGS__); \
+
+#define log4cplus_warn(category, logFmt, ...) \
+if(JL_IOS_LOG_LEVEL & JL_IOS_FLAG_WARN) \
+syslog(LOG_WARNING, "%s:" logFmt, category,##__VA_ARGS__); \
+
+#define log4cplus_info(category, logFmt, ...) \
+if(JL_IOS_LOG_LEVEL & JL_IOS_FLAG_INFO) \
+syslog(LOG_WARNING, "%s:" logFmt, category,##__VA_ARGS__); \
+
+#define log4cplus_debug(category, logFmt, ...) \
+if(JL_IOS_LOG_LEVEL & JL_IOS_FLAG_DEBUG) \
+syslog(LOG_WARNING, "%s:" logFmt, category,##__VA_ARGS__); \
+
+
+#else
+
+#define log4cplus_fatal(category, logFmt, ...); \
+
+#define log4cplus_error(category, logFmt, ...); \
+
+#define log4cplus_warn(category, logFmt, ...); \
+
+#define log4cplus_info(category, logFmt, ...); \
+
+#define log4cplus_debug(category, logFmt, ...); \
+
+#endif
+
+///心率
+typedef void(^JL_CB_HeartRate)(JL_SDM_HeartRate *heartRate);
+///气压
+typedef void(^JL_CB_AirPressure)(JL_SDM_AirPressure *ap);
+///海拔
+typedef void(^JL_CB_Altitude)(JL_SDM_Altitude *altitude);
+///运动步数
+typedef void(^JL_CB_MoveSteps)(JL_SDM_MoveSteps *ms);
+///压力检测
+typedef void(^JL_CB_Stress)(JL_SDM_Stress *stress);
+///血氧饱和度
+typedef void(^JL_CB_Oxsaturation)(JL_SDM_OxSaturation *oxs);
+///训练负荷
+typedef void(^JL_CB_TrainLoad)(JL_SDM_TrainLoad *tl);
+///最大摄氧量
+typedef void(^JL_CB_MaxOxg)(JL_SDM_MaxOxg *mo);
+///运动恢复时间
+typedef void(^JL_CB_RecTime)(JL_SDM_RecTime *rt);
+///运动信息
+typedef void(^JL_CB_SportMsg)(JL_SDM_SportMessage *sm);
+///传感器log
+typedef void(^JL_CB_WatchLog)(JL_WATCH_LOG_TYPE type,NSData *data);
+
+//MARK:设置相关
+///设置状态回复
+typedef void(^JL_CB_Status)(BOOL succeed);
+
+//MARK: - 同步相关
+///读取同步运动状态
+typedef void(^JL_CB_SyncSportInfo)(JLWearSyncInfoModel *infoModel);
+/// 读取同步状态
+typedef void(^JL_CB_SyncSportDataInfo)(JLWearSyncDataModel *infoModel);
+
+
+#endif /* JL_SDM_Header_h */
--- /dev/null
+//
+// JL_SDM_HeartBeat.h
+// Test
+//
+// Created by EzioChan on 2021/4/6.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+/*
+ * 这是一个Sport Data Model的对象
+ */
+///心率model
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 心率相关内容
+@interface JL_SDM_HeartRate : JLSportDataModel
+/// 实时心率
+@property(nonatomic,assign)uint8_t realTime;
+/// 静息心率
+@property(nonatomic,assign)uint8_t resting;
+/// 最大心率
+@property(nonatomic,assign)uint8_t max;
+
+/// 单次测量的心率
+@property(nonatomic,assign)uint8_t singleRate;
+
+/// 是否为单次测量的数据
+@property(nonatomic,assign)BOOL isSingle;
+
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_HeartRate*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求心率内容设置
+/// @param rt 是否需要实时心率
+/// @param rting 是否需要静息心率
+/// @param max 是否需要最大心率
++(JL_SDM_HeartRate*)requireRealTime:(BOOL)rt Resting:(BOOL)rting Max:(BOOL)max;
+
+/// 单次测量
++(JL_SDM_HeartRate*)requireSingle;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_MaxOxg.h
+// Test
+//
+// Created by EzioChan on 2021/4/7.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_SDM_MaxOxg : JLSportDataModel
+
+@property(nonatomic,assign)int max;
+
+///最大摄氧量
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_MaxOxg*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求内容
++(JL_SDM_MaxOxg*)require;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_MoveSteps.h
+// Test
+//
+// Created by EzioChan on 2021/4/6.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+///实时步数
+@interface JL_SDM_MoveSteps : JLSportDataModel
+/// 实时步数
+@property(nonatomic,assign)NSInteger rtStep;
+
+/// 热量,单位:千卡
+@property(nonatomic,assign)NSInteger calories;
+
+/// 距离,单位:0.01公里
+@property(nonatomic,assign)NSInteger distance;
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_MoveSteps*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 选择性请求内容
++(JL_SDM_MoveSteps*)require:(BOOL)rst distance:(BOOL)dts calories:(BOOL)ca;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_OxSaturation.h
+// Test
+//
+// Created by EzioChan on 2021/4/7.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JLOxSaturationType) {
+ //当前血氧饱和度
+ JLOxSaturation_nowSta = 0x01,
+ //最大血氧
+ JLOxSaturation_max = 0x01 << 1,
+ //最小血氧
+ JLOxSaturation_min = 0x01 << 2,
+ //单次测量
+ JLOxSaturation_single = 0x01 << 3
+};
+
+/// 血氧饱和度
+@interface JL_SDM_OxSaturation : JLSportDataModel
+
+/// 饱和度
+@property(nonatomic,assign)int staturation;
+/// 最大饱和度
+@property(nonatomic,assign)uint8_t max;
+/// 最小饱和度
+@property(nonatomic,assign)uint8_t min;
+
+/// 单次测量的饱和度
+@property(nonatomic,assign)uint8_t singleStaturation;
+
+/// 是否为单次测量的数据
+@property(nonatomic,assign)BOOL isSingle;
+
+
+/// 血氧饱和度
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_OxSaturation*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求内容
++(JL_SDM_OxSaturation*)require;
+
+
+/// 请求血氧浓度
+/// @param type 类型
+/// 该类型可以同时请求多个,诸如:JLOxSaturation_nowSta | JLOxSaturation_max | JLOxSaturation_min
++(JL_SDM_OxSaturation*)requireByBit:(JLOxSaturationType)type;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_RecTime.h
+// Test
+//
+// Created by EzioChan on 2021/4/7.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_SDM_RecTime : JLSportDataModel
+
+@property(nonatomic,assign)int hour;
+@property(nonatomic,assign)int min;
+
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_RecTime*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求内容
++(JL_SDM_RecTime*)require;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_SportMessage.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/4/8.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+#import "JLWatchEnum.h"
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_SDM_SportMessage : JLSportDataModel
+
+/// 运动模式
+@property(nonatomic,assign)JL_SportPattern sportPattern;
+/// 距离,单位:0.01km
+@property(nonatomic,assign)int distance;
+/// 开始时间
+@property(nonatomic,strong)NSDate *startTime;
+/// 结束时间
+@property(nonatomic,strong)NSDate *endTime;
+/// 热量,单位:千卡 Kcal
+@property(nonatomic,assign)int xkcal;
+/// 速度。单位:0.01 km/h
+@property(nonatomic,assign)int speed;
+
+
+/// 分析返回的数据
+/// @param value subData
+/// @param submask submask
++(JL_SDM_SportMessage *)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求要获取的内容
+/// @param m 是否请求模式
+/// @param d 是否请求距离
+/// @param st 是否请求开始时间
+/// @param et 是否请求结束时间
+/// @param kcal 是否请求卡路里
+/// @param sp 是否请求速度
++(JL_SDM_SportMessage *)requireModel:(BOOL)m distance:(BOOL)d start:(BOOL)st end:(BOOL)et kcal:(BOOL)kcal speed:(BOOL)sp;
+
+/// 请求全部数据
++(JL_SDM_SportMessage *)requireAll;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_Stress.h
+// Test
+//
+// Created by EzioChan on 2021/4/7.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 实时压力
+@interface JL_SDM_Stress : JLSportDataModel
+
+@property(nonatomic,assign)int stress;
+
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_Stress*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求内容
++(JL_SDM_Stress*)require;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SDM_TrainLoad.h
+// Test
+//
+// Created by EzioChan on 2021/4/7.
+// Copyright © 2021 Zhuhai Jieli Technology Co.,Ltd. All rights reserved.
+//
+
+#import "JLSportDataModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_SDM_TrainLoad : JLSportDataModel
+
+@property(nonatomic,assign)int load;
+
+///训练负荷
+/// 处理回复数据内容
+/// @param value 数据内容
+/// @param submask 功能标记位
++(JL_SDM_TrainLoad*)responseData:(NSData *)value subMask:(NSData *)submask;
+
+/// 请求内容
++(JL_SDM_TrainLoad*)require;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SmallFileManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/12/13.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JLModel_SmallFile.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_SmallFileOperate) {
+ JL_SmallFileOperateFail = 0x00, //失败
+ JL_SmallFileOperateDoing = 0x01, //操作中
+ JL_SmallFileOperateSuceess = 0x02, //成功
+ JL_SmallFileOperateUnknown = 0x03, //未知
+ JL_SmallFileOperateExcess = 0x04, //超量
+ JL_SmallFileOperateCrcError = 0x05, //CRC错误
+ JL_SmallFileOperateTimeout = 0x06, //超时
+};
+typedef void(^JL_SMALLFILE_DEL)(JL_SmallFileOperate status);
+typedef void(^JL_SMALLFILE_READ)(JL_SmallFileOperate status,
+ float progress, NSData* __nullable data);
+typedef void(^JL_SMALLFILE_NEW)(JL_SmallFileOperate status,
+ float progress, uint16_t fileID);
+typedef void(^JL_SMALLFILE_UPDATE)(JL_SmallFileOperate status,
+ float progress);
+typedef void(^JL_SMALLFILE_LIST)(NSArray <JLModel_SmallFile*>* __nullable array);
+typedef void(^JL_SMALLFILE_RT)(uint8_t flag, uint16_t fileID,NSData* __nullable data);
+
+@interface JL_SmallFileManager : JL_FunctionBaseManager
+
+#pragma mark - 查询文件
+
+/// 查询文件
+/// @param type 文件类型
+/// 文件类型除了已有的文件外,还可以扩展类型是Uint8的值
+/// @param result 列表回调
+-(void)cmdSmallFileQueryType:(JL_SmallFileType)type
+ Result:(JL_SMALLFILE_LIST __nullable)result;
+
+#pragma mark - 删除文件
+
+/// 删除文件
+/// @param file 文件模型:JLModel_SmallFile
+/// @param result 操作回调结果
+-(void)cmdSmallFileDelete:(JLModel_SmallFile*)file Result:(JL_SMALLFILE_DEL)result;
+
+#pragma mark - 读取文件
+
+/// 读取文件
+/// @param file 文件模型:JLModel_SmallFile
+/// @param result 回调文件数据以及进度,通过分包式回调。
+-(void)cmdSmallFileRead:(JLModel_SmallFile*)file
+ Result:(JL_SMALLFILE_READ)result;
+
+-(void)cmdSmallFileReadSync:(JLModel_SmallFile*)file
+ Result:(JL_SMALLFILE_READ)result;//同步
+
+#pragma mark - 新增文件
+
+/// 新增文件
+/// @param data 文件数据
+/// @param type 文件类型
+/// @param result 回调的结果,包含分包进度
+-(void)cmdSmallFileNew:(NSData*)data
+ Type:(JL_SmallFileType)type
+ Result:(JL_SMALLFILE_NEW)result;
+
+-(void)cmdSmallFileNewSync:(NSData*)data
+ Type:(JL_SmallFileType)type
+ Result:(JL_SMALLFILE_NEW)result;
+
+#pragma mark - 更新文件
+
+/// 更新文件
+/// @param file 文件模型:JLModel_SmallFile
+/// @param data 文件数据
+/// @param result 回调进度
+-(void)cmdSmallFileUpdate:(JLModel_SmallFile*)file
+ Data:(NSData*)data
+ Result:(JL_SMALLFILE_UPDATE)result;
+
+-(void)cmdSmallFileUpdateSync:(JLModel_SmallFile*)file
+ Data:(NSData*)data
+ Result:(JL_SMALLFILE_UPDATE)result;
+
+#pragma mark - 底层API
+
+/// 读取文件,更低等级的API
+/// @param type 文件类型
+/// @param fileId 文件ID
+/// @param offset 偏移值
+/// @param fileSize 数据大小
+/// @param flag 是否为第一包查询
+/// @param result 回调文件结果
+-(void)cmdSmallFileReadType:(uint8_t)type
+ FileID:(uint16_t)fileId
+ Offset:(uint16_t)offset
+ FileSize:(uint16_t)fileSize
+ Flag:(uint8_t)flag
+ Result:(JL_SMALLFILE_RT __nullable)result;
+
+
+/// 插入新文件,更低等级的API
+/// @param type 文件类型
+/// @param offset 偏移值
+/// @param fileSize 数据量大小
+/// @param crc16 crc校验码
+/// @param data 要插入的数据
+/// @param result 回调结果
+-(void)cmdSmallFileNewType:(uint8_t)type
+ Offset:(uint16_t)offset
+ FileSize:(uint16_t)fileSize
+ Crc16:(uint16_t)crc16
+ FileData:(NSData*)data
+ Result:(JL_SMALLFILE_RT __nullable)result;
+
+/// 更新文件,更低等级的API
+/// @param type 文件类型
+/// @param fileId 文件ID
+/// @param offset 偏移值
+/// @param fileSize 数据包的大小
+/// @param crc16 数据包的crc校验
+/// @param data 数据包
+/// @param result 回调结果
+-(void)cmdSmallFileUpdateType:(uint8_t)type
+ FileID:(uint16_t)fileId
+ Offset:(uint16_t)offset
+ FileSize:(uint16_t)fileSize
+ Crc16:(uint16_t)crc16
+ FileData:(NSData*)data
+ Result:(JL_SMALLFILE_RT __nullable)result;
+
+/// 小文件删除,更低等级的API
+/// @param type 文件类型
+/// @param fileId 文件id
+/// @param result 回调结果
+-(void)cmdSmallFileDeleteType:(uint8_t)type
+ FileID:(uint16_t)fileId
+ Result:(JL_SMALLFILE_RT __nullable)result;
+
+-(void)closeTimer;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SoundCardManager.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/20.
+// Modify by EzioChan on 2023/09/25.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+typedef NS_ENUM(uint8_t, JL_KalaoIndex) {
+ ///卡拉OK 混响
+ JL_KalaoIndexReverberation = 0,
+ ///卡拉OK 延时
+ JL_KalaoIndexDelayed = 1,
+ ///卡拉OK 音量
+ JL_KalaoIndexVolume = 2,
+};
+
+@class JL_ManagerM;
+
+/// 声卡功能
+@interface JLSoundCardIndexValue : NSObject
+
+@property (assign,nonatomic)uint8_t index;
+
+@property (assign,nonatomic)uint16_t value;
+
+@end
+
+@protocol JLSoundCardMgrDelegate <NSObject>
+
+/// 声卡控制回调
+/// - Parameters:
+/// - mask: 掩码
+/// - items: 掩码对应的值
+-(void)jlsoundCardMask:(uint64_t)mask values:(NSArray <JLSoundCardIndexValue *> *)items;
+
+/// 声卡控制回调
+/// - Parameter frequencyArray: 频率数组
+-(void)jlsoundCardMicFrequency:(NSArray*)frequencyArray;
+
+/// 声卡控制回调
+/// - Parameter eqArray: EQ数组
+-(void)jlsoundCardMicEQ:(NSArray*)eqArray;
+
+@end
+
+
+/// 卡拉OK(声卡控制相关)
+@interface JL_SoundCardManager : NSObject
+
+/// 卡拉OK 组件索引
+@property (assign,nonatomic)long index;
+
+/// 卡拉OK 组件的值
+@property (assign,nonatomic)long value;
+
+/// 卡拉OK 固件返回的掩码
+@property (assign,nonatomic)uint64_t mask;
+
+/// 声卡功能参数列表
+@property (strong,nonatomic)NSArray <JLSoundCardIndexValue *>* iVitems;
+
+/// 卡拉OK 频率数组
+@property (strong,nonatomic)NSArray *micFrequencyArray;
+
+/// 卡拉OK EQ数组
+@property (strong,nonatomic)NSArray *micEQArray;
+
+/// 代理
+@property (weak,nonatomic)id<JLSoundCardMgrDelegate> delegate;
+
+/// 设置卡拉OK【index、value】
+/// - Parameters:
+/// - manager: 设备对象
+/// - index: index 参数类型 JL_KalaoIndex 目前支持混响、延时、音量的设置。(具体可以看固件的json文件)
+/// - value: 0-100
+/// - result: 设置结果
+-(void)cmdSetKalaok:(JL_ManagerM *)manager Index:(JL_KalaoIndex)index Value:(uint16_t)value result:(JL_CMD_RESPOND)result;
+
+/// 设置卡拉OK【MIC EQ增益】
+/// - Parameters:
+/// - manager: 设备对象
+/// - array: @[@(0),@(0),@(0),@(0),@(0)] 单个取值范围 [-8.0 , +8.0]。
+/// - result: 设置结果
+-(void)cmdSetKaraoke:(JL_ManagerM *)manager micEQ:(NSArray*)array result:(JL_CMD_RESPOND)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SpeechAIttsHandler.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/7/22.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JLModel_SPEEX.h>
+#import <JL_BLEKit/JL_BigDataManager.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+@protocol JL_SpeechAIttsHandlerDelegate <NSObject>
+
+/// 设备回调ai云数据
+/// - Parameters:
+/// - manager: 设备
+/// - aicloud: AI云数据对象
+-(void)receiveDataFrom:(JL_ManagerM *)manager WithAiCloud:(JLSpeechAiCloud *)aicloud;
+
+/// 设备返回tts合成数据
+/// - Parameters:
+/// - manager: 设备
+/// - tts: tts数据对象
+-(void)receiveDataFrom:(JL_ManagerM *)manager WithTTS:(JLSpeechTTSSynthesis *)tts;
+
+@end
+
+@interface JL_SpeechAIttsHandler : NSObject
+
+@property(nonatomic,weak)id<JL_SpeechAIttsHandlerDelegate> delegate;
+
+
+/// 初始化一个语音大数据传输实例
+/// - Parameter mgr: JL_ManagerM
+- (instancetype)initWithMgr:(JL_ManagerM *)mgr;
+
+/// 发送tts语音合成信息
+/// - Parameters:
+/// - tts: tts语音对象内容
+/// - manager: 设备
+/// - result: 回调结果
+-(void)speechSendTTs:(JLSpeechTTSSynthesis *)tts manager:(JL_ManagerM *)manager result:(JL_BIGDATA_RT)result;
+
+/// 发送ai云数据到设备
+/// - Parameters:
+/// - cloud: ai云数据
+/// - manager: 设备
+/// - result: 回调结果
+-(void)speechSendAiCloud:(JLSpeechAiCloud *)cloud manager:(JL_ManagerM *)manager result:(JL_BIGDATA_RT)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SpeexManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/12/17.
+// Modify By EzioChan on 2023/03/27.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+#import <JL_BLEKit/JLModel_SPEEX.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+@class JL_SpeexManager;
+
+/// 录音状态代理处理
+@protocol JL_SpeexManagerDelegate <NSObject>
+/// 录音状态回调
+/// - Parameters:
+/// - manager: 操作设备
+/// - status: 录音状态
+/// - originator: 状态变更发起端
+/// 当发起者是Device时,才会具备params的参数,其中结束录音时,params的属性仅有mVadWay为可使用内容
+/// - params: 录音参数
+-(void)speexManager:(JL_SpeexManager *)manager Status:(JL_SpeakType)status By:(JLCMDOriginator)originator With:(JLRecordParams *_Nullable) params;
+
+/// 录音数据回调
+/// - Parameters:
+/// - manager: 操作设备
+/// - data: 数据
+-(void)speexManager:(JL_SpeexManager *)manager Audio:(NSData *)data;
+
+@end
+
+/// 设备录音管理对象
+@interface JL_SpeexManager : NSObject
+
+//MARK: - Sync Android Interface
+
+@property(nonatomic,weak)id<JL_SpeexManagerDelegate> delegate;
+
+/// 获取录音状态
+-(JL_SpeakType)cmdCheckRecordStatus;
+
+
+
+/// 开始录音
+/// - Parameters:
+/// - manager: 操作设备
+/// - params: 录音参数
+/// - result: 命令操作结果回调
+-(void)cmdStartRecord:(JL_ManagerM *)manager Params:(JLRecordParams *)params Result:(JL_CMD_RESPOND __nullable)result;
+
+
+/// 停止录音
+/// - Parameters:
+/// - manager: 操作设备
+/// - reason: VAD类型
+/// - result: 命令操作结果回调
+-(void)cmdStopRecord:(JL_ManagerM *)manager Reason:(JLSpeakDownReason) reason Result:(JL_CMD_RESPOND __nullable)result;
+
+/// 停止录音2
+/// - Parameters:
+/// - manager: 操作设备
+/// - reason: vad类型
+/// - schr: 语音设置助手
+/// - result: 回调结果
+-(void)cmdStopRecord:(JL_ManagerM *)manager Reason:(JLSpeakDownReason)reason SpeechHelper:(JLSpeechRecognition *)schr Result:(JL_CMD_RESPOND __nullable)result;
+
+
+/// 发送命令给音箱,允许音箱端开始接收语音,音箱收到这个消息后会发一个提示音
+/// 当前命令用于收到设备主动发起的录音时,同意开始录音。
+/// 即在 speexManagerStatus:(JL_SpeakType)status By:(JLCMDOriginator)originator With:(JLRecordParams *_Nullable) params 的代理回调收到之后的回复处理
+-(void)cmdAllowSpeak;
+
+
+/// 拒绝录音
+/// 发送命令给音箱,不允许接收语音
+/// 当前命令用于收到设备主动发起的录音时,拒绝开始录音。
+/// 即在 speexManagerStatus:(JL_SpeakType)status By:(JLCMDOriginator)originator With:(JLRecordParams *_Nullable) params 的代理回调收到之后的回复处理
+-(void)cmdRejectSpeak;
+
+/** 停止语音
+ 发发送命令给音箱,停止接收数据,即检测到断句
+ */
+-(void)cmdSpeakingDone __attribute__((deprecated ( "当前命令已失效,请使用cmdStopRecord:(JL_ManagerM *)manager Reason:(JLSpeakDownReason) reason")));
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SystemEQ.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/20.
+// Modify by EzioChan on 2023/09/22
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+
+NS_ASSUME_NONNULL_BEGIN
+@class JL_SystemEQ;
+typedef void(^JLSystemEQResult)(JL_CMDStatus status,JL_SystemEQ * _Nullable model);
+
+@interface JL_SystemEQ : JL_FunctionBaseManager
+
+/// 当前EQ模式
+@property (assign,nonatomic) JL_EQMode eqMode;
+
+/// EQ段数类型
+@property (assign,nonatomic) JL_EQType eqType;
+
+/// EQ参数值
+/// (只适用于EQ Mode == CUSTOM情况)
+@property (strong, nonatomic) NSArray *eqArray;
+
+/// 自定义 EQ数组
+@property (strong, nonatomic) NSArray *eqCustomArray;
+
+/// EQ频率
+@property (strong, nonatomic) NSArray *eqFrequencyArray;
+
+/// EQ的预设值数组
+@property (strong,nonatomic) NSArray <JLModel_EQ*> *eqDefaultArray;
+
+
+/// 设置系统EQ
+/// - Parameters:
+/// - eqMode: EQ模式
+/// - params: EQ参数
+-(void)cmdSetSystemEQ:(JL_EQMode)eqMode Params:(NSArray* __nullable)params;
+
+/// 查询系统EQ内容
+-(void)cmdGetSystemEQ:(JLSystemEQResult)result;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SystemTime.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/20.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_SystemTime : JL_FunctionBaseManager
+
+
+/// 设备当前时间
+@property(nonatomic,strong)JLModel_RTC *rtc;
+
+#pragma mark ---> 设置系统时间
+/**
+ @param date 时间类
+ */
+-(void)cmdSetSystemTime:(NSDate*)date __attribute__((deprecated ( "Please use the (cmdSetSystemYear: Month: Day: Hour: Minute: Second) method instead. The current method will be invalid")));
+
+
+/// 设置系统年月日时分秒
+/// @param year 年
+/// @param month 月
+/// @param day 日
+/// @param hour 时
+/// @param min 分
+/// @param sec 秒
+-(void)cmdSetSystemYear:(uint16_t)year
+ Month:(uint8_t)month
+ Day:(uint8_t)day
+ Hour:(uint8_t)hour
+ Minute:(uint8_t)min
+ Second:(uint8_t)sec;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_SystemVolume.h
+// JL_BLEKit
+//
+// Created by 李放 on 2021/12/20.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_TypeEnum.h>
+#import <JL_BLEKit/JL_Tools.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JL_SystemVolume : JL_FunctionBaseManager
+
+#pragma mark ---> 设置系统音量
+/**
+ @param volume 音量值
+ */
+-(void)cmdSetSystemVolume:(UInt8)volume;
+-(void)cmdSetSystemVolume:(UInt8)volume Result:(JL_CMD_RESPOND __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_Tools.h
+// JL_BLEKit
+//
+// Created by zhihui liang on 2018/11/9.
+// Copyright © 2018 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/NSObject+JLTools.h>
+#import <JLLogHelper/JLLogHelper.h>
+
+NS_ASSUME_NONNULL_BEGIN
+typedef void(^JL_Action)(void);
+typedef void(^JL_Timer_BK)(void);
+
+@class JL_Timer;
+@interface JL_Tools : NSObject
+
+
+/**
+ Data自定义截取。
+
+ @param data 数据
+ @param index 偏移
+ @param length 长度
+ @return 截取后的数据
+ */
++(NSData*)data:(NSData*)data R:(NSInteger)index L:(NSInteger)length;
++(NSDictionary*)dictionaryData:(NSData*)data R:(NSInteger)index L:(NSInteger)length;
+
+/**
+ NSData 转成 10进制
+
+ @param data 数据类型
+ @return NSInteger类型
+ */
++(NSInteger)dataToInt:(NSData*)data;
+
+/**
+ NSData 转成 NSString
+
+ @param data 数据
+ @return 字符串
+ */
++(NSString*)dataChangeToString:(NSData*)data;
+
+/**
+ uint8_t 转成 NSData
+
+ @param value uint8_t类型
+ @return NSData
+ */
++(NSData*)uInt8_data:(uint8_t)value;
+
+/**
+ uint16_t 转成 NSData
+
+ @param value uint16_t类型
+ @param endian YES:小端 NO:大端
+ @return NSData
+ */
++(NSData*)uInt16_data:(uint16_t)value Endian:(BOOL)endian;
+
+/**
+ uint32_t 转成 NSData
+
+ @param value uint32_t类型
+ @param endian YES:小端 NO:大端
+ @return NSData
+ */
++(NSData*)uInt32_data:(uint32_t)value Endian:(BOOL)endian;
+
+/**
+ uint64_t 转成 NSData
+
+ @param value uint64_t类型
+ @param endian YES:小端 NO:大端
+ @return NSData
+ */
++(NSData*)uInt64_data:(uint64_t)value Endian:(BOOL)endian;
+
+/**
+ int64_t 转成 NSData
+
+ @param value int64_t类型
+ @param endian YES:小端 NO:大端
+ @return NSData
+ */
++(NSData*)int64_data:(int64_t)value Endian:(BOOL)endian;
+
+/**
+ 大小端转换
+
+ @param data 数据
+ @return 转换后的数据
+ */
++(NSData*)changeBigOrSmall:(NSData*)data;
+
+/**
+ @"ffff0000" 转成 <ffff 0000>,16进制的字符串变成NSData。
+
+ @param hex 类似@"ffff0000"
+ @return NSData类型 => <ffff 0000>
+ */
++(NSMutableData*)HexToData:(NSString*)hex;
+/**
+ * 去除结束符
+ */
++(NSData*)cleanEOF:(NSData*)data;
+/**
+ 求自然数:aByte ==> -2 -1 0 1 2 3...
+ @param aByte 数据
+ @return 自然数
+ */
++(int)getNaturalNumber:(NSData*)aByte;
++(int)getNaturalNumber_u16:(NSData*)u16Bytes;
++(int)getNaturalNumber_u32:(NSData*)u32Bytes;
+
+/**
+ 发出通知事件
+
+ @param name 通知名字
+ @param object 传递的对象
+ */
++(void)post:(NSString*)name Object:(id __nullable)object;
+
+/**
+ 发出通知事件
+
+ @param name 通知名字
+ @param object 传递的对象
+ @param info 传递的信息
+ */
++(void)post:(NSString*)name Object:(id __nullable)object UserInfo:(NSDictionary* __nullable)info;
+/**
+ 监听通知事件
+
+ @param name 通知名字
+ @param action 实现方法
+ @param own 监听者
+ */
++(void)add:(NSString*__nullable)name Action:(SEL)action Own:(id)own;
+
+/**
+ 取消通知监听
+
+ @param name 通知名字
+ @param own 监听者
+ */
++(void)remove:(NSString*__nullable)name Own:(id)own;
+
+/**
+ 往NSUserDefault存入对象(注意:可变类型对象不适用)。
+
+ @param objc 对象
+ @param key 键值
+ */
++(void)setUser:(id)objc forKey:(NSString*)key;
+
+/**
+ 从NSUserDefault取出对象(注意:可变类型对象不适用)。
+
+ @param key 键值
+ @return 返回对象
+ */
++(id _Nullable)getUserByKey:(NSString*)key;
+
+/**
+ 移除NSUserDefault相对应的对象
+
+ @param key 键值
+ */
++(void)removeUserByKey:(NSString*)key;
+
+
+/**
+ 延时执行block。
+
+ @param sec 延时时间(秒)
+ @param block 代码块
+ */
++(void)delay:(double)sec Task:(JL_Action)block;
+
+/**
+ 异步执行block。
+
+ @param block 代码块
+ */
++(void)subTask:(JL_Action)block;
+
+/**
+ 主线程执行block。
+
+ @param block 代码块
+ */
++(void)mainTask:(JL_Action)block;
+
+
+/**
+ 新建定时器
+
+ @param sel 执行方法
+ @param objc 执行对象
+ @param sec 间隔时间(秒)
+ @return NSTimer
+ */
++(NSTimer*)timingStart:(SEL)sel target:(id)objc Time:(NSTimeInterval)sec;
+
+
+/**
+ 暂停定时间器
+
+ @param timer 定时器指针
+ */
++(void)timingPause:(__weak NSTimer*)timer;
+
+/**
+ 继续定时器
+
+ @param timer 定时器指针
+ */
++(void)timingContinue:(__weak NSTimer*)timer;
+
+
+/**
+ 摧毁定时器
+
+ @param timer 定时器指针
+ */
++(void)timingStop:(__weak NSTimer*)timer;
+
+
+/**
+ 在存在的文件路径上,建立新的文件。
+
+ @param sPath 沙盒
+ @param mPath 中间路径
+ @param file 文件名
+ @return 完成路径
+ */
++(NSString*)createOn:(NSSearchPathDirectory)sPath
+ MiddlePath:(NSString*)mPath
+ File:(NSString*)file;
+
+/**
+ 列出文件路径
+
+ @param sPath 沙盒
+ @param mPath 中间路径
+ @param file 文件名
+ @return 完整路径
+ */
++(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;
+
+/**
+ * 用途:从Project资源里寻找文件。
+ * (先把资源文件添加至工程内的Copy Bundle Resources内。)
+ * @param file 文件名
+ * @return 该文件的路径。
+ */
++(NSString*)find:(NSString *)file;
+
+/**
+ * 是否存在某个路径。
+ * @param path 文件路径
+ * @return YES or NO。
+ */
++(BOOL)isExistsPath:(NSString*)path;
+/**
+ 删除文件
+ @param path 完整路径
+ @return 成功与否
+ */
++(BOOL)removePath:(NSString*)path;
+
+/**
+ * 用途:文件夹内文件元素。
+ * @param path 文件夹路径
+ */
++(NSArray*)subPaths:(NSString*)path;
+
+/**
+ * 用途:解析JSON文件。
+ * @param path 文件路径
+ */
++(id)JsonPath:(NSString*)path;
+
+/**
+ * NSArray ==> NSString.
+ */
++(NSString*)arrayToJson:(NSArray *)array;
+
+/**
+ 数据覆盖写进文件
+
+ @param data 数据
+ @param path 文件路径
+ @return 成功与否
+ */
++(BOOL)writeData:(NSData*)data fillFile:(NSString*)path;
+
+/**
+ 数据写进文件的末端
+
+ @param data 数据
+ @param path 文件路径
+ */
++(void)writeData:(NSData*)data endFile:(NSString*)path;
+
+/**
+ 数据写进文件的偏移位置
+
+ @param data 数据
+ @param seek 偏移
+ @param path 文件路径
+ */
++(void)writeData:(NSData*)data Seek:(unsigned long long)seek File:(NSString*)path;
+
+/**
+ * UNICODE 编码字符串(小端)
+ */
++(NSString*)stringUnicode:(NSData*)data;
+
+/**
+ * UNICODE 编码字符串(大端)
+ */
++(NSString*)stringUnicodeBig:(NSData*)data;
+
+/**
+ * ANSI 编码字符串
+ */
++(NSString*)stringANSI:(NSData*)data;
+
+/**
+ * GBK 编码字符串
+ */
++(NSString*)stringGBK:(NSData*)data;
+
+/**
+ * 大文件传输,长短文件名(移除不必要字符)
+ */
++(NSData*)stringBigFileWithNeedRemoveUnnecessaryPunctuationCharactersWithString:(NSString*)name withFileNameIndex:(int)fileNameIndex;
+
+
+/// 大文件传输文件名设置
+/// Unicode编码
+/// - Parameters:
+/// - name: 文件名
+/// - fileNameIndex: index
+/// - encodeType: 编码格式
++(NSData *)stringBigFileUnicode:(NSString *)name withFileNameIndex:(int)fileNameIndex WithEncode:(NSStringEncoding) encodeType;
+/**
+ * 移除不必要字符 \ / : " < > .
+ */
++(NSString *)removeUnnecessaryPunctuationCharactersWithString:(NSString *)textString;
+
+/**
+ * 名字移除目标字符
+ * @param pattern 目标需要移除的字符
+ * NSString *pattern = @"[/:*?\"<>|]";
+ * @param textString 源字符串
+ */
++(NSString *)removeCharacters:(NSString*)pattern WithString:(NSString *)textString;
+
+/**
+ * 大文件传输,长短文件名
+ */
++(NSData*)stringBigFile:(NSString*)name withFileNameIndex:(int)fileNameIndex;
+
+/**
+ * 去除特殊字符串
+ */
++(NSString*)removeSpecialStrings:(NSString*)name;
+/**
+ * 返回时间戳(单位:秒)
+ */
++(long)dateCurrent;
+
+
+/// 把data变成LTV格式
+/// @param type 类型
+/// @param data 数据
++(NSData *)beLtv:(uint8_t)type Data:(NSData*)data;
+
+
+
+@end
+
+@interface JL_Timer : NSObject
+@property(nonatomic,assign)NSInteger subTimeout; //超时时间(默认5s)
+@property(nonatomic,assign)NSTimeInterval subScale; //默认1.0s
+-(void)waitForTimeoutResult:(JL_Timer_BK)result;
+-(void)continueTimeout;
+-(void)cancelTimeout;
+-(void)threadWait;
+-(void)threadContinue;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_TwsManager.h
+// JL_BLEKit
+//
+// Created by 凌煊峰 on 2021/12/17.
+// Modify by EzioChan on 2023/08/18
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_FunctionBaseManager.h>
+#import <JL_BLEKit/JL_Tools.h>
+#import <JL_BLEKit/JLModel_ANC.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+//MARK: - 耳机电量
+/// 耳机电量
+/// TWS earphones Electricity
+@interface TwsElectricity:NSObject
+/// 左耳充电中
+@property(nonatomic,assign) BOOL isChargingLeft;
+
+/// 右耳充电中
+@property(nonatomic,assign) BOOL isChargingRight;
+
+/// 充电仓正在充电中
+@property(nonatomic,assign) BOOL isChargingCenter;
+
+/// 左耳电量
+@property(nonatomic,assign) int powerLeft;
+
+/// 右耳电量
+@property(nonatomic,assign) int powerRight;
+
+/// 充电舱电量
+@property(nonatomic,assign) int powerCenter;
+
+@end
+
+//MARK: - TWS耳机扩展功能支持类型
+/// TWS耳机扩展功能支持类型
+@interface TwsSupportFuncs : NSObject
+
+/// 是否支持ANC功能
+@property(nonatomic,assign)BOOL isSupportAnc;
+
+/// 是否支持游戏模式
+@property(nonatomic,assign)BOOL isSupportGameMode;
+
+/// 是否支持自适应ANC
+@property(nonatomic,assign)BOOL isSupportAutoAnc;
+
+/// 是否支持智能免摘
+@property(nonatomic,assign)BOOL isSupportSmartPickFree;
+
+/// 是否支持场景降噪
+/// scene noise reduction
+@property(nonatomic,assign)BOOL isSupportSceneNoiseReduction;
+
+/// 是否支持风噪检测
+/// Noise detection
+@property(nonatomic,assign)BOOL isSupportNoiseDetection;
+
+/// 是否支持人声增强模式
+/// Vocal Boost Mode
+@property(nonatomic,assign)BOOL isSupportVocalBoostMode;
+
+/// 固件是否支持“一拖二”开 关功能
+/// Does the firmware support the "one drag two" switch function
+@property(nonatomic,assign)BOOL isSupportDragWithMore;
+
+
+@end
+
+
+
+//MARK: - TWS 控制类
+/// TWS 管理者
+@interface JL_TwsManager : JL_FunctionBaseManager
+
+/// 扩展功能支持
+@property(nonatomic,strong)TwsSupportFuncs *supports;
+
+///耳机电量
+///TWS earphones Electricity
+@property (nonatomic,strong)TwsElectricity *electricity;
+
+/// 设备名称
+@property (nonatomic,strong)NSString *edrName;
+
+/// 按键功能设置
+@property (nonatomic,strong)NSArray *keySettings;
+
+/// 灯光场景类型
+@property (nonatomic,assign)int ledScen;
+
+/// 灯光效果类型
+@property (nonatomic,assign)int ledEffect;
+
+/// 设备麦克风channel
+/// 若为空或者0则视为此功能不支持
+/// 1:自动切换
+/// 2:始终左耳
+/// 3:始终右耳
+@property (nonatomic,assign)int micMode;
+
+/// 工作模式
+/// 若为空或者0则视为此功能不支持
+/// 1:普通模式
+/// 2:游戏模式
+@property (nonatomic,assign)int workMode;
+
+/// 供应商ID
+@property (nonatomic,assign)uint16_t vid;
+
+/// 厂商ID
+@property (nonatomic,assign)uint16_t uid;
+
+/// 产品ID
+@property (nonatomic,assign)uint16_t pid;
+
+/// 连接时长
+@property (nonatomic,assign)uint32_t linkTime;
+
+/// 入耳检测
+/// 0 -- 不支持此功能
+/// 1 -- 关闭
+/// 2 -- 打开
+@property (nonatomic,assign)uint8_t earEntryDection;
+
+/// 设备语言类型
+/// zh -- 中文
+/// en -- 英文
+@property (nonatomic,strong)NSString *deviceLanguage;
+
+///ANC的模式数组
+@property (nonatomic,strong)NSArray *ancModels;
+
+/// HeadSetInfoDict
+/// 耳机信息字典
+/// 当app端收到设备返回的信息时会更新此值
+/// 此值变化较大不适合作为唯一判断依据,容易发生部分值获取失败的问题
+@property (nonatomic,strong)NSDictionary *_Nullable headSetInfoDict;
+
+
+/// 一拖二开关状态
+@property(nonatomic,readonly,assign)BOOL dragWithMore;
+
+
+/**
+ @param name 设置对耳设备的EDR名字
+ */
+-(void)cmdHeadsetEdrName:(NSData*)name;
+
+#pragma mark ---> 按键设置(对耳)
+typedef NS_ENUM(UInt8, JL_HeadsetButtonSettingKey) {
+ JL_HeadsetButtonSettingKeyOnlyLeftEar = 0x01, //左耳
+ JL_HeadsetButtonSettingKeyOnlyRightEar = 0x02, //\10右耳
+};
+typedef NS_ENUM(UInt8, JL_HeadsetButtonSettingAction) {
+ JL_HeadsetButtonSettingActionClick = 0x01, //单击
+ JL_HeadsetButtonSettingActionDoubleClick = 0x02, //双击
+};
+typedef NS_ENUM(UInt8, JL_HeadsetButtonSettingFunction) {
+ JL_HeadsetButtonSettingFunctionNone = 0x00, //无作用
+ JL_HeadsetButtonSettingFunctionBoot = 0x01, //开机
+ JL_HeadsetButtonSettingFunctionTurnOff = 0x02, //关机
+ JL_HeadsetButtonSettingFunctionPlayPrevious = 0x03, //上一曲
+ JL_HeadsetButtonSettingFunctionPlayNext = 0x04, //下一曲
+ JL_HeadsetButtonSettingFunctionPlayOrPause = 0x05, //播放/暂停
+ JL_HeadsetButtonSettingFunctionAnswerOrHangup = 0x06, //接听/挂断
+ JL_HeadsetButtonSettingFunctionReject = 0x07, //拒听
+ JL_HeadsetButtonSettingFunctionTakePhoto = 0x08, //拍照
+};
+/**
+ @param key 左耳0x01 右耳0x02
+ @param act 单击0x01 双击0x02
+ @param fuc 0x00 无作用
+ 0x01 开机
+ 0x02 关机
+ 0x03 上一曲
+ 0x04 下一曲
+ 0x05 播放/暂停
+ 0x06 接听/挂断
+ 0x07 拒听
+ 0x08 拍照
+ */
+-(void)cmdHeadsetKeySettingKey:(JL_HeadsetButtonSettingKey)key
+ Action:(JL_HeadsetButtonSettingAction)act
+ Function:(JL_HeadsetButtonSettingFunction)fuc;
+
+#pragma mark ---> LED设置(对耳)
+
+typedef NS_ENUM(UInt8, JL_HeadsetScene) {
+ JL_HeadsetSceneNotPaired = 0x01, //未配对
+ JL_HeadsetSceneDisConnected = 0x02, //未连接
+ JL_HeadsetSceneConnected = 0x03, //已连接
+ JL_HeadsetScenePlayDeviceMusic = 0x04, //播放设备音乐
+ JL_HeadsetScenePauseDeviceMusic = 0x05, //暂停设备音乐
+ JL_HeadsetScenePlayExternalAudioSource = 0x06, //外部音源播放
+ JL_HeadsetScenePauseExternalAudioSource = 0x07, //外部音源暂停
+};
+typedef NS_ENUM(UInt8, JL_HeadsetLedEffect) {
+ JL_HeadsetLedEffectAllClose = 0x00, //全灭
+ JL_HeadsetLedEffectRedLightOn = 0x01, //红灯常亮
+ JL_HeadsetLedEffectBlueLightOn = 0x02, //蓝灯常亮
+ JL_HeadsetLedEffectRedLightBreathing = 0x03, //红灯呼吸
+ JL_HeadsetLedEffectBlueLightBreathing = 0x04, //蓝灯呼吸
+ JL_HeadsetLedEffectRedBlueLightQuickFlash = 0x05, //红蓝交替快闪
+ JL_HeadsetLedEffectRedBlueLightSlowFlash = 0x06, //红蓝交替慢闪
+};
+/**
+ @param scene 0x01 未配对
+ 0x02 未连接
+ 0x03 连接
+ 0x04: 播放设备音乐
+ 0x05:暂停设备音乐
+ 0x06:外部音源播放
+ 0x07:外部音源暂停
+ @param effect 0x00 全灭
+ 0x01 红灯常亮
+ 0x02 蓝灯常亮
+ 0x03 红灯呼吸
+ 0x04 蓝灯呼吸
+ 0x05 红蓝交替快闪
+ 0x06 红蓝交替慢闪
+ */
+-(void)cmdHeadsetLedSettingScene:(JL_HeadsetScene)scene
+ Effect:(JL_HeadsetLedEffect)effect;
+
+#pragma mark ---> MIC设置(耳机)
+typedef NS_ENUM(UInt8, JL_HeadsetMicSettingMode) {
+ JL_HeadsetMicSettingModeOnlyLeftEar = 0x00, //仅左耳
+ JL_HeadsetMicSettingModeOnlyRightEar = 0x01, //仅\10右耳
+ JL_HeadsetMicSettingModeAutomatic = 0x02, //自动选择
+};
+/**
+ @param mode JL_HeadsetMicSettingMode
+ */
+-(void)cmdHeadsetMicSettingMode:(JL_HeadsetMicSettingMode)mode
+ Result:(JL_CMD_RESPOND __nullable)result;
+
+#pragma mark ---> 工作模式(耳机)
+typedef NS_ENUM(UInt8, JL_HeadsetWorkingMode) {
+ JL_HeadsetWorkingModeNormal = 0x01, //普通模式
+ JL_HeadsetWorkingModeGame = 0x02, //游戏模式
+};
+/**
+ @param mode 1: 普通模式
+ 2: 游戏模式
+ */
+-(void)cmdHeadsetWorkSettingMode:(JL_HeadsetWorkingMode)mode;
+
+#pragma mark ---> 同步时间戳(耳机)
+/**
+ @param date 当前系统时间
+*/
+-(void)cmdHeadsetTimeSetting:(NSDate*)date;
+
+#pragma mark ---> 获取设备信息(耳机)
+typedef void(^JL_HEADSET_BK)(NSDictionary* __nullable dict);
+typedef NS_ENUM(uint32_t, JL_HeadsetAdviceFlag) {
+ JL_HeadsetAdviceFlagGetElectricity = 1, //小机电量获取
+ JL_HeadsetAdviceFlagEdrName = 1 << 1, //Edr名称
+ JL_HeadsetAdviceFlagButtonFunction = 1 << 2, //按键功能
+ JL_HeadsetAdviceFlagLedStatus = 1 << 3, //LED显示状态
+ JL_HeadsetAdviceFlagMicMode = 1 << 4, //MIC模式
+ JL_HeadsetAdviceFlagWorkMode = 1 << 5, //工作模式
+ JL_HeadsetAdviceFlagProductInfo = 1 << 6, //产品信息
+ JL_HeadsetAdviceFlagConnectingTime = 1 << 7, //连接时间
+ JL_HeadsetAdviceFlagEarDetection = 1 << 8, //入耳检测
+ JL_HeadsetAdviceFlagLanguage = 1 << 9, //语言类型
+};
+/**
+ @param flag BIT0 小机电量获取 格式为3个字节 参考广播包格式
+ BIT1 Edr 名称
+ BIT2 按键功能
+ BIT3 LED 显示状态
+ BIT4 MIC 模式
+ BIT5 工作模式
+ BIT6 产品信息
+ BIT7 连接时间
+ BIT8 入耳检测
+ BIT9 语言类型
+ @param result 返回字典:
+ @"ISCHARGING_L"
+ @"ISCHARGING_R"
+ @"ISCHARGING_C"
+ @"POWER_L"
+ @"POWER_R"
+ @"POWER_C"
+ @"EDR_NAME"
+ @"KEY_LR"
+ @"KEY_ACTION"
+ @"KEY_FUNCTION"
+ @"LED_SCENE"
+ @"LED_EFFECT"
+ @"MIC_MODE"
+ @"WORK_MODE"
+ @"VID"
+ @"UID"
+ @"PID"
+ @"LINK_TIME"
+ @""IN_EAR_TEST"
+ @"DEVICE_LANGUAGE"
+ @"KEY_ANC_MODE" ANC的模式数组
+ */
+-(void)cmdHeadsetGetAdvFlag:(JL_HeadsetAdviceFlag)flag
+ Result:(JL_HEADSET_BK __nullable)result;
+
+#pragma mark ---> 设备广播通知(耳机)
+/**
+ @{@"JLID": 杰理ID,
+ @"VID": ,
+ @"PID": ,
+ @"EDR": ,
+ @"SCENE": ,
+ @"ISCHARGING_L": ,
+ @"ISCHARGING_R": ,
+ @"ISCHARGING_C": ,
+ @"POWER_L": ,
+ @"POWER_R": ,
+ @"POWER_C": ,
+ @"CHIP_TYPE": ,
+ @"PROTOCOL_TYPE": ,
+ @"SEQ":};
+ */
+extern NSString *kJL_MANAGER_HEADSET_ADV;
+
+#pragma mark ---> 设置命令成功/错误回复(耳机)
+/**
+ 0x00:成功
+ 0x01:游戏模式导致设置失效
+ 0x02:蓝牙名字长度超出限制
+ 0x03:非蓝牙模式设置闪灯失败
+ */
+extern NSString *kJL_MANAGER_HEADSET_SET_ERR;
+
+#pragma mark ---> 关闭或开启设备广播(耳机)
+/**
+ @param enable 使能位
+ */
+-(void)cmdHeadsetAdvEnable:(BOOL)enable;
+
+#pragma mark ---> 用于ADV设置同步后需要主机操作的行为。
+/**
+ 1:更新配置信息,需要重启生效。
+ 2:同步时间戳
+ 3:请求手机回连BLE
+ 4:同步设备信息
+ */
+extern NSString *kJL_MANAGER_HEADSET_TIPS;
+
+#pragma mark ---> 发射频点
+/**
+@param fmtx 频点
+*/
+-(void)cmdSetFMTX:(uint16_t)fmtx;
+
+#pragma mark ---> 设置耳机ANC模式列表
+/**
+ * 设置耳机ANC模式列表
+ * @param array 频点 JL_AncMode的NSNumber对象数组 @[@(JL_AncMode_Normal), @(JL_AncMode_NoiseReduction)]
+ */
+-(void)cmdHeadsetAncArray:(NSArray*)array;
+
+#pragma mark ---> 耳机主动降噪ANC设置
+-(void)cmdSetANC:(JLModel_ANC*)model;
+
+
+
+//MARK: - 一拖二相关命令
+
+typedef void(^JL_MulitLinksInfo_BK)(JL_CMDStatus status,NSArray <JLTWSAddrNameInfo *>* __nullable phoneInfos);
+
+/// 设备上传一拖二设备信息列表
+extern NSString* kJL_MULIT_NAME_LIST;
+
+/// 获取设备已连接手机名
+/// 通知设备上传一拖二设备信息列表
+/// @param result 设备所连接的手机名字列表
+-(void)cmdGetDeviceInfoListResult:(JL_MulitLinksInfo_BK)result;
+
+/// 通知设备一连上手机地址和绑定信息
+/// - Parameters:
+/// - addr: 手机EDR地址
+/// - name: 手机蓝牙名称
+/// - result: 结果
+-(void)cmdBindDeviceInfo:(NSData *)addr phone:(NSString *)name result:(JL_MulitLinksInfo_BK)result;
+
+/// 一拖二开关
+/// @param dragWithMore 开关状态
+/// @param addr 手机的经典蓝牙地址(通过cmdGetDeviceInfoList 获取)
+/// @param result 结果回调
+-(void)setDragWithMore:(BOOL)dragWithMore phoneBleAddr:(NSData *) addr result:(JL_CMD_RESPOND)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_TypeEnum.h
+// JL_BLEKit
+//
+// Created by DFung on 2018/11/29.
+// Copyright © 2018 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JLModel_SmallFile.h>
+
+typedef NS_ENUM(NSInteger, JL_BLEStatus) {
+ JL_BLEStatusFound, //发现设备,对应 kUI_JL_BLE_FOUND
+ JL_BLEStatusPaired, //已配对, 对应 kUI_JL_BLE_PAIRED
+ JL_BLEStatusDisconnected, //断开连接,对应 kUI_JL_BLE_DISCONNECTED
+ JL_BLEStatusOn, //蓝牙开启,对应 kUI_JL_BLE_ON
+ JL_BLEStatusOff, //蓝牙关闭,对应 kUI_JL_BLE_OFF
+ JL_BLEStatusUnknown, //状态未知
+};
+typedef NS_ENUM(NSInteger, JL_DeviceBTStatus) {
+ JL_DeviceBTStatusDisconnected = 0, //设备经典蓝牙已断开
+ JL_DeviceBTStatusConnected = 1, //设备经典蓝牙已连接
+ JL_DeviceBTStatusUnknown,
+};
+typedef NS_ENUM(UInt8, JL_CMDStatus) {
+ JL_CMDStatusSuccess = 0x00, //成功
+ JL_CMDStatusFail = 0x01, //失败
+ JL_CMDStatusUnknownCmd = 0x02, //未定义命令
+ JL_CMDStatusBusy = 0x03, //忙碌
+ JL_CMDStatusNoResponse = 0x04, //没有收到回复
+ JL_CMDStatusCrcErr = 0x05, //CRC错误
+ JL_CMDStatusDataCrcErr = 0x06, //数据CRC错误
+ JL_CMDStatusParamErr = 0x07, //参数错误
+ JL_CMDStatusOverLimit = 0x08, //数据溢出
+ JL_CMDStatusLrcError = 0x09, //LRC获取出错
+ JL_CMDStatusUnknown,
+};
+typedef void(^JL_CMD_RESPOND)(JL_CMDStatus status, uint8_t sn, NSData* __nullable data);
+
+//---------------------------------------------------------//
+
+typedef NS_ENUM(UInt8,JLDevSpecialType) {
+ ///普通正常设备
+ JLDevSpecialType_Normal = 0x00,
+ ///回连设备
+ JLDevSpecialType_Reconnect = 0x01,
+};
+
+typedef NS_ENUM(int64_t,JL_CLASS) {
+ JL_CLASS_SmallFile = 0,
+ JL_CLASS_File = 1,
+ JL_CLASS_OTA = 2,
+ JL_CLASS_Flash = 3,
+ JL_CLASS_ChargingBin = 4,
+ JL_CLASS_AlarmClock = 5,
+ JL_CLASS_Light = 6,
+ JL_CLASS_Tws = 7,
+ JL_CLASS_SoundCard = 8,
+ JL_CLASS_Call = 9,
+ JL_CLASS_Speex = 10,
+ JL_CLASS_Lrc = 11,
+ JL_CLASS_FindDevice = 12,
+ JL_CLASS_MusicControl = 13,
+ JL_CLASS_Fm = 14,
+ JL_CLASS_SystemEQ = 15,
+ JL_CLASS_SystemTime = 16,
+ JL_CLASS_SystemVolume = 17,
+ JL_CLASS_Custom = 18,
+ JL_CLASS_Batch = 19,
+ JL_CLASS_DeviceLogs = 20,
+ JL_CLASS_BigData = 21,
+};
+
+//---------------------------------------------------------//
+
+
+///命令发起者
+typedef NS_ENUM(UInt8, JLCMDOriginator) {
+ ///SDK端发起
+ JLCMDOriginatorApp = 0x00,
+ ///设备端发起
+ JLCMDOriginatorDevice = 0x01
+};
--- /dev/null
+//
+// JL_WatchProtocolDelegate.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/8/11.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "JL_SDM_Header.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol JL_WatchProtocol <NSObject>
+
+@optional
+/// 设备回调心率相关内容
+/// @param heartRate 心率对象
+-(void)jlWatchHeartRate:(JL_SDM_HeartRate *)heartRate;
+
+/// 设备回调大气压强相关内容
+/// @param airPressure 气压对象
+-(void)jlWatchAirPressure:(JL_SDM_AirPressure *)airPressure;
+
+/// 设备回调海拔高度相关内容
+/// @param alititude 海拔对象
+-(void)jlWatchAltitude:(JL_SDM_Altitude *)alititude;
+
+/// 设备回调步数相关内容
+/// @param moveStep 步数对象
+-(void)jlWatchMoveSteps:(JL_SDM_MoveSteps *)moveStep;
+
+/// 设备回调压力相关内容
+/// @param stress 压力对象
+-(void)jlWatchStress:(JL_SDM_Stress *)stress;
+
+/// 设备回调血氧饱和度相关内容
+/// @param oxStaturation 血氧饱和度对象
+-(void)jlWatchOxsaturation:(JL_SDM_OxSaturation*)oxStaturation;
+
+/// 设备回调训练负荷相关内容
+/// @param trainLoad 训练负荷对象
+-(void)jlWatchTrainLoad:(JL_SDM_TrainLoad *)trainLoad;
+
+/// 设备回调最大摄氧量相关内容
+/// @param maxOxg 最大摄氧量对象
+-(void)jlWatchMaxOxg:(JL_SDM_MaxOxg *)maxOxg;
+
+/// 设备回调运动恢复时间相关内容
+/// @param rectime 运动恢复时间对象
+-(void)jlWatchRecTime:(JL_SDM_RecTime *)rectime;
+
+/// 设备回调运动数据的相关内容
+/// @param sportMsg 运动数据对象
+-(void)jlWatchSportMessage:(JL_SDM_SportMessage *)sportMsg;
+
+
+/// 设备回调无法区分的数据内容
+/// @param value 数据区域,根据类型解析数据
+/// @param submask 对应查询的参数,描述功能类型,作用域
+/// @param type 数据类型
+-(void)jlWatchUnDefineData:(NSData *)value subMask:(NSData *)submask Type:(UInt8)type;
+
+/// 设备回调传感器相关数据
+/// @param type 数据类型
+/// @param data 数据内容
+-(void)jlWatchWatchLog:(JL_WATCH_LOG_TYPE) type with:(NSData *)data;
+
+//MARK: - 健康设置回调
+
+/// 接收整个设置返回的数组
+/// @param models JLwSettingModels
+-(void)jlWatchSetAllFunc:(NSArray<JLwSettingModel *> *)models;
+
+/// 回调传感器相关设置
+/// @param model 传感器功能
+-(void)jlWatchSetSensorFunc:(JLSensorFuncModel *)model;
+
+/// 久坐提醒
+/// @param model 久坐提醒功能
+-(void)jlWatchSetSedentaryRmd:(JLSedentaryRmdModel *)model;
+
+/// 心率测量功能
+/// @param model 心率模块
+-(void)jlWatchSetConsequentHeartRate:(JLConsequentHeartRateModel *)model;
+
+/// 运动心率测试功能
+/// @param model 运动心率
+-(void)jlWatchSetExerciseHeartRateRemind:(JLExerciseHeartRateRemindModel *)model;
+
+/// 自动压力测试
+/// @param model 压力测试
+-(void)jlWatchSetAutoPressure:(JLAutoPressureModel *)model;
+
+/// 睡眠监测
+/// @param model 睡眠
+-(void)jlWatchSetSleepMonitor:(JLSleepMonitorModel *)model;
+
+/// 跌到监测
+/// @param model 跌倒监测
+-(void)jlWatchSetFallDetectionModel:(JLFallDetectionModel *)model;
+
+/// 抬腕监测
+/// @param model 抬腕监测
+-(void)jlWatchSetWristLiftDetectionModel:(JLWristLiftDetectionModel *)model;
+
+/// 个人信息
+/// @param model 个人信息
+-(void)jlWatchSetPersonInfoModel:(JLPersonInfoModel *)model;
+
+/// 蓝牙断开设置
+/// @param model 断开设置
+-(void)jlWatchSetDisconnectRemindModel:(JLDisconnectRemindModel *)model;
+
+/// 紧急联系人
+/// @param model 紧急联系人设置
+-(void)jlWatchSetEmergencyContactModel:(JLEmergencyContactModel *)model;
+
+/// 血氧测量
+/// @param model 血氧测量模式
+-(void)jlWatchSetOxygenSturationRemindModel:(JLOxygenSturationRemindModel *)model;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_WatchSyncProtocol.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/27.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+#import <Foundation/Foundation.h>
+#import "JL_SDM_Header.h"
+#import "JL_EntityM.h"
+
+#ifndef JL_WatchSyncProtocol_h
+#define JL_WatchSyncProtocol_h
+
+@protocol JLWearSyncProtocol <NSObject>
+
+@optional
+/// 运动信息返回
+/// @param model 运动信息对象
+/// @param entity 设备entity
+-(void)jlWearSyncSportInfo:(JLWearSyncInfoModel *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+
+/// 结束运动返回内容
+/// @param model 结束时间相隔信息对象
+/// @param entity 设备entity
+-(void)jlWearSyncStopMotion:(JLWearSyncFinishModel *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+
+/// 开始运动返回消息
+/// @param entity 设备entity
+-(void)jlWearSyncStartMotionWith:(JL_EntityM *_Nonnull)entity;
+
+/// 暂停运动
+/// @param entity 设备entity
+-(void)jlWearSyncStatusPauseWith:(JL_EntityM *_Nonnull)entity;
+
+/// 继续运动
+/// @param entity 设备entity
+-(void)jlWearSyncStatusContiuneWith:(JL_EntityM *_Nonnull)entity;
+
+/// 实时数据回调
+/// @param model 实时数据模型
+/// @param entity 设备entity
+-(void)jlWearSyncRealTimeData:(JLWearSyncRealTimeModel *_Nonnull)model With:(JL_EntityM *_Nonnull)entity;
+
+@end
+
+#endif /* JL_WatchSyncProtocol_h */
--- /dev/null
+//
+// JL_vad.h
+// Test
+//
+// Created by DFung on 2018/2/28.
+// Copyright © 2018年 DFung. All rights reserved.
+//
+
+#ifndef JL_vad_h
+#define JL_vad_h
+
+
+
+#define CONT_AD_ADFRMSIZE 16
+#define DEFAULT_RADIX 12
+#define SMOOTH_WINDOW 4
+#define MIN_FIXLOG -2829416
+#define KWSNUM 1 //¥˝ ∂±¥ ∏ˆ ˝
+
+
+//typedef long long __int64;
+typedef int int32;
+typedef short int16;
+typedef signed char int8;
+typedef unsigned int uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+typedef long long int64;
+typedef int32 fixed32;
+typedef float float32;
+
+
+
+
+struct noise_stats_s {
+ /* Smoothed power */
+ int power[40];
+ int max_power[40];
+ /* Noise estimate */
+ int noise[40];
+ int max_noise[40];
+ /* Signal floor estimate */
+ int floor[40];
+ int max_floor[40];
+ /* Peak for temporal masking */
+ int peak[40];
+ int max_peak[40];
+
+ int signal[40];
+ int gain[40];
+ char remove_noi;
+ /* Initialize it next time */
+ uint8 undefined;
+ /* Number of items to process */
+ uint32 num_filters;
+
+ /* Sum of slow peaks for VAD */
+ int64 slow_peak_sum;
+ int64 max_slow_peak_sum;
+
+ /* Precomputed constants */
+ int lambda_power;
+ int comp_lambda_power;
+ int lambda_a;
+ int comp_lambda_a;
+ int lambda_b;
+ int comp_lambda_b;
+ int lambda_t;
+ int mu_t;
+ int max_gain;
+ int inv_max_gain;
+
+ int smooth_scaling[2 * 4 + 3];
+};
+typedef struct noise_stats_s noise_stats_t;
+struct htk_fe_s
+{
+ unsigned short pow_hist[98];
+ noise_stats_t *noise_stats;
+
+
+ int fe_prior;
+ uint32 int_frame;
+ char int_flag;
+
+
+ unsigned char sum_cnt;
+
+ uint8 voice_state;
+ uint8 in_speech;
+ int16 pre_speech_frames;
+ int16 post_speech_frames;
+
+ int16 inout_spch[410];
+ int fe_tmp_spch[250];
+ int fe_fft_buf[512];
+ int fe_mfspec[40];
+ int cmn_sum[13];
+ int mfcc_fifo[9][13];
+ int *cmn_mfcc_fifo[9];
+ //int fe_prior;
+ char speech_fifo[16];
+ char init_speech_n;
+ char vad_cnt;
+ int buf_cep[21][13];
+ int buf_pow[21];
+ uint8 speech_indexw;
+ uint8 speech_indexr;
+ uint8 speech_cnt;
+
+
+ int16 sp_threshold;
+ int16 nsp_threshold;
+};
+
+typedef struct htk_fe_s htk_fe_t;
+/*
+ * How to use? See follow...
+ *
+ * 1、开启录音前:
+ * /--- 开启Vad ---/
+ * int need_buf_size = vad_get_need_buf_size();
+ * vad_hdl = malloc(need_buf_size);
+ * vad_init(vad_hdl, 10, 51);
+ *
+ * 2、结束录音后:
+ * /--- 关闭Vad ---/
+ * free(vad_hdl);
+ *
+ * 3、录音数据回调:
+ * buf:录音数据 ,需要320Bytes!
+ * ret:0->静音状态 1->正在说话 2->结束说话
+ * int ret = vad_main(vad_hdl, (int*)buf);
+ */
+int vad_get_need_buf_size(void);
+int vad_init(void *p, short sp_threshold, short nsp_threshold);
+int vad_main(void *p,int *inout_spch);
+
+fixed32 fe_log_add(fixed32 x, fixed32 y);
+fixed32 fe_log_sub(fixed32 x, fixed32 y);
+int32 fixlog2(uint32 x);
+int fixlog(uint32 x);
+
+#endif /* JL_vad_h */
--- /dev/null
+//
+// JLeSimManager.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/12/4.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class JL_ManagerM;
+
+@protocol JLEsimFinishDelegate <NSObject>
+
+/// 设备推送esim 信息内容
+/// - Parameters:
+/// - version: 版本
+/// - data: 内容
+-(void)jlEsimDidGetData:(uint8_t)version ESimData:(NSData *)data;
+
+@end
+
+typedef void(^JLESimFinishBlock)(NSError * _Nullable err);
+
+/// esim 信息交互类
+@interface JLeSimManager : NSObject
+
+@property(nonatomic,assign)id<JLEsimFinishDelegate> delegate;
+
+/// 下发 esim 信息到设备
+/// - Parameters:
+/// - mgr: 设备
+/// - data: esim 信息
+/// - block: 完成回调
+-(void)sendToDev:(JL_ManagerM *)mgr Data:(NSData *)data Result:(JLESimFinishBlock)block;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// LtvSettingModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/10/12.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+typedef NS_ENUM(UInt8, WatchSettingFunc) {
+ ///传感器功能
+ WatchSettingFunc_SensorFunction = 0x01 ,
+ ///久坐提醒
+ WatchSettingFunc_SedentaryReminder = 0x02,
+ ///连续测量心率
+ WatchSettingFunc_ContinuousHeartRateMeasurement = 0x03,
+ ///运动心率提醒
+ WatchSettingFunc_ExerciseHeartRateReminder = 0x04,
+ ///压力自动检测
+ WatchSettingFunc_AutomaticPressureDetection = 0x05,
+ ///睡眠检测
+ WatchSettingFunc_SleepMonitoring = 0x06,
+ ///跌倒检测
+ WatchSettingFunc_FallDetection = 0x07,
+ ///抬腕检测
+ WatchSettingFunc_WristLiftDetection = 0x08,
+ ///个人信息
+ WatchSettingFunc_PersonInfo = 0x09,
+ /// 蓝牙断开提醒
+ WatchSettingFunc_DisconnectReminder = 0xA,
+ /// 血氧测量提醒
+ WatchSettingFunc_OxygenSturation = 0x0B,
+ /// 紧急联系人
+ WatchSettingFunc_EmergencyContact = 0x0C
+};
+
+///提醒模式
+typedef NS_ENUM(UInt8, WatchRemindType) {
+ /// 亮屏
+ WatchRemind_BrightScreen = 0x00,
+ ///震动
+ WatchRemind_Shake = 0x01,
+ /// 打电话(抬腕不支持该提示)
+ WatchRemind_Call = 0x02
+};
+
+///连续测量心率模式
+typedef NS_ENUM(UInt8, WatchConsequentType) {
+ //智能
+ WatchConsequent_Intelligent = 0x00,
+ //实时
+ WatchConsequent_realTime = 0x01
+};
+
+/// 连续血氧测量模式
+typedef NS_ENUM(UInt8,WatchOxygenMsmType){
+ //智能
+ WatchOxygenMsm_Intelligent = 0x00,
+ //定时
+ WatchOxygenMsm_runTime = 0x01
+};
+
+///监察开关类型
+typedef NS_ENUM(UInt8, WatchSwitchType) {
+ ///关闭
+ WatchSwitchType_Close = 0x00,
+ ///全天开启
+ WatchSwitchType_AllDay = 0x01,
+ ///自定义时间
+ WatchSwitchType_Customer = 0x02,
+};
+
+@interface WatchTimer : NSObject
+/// 时
+@property(nonatomic,assign,readonly)UInt8 hour;
+/// 分
+@property(nonatomic,assign,readonly)UInt8 min;
+
+-(instancetype _Nonnull)initWithData:(NSData *_Nonnull)data;
+
+-(instancetype _Nonnull)initWith:(uint8_t)h Min:(uint8_t)m;
+
+@end
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface JLwSettingModel : NSObject
+@property(nonatomic,assign)uint8_t length;
+@property(nonatomic,assign)WatchSettingFunc type;
+@property(nonatomic,strong)NSData *value;
+
+/// 设备UUID
+@property(nonatomic,strong)NSString *deviceID;
+
+
+-(NSData *)beData;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// NSData+ToUnit.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/4/7.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NSData (ToUnit)
+
+
+-(BOOL)beBool;
+
+-(uint8_t)beUint8;
+
+-(UInt16)beLittleUint16;
+
+-(UInt16)beBigendUint16;
+
+-(UInt32)beLittleUint32;
+
+-(UInt32)beBigendUint32;
+
+-(UInt64)beLittleUint64;
+
+-(UInt64)beBigendUint64;
+
+-(NSString *)dataToAltitude;
+
+-(NSString *)beHexStr;
+
+-(NSDate *)toDate;
+
+/// 裁剪Data
+/// @param from 开始
+/// @param to 长度
+-(NSData *)subf:(NSInteger)from t:(NSInteger)to;
+
+
+
+@end
+
+
+@interface NSMutableData(WithUnit)
+
+-(void)appendUint8:(uint8_t)k;
+
+-(void)appendUint16:(uint16_t)k;
+
+-(void)appendUint32:(uint32_t)k;
+@end
+
+
+@interface NSString(WithUnit)
+
+-(NSString *)formatLog;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// NSObject+JLTools.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/8/17.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NSObject (JLTools)
+
+
+- (NSString *) logProperties;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// NfcModel.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2021/8/3.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+@interface NfcModel : NSObject
+
+/// NFC标签
+@property(nonatomic,assign)UInt16 idCard;
+
+/// 保留位
+@property(nonatomic,strong)NSData *reserver;
+
+/// 设备索引
+@property(nonatomic,strong)NSData *devHandler;
+
+/// 更新时间戳,用于排序
+@property(nonatomic,strong)NSDate *updateTime;
+
+/// nfc数据文件名,格式如下:XX.nfc,XX是0~9
+@property(nonatomic,strong)NSString *nfcFileName;
+
+/// 别名,最大字符长度为26, 不足部分补‘\0’ 编码格式:UTF-8(以后可以保留位决定) 例如:公司门禁卡,家里门禁等等
+@property(nonatomic,strong)NSString *nickName;
+
+/// 可变字段长度,包含crc + nfc_id
+@property(nonatomic,assign)UInt16 variableLength;
+
+/// NFC 数据的CRC
+@property(nonatomic,strong)NSData *crc;
+
+/// nfc数据的唯一值
+@property(nonatomic,strong)NSData *nfc_id;
+
+
++(NfcModel *)initMsgModel:(NSData *)data;
+
+/// 解析NFC头部数据
+/// @param basicData 裸数据
++(NSArray<NfcModel *> *)initMSGModels:(NSData *)basicData;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+
+
+
+
+@interface NfcFileModel : NfcModel
+
+/// NFC 数据
+@property(nonatomic,strong)NSData * _Nonnull nfcData;
+@property(nonatomic,assign,readonly)UInt32 length;
++(NfcFileModel *_Nonnull)initFileModel:(NSData *_Nonnull)data;
+
+@end
+
+
+
+
--- /dev/null
+//
+// RTC_RingInfo.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/10/15.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// 闹铃信息
+@interface RTC_RingInfo : NSObject
+
+/// 铃声类型
+/// 0x00 设备默认
+/// 0x01 多媒体选取
+@property (assign,nonatomic) uint8_t type;
+
+/// 设备索引
+/// 当type = 0时,dev保留
+/// 当type = 1时,dev为选取的设备
+@property (assign,nonatomic) uint8_t dev;
+
+/// 闹铃文件簇号
+/// 当type = 0时,clust 为对应 JLModel_Ring 的 index
+/// 当type = 1时,clust为选取的闹铃文件簇号
+@property (assign,nonatomic) uint32_t clust;
+
+/// 铃声名称长度
+@property (assign,nonatomic) uint8_t len;
+
+/// 铃声名称
+@property (strong,nonatomic) NSData *data;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+framework module JL_BLEKit {
+ umbrella header "JL_BLEKit.h"
+ export *
+
+ module * { export * }
+}
--- /dev/null
+//
+// BtHash.h
+// BtHash
+//
+// Created by huanghaibo on 2019/7/28.
+// Copyright © 2019 jieli. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface BtHash : NSObject
+/*
+ @param [in] pt[*1] The plaintext
+ @param ptlen The length of the plaintext(octets) range: 1~32
+ @param [in] key[*1] The key for encrypt
+ @param keylen[*1] The length of the key(octets) range: 1~32
+ @param [out] mac[*1] output : The Message Authentication Code 16 bytes.
+ @return error if < 0, 0 is normal.
+ */
++(int)decryptWithPlaintext:(unsigned char *)pt
+ andPlaintextLen:(int)ptlen
+ andKey: (unsigned char *)key
+ andKeyLen: (int)keylen
+ andMac:(unsigned char *)mac;
+@end
--- /dev/null
+//
+// JLHashHandler.h
+// JL_BLEKit
+//
+// Created by EzioChan on 2023/1/30.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JLLogHelper/JLLogHelper.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef void(^JLHashBlock)(BOOL ret);
+
+@protocol JLHashHandlerDelegate <NSObject>
+
+/// 需要发送到设备校验认证的数据
+/// - Parameter data: 数据
+-(void)hashOnPairOutputData:(NSData*)data;
+
+@end
+
+
+/// 设备认证
+@interface JLHashHandler : NSObject
+
+@property(nonatomic,weak)id<JLHashHandlerDelegate> delegate;
+
+
+/// APP端发起设备认证
+/// - Parameters:
+/// - pKey: 加密Key(默认为空)
+/// - bk: 配对认证回调结果
+-(void)bluetoothPairingKey:(NSData *__nullable)pKey Result:(JLHashBlock)bk;
+
+
+/// 重置设备认证过程
+-(void)hashResetPair;
+
+
+/// 填入设备回复数据
+/// - Parameter rData: 数据
+-(void)inputPairData:(NSData*)rData;
+
+
+/// 打印当前SDK的版本
++(void)sdkVersion;
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_HashPair.h
+// JL_HashPair
+//
+// Created by EzioChan on 2023/1/30.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+//! Project version number for JL_HashPair.
+FOUNDATION_EXPORT double JL_HashPairVersionNumber;
+
+//! Project version string for JL_HashPair.
+FOUNDATION_EXPORT const unsigned char JL_HashPairVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import <JL_HashPair/PublicHeader.h>
+
+#import <JL_HashPair/BtHash.h>
+#import <JL_HashPair/JLHashHandler.h>
+#import <JL_HashPair/JL_ble_pair.h>
--- /dev/null
+//
+// JL_ble_pair.h
+// JL_BLEKit
+//
+// Created by zhihui liang on 2018/11/10.
+// Copyright © 2018 www.zh-jieli.com. All rights reserved.
+//
+
+#ifndef JL_ble_pair_h
+#define JL_ble_pair_h
+
+#include <stdio.h>
+#include <stdint.h>
+
+void function_jieli(uint8_t *address,uint8_t *RAND,uint8_t *K,uint8_t *result);
+
+#pragma mark CRC校验
+unsigned short JL_CRC16(unsigned char *ptr, int len, uint16_t lastCrc);
+
+#endif /* JL_ble_pair_h */
--- /dev/null
+framework module JL_HashPair {
+ umbrella header "JL_HashPair.h"
+ export *
+
+ module * { export * }
+}
--- /dev/null
+//
+// JLOTAFile.h
+// JL_OTALib
+//
+// Created by EzioChan on 2024/7/26.
+// Copyright © 2024 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_OTAUrlResult) {
+ JL_OTAUrlResultSuccess = 0x00, //OTA文件获取成功
+ JL_OTAUrlResultFail = 0x01, //OTA文件获取失败
+ JL_OTAUrlResultDownloadFail = 0x02, //OTA文件下载失败
+};
+
+typedef void(^JL_OTA_URL)(JL_OTAUrlResult result,
+ NSString* __nullable version,
+ NSString* __nullable url,
+ NSString* __nullable explain);
+
+@interface JLOTAFile : NSObject
+
+
+#pragma mark -文件下载
+/**
+ 文件下载
+ @param key 授权key
+ @param code 授权code
+ @param result 回复
+ */
+-(void)cmdGetOtaFileKey:(NSString*)key
+ Code:(NSString*)code
+ Result:(JL_OTA_URL __nullable)result;
+
+/**
+ OTA升级文件下载【MD5】
+@param key 授权key
+@param code 授权code
+@param hash MD5值
+@param result 回复
+*/
+-(void)cmdGetOtaFileKey:(NSString*)key
+ Code:(NSString*)code
+ hash:(NSString*)hash
+ Result:(JL_OTA_URL __nullable)result;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_OTALib.h
+// JL_OTALib
+//
+// Created by EzioChan on 2023/1/29.
+// Copyright © 2023 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+//! Project version number for JL_OTALib.
+FOUNDATION_EXPORT double JL_OTALibVersionNumber;
+
+//! Project version string for JL_OTALib.
+FOUNDATION_EXPORT const unsigned char JL_OTALibVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import <JL_OTALib/PublicHeader.h>
+#import <JL_OTALib/JL_OTAManager.h>
+#import <JL_OTALib/jl_ufw.h>
+#import <JL_OTALib/JLOTAFile.h>
--- /dev/null
+//
+// JL_OTAManager.h
+// JL_BLEKit
+//
+// Created by 杰理科技 on 2021/11/16.
+// Copyright © 2021 www.zh-jieli.com. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <JLLogHelper/JLLogHelper.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(UInt8, JL_OTAResult) {
+ JL_OTAResultSuccess = 0x00, // OTA升级成功
+ JL_OTAResultFail = 0x01, // OTA升级失败
+ JL_OTAResultDataIsNull = 0x02, // OTA升级数据为空
+ JL_OTAResultCommandFail = 0x03, // OTA指令失败
+ JL_OTAResultSeekFail = 0x04, // OTA标示偏移查找失败
+ JL_OTAResultInfoFail = 0x05, // OTA升级固件信息错误
+ JL_OTAResultLowPower = 0x06, // OTA升级设备电压低
+ JL_OTAResultEnterFail = 0x07, // 未能进入OTA升级模式
+ JL_OTAResultUpgrading = 0x08, // OTA升级中
+ JL_OTAResultReconnect = 0x09, // OTA需重连设备(uuid方式)
+ JL_OTAResultReboot = 0x0a, // OTA需设备重启
+ JL_OTAResultPreparing = 0x0b, // OTA准备中
+ JL_OTAResultPrepared = 0x0f, // OTA准备完成
+ JL_OTAResultStatusIsUpdating = 0x10, // 设备已在升级中
+ JL_OTAResultFailedConnectMore = 0x11, // 当前固件多台设备连接,请手动断开另 一个设备连接
+ JL_OTAResultFailSameSN = 0xe0, // 升级数据校验失败,SN 多次重复
+ JL_OTAResultCancel = 0xe1, // 升级取消
+ JL_OTAResultFailVerification = 0xf1, // 升级数据校验失败
+ JL_OTAResultFailCompletely = 0xf2, // 升级失败
+ JL_OTAResultFailKey = 0xf3, // 升级数据校验失败,加密Key不对
+ JL_OTAResultFailErrorFile = 0xf4, // 升级文件出错
+ JL_OTAResultFailUboot = 0xf5, // uboot不匹配
+ JL_OTAResultFailLenght = 0xf6, // 升级过程长度出错
+ JL_OTAResultFailFlash = 0xf7, // 升级过程flash读写失败
+ JL_OTAResultFailCmdTimeout = 0xf8, // 升级过程指令超时
+ JL_OTAResultFailSameVersion = 0xf9, // 相同版本
+ JL_OTAResultFailTWSDisconnect = 0xfa, // TWS耳机未连接
+ JL_OTAResultFailNotInBin = 0xfb, // 耳机未在充电仓
+ JL_OTAResultReconnectWithMacAddr = 0xfc, // OTA需重连设备(mac方式)
+ JL_OTAResultDisconnect = 0xfd, // OTA设备断开
+ JL_OTAResultUnknown, // OTA未知错误
+};
+
+typedef NS_ENUM(UInt8, JL_OTAReconnectType) {
+ JL_OTAReconnectTypeUUID = 0x00, // OTA升级回连使用uuid
+ JL_OTAReconnectTypeMACAddr = 0x01, // OTA升级回连使用mac地址
+};
+
+typedef NS_ENUM(UInt8, JL_OtaStatus) {
+ JL_OtaStatusNormal = 0, // 正常升级
+ JL_OtaStatusForce = 1, // 强制升级
+};
+typedef NS_ENUM(UInt8, JL_OtaHeadset) {
+ JL_OtaHeadsetNO = 0, // 耳机单备份 正常升级
+ JL_OtaHeadsetYES = 1, // 耳机单备份 强制升级
+};
+typedef NS_ENUM(UInt8, JL_OtaWatch) {
+ JL_OtaWatchNO = 0, // 手表资源 正常升级
+ JL_OtaWatchYES = 1, // 手表资源 强制升级
+};
+typedef NS_ENUM(UInt8, JL_BootLoader) {
+ JL_BootLoaderNO = 0, // 不需要下载Bootloader
+ JL_BootLoaderYES = 1, // 需要下载BootLoader
+};
+typedef NS_ENUM(UInt8, JL_Partition) {
+ JL_PartitionSingle = 0, // 固件单备份
+ JL_PartitionDouble = 1, // 固件双备份
+};
+
+typedef void (^JL_OTA_RT)(JL_OTAResult result, float progress);
+
+typedef void (^JL_OTA_RESULT)(uint8_t status, uint8_t sn, NSData *__nullable data);
+
+@class JL_OTAManager;
+
+/// OTA 升级管理对象回调
+@protocol JL_OTAManagerDelegate <NSObject>
+
+/// 即将被发送的数据
+/// @param data 数据内容
+- (void)otaDataSend:(NSData *_Nonnull)data;
+
+@optional
+/// 回调设备状态信息
+/// @param manager 对象状态
+- (void)otaFeatureResult:(JL_OTAManager *_Nonnull)manager;
+
+/// 回调升级状态以及进度等
+/// @param result 状态以及进度信息
+/// @param progress 进度信息
+- (void)otaUpgradeResult:(JL_OTAResult)result Progress:(float)progress;
+
+/// 取消OTA升级
+- (void)otaCancel;
+
+@end
+
+/// OTA升级管理对象
+@interface JL_OTAManager : NSObject
+
+/// 设备UUID(需要开发者填入)
+@property(strong, nonatomic) NSString *mBLE_UUID;
+
+/// 设备名称(需要开发者填入)
+@property(strong, nonatomic) NSString *mBLE_NAME;
+
+/// 是否仅仅支持BLE
+@property(assign, nonatomic) BOOL bleOnly;
+
+/// ble蓝牙地址
+@property(strong, nonatomic) NSString *bleAddr;
+
+/// SN值
+@property(assign, nonatomic) uint8_t mCmdSN;
+
+/// 设备版本号
+@property(assign, nonatomic) uint16_t version;
+
+/// 设备版本信息
+@property(strong, nonatomic) NSString *versionFirmware;
+
+/// 设备OTA状态
+@property(assign, nonatomic) JL_OtaStatus otaStatus;
+
+/// 耳机单备份 是否需要强制升级
+@property(assign, nonatomic) JL_OtaHeadset otaHeadset;
+
+/// 手表资源 是否需要强制升级
+@property(assign, nonatomic) JL_OtaWatch otaWatch;
+
+/// 设备OTA时支持单/双备份
+@property(assign, nonatomic) JL_Partition otaPartition;
+
+/// 设备是否需要下载Loader
+@property(assign, nonatomic) JL_BootLoader bootloaderType;
+
+/// OTA升级回连方式
+@property(assign, nonatomic) JL_OTAReconnectType otaReconnectType;
+
+/// OTA升级内容大小(设备通知的)
+@property(assign, nonatomic, readonly) int64_t otaLength;
+
+/// 已传输的数据大小
+@property(assign, nonatomic, readonly) uint32_t otaSent;
+
+/// 设备交互回调代理
+@property(weak, nonatomic) id<JL_OTAManagerDelegate> delegate;
+
+/// 获取 OTA 升级对象
++ (JL_OTAManager *)getOTAManager;
+
+/// 不建议使用自行初始化
+/// 推荐获取 getOTAManager
+- (instancetype)init __attribute__((deprecated("Please use getOTAManager instead.")));
+;
+
+/// 打印OTA发送的数据内容
+/// - Parameter status: 开关
+- (void)logSendData:(BOOL)status;
+
+/// 当BLE连接上时告知SDK
+- (void)noteEntityConnected;
+
+/// 当BLE断开时告知SDK
+- (void)noteEntityDisconnected;
+
+/// 设置最大丢包次数
+/// - Parameter count: 次数
+/// default: 2
+- (void)maxLostCount:(int)count;
+
+/// Receive data from rcsp
+/// 设备端过来的数据
+/// - Parameter data: data
+- (void)cmdOtaDataReceive:(NSData *)data;
+
+/// 查询设备OTA信息
+/// 所有情况下都需要执行,而且是在连上后(认证完成)第一步执行
+- (void)cmdTargetFeature;
+
+/// 查询设备系统状态
+/// 当设备需要挂载外置flash才能正常升级时需要执行,其他情况则无需执行
+- (void)cmdSystemFunction;
+
+/// OTA单备份,是否正在回连
+- (BOOL)cmdOtaIsRelinking;
+
+#pragma mark---> OTA升级
+/**
+ 开始OTA升级
+ @param data 升级数据
+ @param result 升级结果
+ */
+- (void)cmdOTAData:(NSData *)data
+ Result:(JL_OTA_RT __nullable)result;
+
+/// OTA升级II
+/// 单备份升级特有!!!!
+/// 此接口可用于 OTA 回连成功后,再次发起升级使用
+/// @param result 升级结果回调
+- (void)cmdOtaDataIIResult:(JL_OTA_RT __nullable)result;
+
+/**
+ OTA升级取消
+ @param result 回复
+ */
+- (void)cmdOTACancelResult:(JL_OTA_RESULT __nullable)result;
+
+/// 重启设备
+- (void)cmdRebootDevice;
+
+/// 强制重启设备
+- (void)cmdRebootForceDevice;
+
+/// 重置OTA manager
+- (void)resetOTAManager;
+
+/// 打印OTA SDK版本
++ (NSString *)logSDKVersion;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+/**\r
+ * Des: \r
+ * author: Bob\r
+ * date: 2022/11/29\r
+ * Copyright: Jieli Technology\r
+ */\r
+\r
+#ifndef NATIVEAPPLICATION_JL_UFW_H\r
+#define NATIVEAPPLICATION_JL_UFW_H\r
+\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+//#include <android/log.h>\r
+//#include <jni.h>\r
+//\r
+//#define tag "myJNI"\r
+//#define logi(TAG, ...) ((void)__android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__))\r
+//#define logw(TAG, ...) ((void)__android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__))\r
+//#define loge(TAG, ...) ((void)__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__))\r
+\r
+int parse_fw_info(const char *data, int size, uint8_t *resultBuff, uint32_t buffSize);\r
+#define BIT(n) (1 << n)\r
+\r
+// for FW file\r
+enum eFW_FILE_TYPE {\r
+\r
+ FILE_TYPE_FW_FLASH_BIN = 0, // FLASH文件,第一块FLASH数据\r
+ FILE_TYPE_FW_OTP_BIN = 1, // OTP文件\r
+ FILE_TYPE_FW_INFO_LOG = 2, // FW文件中保存的描述信息\r
+ FILE_TYPE_FW_BURN_CFG = 3, // 烧写器配置文件\r
+ FILE_TYPE_FW_SCRIPT_DATA = 4, // 烧写器打包烧写器下载文件时,需要执行的脚本数据\r
+ FILE_TYPE_FW_SRC = 5, // 需要保存在FW文件中的代码文件, FW文件查看/编辑器都不能显示这些数据\r
+ FILE_TYPE_FW_NAME_BIN = 6, // 升级名字用的FW文件,已经废除\r
+ FILE_TYPE_FW_OTP_VER_BIN = 7, // OTP maskrom版本\r
+ FILE_TYPE_FW_OTPCFG_BIN = 8, // OTP配置信息\r
+ FILE_TYPE_FW_OTP_CHIP_CONTROL_BIN = 9, // OTP芯片控制信息\r
+\r
+ FILE_TYPE_FW_OTP_MINI_UBOOT = 0xA, // 烧写到OTP的MINI UBOOT文件\r
+ FILE_TYPE_FW_OTP_FIX_UBOOT = 0xB, // 烧写到OTP的FIX UBOOT文件\r
+ FILE_TYPE_FW_FLASH_2_BIN = 0xC, // 第二块FLASH数据\r
+ FILE_TYPE_FW_BR18_EFUSE_CONFIG_BIN = 0xD, // BR18 24BIT EFUSE配置数据\r
+ FILE_TYPE_FW_RESOURCE_FILE = 0xE, // 资源文件\r
+ FILE_TYPE_FW_2018KEY_INFO = 0xF, // 2018年的新KEY信息\r
+\r
+ FILE_TYPE_FW_BURNER_CUSTOMER_DATA = 0x10, // 一拖八烧写器用户信息\r
+ FILE_TYPE_FW_BURNER_DV15_FLASH_BIN = 0x11, // 一拖八烧写器第一块FLASH数据\r
+ FILE_TYPE_FW_BURNER_APP_FLASH_BIN = 0x12, // 一拖八烧写器第二块FLASH数据\r
+ FILE_TYPE_FW_BURNER_DATA_FLASH_BIN = 0x13, // 一拖八烧写器第三块FLASH数据\r
+ FILE_TYPE_FW_BURNER_BR21_FLASH_BIN = 0x14, // 一拖八烧写器第四块FLASH数据\r
+\r
+ FILE_TYPE_FW_FLASH_BIN_2 = 0x20, // 下载到第一块FLASH的文件,下载工具根据条件要么下载FILE_TYPE_FW_FLASH_BIN,要么下载FILE_TYPE_FW_FLASH_BIN_2\r
+ FILE_TYPE_FW_FLASH_BIN_3,\r
+ FILE_TYPE_FW_FLASH_BIN_4,\r
+\r
+ FILE_TYPE_FW_LOADER_BIN = 0x31, // 打包的LOADER程序代码\r
+\r
+ FILE_TYPE_FW_TEST_BOX_OTA_BIN = 0x64, // 测试盒使用的ota.bin\r
+\r
+ FILE_TYPE_FW_3RD_DATA_FILE = 0x71, // 第三方烧写数据\r
+\r
+ FILE_TYPE_FW_OTA_TARGET_DEVICE_INFO = 0xA0,\r
+ FILE_TYPE_FW_BURN_COUNT_LIMIT = 0xA1, // 烧写授权信息\r
+\r
+ FILE_TYPE_FW_ADDITIONAL_FILE = 0xEE, // 附加文件,由烧写器根据名字决定用途\r
+ FILE_TYPE_FW_PASSTHROUGH_DATA = 0xEF, // AC691X BTIF数据\r
+ // 仅存在于FW文件中的数据\r
+ FILE_TYPE_FW_HIDDEN_CFG_BIN = 0xFA,\r
+ FILE_TYPE_FW_INVISIBLE_DATA = 0xFB, // 保存在FW文件中的隐藏数据,FW文件查看/编辑器都不能显示这些数据\r
+ FILE_TYPE_FW_VISIBLE_DATA = 0xFE, // 仅保存在FW文件中的HEX数据\r
+\r
+ FILE_TYPE_FW_TAIL = 0xFF, // FW文件尾部标识\r
+};\r
+\r
+typedef struct U16BIT\r
+{\r
+ unsigned char b0 : 1;\r
+ unsigned char b1 : 1;\r
+ unsigned char b2 : 1;\r
+ unsigned char b3 : 1;\r
+ unsigned char b4 : 1;\r
+ unsigned char b5 : 1;\r
+ unsigned char b6 : 1;\r
+ unsigned char b7 : 1;\r
+ unsigned char b8 : 1;\r
+ unsigned char b9 : 1;\r
+ unsigned char b10 : 1;\r
+ unsigned char b11 : 1;\r
+ unsigned char b12 : 1;\r
+ unsigned char b13 : 1;\r
+ unsigned char b14 : 1;\r
+ unsigned char b15 : 1;\r
+\r
+} U16BIT;\r
+typedef union UBIT16\r
+{\r
+ U16BIT bits;\r
+ uint16_t val;\r
+} UBIT16;\r
+\r
+typedef struct stRES_FILE_HEAD {\r
+ uint32_t u32Tag;\r
+ uint16_t u16Crc;\r
+ uint16_t u16CrcOfItems;\r
+ uint32_t u32Len;\r
+ uint16_t u16Count;\r
+ uint16_t u16Res;\r
+ uint8_t u8Res16[16];\r
+}RES_FILE_HEAD;\r
+\r
+typedef struct stRES_CONFIG_ITEM {\r
+ uint16_t u16Index;\r
+ uint16_t u16Type;\r
+ uint32_t u32Addr;\r
+ uint32_t u32Len;\r
+ uint16_t u16CrcOfData;\r
+ uint16_t u16Res;\r
+ char szName[16];\r
+}RES_CONFIG_ITEM;\r
+static uint16_t m_u16ChipKey = 0xFFFF;\r
+static uint16_t m_u16DefaultKey = 0xFFFF;\r
+\r
+\r
+#pragma pack(1)\r
+#define JL_FILE_ITEM_NAME_MAX_LEN 16\r
+#define JL_CHIP_KEY_ENC_LENGTH 32\r
+\r
+typedef struct stUFW_SYD_HEAD_V1 {\r
+ uint16_t u16Crc; // crc16 for this struct\r
+ uint16_t u16CrcOfSydFileHead;\r
+ uint32_t u32FileLength; // file length\r
+ uint16_t u16FileCount; // 此FW文件中包含的子文件个数\r
+ uint16_t u16Version;\r
+ uint32_t u32Res;\r
+ char szChipName[16]; // 此FW文件对应的芯片类型,如AC690X,AC691X\r
+ uint32_t u32Res2[4];\r
+ uint32_t u32Res3[4];\r
+}UFW_SYD_HEAD_V1;\r
+\r
+typedef struct stUFW_FILE_HEAD_V1 {\r
+ uint8_t u8FileType; // 文件类型\r
+ uint8_t u8Res; // 保留\r
+ uint16_t u16Index; // 文件索引号\r
+ uint16_t u16Crc; // 明文数据的校验码\r
+ uint16_t u16Version; // 本结构体版本\r
+ uint32_t u32Addr; // 地址\r
+ uint32_t u32Length; // 数据长度\r
+ uint32_t u32AllLength; // 数据长度+尾部对齐的数据长度\r
+ uint32_t u32EncryptedAddr; // 加密数据的地址偏移(相对u32Addr的地址)\r
+ uint32_t u32EncryptedLength; // 加密的数据长度\r
+ uint32_t u32Res; // 保留\r
+ uint32_t u64Res1[4]; // 保留\r
+ uint32_t u64Res2[4]; // 保留\r
+ char name[JL_FILE_ITEM_NAME_MAX_LEN];\r
+\r
+}UFW_FILE_HEAD_V1;\r
+\r
+typedef struct stJL_FILE_TAIL {\r
+ char szChipKey[JL_CHIP_KEY_ENC_LENGTH]; // 32 // 固定位置\r
+ uint16_t u16ChipKeyCRC16; // 34 // 固定位置\r
+ uint8_t u8Magic[6]; // 40 // 固定位置\r
+ uint8_t u8Res8[8]; // 48\r
+ char szTailChipName[6]; // 54 // 固定位置\r
+ uint8_t u8Reserv10[10]; // 64\r
+}JL_FILE_TAIL;\r
+\r
+typedef struct {\r
+ char szName[3];\r
+ char szVersion[3];\r
+ uint8_t u8Flag;\r
+ uint8_t u8Res;\r
+ uint32_t u32Crc;\r
+ uint16_t u16Crc;\r
+ uint16_t u16Res;\r
+}JL_FLASH_BIN_TAIL;\r
+\r
+typedef UFW_SYD_HEAD_V1 jl_ufw_syd_head;\r
+typedef UFW_FILE_HEAD_V1 jl_ufw_file_head;\r
+typedef JL_FILE_TAIL jl_ufw_tail;\r
+\r
+typedef struct stJL_BR22_FLASH_HEAD {\r
+ uint16_t u16Crc; // 结构体自身校验码\r
+ uint8_t u8SizeForBurner; // 为烧写器保留的空间大小\r
+ uint8_t u8Version; // FLASH FS版本号\r
+ char vid[4]; // 4byte的vid\r
+ uint32_t u32FlashSize; // FLASH大小,由isd_download计算得出\r
+ uint8_t u8FsVersion; // 类型:br18/br22\r
+ uint8_t u8BlockAlingnModulus; // 对齐系数\r
+ uint8_t u8Res; // 保留,以后有可能会用于存放顶层目录的偏移和文件目录内偏移信息\r
+ uint8_t u8SpecialOptFlag; // 用于标记是否需要生成2种flash格式的标记位,目前只用1位,以后如果需要特殊操作需要标记,再用其他位\r
+ char pid[16]; // 16byte的pid\r
+}JL_BR22_FLASH_HEAD;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#pragma pack()\r
+\r
+\r
+#endif //NATIVEAPPLICATION_JL_UFW_H\r
--- /dev/null
+framework module JL_OTALib {
+ umbrella header "JL_OTALib.h"
+ export *
+
+ module * { export * }
+}
--- /dev/null
+//
+// JL_RunSDK.h
+// JL_OTA_InnerBle
+//
+// Created by 凌煊峰 on 2021/10/9.
+//
+
+#import <Foundation/Foundation.h>
+#import <JL_BLEKit/JL_BLEKit.h>
+
+#define SMALL_V @"v"
+
+#define BIG_V @"V"
+
+#define kJL_AGRESS_PROTOCOL @"agress_protocol"
+
+#define KEY_COMMIT_PROTOCOL @"commit_protocol"
+
+#define kJL_HeightNavBar ([UIApplication sharedApplication].delegate.window.safeAreaInsets.top+44.0)
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol JL_RunSDKOtaDelegate <NSObject>
+
+@required
+/**
+ * ota升级过程状态回调
+ */
+- (void)otaProgressWithOtaResult:(JL_OTAResult)result withProgress:(float)progress;
+
+@end
+
+@interface JL_RunSDK : NSObject
+
+@property (strong, nonatomic) JL_BLEMultiple *mBleMultiple;
+@property (weak, nonatomic) JL_EntityM *__nullable mBleEntityM;
+@property (weak, nonatomic) id<JL_RunSDKOtaDelegate> otaDelegate;
+
+/**
+ * 单例
+ */
++ (instancetype)sharedInstance;
+
+//+ (NSString *)textEntityStatus:(JL_EntityM_Status)status;
+- (JL_EntityM *)getEntity:(NSString *)uuid;
+
+#pragma mark - 杰理蓝牙库OTA流程相关业务
+
+typedef void(^GET_DEVICE_CALLBACK)(BOOL needForcedUpgrade);
+
+
+-(void)startLoopConnect:(NSString *)uuid;
+
+/**
+ * 获取已连接的蓝牙设备信息
+ */
+- (void)getDeviceInfo:(GET_DEVICE_CALLBACK _Nonnull)callback;
+
+/**
+ * OTA升级
+ */
+- (void)otaFuncWithFilePath:(NSString *)otaFilePath;
+
++(double)getWidthWithString:(NSString*)str font:(UIFont*)font;
+
++(NSAttributedString *)getAttributeWith:(id)sender string:(NSString *)string orginFont:(CGFloat)orginFont orginColor:(UIColor *)orginColor attributeFont:(CGFloat)attributeFont attributeColor:(UIColor *)attributeColor;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// JL_RunSDK.m
+// JL_OTA_InnerBle
+//
+// Created by 凌煊峰 on 2021/10/9.
+//
+
+#import "JL_RunSDK.h"
+
+@interface JL_RunSDK() <JL_ManagerMDelegate>
+
+@property (strong, nonatomic) NSString *selectedOtaFilePath;
+@property (strong, nonatomic) NSString *connectUUID;
+
+@end
+
+@implementation JL_RunSDK
+
+
+//+ (NSString *)textEntityStatus:(JL_EntityM_Status)status {
+// if (status < 0) return kJL_TXT("未知错误");
+// NSArray *arr = @[kJL_TXT("蓝牙未开启"), kJL_TXT("连接失败"), kJL_TXT("正在连接"), kJL_TXT("重复连接"),
+// kJL_TXT("连接超时"), kJL_TXT("被拒绝"), kJL_TXT("配对失败"), kJL_TXT("配对超时"), kJL_TXT("已配对"),
+// kJL_TXT("正在主从切换"), kJL_TXT("断开成功"), kJL_TXT("请打开蓝牙")];
+// if (status+1 <= arr.count) {
+// return arr[status];
+// } else {
+// return kJL_TXT("未知错误");
+// }
+//}
+
++ (instancetype)sharedInstance {
+ static JL_RunSDK *singleton = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ singleton = [[self alloc] init];
+ });
+ return singleton;
+}
+
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ /*--- 初始化JL_SDK ---*/
+ self.mBleMultiple = [[JL_BLEMultiple alloc] init];
+ self.mBleMultiple.BLE_FILTER_ENABLE = YES;
+ self.mBleMultiple.BLE_PAIR_ENABLE = YES;
+ self.mBleMultiple.BLE_TIMEOUT = 7;
+ self.connectUUID = nil;
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(noteListen:) name:nil object:nil];
+ }
+ return self;
+}
+
+
+-(void)noteListen:(NSNotification *)note{
+ NSString *name = note.name;
+ if(!self.connectUUID) return;
+ if([name isEqual:kJL_BLE_M_FOUND]){
+ NSArray *itemsArray = [note object];
+ __weak typeof(self) weakSelf = self;
+ for (JL_EntityM *entity in itemsArray) {
+ if([entity.mPeripheral.identifier.UUIDString isEqualToString:self.connectUUID]){
+ [self.mBleMultiple scanStop];
+ self.connectUUID = nil;
+ [self.mBleMultiple connectEntity:entity Result:^(JL_EntityM_Status status) {
+ if(status == JL_EntityM_StatusPaired){
+ weakSelf.mBleEntityM = entity;
+ }
+ }];
+ }
+ }
+
+ }
+}
+
+-(void)startLoopConnect:(NSString *)uuid{
+ self.connectUUID = uuid;
+ [self.mBleMultiple scanStart];
+}
+
+
+- (JL_EntityM *)getEntity:(NSString *)uuid {
+ NSMutableArray *mConnectArr = self.mBleMultiple.bleConnectedArr;
+ for (JL_EntityM *entity in mConnectArr) {
+ NSString *inUnid = entity.mPeripheral.identifier.UUIDString;
+ if ([uuid isEqual:inUnid]) {
+ return entity;
+ }
+ }
+ return nil;
+}
+
+
+-(void)handelDeviceInfo{
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ [self getDeviceInfo:^(BOOL needForcedUpgrade) {
+
+ }];
+ });
+}
+
+#pragma mark - 杰理蓝牙库OTA流程相关业务
+
+/**
+ * 获取已连接的蓝牙设备信息,这里如果上次设备升级没有成功,会要求执行otaFuncWithFilePath:强制升级
+ */
+- (void)getDeviceInfo:(GET_DEVICE_CALLBACK _Nonnull)callback {
+ __weak typeof(self) weakSelf = self;
+ /*--- 获取设备信息 ---*/
+ [self.mBleEntityM.mCmdManager cmdTargetFeatureResult:^(JL_CMDStatus status, uint8_t sn, NSData * _Nullable data) {
+ if (status == JL_CMDStatusSuccess) {
+ JLModel_Device *model = [weakSelf.mBleEntityM.mCmdManager outputDeviceModel];
+ JL_OtaStatus upSt = model.otaStatus;
+ if (upSt == JL_OtaStatusForce) {
+ kJLLog(JLLOG_DEBUG, @"---> 进入强制升级.");
+ if (weakSelf.selectedOtaFilePath) {
+ [weakSelf otaFuncWithFilePath:weakSelf.selectedOtaFilePath];
+ } else {
+ callback(true);
+ }
+ return;
+ } else {
+ if (model.otaHeadset == JL_OtaHeadsetYES) {
+ kJLLog(JLLOG_DEBUG, @"---> 进入强制升级: OTA另一只耳机.");
+ if (weakSelf.selectedOtaFilePath) {
+ [weakSelf otaFuncWithFilePath:weakSelf.selectedOtaFilePath];
+ } else {
+ callback(true);
+ }
+ return;
+ }
+ }
+ kJLLog(JLLOG_DEBUG, @"---> 设备正常使用...");
+ [JL_Tools mainTask:^{
+ /*--- 获取公共信息 ---*/
+ [weakSelf.mBleEntityM.mCmdManager cmdGetSystemInfo:JL_FunctionCodeCOMMON Result:nil];
+ callback(false);
+ }];
+ } else {
+ kJLLog(JLLOG_DEBUG, @"---> ERROR:设备信息获取错误!");
+ }
+ }];
+}
+
+- (void)otaFuncWithFilePath:(NSString *)otaFilePath {
+ kJLLog(JLLOG_DEBUG, @"current otaFilePath ---> %@", otaFilePath);
+ self.selectedOtaFilePath = otaFilePath;
+ __weak typeof(self) weakSelf = self;
+ [self.mBleMultiple otaFuncWithEntityM:self.mBleEntityM withFilePath:otaFilePath Result:^(JL_OTAResult result, float progress) {
+ if ([weakSelf.otaDelegate respondsToSelector:@selector(otaProgressWithOtaResult:withProgress:)]) {
+ [weakSelf.otaDelegate otaProgressWithOtaResult:result withProgress:progress];
+ }
+ }];
+}
+
++(double)getWidthWithString:(NSString*)str font:(UIFont*)font{
+ NSDictionary *dict = @{NSFontAttributeName:font};
+ CGSize detailSize = [str sizeWithAttributes:dict];
+ return detailSize.width;
+}
+
++ (NSString *)getStringWithRange:(NSRange)range
+{
+ NSMutableString *string = [NSMutableString string];
+ for (int i = 0; i < range.length ; i++) {
+ [string appendString:@" "];
+ }
+ return string;
+}
+
+@end
--- /dev/null
+////
+//// SDKBleHelper.h
+//// JL_OTA
+////
+//// Created by EzioChan on 2022/10/12.
+//// Copyright © 2022 Zhuhia Jieli Technology. All rights reserved.
+////
+//
+//#import <Foundation/Foundation.h>
+//#import <JL_BLEKit/JL_BLEKit.h>
+//
+//NS_ASSUME_NONNULL_BEGIN
+//
+//@interface SDKBleHelper : NSObject
+//
+//+(NSMutableArray <JL_EntityM *>*)fitterHandle:(NSArray*)basicArray;
+//
+//
+//
+//@end
+//
+//NS_ASSUME_NONNULL_END
--- /dev/null
+////
+//// SDKBleHelper.m
+//// JL_OTA
+////
+//// Created by EzioChan on 2022/10/12.
+//// Copyright © 2022 Zhuhia Jieli Technology. All rights reserved.
+////
+//
+//#import "SDKBleHelper.h"
+//#import "FittingView.h"
+//#import <JL_BLEKit/JL_BLEKit.h>
+//
+//@implementation SDKBleHelper
+//
+//+(NSMutableArray <JL_EntityM *>*)fitterHandle:(NSArray*)basicArray{
+// NSMutableArray *localArray = [NSMutableArray new];
+// NSString *key = [[FittingView getFitterKey] uppercaseString];
+// for (JL_EntityM *entity in basicArray) {
+// if ([key isEqualToString:@""]) {
+// [localArray addObject:entity];
+// }else{
+// if ([[entity.mItem uppercaseString] rangeOfString:key].location == NSNotFound || !entity.mItem) {
+// //
+// kJLLog(JLLOG_DEBUG, @"过滤 ----> NAME:%@ RSSI:%@", entity.mItem,entity.mRSSI);
+// }else{
+// [localArray addObject:entity];
+// }
+// }
+// }
+// return localArray;
+//}
+//
+//
+//
+//@end
--- /dev/null
+//
+// YLOtaManager.h
+// JL_OTA
+//
+// Created by liangshi on 2025/8/16.
+// Copyright © 2025 Zhuhia Jieli Technology. All rights reserved.
+//
+
+//#import <Foundation/Foundation.h>
+//#import "HandleBroadcastPtl.h"
+#import <JL_BLEKit/JL_BLEKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol YLOtaDelegate <NSObject>
+
+@required
+
+
+- (void)otaProgressWithOtaResult:(JL_OTAResult)result withProgress:(float)progress;
+
+- (void)otaCancel;
+
+@end
+
+
+@interface YLOtaManager : NSObject
+@property(nonatomic,weak)id<YLOtaDelegate> delegate;
+@property (strong, nonatomic) JL_BLEMultiple *mBleMultiple;
+@property (weak, nonatomic) JL_EntityM *__nullable mBleEntityM;
+
++ (instancetype)shared;
+
+
+- (void)otaFuncWithFilePath:(NSString *)otaFilePath;
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// YLOtaManager.m
+// JL_OTA
+//
+// Created by suhailian on 2025/8/4.
+// Copyright © 2025 Zhuhia Jieli Technology. All rights reserved.
+//
+
+#import "YLOtaManager2.h"
+#import "JL_RunSDK.h"
+#import "SDKBleHelper.h"
+@interface YLOtaManager() <JL_RunSDKOtaDelegate>
+
+@property (strong, nonatomic) NSString *otaFilePath;
+@property (strong, nonatomic) NSString *connectUUID;
+
+@end
+@implementation YLOtaManager
+
++ (instancetype)shared {
+ static YLOtaManager *singleton = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ singleton = [[self alloc] init];
+ });
+ return singleton;
+}
+
+
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(allNoteListen:) name:nil object:nil];
+ }
+ return self;
+}
+
+- (void)allNoteListen:(NSNotification*)note {
+ NSString *name = note.name;
+
+ if([name isEqual:kJL_BLE_M_FOUND]){
+ NSArray *itemsArray = [note object];
+// NSArray *list = [SDKBleHelper fitterHandle:itemsArray];
+ JL_EntityM *entity = [[JL_RunSDK sharedInstance] mBleEntityM];
+ if ( entity.mBLE_IS_PAIRED ) {
+// [self.btEnityList insertObject:entity atIndex:0];
+ }
+ for (JL_EntityM *model in itemsArray) {
+ NSLog(@"%@",@"发现设备");
+ if ([@"EB_002111108" isEqualToString:model.mPeripheral.name]) {
+ JL_EntityM *selectedItem = model;
+ CBPeripheral *item = selectedItem.mPeripheral;
+// if (item.state == CBPeripheralStateConnected || item.state == CBPeripheralStateConnecting) {
+// return;
+// }
+// if (item.state == CBPeripheralStateConnected || item.state == CBPeripheralStateConnecting) {
+// return;
+// }
+ NSLog(@"%@",@"开始连接");
+ [JL_RunSDK sharedInstance].mBleMultiple.BLE_PAIR_ENABLE = true;
+ [[JL_RunSDK sharedInstance].mBleMultiple connectEntity:selectedItem Result:^(JL_EntityM_Status status) {
+ if(status == JL_EntityM_StatusPaired){
+ NSLog(@"%@",@"配对成功");
+ }
+ }];
+ }
+ }
+ }
+
+ if ([name isEqual:kJL_BLE_M_ENTITY_CONNECTED]) {
+ NSLog(@"%@",@"已连接");
+ CBPeripheral *cpb = note.object;
+ NSArray *list = [JL_RunSDK sharedInstance].mBleMultiple.bleConnectedArr;
+ for (JL_EntityM *entity in list) {
+ if([entity.mPeripheral.identifier.UUIDString isEqualToString:cpb.identifier.UUIDString]){
+ [JL_RunSDK sharedInstance].mBleEntityM = entity;
+ break;
+ }
+ }
+ [JL_Tools delay:0.5 Task:^{
+ [[JL_RunSDK sharedInstance] getDeviceInfo:^(BOOL needForcedUpgrade) {
+ [[JL_RunSDK sharedInstance] otaFuncWithFilePath:self.otaFilePath];
+ }];
+ }];
+ }
+
+ if ([name isEqual:kJL_BLE_M_ENTITY_DISCONNECTED]) {
+ NSLog(@"%@",@"断开连接");
+ }
+}
+
+- (void)startSearch{
+ NSMutableArray *mConnectArr = self.mBleMultiple.bleConnectedArr;
+ NSLog(@"已连接==== %@",mConnectArr);
+ [[JL_RunSDK sharedInstance].mBleMultiple scanStart];
+}
+
+- (void)otaFuncWithFilePath:(NSString *)otaFilePath{
+ self.otaFilePath = otaFilePath;
+ [JL_RunSDK sharedInstance].otaDelegate = self;
+ [self startSearch];
+}
+
+- (void)otaProgressWithOtaResult:(JL_OTAResult)result withProgress:(float)progress {
+ if (result == JL_OTAResultUpgrading || result == JL_OTAResultPreparing) {
+ if (result == JL_OTAResultPreparing){
+ NSLog(@"%@",@"校验文件中");
+ }
+ if (result == JL_OTAResultUpgrading){
+ NSLog(@"%@",@"正在升级");
+ }
+ } else if (result == JL_OTAResultPrepared) {
+ NSLog(@"---> 检验文件【完成】");
+ } else if (result == JL_OTAResultReconnect) {
+ NSLog(@"---> OTA正在回连设备... %@", [JL_RunSDK sharedInstance].mBleEntityM.mPeripheral.name);
+ } else if (result == JL_OTAResultReconnectWithMacAddr) {
+ NSLog(@"---> OTA正在通过Mac Addr方式回连设备... %@", [JL_RunSDK sharedInstance].mBleEntityM.mPeripheral.name);
+ } else if (result == JL_OTAResultSuccess) {
+ NSLog(@"--->升级成功.");
+ } else if (result == JL_OTAResultReboot) {
+ NSLog(@"--->设备重启.");
+ } else {
+ // 其余错误码详细 Command+点击JL_OTAResult 查看说明
+ NSLog(@"ota update result: %d", result);
+ }
+}
+@end
"连接失败":"連接失敗",
"智能体":"智能體",
"已成功更新到云储存空间":"已成功更新到雲存儲空間",
+ "按日期查找":"Buscar por fecha",
+ "绑定安全手机":"Vincular teléfono móvil seguro",
]
"连接失败":"Kết nối thất bại",
"智能体":"Thiết bị thông minh",
"已成功更新到云储存空间":"Đã cập nhật thành công lên kho lưu trữ đám mây",
+ "按日期查找":"Tìm kiếm theo ngày",
+ "绑定安全手机":"Li kết nối điện an toàn",
]
"连接失败":"",
"智能体":"",
"已成功更新到云储存空间":"",
+ "按日期查找":"",
+ "绑定安全手机":"",
]
"连接失败":"Connection Failed",
"智能体":"Intelligent Agent",
"已成功更新到云储存空间":"Successfully updated to cloud storage space",
+ "按日期查找":"Search by Date",
+ "绑定安全手机":"Bind Secure Mobile Phone",
]
"连接失败":"Connexion échouée",
"智能体":"Agent intelligent",
"已成功更新到云储存空间":"Mise à jour réussie dans l'espace de stockage cloud",
+ "按日期查找":"Rechercher par date",
+ "绑定安全手机":"Lier le téléphone sécurisé",
]
"连接失败":"Koneksi Gagal",
"智能体":"Agen Cerdas",
"已成功更新到云储存空间":"Berhasil diperbarui ke ruang penyimpanan cloud",
+ "按日期查找":"Cari berdasarkan tanggal",
+ "绑定安全手机":"Hubungkan ponsel aman",
]
"连接失败":"接続失敗",
"智能体":"インテリジェントエージェント",
"已成功更新到云储存空间":"クラウドストレージスペースに正常に更新されました",
+ "按日期查找":"日付",
+ "绑定安全手机":"安全な携帯電話",
]
"连接失败":"연결 실패",
"智能体":"지능체",
"已成功更新到云储存空间":"클라우드 저장 공간에 성공적으로 업데이트되었습니다",
+ "按日期查找":"날짜별 검색",
+ "绑定安全手机":"보안 휴대폰 연결",
]
"连接失败":"Penyambungan Gagal",
"智能体":"Agen Pintar",
"已成功更新到云储存空间":"Telah berjaya dikemas kini ke ruang penyimpanan awan",
+ "按日期查找":"Cari mengikut tarikh",
+ "绑定安全手机":"Hubungkan telefon selamat",
]
"连接失败":"Ошибка подключения",
"智能体":"Интеллектуальный агент",
"已成功更新到云储存空间":"Успешно обновлено в облачное хранилище",
+ "按日期查找":"Поиск по дате",
+ "绑定安全手机":"Привязать безопасный мобильный телефон",
]
"连接失败":"Conexión fallida",
"智能体":"Agente inteligente",
"已成功更新到云储存空间":"Se ha actualizado exitosamente al espacio de almacenamiento en nube",
+ "按日期查找":"Buscar por fecha",
+ "绑定安全手机":"Vincular teléfono móvil seguro",
]
"连接失败":"เชื่อมต่อไม่สำเร็จ",
"智能体":"อัจฉริยะ",
"已成功更新到云储存空间":"อัปเดต到พื้นที่เก็บข้อมูลคลาวด์สำเร็จแล้ว",
+ "按日期查找":"ค้น โดยตามวันที่",
+ "绑定安全手机":"เชื่อมโยงโทรศัพท์มือถือปลอดภัย",
]