diff --git a/Meshtastic/Enums/CannedMessagesConfigEnums.swift b/Meshtastic/Enums/CannedMessagesConfigEnums.swift index 0864e5d4..217bcd60 100644 --- a/Meshtastic/Enums/CannedMessagesConfigEnums.swift +++ b/Meshtastic/Enums/CannedMessagesConfigEnums.swift @@ -11,7 +11,6 @@ enum ConfigPresets : Int, CaseIterable, Identifiable { case unset = 0 case rakRotaryEncoder = 1 case cardKB = 2 - case facesKB = 3 var id: Int { self.rawValue } var description: String { @@ -23,9 +22,7 @@ enum ConfigPresets : Int, CaseIterable, Identifiable { case .rakRotaryEncoder: return "RAK Rotary Encoder Module" case .cardKB: - return "M5 Stack Card KeyBoard" - case .facesKB: - return "M5 Stack Faces KeyBoard" + return "M5 Stack Card KB / RAK Keypad" } } } diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 6b95bf61..80af2665 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -511,7 +511,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if decodedInfo.nodeInfo.num != 0 && !invalidVersion { nowKnown = true - let nodeInfo = nodeInfoPacket(nodeInfo: decodedInfo.nodeInfo, context: context!) + let nodeInfo = nodeInfoPacket(nodeInfo: decodedInfo.nodeInfo, channel: decodedInfo.packet.channel, context: context!) if nodeInfo != nil { if self.connectedPeripheral != nil && self.connectedPeripheral.num == nodeInfo!.num { @@ -1073,12 +1073,10 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph print("Failed to clear existing channels from local app database") } } - } catch { print("Failed to find a node MyInfo to save these channels to") } - let decodedString = base64UrlString.base64urlToBase64() if let decodedData = Data(base64Encoded: decodedString) { do { @@ -1188,7 +1186,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. NodeInfoEntity? { +func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObjectContext) -> NodeInfoEntity? { let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeInfo.num)) @@ -811,6 +811,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, context: NSManagedObjectContext) -> Nod let newNode = NodeInfoEntity(context: context) newNode.id = Int64(nodeInfo.num) newNode.num = Int64(nodeInfo.num) + newNode.channel = Int32(channel) if nodeInfo.hasDeviceMetrics { @@ -898,6 +899,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, context: NSManagedObjectContext) -> Nod fetchedNode[0].num = Int64(nodeInfo.num) fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(nodeInfo.lastHeard))) fetchedNode[0].snr = nodeInfo.snr + fetchedNode[0].channel = Int32(channel) if nodeInfo.hasUser { @@ -999,6 +1001,7 @@ func nodeInfoAppPacket (packet: MeshPacket, context: NSManagedObjectContext) { fetchedNode[0].num = Int64(packet.from) fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime))) fetchedNode[0].snr = packet.rxSnr + fetchedNode[0].channel = Int32(packet.channel) if let nodeInfoMessage = try? NodeInfo(serializedData: packet.decoded.payload) { @@ -1025,6 +1028,9 @@ func nodeInfoAppPacket (packet: MeshPacket, context: NSManagedObjectContext) { fetchedNode[0].user!.hwModel = String(describing: nodeInfoMessage.user.hwModel).uppercased() } } + } else { + + // New node info not from device but potentially from another network } do { diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel.xcdatamodel/contents index 849a579a..f92b0c92 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel.xcdatamodel/contents @@ -135,6 +135,7 @@ + diff --git a/Meshtastic/Protobufs/config.pb.swift b/Meshtastic/Protobufs/config.pb.swift index 22774a27..a70a48aa 100644 --- a/Meshtastic/Protobufs/config.pb.swift +++ b/Meshtastic/Protobufs/config.pb.swift @@ -435,57 +435,39 @@ struct Config { /// /// Enable WiFi (disables Bluetooth) - var wifiEnabled: Bool { - get {return _storage._wifiEnabled} - set {_uniqueStorage()._wifiEnabled = newValue} - } + var wifiEnabled: Bool = false /// /// If set, this node will try to join the specified wifi network and /// acquire an address via DHCP - var wifiSsid: String { - get {return _storage._wifiSsid} - set {_uniqueStorage()._wifiSsid = newValue} - } + var wifiSsid: String = String() /// /// If set, will be use to authenticate to the named wifi - var wifiPsk: String { - get {return _storage._wifiPsk} - set {_uniqueStorage()._wifiPsk = newValue} - } + var wifiPsk: String = String() /// /// NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org` - var ntpServer: String { - get {return _storage._ntpServer} - set {_uniqueStorage()._ntpServer = newValue} - } + var ntpServer: String = String() /// /// Enable Ethernet - var ethEnabled: Bool { - get {return _storage._ethEnabled} - set {_uniqueStorage()._ethEnabled = newValue} - } + var ethEnabled: Bool = false /// /// acquire an address via DHCP or assign static - var ethMode: Config.NetworkConfig.EthMode { - get {return _storage._ethMode} - set {_uniqueStorage()._ethMode = newValue} - } + var ethMode: Config.NetworkConfig.EthMode = .dhcp /// /// struct to keep static address - var ethConfig: Config.NetworkConfig { - get {return _storage._ethConfig ?? Config.NetworkConfig()} - set {_uniqueStorage()._ethConfig = newValue} + var ipv4Config: Config.NetworkConfig.IpV4Config { + get {return _ipv4Config ?? Config.NetworkConfig.IpV4Config()} + set {_ipv4Config = newValue} } - /// Returns true if `ethConfig` has been explicitly set. - var hasEthConfig: Bool {return _storage._ethConfig != nil} - /// Clears the value of `ethConfig`. Subsequent reads from it will return its default value. - mutating func clearEthConfig() {_uniqueStorage()._ethConfig = nil} + /// Returns true if `ipv4Config` has been explicitly set. + var hasIpv4Config: Bool {return self._ipv4Config != nil} + /// Clears the value of `ipv4Config`. Subsequent reads from it will return its default value. + mutating func clearIpv4Config() {self._ipv4Config = nil} var unknownFields = SwiftProtobuf.UnknownStorage() @@ -563,7 +545,7 @@ struct Config { } - struct TcpConfig { + struct IpV4Config { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -591,7 +573,7 @@ struct Config { init() {} - fileprivate var _storage = _StorageClass.defaultInstance + fileprivate var _ipv4Config: Config.NetworkConfig.IpV4Config? = nil } /// @@ -1179,7 +1161,7 @@ extension Config.PowerConfig: @unchecked Sendable {} extension Config.NetworkConfig: @unchecked Sendable {} extension Config.NetworkConfig.WiFiMode: @unchecked Sendable {} extension Config.NetworkConfig.EthMode: @unchecked Sendable {} -extension Config.NetworkConfig.TcpConfig: @unchecked Sendable {} +extension Config.NetworkConfig.IpV4Config: @unchecked Sendable {} extension Config.DisplayConfig: @unchecked Sendable {} extension Config.DisplayConfig.GpsCoordinateFormat: @unchecked Sendable {} extension Config.DisplayConfig.DisplayUnits: @unchecked Sendable {} @@ -1572,108 +1554,64 @@ extension Config.NetworkConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp 5: .standard(proto: "ntp_server"), 6: .standard(proto: "eth_enabled"), 7: .standard(proto: "eth_mode"), - 8: .standard(proto: "eth_config"), + 8: .standard(proto: "ipv4_config"), ] - fileprivate class _StorageClass { - var _wifiEnabled: Bool = false - var _wifiSsid: String = String() - var _wifiPsk: String = String() - var _ntpServer: String = String() - var _ethEnabled: Bool = false - var _ethMode: Config.NetworkConfig.EthMode = .dhcp - var _ethConfig: Config.NetworkConfig? = nil - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _wifiEnabled = source._wifiEnabled - _wifiSsid = source._wifiSsid - _wifiPsk = source._wifiPsk - _ntpServer = source._ntpServer - _ethEnabled = source._ethEnabled - _ethMode = source._ethMode - _ethConfig = source._ethConfig - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBoolField(value: &_storage._wifiEnabled) }() - case 3: try { try decoder.decodeSingularStringField(value: &_storage._wifiSsid) }() - case 4: try { try decoder.decodeSingularStringField(value: &_storage._wifiPsk) }() - case 5: try { try decoder.decodeSingularStringField(value: &_storage._ntpServer) }() - case 6: try { try decoder.decodeSingularBoolField(value: &_storage._ethEnabled) }() - case 7: try { try decoder.decodeSingularEnumField(value: &_storage._ethMode) }() - case 8: try { try decoder.decodeSingularMessageField(value: &_storage._ethConfig) }() - default: break - } + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self.wifiEnabled) }() + case 3: try { try decoder.decodeSingularStringField(value: &self.wifiSsid) }() + case 4: try { try decoder.decodeSingularStringField(value: &self.wifiPsk) }() + case 5: try { try decoder.decodeSingularStringField(value: &self.ntpServer) }() + case 6: try { try decoder.decodeSingularBoolField(value: &self.ethEnabled) }() + case 7: try { try decoder.decodeSingularEnumField(value: &self.ethMode) }() + case 8: try { try decoder.decodeSingularMessageField(value: &self._ipv4Config) }() + default: break } } } func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if _storage._wifiEnabled != false { - try visitor.visitSingularBoolField(value: _storage._wifiEnabled, fieldNumber: 1) - } - if !_storage._wifiSsid.isEmpty { - try visitor.visitSingularStringField(value: _storage._wifiSsid, fieldNumber: 3) - } - if !_storage._wifiPsk.isEmpty { - try visitor.visitSingularStringField(value: _storage._wifiPsk, fieldNumber: 4) - } - if !_storage._ntpServer.isEmpty { - try visitor.visitSingularStringField(value: _storage._ntpServer, fieldNumber: 5) - } - if _storage._ethEnabled != false { - try visitor.visitSingularBoolField(value: _storage._ethEnabled, fieldNumber: 6) - } - if _storage._ethMode != .dhcp { - try visitor.visitSingularEnumField(value: _storage._ethMode, fieldNumber: 7) - } - try { if let v = _storage._ethConfig { - try visitor.visitSingularMessageField(value: v, fieldNumber: 8) - } }() + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if self.wifiEnabled != false { + try visitor.visitSingularBoolField(value: self.wifiEnabled, fieldNumber: 1) } + if !self.wifiSsid.isEmpty { + try visitor.visitSingularStringField(value: self.wifiSsid, fieldNumber: 3) + } + if !self.wifiPsk.isEmpty { + try visitor.visitSingularStringField(value: self.wifiPsk, fieldNumber: 4) + } + if !self.ntpServer.isEmpty { + try visitor.visitSingularStringField(value: self.ntpServer, fieldNumber: 5) + } + if self.ethEnabled != false { + try visitor.visitSingularBoolField(value: self.ethEnabled, fieldNumber: 6) + } + if self.ethMode != .dhcp { + try visitor.visitSingularEnumField(value: self.ethMode, fieldNumber: 7) + } + try { if let v = self._ipv4Config { + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + } }() try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: Config.NetworkConfig, rhs: Config.NetworkConfig) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._wifiEnabled != rhs_storage._wifiEnabled {return false} - if _storage._wifiSsid != rhs_storage._wifiSsid {return false} - if _storage._wifiPsk != rhs_storage._wifiPsk {return false} - if _storage._ntpServer != rhs_storage._ntpServer {return false} - if _storage._ethEnabled != rhs_storage._ethEnabled {return false} - if _storage._ethMode != rhs_storage._ethMode {return false} - if _storage._ethConfig != rhs_storage._ethConfig {return false} - return true - } - if !storagesAreEqual {return false} - } + if lhs.wifiEnabled != rhs.wifiEnabled {return false} + if lhs.wifiSsid != rhs.wifiSsid {return false} + if lhs.wifiPsk != rhs.wifiPsk {return false} + if lhs.ntpServer != rhs.ntpServer {return false} + if lhs.ethEnabled != rhs.ethEnabled {return false} + if lhs.ethMode != rhs.ethMode {return false} + if lhs._ipv4Config != rhs._ipv4Config {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -1694,8 +1632,8 @@ extension Config.NetworkConfig.EthMode: SwiftProtobuf._ProtoNameProviding { ] } -extension Config.NetworkConfig.TcpConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Config.NetworkConfig.protoMessageName + ".TcpConfig" +extension Config.NetworkConfig.IpV4Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Config.NetworkConfig.protoMessageName + ".IpV4Config" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .same(proto: "ip"), 2: .same(proto: "gateway"), @@ -1734,7 +1672,7 @@ extension Config.NetworkConfig.TcpConfig: SwiftProtobuf.Message, SwiftProtobuf._ try unknownFields.traverse(visitor: &visitor) } - static func ==(lhs: Config.NetworkConfig.TcpConfig, rhs: Config.NetworkConfig.TcpConfig) -> Bool { + static func ==(lhs: Config.NetworkConfig.IpV4Config, rhs: Config.NetworkConfig.IpV4Config) -> Bool { if lhs.ip != rhs.ip {return false} if lhs.gateway != rhs.gateway {return false} if lhs.subnet != rhs.subnet {return false} diff --git a/Meshtastic/Protobufs/device_metadata.pb.swift b/Meshtastic/Protobufs/device_metadata.pb.swift index 5c6ed312..5e6698dc 100644 --- a/Meshtastic/Protobufs/device_metadata.pb.swift +++ b/Meshtastic/Protobufs/device_metadata.pb.swift @@ -35,6 +35,22 @@ struct DeviceMetadata { /// Device state version var deviceStateVersion: UInt32 = 0 + /// + /// Indicates whether the device can shutdown CPU natively or via power management chip + var canShutdown: Bool = false + + /// + /// Indicates that the device has native wifi capability + var hasWifi_p: Bool = false + + /// + /// Indicates that the device has native bluetooth capability + var hasBluetooth_p: Bool = false + + /// + /// Indicates that the device has an ethernet peripheral + var hasEthernet_p: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -51,6 +67,10 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "firmware_version"), 2: .standard(proto: "device_state_version"), + 3: .same(proto: "canShutdown"), + 4: .same(proto: "hasWifi"), + 5: .same(proto: "hasBluetooth"), + 6: .same(proto: "hasEthernet"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -61,6 +81,10 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement switch fieldNumber { case 1: try { try decoder.decodeSingularStringField(value: &self.firmwareVersion) }() case 2: try { try decoder.decodeSingularUInt32Field(value: &self.deviceStateVersion) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self.canShutdown) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.hasWifi_p) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self.hasBluetooth_p) }() + case 6: try { try decoder.decodeSingularBoolField(value: &self.hasEthernet_p) }() default: break } } @@ -73,12 +97,28 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement if self.deviceStateVersion != 0 { try visitor.visitSingularUInt32Field(value: self.deviceStateVersion, fieldNumber: 2) } + if self.canShutdown != false { + try visitor.visitSingularBoolField(value: self.canShutdown, fieldNumber: 3) + } + if self.hasWifi_p != false { + try visitor.visitSingularBoolField(value: self.hasWifi_p, fieldNumber: 4) + } + if self.hasBluetooth_p != false { + try visitor.visitSingularBoolField(value: self.hasBluetooth_p, fieldNumber: 5) + } + if self.hasEthernet_p != false { + try visitor.visitSingularBoolField(value: self.hasEthernet_p, fieldNumber: 6) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: DeviceMetadata, rhs: DeviceMetadata) -> Bool { if lhs.firmwareVersion != rhs.firmwareVersion {return false} if lhs.deviceStateVersion != rhs.deviceStateVersion {return false} + if lhs.canShutdown != rhs.canShutdown {return false} + if lhs.hasWifi_p != rhs.hasWifi_p {return false} + if lhs.hasBluetooth_p != rhs.hasBluetooth_p {return false} + if lhs.hasEthernet_p != rhs.hasEthernet_p {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 9f7efe1d..7517edbb 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -239,7 +239,7 @@ struct CannedMessagesConfig: View { if rotary1Enabled { /// Input event origin accepted by the canned messages - /// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", "faceskb" or keyword "_any" + /// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", or keyword "_any" cmc.allowInputSource = "rotEnc1" } else if updown1Enabled { @@ -322,15 +322,15 @@ struct CannedMessagesConfig: View { } else if newPreset == 2 { - // TBeam Three Button 1.3" OLED Screen - updown1Enabled = true + // CardKB / RAK Keypad + updown1Enabled = false rotary1Enabled = false - inputbrokerPinA = 25 - inputbrokerPinB = 39 - inputbrokerPinPress = 36 - inputbrokerEventCw = InputEventChars.up.rawValue - inputbrokerEventCcw = InputEventChars.down.rawValue - inputbrokerEventPress = InputEventChars.select.rawValue + inputbrokerPinA = 0 + inputbrokerPinB = 0 + inputbrokerPinPress = 0 + inputbrokerEventCw = InputEventChars.none.rawValue + inputbrokerEventCcw = InputEventChars.none.rawValue + inputbrokerEventPress = InputEventChars.none.rawValue } hasChanges = true