diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index c83504f3..6d5bb1f1 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -1318,43 +1318,45 @@ func routingPacket (packet: MeshPacket, meshLogging: Bool, context: NSManagedObj if meshLogging { MeshLogger.log("πŸ•ΈοΈ ROUTING PACKET received for RequestID: \(packet.decoded.requestID) Error: \(errorExplanation)") } - if routingMessage.errorReason == Routing.Error.none { - let fetchMessageRequest: NSFetchRequest = NSFetchRequest.init(entityName: "MessageEntity") - fetchMessageRequest.predicate = NSPredicate(format: "messageId == %lld", Int64(packet.decoded.requestID)) + let fetchMessageRequest: NSFetchRequest = NSFetchRequest.init(entityName: "MessageEntity") + fetchMessageRequest.predicate = NSPredicate(format: "messageId == %lld", Int64(packet.decoded.requestID)) - do { + do { - let fetchedMessage = try context.fetch(fetchMessageRequest) as? [MessageEntity] + let fetchedMessage = try context.fetch(fetchMessageRequest) as? [MessageEntity] + + if fetchedMessage?.count ?? 0 > 0 { - if fetchedMessage?.count ?? 0 > 0 { + fetchedMessage![0].ackError = Int32(routingMessage.errorReason.rawValue) + + if routingMessage.errorReason == Routing.Error.none { fetchedMessage![0].receivedACK = true - fetchedMessage![0].ackSNR = packet.rxSnr - fetchedMessage![0].ackTimestamp = Int32(packet.rxTime) - fetchedMessage![0].objectWillChange.send() - fetchedMessage![0].fromUser?.objectWillChange.send() - fetchedMessage![0].toUser?.objectWillChange.send() - - } else { - - return } + fetchedMessage![0].ackSNR = packet.rxSnr + fetchedMessage![0].ackTimestamp = Int32(packet.rxTime) + fetchedMessage![0].objectWillChange.send() - try context.save() - - if meshLogging { - MeshLogger.log("πŸ’Ύ ACK Received and saved for MessageID \(packet.decoded.requestID)") - } + } else { - } catch { - - context.rollback() - - let nsError = error as NSError - print("πŸ’₯ Error Saving ACK for message MessageID \(packet.id) Error: \(nsError)") + return } + + try context.save() + + if meshLogging { + MeshLogger.log("πŸ’Ύ ACK Received and saved for MessageID \(packet.decoded.requestID)") + } + + } catch { + + context.rollback() + + let nsError = error as NSError + print("πŸ’₯ Error Saving ACK for message MessageID \(packet.id) Error: \(nsError)") } + } } diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 5.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 5.xcdatamodel/contents index 84e9cfee..54fd678a 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 5.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 5.xcdatamodel/contents @@ -47,6 +47,7 @@ + @@ -194,6 +195,7 @@ + @@ -205,7 +207,7 @@ - + @@ -215,6 +217,6 @@ - + \ No newline at end of file diff --git a/Meshtastic/Protobufs/config.pb.swift b/Meshtastic/Protobufs/config.pb.swift index d37e9615..ad46c586 100644 --- a/Meshtastic/Protobufs/config.pb.swift +++ b/Meshtastic/Protobufs/config.pb.swift @@ -527,6 +527,10 @@ struct Config { /// If set, the node AP will broadcast as a hidden SSID var apHidden: Bool = false + /// + /// If set, wifi is enabled. Previously done through setting ssid and psk + var enabled: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -1381,6 +1385,7 @@ extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem 2: .same(proto: "psk"), 3: .standard(proto: "ap_mode"), 4: .standard(proto: "ap_hidden"), + 5: .same(proto: "enabled"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -1393,6 +1398,7 @@ extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem case 2: try { try decoder.decodeSingularStringField(value: &self.psk) }() case 3: try { try decoder.decodeSingularBoolField(value: &self.apMode) }() case 4: try { try decoder.decodeSingularBoolField(value: &self.apHidden) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.enabled) }() default: break } } @@ -1411,6 +1417,9 @@ extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if self.apHidden != false { try visitor.visitSingularBoolField(value: self.apHidden, fieldNumber: 4) } + if self.enabled != false { + try visitor.visitSingularBoolField(value: self.enabled, fieldNumber: 5) + } try unknownFields.traverse(visitor: &visitor) } @@ -1419,6 +1428,7 @@ extension Config.WiFiConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if lhs.psk != rhs.psk {return false} if lhs.apMode != rhs.apMode {return false} if lhs.apHidden != rhs.apHidden {return false} + if lhs.enabled != rhs.enabled {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Meshtastic/Protobufs/mesh.pb.swift b/Meshtastic/Protobufs/mesh.pb.swift index a09549de..d528fb7e 100644 --- a/Meshtastic/Protobufs/mesh.pb.swift +++ b/Meshtastic/Protobufs/mesh.pb.swift @@ -130,6 +130,10 @@ enum HardwareModel: SwiftProtobuf.Enum { /// M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ case m5Stack // = 44 + /// + /// B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station + case stationG1 // = 45 + /// /// Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. case privateHw // = 255 @@ -166,6 +170,7 @@ enum HardwareModel: SwiftProtobuf.Enum { case 42: self = .nrf52840Pca10059 case 43: self = .drDev case 44: self = .m5Stack + case 45: self = .stationG1 case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } @@ -198,6 +203,7 @@ enum HardwareModel: SwiftProtobuf.Enum { case .nrf52840Pca10059: return 42 case .drDev: return 43 case .m5Stack: return 44 + case .stationG1: return 45 case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } @@ -235,6 +241,7 @@ extension HardwareModel: CaseIterable { .nrf52840Pca10059, .drDev, .m5Stack, + .stationG1, .privateHw, ] } @@ -2176,6 +2183,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 42: .same(proto: "NRF52840_PCA10059"), 43: .same(proto: "DR_DEV"), 44: .same(proto: "M5STACK"), + 45: .same(proto: "STATION_G1"), 255: .same(proto: "PRIVATE_HW"), ] } diff --git a/Meshtastic/Views/Messages/UserMessageList.swift b/Meshtastic/Views/Messages/UserMessageList.swift index e4941797..ed4366ef 100644 --- a/Meshtastic/Views/Messages/UserMessageList.swift +++ b/Meshtastic/Views/Messages/UserMessageList.swift @@ -236,6 +236,9 @@ struct UserMessageList: View { Text("Unknown Age").font(.caption2).foregroundColor(.gray) } } + } else if message.ackError > 0 { + + Text("Ack Failure") } if message.ackSNR != 0 { VStack { diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 94c6bd06..95755bd4 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -19,7 +19,7 @@ struct NodeList: View { @State var initialLoad: Bool = true @FetchRequest( - sortDescriptors: [NSSortDescriptor(key: "lastHeard", ascending: false)], + sortDescriptors: [NSSortDescriptor(key: "user.shortName", ascending: true)], animation: .default) private var nodes: FetchedResults @@ -61,7 +61,7 @@ struct NodeList: View { if UIDevice.current.userInterfaceIdiom == .pad { Text(node.user?.longName ?? "Unknown").font(.headline) .offset(x: -15) } else { - Text(node.user?.longName ?? "Unknown").font(.title).offset(x: -15) + Text(node.user?.longName ?? "Unknown").font(.title2).offset(x: -15) } } .padding(.bottom, 10) @@ -106,16 +106,16 @@ struct NodeList: View { if initialLoad { - self.bleManager.context = context self.bleManager.userSettings = userSettings + self.bleManager.context = context self.initialLoad = false - if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { - - if nodes.count > 0 { - selection = "0" - } - } +// if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { +// +// if nodes.count > 0 { +// selection = "0" +// } +// } } } } diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index fe3ec406..3fe04782 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -376,9 +376,12 @@ struct CannedMessagesConfig: View { // RAK Rotary Encoder updown1Enabled = true rotary1Enabled = false - inputbrokerEventCw = InputEventChars.keyUp.rawValue - inputbrokerEventCcw = InputEventChars.keyDown.rawValue - inputbrokerEventPress = InputEventChars.keySelect.rawValue + inputbrokerPinA = 4 + inputbrokerPinB = 10 + inputbrokerPinPress = 3 + inputbrokerEventCw = InputEventChars.keyNone.rawValue + inputbrokerEventCcw = InputEventChars.keyNone.rawValue + inputbrokerEventPress = InputEventChars.keyNone.rawValue } else if newPreset == 2 { diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index e54f3617..3769d4f6 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -139,7 +139,7 @@ struct ExternalNotificationConfig: View { Label("Save", systemImage: "square.and.arrow.down") } - .disabled(bleManager.connectedPeripheral == nil || !hasChanges || !(node!.myInfo?.hasWifi ?? false)) + .disabled(bleManager.connectedPeripheral == nil || !hasChanges) .buttonStyle(.bordered) .buttonBorderShape(.capsule) .controlSize(.large) diff --git a/Meshtastic/Views/Settings/Config/WiFiConfig.swift b/Meshtastic/Views/Settings/Config/WiFiConfig.swift index 246c2e0b..a569f9d3 100644 --- a/Meshtastic/Views/Settings/Config/WiFiConfig.swift +++ b/Meshtastic/Views/Settings/Config/WiFiConfig.swift @@ -17,6 +17,8 @@ struct WiFiConfig: View { @State private var isPresentingSaveConfirm: Bool = false @State var initialLoad: Bool = true @State var hasChanges: Bool = false + + @State var enabled = false @State var ssid = "" @State var password = "" @@ -28,16 +30,29 @@ struct WiFiConfig: View { VStack { - Text("Enabling WiFi will disable bluetooth, only one connection method works at a time. Saving these settings will disconnect your device from the app.") - .font(.title3) + Text("Enabling WiFi will disable the bluetooth connection to the app.") + .font(.callout) .padding() Form { - Section(header: Text("SSID & Password")) { + + Section(header: Text("Options")) { + + Text("WiFi client mode is enabled by default, if Soft AP is enabled the SSID and psk will be used as the default credentials for the access point.") + .font(.caption) + + //HStack { + + Toggle(isOn: $enabled) { + + Label("Enable", systemImage: "wifi") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + // } HStack { - Label("SSID", systemImage: "wifi") + Label("SSID", systemImage: "network") TextField("SSID", text: $ssid) .foregroundColor(.gray) .onChange(of: ssid, perform: { value in @@ -91,19 +106,21 @@ struct WiFiConfig: View { Toggle(isOn: $apMode) { - Label("Soft AP Mode", systemImage: "wifi") + Label("Soft AP Mode", systemImage: "externaldrive.fill.badge.wifi") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) - Text("If set the software access point mode will be activated.") - .font(.caption) - Toggle(isOn: $apHidden) { + if apMode { + + Toggle(isOn: $apHidden) { - Label("Hidden AP", systemImage: "eye.slash") + Label("Hidden AP", systemImage: "eye.slash") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + Text("If set the SSID for the AP will be hidden.") + .font(.caption) } - .toggleStyle(SwitchToggleStyle(tint: .accentColor)) - Text("If set the SSID for the AP will be hidden.") - .font(.caption) + } } @@ -171,6 +188,13 @@ struct WiFiConfig: View { self.initialLoad = false } } + .onChange(of: enabled) { newEnabled in + + if node != nil && node!.wiFiConfig != nil { + + if newEnabled != node!.wiFiConfig!.enabled { hasChanges = true } + } + } .onChange(of: ssid) { newSsid in if node != nil && node!.wiFiConfig != nil {