From 405e52fd35df341b69131b07672aa165f0793962 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 3 Dec 2022 09:32:20 -0800 Subject: [PATCH 1/6] Fix rak canned messages preset --- .../Views/Settings/Config/Module/CannedMessagesConfig.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 4d11470e..cf306c54 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -287,7 +287,7 @@ struct CannedMessagesConfig: View { if newPreset == 1 { // RAK Rotary Encoder - updown1Enabled = false + updown1Enabled = true rotary1Enabled = false inputbrokerPinA = 4 inputbrokerPinB = 10 From 6081d8c30cede937a005dc4cd42f0490cc9abf58 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 4 Dec 2022 00:28:26 -0800 Subject: [PATCH 2/6] * Add Libraries for OTA * Refactor BLE Manager a bit * Add signal strength indicator graphic to ble connect view * Order BLE devices by name --- Meshtastic.xcodeproj/project.pbxproj | 21 +++ .../xcshareddata/swiftpm/Package.resolved | 18 +++ Meshtastic/Helpers/BLEManager.swift | 124 ++++++++++-------- Meshtastic/MeshtasticApp.swift | 2 +- Meshtastic/Model/PeripheralModel.swift | 12 ++ Meshtastic/Views/Bluetooth/Connect.swift | 6 +- .../Helpers/SignalStrengthIndicator.swift | 78 +++++++++++ .../Views/Settings/Config/DeviceConfig.swift | 2 + .../Config/Module/CannedMessagesConfig.swift | 2 +- .../Module/ExternalNotificationConfig.swift | 1 + 10 files changed, 205 insertions(+), 61 deletions(-) create mode 100644 Meshtastic/Views/Helpers/SignalStrengthIndicator.swift diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index e2de45de..c17157b8 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -33,6 +33,8 @@ DD41582628582E9B009B0E59 /* DeviceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582528582E9B009B0E59 /* DeviceConfig.swift */; }; DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD415827285859C4009B0E59 /* TelemetryConfig.swift */; }; DD41582A28585C32009B0E59 /* RangeTestConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582928585C32009B0E59 /* RangeTestConfig.swift */; }; + DD457184293C55CD000C49FB /* NordicDFU in Frameworks */ = {isa = PBXBuildFile; productRef = DD457183293C55CD000C49FB /* NordicDFU */; }; + DD457188293C7E63000C49FB /* SignalStrengthIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD457187293C7E63000C49FB /* SignalStrengthIndicator.swift */; }; DD47E3CE26F103C600029299 /* NodeList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3CD26F103C600029299 /* NodeList.swift */; }; DD47E3D626F17ED900029299 /* CircleText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3D526F17ED900029299 /* CircleText.swift */; }; DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3D826F3093800029299 /* MessageBubble.swift */; }; @@ -148,6 +150,7 @@ DD41582528582E9B009B0E59 /* DeviceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceConfig.swift; sourceTree = ""; }; DD415827285859C4009B0E59 /* TelemetryConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryConfig.swift; sourceTree = ""; }; DD41582928585C32009B0E59 /* RangeTestConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RangeTestConfig.swift; sourceTree = ""; }; + DD457187293C7E63000C49FB /* SignalStrengthIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignalStrengthIndicator.swift; sourceTree = ""; }; DD47E3CD26F103C600029299 /* NodeList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeList.swift; sourceTree = ""; }; DD47E3D526F17ED900029299 /* CircleText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleText.swift; sourceTree = ""; }; DD47E3D826F3093800029299 /* MessageBubble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBubble.swift; sourceTree = ""; }; @@ -233,6 +236,7 @@ buildActionMask = 2147483647; files = ( C9697FA527933B8C00250207 /* SQLite in Frameworks */, + DD457184293C55CD000C49FB /* NordicDFU in Frameworks */, DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -517,6 +521,7 @@ DDB6ABDA28B0AC6000384BA1 /* DistanceText.swift */, DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */, DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */, + DD457187293C7E63000C49FB /* SignalStrengthIndicator.swift */, ); path = Helpers; sourceTree = ""; @@ -566,6 +571,7 @@ packageProductDependencies = ( DD5394FB276993AD00AD86B1 /* SwiftProtobuf */, C9697FA427933B8C00250207 /* SQLite */, + DD457183293C55CD000C49FB /* NordicDFU */, ); productName = MeshtasticClient; productReference = DDC2E15426CE248E0042C5E4 /* Meshtastic.app */; @@ -643,6 +649,7 @@ packageReferences = ( DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */, C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */, + DD457182293C55CD000C49FB /* XCRemoteSwiftPackageReference "IOS-DFU-Library" */, ); productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */; projectDirPath = ""; @@ -707,6 +714,7 @@ buildActionMask = 2147483647; files = ( DD4DED9027AD2975004BA27E /* cannedmessages.pb.swift in Sources */, + DD457188293C7E63000C49FB /* SignalStrengthIndicator.swift in Sources */, DDCFF601285453A7005FA625 /* localonly.pb.swift in Sources */, DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */, DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */, @@ -1153,6 +1161,14 @@ minimumVersion = 0.9.2; }; }; + DD457182293C55CD000C49FB /* XCRemoteSwiftPackageReference "IOS-DFU-Library" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/NordicSemiconductor/IOS-DFU-Library"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.0.0; + }; + }; DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/apple/swift-protobuf.git"; @@ -1169,6 +1185,11 @@ package = C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */; productName = SQLite; }; + DD457183293C55CD000C49FB /* NordicDFU */ = { + isa = XCSwiftPackageProductDependency; + package = DD457182293C55CD000C49FB /* XCRemoteSwiftPackageReference "IOS-DFU-Library" */; + productName = NordicDFU; + }; DD5394FB276993AD00AD86B1 /* SwiftProtobuf */ = { isa = XCSwiftPackageProductDependency; package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */; diff --git a/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index bccfe8c9..b1fa0604 100644 --- a/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,14 @@ { "pins" : [ + { + "identity" : "ios-dfu-library", + "kind" : "remoteSourceControl", + "location" : "https://github.com/NordicSemiconductor/IOS-DFU-Library", + "state" : { + "revision" : "ec5364755f4fcdf68d62ff4cf796d22e7b935f40", + "version" : "4.13.0" + } + }, { "identity" : "sqlite.swift", "kind" : "remoteSourceControl", @@ -17,6 +26,15 @@ "revision" : "e1499bc69b9040b29184f7f2996f7bab467c1639", "version" : "1.19.0" } + }, + { + "identity" : "zipfoundation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/weichsel/ZIPFoundation", + "state" : { + "revision" : "ec32d62d412578542c0ffb7a6ce34d3e64b43b94", + "version" : "0.9.11" + } } ], "version" : 2 diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index c93cee1b..e0dd2445 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -7,9 +7,9 @@ import MapKit // --------------------------------------------------------------------------------------- // Meshtastic BLE Device Manager // --------------------------------------------------------------------------------------- -class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeripheralDelegate { +class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { - static let shared = BLEManager() + //static let shared = BLEManager() private static var documentsFolder: URL { do { @@ -25,19 +25,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph private var centralManager: CBCentralManager! - @Published var peripherals: [Peripheral] + @Published var peripherals: [Peripheral] = [] @Published var connectedPeripheral: Peripheral! - @Published var lastConnectionError: String - @Published var minimumVersion = "1.3.48" - @Published var connectedVersion: String - @Published var invalidVersion = false - @Published var preferredPeripheral = false + public var lastConnectionError: String + public var minimumVersion = "1.3.48" + public var connectedVersion: String + public var invalidVersion = false + public var preferredPeripheral = false - @Published var isSwitchedOn: Bool = false - @Published var isScanning: Bool = false - @Published var isConnecting: Bool = false - @Published var isConnected: Bool = false - @Published var isSubscribed: Bool = false + public var isSwitchedOn: Bool = false + public var isScanning: Bool = false + public var isConnecting: Bool = false + public var isConnected: Bool = false + public var isSubscribed: Bool = false /// Used to make sure we never get foold by old BLE packets private var configNonce: UInt32 = 1 @@ -80,29 +80,16 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph self.lastConnectionError = "" self.connectedVersion = "0.0.0" - self.peripherals = [Peripheral]() super.init() // let bleQueue: DispatchQueue = DispatchQueue(label: "CentralManager") centralManager = CBCentralManager(delegate: self, queue: nil) } - // MARK: Bluetooth enabled/disabled for the app - func centralManagerDidUpdateState(_ central: CBCentralManager) { - if central.state == .poweredOn { - - isSwitchedOn = true - startScanning() - } else { - - isSwitchedOn = false - } - } - // MARK: Scanning for BLE Devices // Scan for nearby BLE devices using the Meshtastic BLE service ID func startScanning() { if isSwitchedOn { - centralManager.scanForPeripherals(withServices: [meshtasticServiceCBUUID], options: nil) + centralManager.scanForPeripherals(withServices: [meshtasticServiceCBUUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: true]) DispatchQueue.main.async { self.isScanning = self.centralManager.isScanning } @@ -192,36 +179,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } // Called each time a peripheral is discovered - func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { - - var peripheralName: String = peripheral.name ?? "Unknown" - - if let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String { - peripheralName = name - } - - let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: "????", longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, lastUpdate: Date(), peripheral: peripheral) - let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id }) - - if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected { - - peripherals[peripheralIndex!] = newPeripheral - peripherals.remove(at: peripheralIndex!) - peripherals.append(newPeripheral) - - } else { - - if newPeripheral.peripheral.state != CBPeripheralState.connected { - peripherals.append(newPeripheral) - } - } - - let today = Date() - let visibleDuration = Calendar.current.date(byAdding: .second, value: -5, to: today)! - peripherals.removeAll(where: { $0.lastUpdate < visibleDuration}) - } - - // Called when a peripheral is connected func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { isConnecting = false isConnected = true @@ -1608,3 +1565,56 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return false } } + +// MARK: - CB Central Manager implmentation +extension BLEManager: CBCentralManagerDelegate { + + // MARK: Bluetooth enabled/disabled + func centralManagerDidUpdateState(_ central: CBCentralManager) { + if central.state == CBManagerState.poweredOn { + print("BLE powered on") + isSwitchedOn = true + startScanning() + } + else { + isSwitchedOn = false + } + + var status = "" + + switch central.state { + case .poweredOff: + status = "BLE is powered off" + case .poweredOn: + status = "BLE is poweredOn" + case .resetting: + status = "BLE is resetting" + case .unauthorized: + status = "BLE is unauthorized" + case .unknown: + status = "BLE is unknown" + case .unsupported: + status = "BLE is unsupported" + default: + status = "default" + } + print("BLEManager status: \(status)") + } + + // Called each time a peripheral is discovered + func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { + + let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String + let device = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: name ?? "Unknown", shortName: "????", longName: name ?? "Unknown", firmwareVersion: "Unknown", rssi: RSSI.intValue, lastUpdate: Date(), peripheral: peripheral) + let index = peripherals.map { $0.peripheral }.firstIndex(of: peripheral) + + if let peripheralIndex = index { + peripherals[peripheralIndex] = device + } else { + peripherals.append(device) + } + let today = Date() + let visibleDuration = Calendar.current.date(byAdding: .second, value: -5, to: today)! + self.peripherals.removeAll(where: { $0.lastUpdate < visibleDuration}) + } +} diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index 87a218c5..98958a3e 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -7,7 +7,7 @@ import CoreData struct MeshtasticAppleApp: App { let persistenceController = PersistenceController.shared - @ObservedObject private var bleManager: BLEManager = BLEManager.shared + @ObservedObject private var bleManager: BLEManager = BLEManager() @ObservedObject private var userSettings: UserSettings = UserSettings() @Environment(\.scenePhase) var scenePhase diff --git a/Meshtastic/Model/PeripheralModel.swift b/Meshtastic/Model/PeripheralModel.swift index 758dc8e8..4da4b264 100644 --- a/Meshtastic/Model/PeripheralModel.swift +++ b/Meshtastic/Model/PeripheralModel.swift @@ -23,4 +23,16 @@ struct Peripheral: Identifiable { self.lastUpdate = lastUpdate self.peripheral = peripheral } + + func getSignalStrength() -> SignalStrength { + if (NSNumber(value: rssi).compare(NSNumber(-65)) == ComparisonResult.orderedDescending) { + return SignalStrength.strong + } + else if (NSNumber(value: rssi).compare(NSNumber(-85)) == ComparisonResult.orderedDescending) { + return SignalStrength.normal + } + else { + return SignalStrength.weak + } + } } diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 71293092..8b534621 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -161,7 +161,7 @@ struct Connect: View { if self.bleManager.isScanning { Section(header: Text("Available Radios").font(.title)) { - ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.rssi > $1.rssi })) { peripheral in + ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name > $1.name })) { peripheral in HStack { Image(systemName: "circle.fill") .imageScale(.large).foregroundColor(.gray) @@ -184,7 +184,9 @@ struct Connect: View { Text(peripheral.name).font(.title3) } Spacer() - Text(String(peripheral.rssi) + " dB").font(.title3) + VStack { + SignalStrengthIndicator(signalStrength: peripheral.getSignalStrength()) + } }.padding([.bottom, .top]) } }.textCase(nil) diff --git a/Meshtastic/Views/Helpers/SignalStrengthIndicator.swift b/Meshtastic/Views/Helpers/SignalStrengthIndicator.swift new file mode 100644 index 00000000..29b020b1 --- /dev/null +++ b/Meshtastic/Views/Helpers/SignalStrengthIndicator.swift @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2022, Nordic Semiconductor +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +import Foundation +import SwiftUI + +struct SignalStrengthIndicator: View { + let signalStrength: SignalStrength + + var body: some View { + HStack { + ForEach(0..<3) { bar in + RoundedRectangle(cornerRadius: 3) + .divided(amount: (CGFloat(bar) + 1) / CGFloat(3)) + .fill(getColor().opacity(bar <= signalStrength.rawValue ? 1 : 0.3)) + .frame(width: 8, height: 30) + } + } + } + + private func getColor() -> Color { + switch signalStrength { + case .weak: + return Color.red + case .normal: + return Color.yellow + case .strong: + return Color.green + } + } +} + +struct Divided: Shape { + var amount: CGFloat // Should be in range 0...1 + var shape: S + func path(in rect: CGRect) -> Path { + shape.path(in: rect.divided(atDistance: amount * rect.height, from: .maxYEdge).slice) + } +} + +extension Shape { + func divided(amount: CGFloat) -> Divided { + return Divided(amount: amount, shape: self) + } +} + +enum SignalStrength : Int { + case weak = 0 + case normal = 1 + case strong = 2 +} diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index 26b3bcdc..49d51032 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -19,6 +19,7 @@ struct DeviceConfig: View { @State var hasChanges = false @State var deviceRole = 0 + //@State var buzzerGPIO = 12 @State var serialEnabled = true @State var debugLogEnabled = false @@ -135,6 +136,7 @@ struct DeviceConfig: View { dc.role = DeviceRoles(rawValue: deviceRole)!.protoEnumValue() dc.serialEnabled = serialEnabled dc.debugLogEnabled = debugLogEnabled + //dc.buzzerGpio = UInt32(buzzerGPIO) let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: node!.user!, toUser: node!.user!) diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index cf306c54..13f8a109 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -236,7 +236,7 @@ struct CannedMessagesConfig: View { /// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", or keyword "_any" cmc.allowInputSource = "rotEnc1" } else if updown1Enabled { - cmc.allowInputSource = "_any" + cmc.allowInputSource = "upDown1" } else { cmc.allowInputSource = "_any" } diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index 3e3c4bc0..b1665c6e 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -142,6 +142,7 @@ struct ExternalNotificationConfig: View { enc.active = active enc.output = UInt32(output) enc.outputMs = UInt32(outputMilliseconds) + enc.usePwm = usePWM let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, fromUser: node!.user!, toUser: node!.user!) if adminMessageId > 0{ // Should show a saved successfully alert once I know that to be true From 674178469f5925b7f667689ecd8a5af99c8e26f9 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 4 Dec 2022 00:34:10 -0800 Subject: [PATCH 3/6] Fix scanning button --- Meshtastic/Helpers/BLEManager.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index e0dd2445..91a252c7 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -20,13 +20,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { } var context: NSManagedObjectContext? - var userSettings: UserSettings? - private var centralManager: CBCentralManager! @Published var peripherals: [Peripheral] = [] @Published var connectedPeripheral: Peripheral! + @Published var isScanning: Bool = false public var lastConnectionError: String public var minimumVersion = "1.3.48" public var connectedVersion: String @@ -34,7 +33,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { public var preferredPeripheral = false public var isSwitchedOn: Bool = false - public var isScanning: Bool = false + public var isConnecting: Bool = false public var isConnected: Bool = false public var isSubscribed: Bool = false From 6a09b278885e39552844ce66ff9540e6d6dc2ef2 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 4 Dec 2022 06:56:55 -0800 Subject: [PATCH 4/6] Clean up BLEManager refactoring --- Meshtastic/Helpers/BLEManager.swift | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 91a252c7..20a45809 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -9,8 +9,6 @@ import MapKit // --------------------------------------------------------------------------------------- class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { - //static let shared = BLEManager() - private static var documentsFolder: URL { do { return try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) @@ -26,14 +24,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { @Published var peripherals: [Peripheral] = [] @Published var connectedPeripheral: Peripheral! @Published var isScanning: Bool = false - public var lastConnectionError: String + @Published var lastConnectionError: String + @Published var invalidVersion = false public var minimumVersion = "1.3.48" public var connectedVersion: String - public var invalidVersion = false public var preferredPeripheral = false - public var isSwitchedOn: Bool = false - public var isConnecting: Bool = false public var isConnected: Bool = false public var isSubscribed: Bool = false @@ -76,11 +72,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { // MARK: init BLEManager override init() { - self.lastConnectionError = "" self.connectedVersion = "0.0.0" super.init() - // let bleQueue: DispatchQueue = DispatchQueue(label: "CentralManager") centralManager = CBCentralManager(delegate: self, queue: nil) } From 87adad82798da61889b4c860a817779e8309b66d Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 5 Dec 2022 19:32:58 -0800 Subject: [PATCH 5/6] Remove old DFU code --- Meshtastic/Helpers/BLEManager.swift | 42 ++--------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 20a45809..e0d43975 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -52,20 +52,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { let FROMRADIO_UUID = CBUUID(string: "0x2C55E69E-4993-11ED-B878-0242AC120002") let EOL_FROMRADIO_UUID = CBUUID(string: "0x8BA2BCC2-EE02-4A55-A531-C525C5E454D5") let FROMNUM_UUID = CBUUID(string: "0xED9DA18C-A800-4F66-A670-AA7547E34453") - - // Meshtastic DFU details - let DFUSERVICE_UUID = CBUUID(string : "cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30") - let DFUSIZE_UUID = CBUUID(string: "e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e") - let DFUDATA_UUID = CBUUID(string: "e272ebac-d463-4b98-bc84-5cc1a39ee517") - let DFUCRC32_UUID = CBUUID(string: "4826129c-c22a-43a3-b066-ce8f0d5bacc6") - let DFURESULT_UUID = CBUUID(string: "5e134862-7411-4424-ac4a-210937432c77") - let DFUREGION_UUID = CBUUID(string: "5e134862-7411-4424-ac4a-210937432c67") - - var DFUSIZE_characteristic: CBCharacteristic? - var DFUDATA_characteristic: CBCharacteristic? - var DFUCRC32_characteristic: CBCharacteristic? - var DFURESULT_characteristic: CBCharacteristic? - var DFUREGION_characteristic: CBCharacteristic? //private var meshLoggingEnabled: Bool = true let meshLog = documentsFolder.appendingPathComponent("meshlog.txt") @@ -204,7 +190,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { return } // Discover Services - peripheral.discoverServices([meshtasticServiceCBUUID, DFUSERVICE_UUID]) + peripheral.discoverServices([meshtasticServiceCBUUID]) MeshLogger.log("✅ BLE Connected: \(peripheral.name ?? "Unknown")") } @@ -262,17 +248,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { if service.uuid == meshtasticServiceCBUUID { peripheral.discoverCharacteristics([TORADIO_UUID, FROMRADIO_UUID, FROMNUM_UUID], for: service) MeshLogger.log("✅ BLE Service for Meshtastic discovered by \(peripheral.name ?? "Unknown")") - } else if (service.uuid == DFUSERVICE_UUID) { - peripheral.discoverCharacteristics([DFUDATA_UUID, DFUSIZE_UUID, DFUREGION_UUID, DFURESULT_UUID, DFUCRC32_UUID], for: service) - MeshLogger.log("✅ BLE Service for Meshtastic DFU discovered by \(peripheral.name ?? "Unknown")") - } + } } } // MARK: Discover Characteristics Event func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { - if let e = error { MeshLogger.log("🚫 BLE Discover Characteristics error for \(peripheral.name ?? "Unknown") \(e) disconnecting device") // Try and stop crashes when this error occurs @@ -298,26 +280,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { MeshLogger.log("✅ BLE did discover FROMNUM (Notify) characteristic for Meshtastic by \(peripheral.name ?? "Unknown")") FROMNUM_characteristic = characteristic peripheral.setNotifyValue(true, for: characteristic) - - case DFUSIZE_UUID: - MeshLogger.log("✅ BLE did discover DFU Size characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") - DFUSIZE_characteristic = characteristic - - case DFUDATA_UUID: - MeshLogger.log("✅ BLE did discover DFU Data characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") - DFUDATA_characteristic = characteristic - - case DFUCRC32_UUID: - MeshLogger.log("✅ BLE did discover DFU CRC32 characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") - DFUCRC32_characteristic = characteristic - - case DFURESULT_UUID: - MeshLogger.log("✅ BLE did discover DFU Result characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") - DFURESULT_characteristic = characteristic - - case DFUREGION_UUID: - MeshLogger.log("✅ BLE did discover DFU Region characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") - DFUREGION_characteristic = characteristic default: break From 0787587cb455360de340ba01e88ad3374fad223e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 5 Dec 2022 19:47:56 -0800 Subject: [PATCH 6/6] Add gpio settings to device config --- .../Views/Settings/Config/DeviceConfig.swift | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index 49d51032..58be6096 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -19,7 +19,8 @@ struct DeviceConfig: View { @State var hasChanges = false @State var deviceRole = 0 - //@State var buzzerGPIO = 12 + @State var buzzerGPIO = 0 + @State var buttonGPIO = 0 @State var serialEnabled = true @State var debugLogEnabled = false @@ -56,6 +57,30 @@ struct DeviceConfig: View { .toggleStyle(SwitchToggleStyle(tint: .accentColor)) } + Section(header: Text("GPIO")) { + + Picker("Button GPIO", selection: $buttonGPIO) { + ForEach(0..<40) { + if $0 == 0 { + Text("Unset") + } else { + Text("Pin \($0)") + } + } + } + .pickerStyle(DefaultPickerStyle()) + Picker("Buzzer GPIO", selection: $buzzerGPIO) { + ForEach(0..<40) { + if $0 == 0 { + Text("Unset") + } else { + Text("Pin \($0)") + } + } + } + .pickerStyle(DefaultPickerStyle()) + } + } .disabled(bleManager.connectedPeripheral == nil) @@ -136,7 +161,8 @@ struct DeviceConfig: View { dc.role = DeviceRoles(rawValue: deviceRole)!.protoEnumValue() dc.serialEnabled = serialEnabled dc.debugLogEnabled = debugLogEnabled - //dc.buzzerGpio = UInt32(buzzerGPIO) + dc.buttonGpio = UInt32(buttonGPIO) + dc.buzzerGpio = UInt32(buzzerGPIO) let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: node!.user!, toUser: node!.user!) @@ -171,6 +197,8 @@ struct DeviceConfig: View { self.deviceRole = Int(node?.deviceConfig?.role ?? 0) self.serialEnabled = (node?.deviceConfig?.serialEnabled ?? true) self.debugLogEnabled = node?.deviceConfig?.debugLogEnabled ?? false + self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0) + self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0) self.hasChanges = false } .onChange(of: deviceRole) { newRole in @@ -194,5 +222,19 @@ struct DeviceConfig: View { if newDebugLog != node!.deviceConfig!.debugLogEnabled { hasChanges = true } } } + .onChange(of: buttonGPIO) { newButtonGPIO in + + if node != nil && node!.deviceConfig != nil { + + if newButtonGPIO != node!.deviceConfig!.buttonGpio { hasChanges = true } + } + } + .onChange(of: buzzerGPIO) { newBuzzerGPIO in + + if node != nil && node!.deviceConfig != nil { + + if newBuzzerGPIO != node!.deviceConfig!.buttonGpio { hasChanges = true } + } + } } }