Commit 7a10e2ea6857bbd3cee12b64fc22fa82feb91442
1 parent
60a29b2c
feat:BluetoothManager support ota
Showing
5 changed files
with
109 additions
and
7 deletions
HDFwear/20240126ReadMe.md
... | ... | @@ -143,3 +143,11 @@ BluetoothManager+Function |
143 | 143 | |
144 | 144 | |
145 | 145 | 接受数据类 |
146 | + | |
147 | +固件升级 | |
148 | +固件升级的文件在OTA文件之中 | |
149 | +OTAManager处理ota升级的设置与业务流程 | |
150 | +LETransceiver处理底层的数据的读写与相关设置 | |
151 | +OTAUpdateViewController展示页面处理相关交互 | |
152 | +在对外设peripheral的服务进行设置setNotifyValue会进入固件升级模式,在退出固件升级模式后,会重置该值并断开重连回到常规模式 | |
153 | +移除了mtk的底层代码,重做了BluetoothManager的reConnect,在BluetoothManager实例化CBCentralManager时会去尝试一次重连 | ... | ... |
HDFwear/OTA/LETransceiver.h
... | ... | @@ -17,7 +17,8 @@ NS_ASSUME_NONNULL_BEGIN |
17 | 17 | #define KeyIndicateCharacteristicUUID @"kIndicateCharacteristicUUID" |
18 | 18 | |
19 | 19 | @protocol LEConnctionDelegate <NSObject> |
20 | -- (void)onConnectedPeripheral:(CBPeripheral *) peripheral; | |
20 | +// 当做完相关ota的连接动作后的回调,此时手表进入固件升级进度状态 | |
21 | +- (void)onPeripheralOtaConnected:(CBPeripheral *) peripheral; | |
21 | 22 | @end |
22 | 23 | |
23 | 24 | @interface LETransceiver : NSObject | ... | ... |
HDFwear/OTA/LETransceiver.m
... | ... | @@ -133,8 +133,8 @@ |
133 | 133 | connectedPeripheral = peripheral; |
134 | 134 | [connectTimer invalidate]; |
135 | 135 | |
136 | - if(_connectionDelegate && [_connectionDelegate respondsToSelector:@selector(onConnectedPeripheral:)]) { | |
137 | - [_connectionDelegate onConnectedPeripheral:peripheral]; | |
136 | + if(_connectionDelegate && [_connectionDelegate respondsToSelector:@selector(onPeripheralOtaConnected:)]) { | |
137 | + [_connectionDelegate onPeripheralOtaConnected:peripheral]; | |
138 | 138 | } |
139 | 139 | } |
140 | 140 | } | ... | ... |
HDFwear/Tools/BluetoothManager+OTA.swift
... | ... | @@ -6,3 +6,83 @@ |
6 | 6 | // |
7 | 7 | |
8 | 8 | import Foundation |
9 | + | |
10 | +extension BluetoothManager { | |
11 | + // 开始ota需要做的几个动作 | |
12 | + // 生成一个新的ota的页面,在该页面内做ota的相关行为,传入一些必要参数,当前的peripheral,otaManager,ota文件path,以及关闭页面的回调 | |
13 | + // 设置isOTAUpdating,discoverServices扫描当前外设的服务,并在回调中进行设置,该动作触发手表进入固件升级状态 | |
14 | + func startOtaUpdate() { | |
15 | + let a = OTAUpdateViewController(nibName: "OTAUpdateViewController", bundle: nil) | |
16 | + a.currentPeripheral = peripheral | |
17 | + a.otaManager = otaManager | |
18 | + a.closeBlock = {[weak self] in | |
19 | + self?.isOTAUpdating = false | |
20 | + self?.otaTransceiver.closeOTA() | |
21 | + self?.disconnect() | |
22 | + self?.reConnect() | |
23 | + } | |
24 | + let docPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! | |
25 | + print("nick_path: \(docPath)") | |
26 | + let fullPath = (docPath as NSString).appendingPathComponent("QW230288A_HW_V1.5_0119.bin") | |
27 | + print(fullPath) | |
28 | + a.path = fullPath | |
29 | + getCurrentVC().navigationController?.pushViewController(a, animated: true) | |
30 | + | |
31 | + isOTAUpdating = true | |
32 | + peripheral?.discoverServices(nil) | |
33 | + } | |
34 | + | |
35 | +} | |
36 | + | |
37 | +extension BluetoothManager: LEConnctionDelegate { | |
38 | + func onPeripheralOtaConnected(_ peripheral: CBPeripheral) { | |
39 | + let nc = NotificationCenter.default | |
40 | + nc.post(name: Notification.Name("kMsgPeripheralConnected"), object: self, userInfo: nil) | |
41 | + | |
42 | + let mtu = peripheral.maximumWriteValueLength(for: .withoutResponse) | |
43 | + print("mtu view:%d", mtu); | |
44 | + otaManager.setMaxMtu(mtu) | |
45 | + } | |
46 | +} | |
47 | + | |
48 | +extension BluetoothManager: OTAManagerDelegate { | |
49 | + func send(_ data: Data) { | |
50 | + otaTransceiver.write(data) | |
51 | + } | |
52 | + | |
53 | + func send(_ data: Data, index i: Int32) { | |
54 | + otaTransceiver.write(data) | |
55 | + } | |
56 | + | |
57 | + func receiveAudioPSN(_ psn: Int, data: Data) { | |
58 | + print("nick_receiveAudioPSN") | |
59 | + var dic = [String: Any]() | |
60 | + dic["psn"] = psn | |
61 | + dic["data"] = data | |
62 | + NotificationCenter.default.post(name: NSNotification.Name(kMsgAudioPackageRecevied), object: self, userInfo: dic) | |
63 | + } | |
64 | + | |
65 | + func receiveSpeed(_ speed: Int) { | |
66 | + var dic = [String: Any]() | |
67 | + dic["speed"] = speed | |
68 | + NotificationCenter.default.post(name: NSNotification.Name(kMsgAudioSpeedRecevied), object: self, userInfo: dic) | |
69 | + } | |
70 | + | |
71 | + func receive(_ status: RemoteStatus) { | |
72 | + print("receiveRemoteStatus: \(status), \(String(describing: status.versionName)), \(String(describing: status.boardName))") | |
73 | + var dic = [String: Any]() | |
74 | + dic["status"] = status | |
75 | + NotificationCenter.default.post(name: NSNotification.Name(kMsgRemoteStatusRecevied), object: self, userInfo: dic) | |
76 | + } | |
77 | + | |
78 | + func onStatus(_ state: OTAStatus) { | |
79 | + let dic = ["status": state.rawValue] | |
80 | + NotificationCenter.default.post(name: NSNotification.Name(kMsgOTAStatus), object: self, userInfo: dic) | |
81 | + } | |
82 | + | |
83 | + func onError(_ errCode: Int) { | |
84 | + print("onError: \(errCode)") | |
85 | + } | |
86 | + | |
87 | +} | |
88 | + | ... | ... |
HDFwear/Tools/BluetoothManager.swift
... | ... | @@ -148,7 +148,7 @@ class BluetoothManager: NSObject { |
148 | 148 | |
149 | 149 | //ota |
150 | 150 | var isOTAUpdating: Bool = false |
151 | - var otaTransceiver : LETransceiver? | |
151 | + var otaTransceiver = LETransceiver() | |
152 | 152 | var otaManager = OTAManager() |
153 | 153 | |
154 | 154 | //mergeData |
... | ... | @@ -178,7 +178,8 @@ class BluetoothManager: NSObject { |
178 | 178 | // registerClientProfile() |
179 | 179 | // let options = ["CBCentralManagerOptionShowPowerAlertKey":false] |
180 | 180 | centralManger = CBCentralManager(delegate: self, queue: .main) |
181 | - | |
181 | + otaTransceiver.connectionDelegate = self | |
182 | + otaManager.delegate = self | |
182 | 183 | } |
183 | 184 | // private func setupManger(_ peripheral: CBPeripheral?) { |
184 | 185 | // if peripheral == nil { |
... | ... | @@ -259,7 +260,7 @@ class BluetoothManager: NSObject { |
259 | 260 | // 这里是根据名字来判断其平台类型 |
260 | 261 | platform = ._828 |
261 | 262 | if centralManger != nil { |
262 | - centralManger!.connect(peripheral, options: nil) | |
263 | + centralManger!.connect(peripheral, options: [CBConnectPeripheralOptionNotifyOnConnectionKey:true]) | |
263 | 264 | } |
264 | 265 | // registerClientProfile() |
265 | 266 | // manger?.connectPeripheral(peripheral) |
... | ... | @@ -1754,7 +1755,10 @@ extension BluetoothManager: CBCentralManagerDelegate { |
1754 | 1755 | } |
1755 | 1756 | |
1756 | 1757 | func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { |
1757 | - | |
1758 | + for delegate in delegateList { | |
1759 | + delegate.didDisconnected() | |
1760 | + } | |
1761 | + print("断开连接") | |
1758 | 1762 | } |
1759 | 1763 | } |
1760 | 1764 | |
... | ... | @@ -1776,6 +1780,10 @@ extension BluetoothManager: CBPeripheralDelegate { |
1776 | 1780 | } |
1777 | 1781 | |
1778 | 1782 | func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { |
1783 | + if isOTAUpdating { | |
1784 | + otaTransceiver.peripheral(peripheral, didDiscoverCharacteristicsFor: service, error: error) | |
1785 | + return | |
1786 | + } | |
1779 | 1787 | print("jason_bluetooth_action_6:得到发现特征回调"); |
1780 | 1788 | if service.characteristics == nil { |
1781 | 1789 | return |
... | ... | @@ -1803,6 +1811,11 @@ extension BluetoothManager: CBPeripheralDelegate { |
1803 | 1811 | guard let data = characteristic.value, data.count >= 0 else { |
1804 | 1812 | return |
1805 | 1813 | } |
1814 | + if isOTAUpdating { | |
1815 | + print("didUpdateValueForCharacteristic: %@ %@", characteristic.uuid.uuidString, characteristic.value ?? "") | |
1816 | + otaManager.receive(data) | |
1817 | + return | |
1818 | + } | |
1806 | 1819 | |
1807 | 1820 | switch characteristic.uuid.uuidString { |
1808 | 1821 | case BLEConfig.MTKBasReadUUID: | ... | ... |