mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Assorted updates
This commit is contained in:
parent
0108080c87
commit
921f95cc63
11 changed files with 227 additions and 45 deletions
|
|
@ -22,6 +22,8 @@ enum RegionCodes : Int, CaseIterable, Identifiable {
|
|||
case `in` = 10
|
||||
case nz865 = 11
|
||||
case th = 12
|
||||
case ua433 = 14
|
||||
case ua868 = 15
|
||||
case lora24 = 13
|
||||
|
||||
var id: Int { self.rawValue }
|
||||
|
|
@ -54,6 +56,10 @@ enum RegionCodes : Int, CaseIterable, Identifiable {
|
|||
return "New Zealand 865mhz"
|
||||
case .th:
|
||||
return "Thailand"
|
||||
case .ua433:
|
||||
return "Ukraine 433mhz"
|
||||
case .ua868:
|
||||
return "Ukraine 868mhz"
|
||||
case .lora24:
|
||||
return "2.4 GHZ"
|
||||
}
|
||||
|
|
@ -90,6 +96,10 @@ enum RegionCodes : Int, CaseIterable, Identifiable {
|
|||
return Config.LoRaConfig.RegionCode.nz865
|
||||
case .th:
|
||||
return Config.LoRaConfig.RegionCode.th
|
||||
case .ua433:
|
||||
return Config.LoRaConfig.RegionCode.ua433
|
||||
case .ua868:
|
||||
return Config.LoRaConfig.RegionCode.ua868
|
||||
case .lora24:
|
||||
return Config.LoRaConfig.RegionCode.lora24
|
||||
}
|
||||
|
|
@ -100,6 +110,7 @@ enum ModemPresets : Int, CaseIterable, Identifiable {
|
|||
|
||||
case LongFast = 0
|
||||
case LongSlow = 1
|
||||
case LongModerate = 7
|
||||
case VLongSlow = 2
|
||||
case MedSlow = 3
|
||||
case MedFast = 4
|
||||
|
|
@ -115,6 +126,8 @@ enum ModemPresets : Int, CaseIterable, Identifiable {
|
|||
return "Long Range - Fast"
|
||||
case .LongSlow:
|
||||
return "Long Range - Slow"
|
||||
case .LongModerate:
|
||||
return "Long Range - Moderate"
|
||||
case .VLongSlow:
|
||||
return "Very Long Range - Slow"
|
||||
case .MedSlow:
|
||||
|
|
@ -136,10 +149,12 @@ enum ModemPresets : Int, CaseIterable, Identifiable {
|
|||
return Config.LoRaConfig.ModemPreset.longFast
|
||||
case .LongSlow:
|
||||
return Config.LoRaConfig.ModemPreset.longSlow
|
||||
case .LongModerate:
|
||||
return Config.LoRaConfig.ModemPreset.longModerate
|
||||
case .VLongSlow:
|
||||
return Config.LoRaConfig.ModemPreset.veryLongSlow
|
||||
return Config.LoRaConfig.ModemPreset.veryLongSlow
|
||||
case .MedSlow:
|
||||
return Config.LoRaConfig.ModemPreset.mediumSlow
|
||||
return Config.LoRaConfig.ModemPreset.mediumSlow
|
||||
case .MedFast:
|
||||
return Config.LoRaConfig.ModemPreset.mediumFast
|
||||
case .ShortSlow:
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func localConfig (config: Config, context:NSManagedObjectContext, nodeNum: Int64
|
|||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.display(config.display) {
|
||||
upsertDisplayConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) {
|
||||
upsertLoRaConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
upsertLoRaConfigPacket(config: config.lora, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.network(config.network) {
|
||||
upsertNetworkConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.position(config.position) {
|
||||
|
|
@ -759,8 +759,6 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
|
||||
if let adminMessage = try? AdminMessage(serializedData: packet.decoded.payload) {
|
||||
|
||||
|
||||
|
||||
if adminMessage.payloadVariant == AdminMessage.OneOf_PayloadVariant.getCannedMessageModuleMessagesResponse(adminMessage.getCannedMessageModuleMessagesResponse) {
|
||||
|
||||
if let cmmc = try? CannedMessageModuleConfig(serializedData: packet.decoded.payload) {
|
||||
|
|
@ -811,7 +809,9 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
upsertDeviceConfigPacket(config: config, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) {
|
||||
upsertLoRaConfigPacket(config: config, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
let lc = try? Config.LoRaConfig(serializedData: packet.decoded.payload)
|
||||
upsertLoRaConfigPacket(config: lc!, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.network(config.network) {
|
||||
upsertNetworkConfigPacket(config: config, nodeNum: Int64(packet.from), context: context)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,38 @@
|
|||
|
||||
import CoreData
|
||||
|
||||
public func getNodeInfo(id: Int64, context: NSManagedObjectContext) -> NodeInfoEntity {
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
|
||||
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
|
||||
|
||||
do {
|
||||
let fetchNodeInfo = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
|
||||
if fetchNodeInfo.count == 1 {
|
||||
return fetchNodeInfo[0]
|
||||
}
|
||||
} catch {
|
||||
return NodeInfoEntity(context: context)
|
||||
}
|
||||
return NodeInfoEntity(context: context)
|
||||
}
|
||||
|
||||
public func getUser(id: Int64, context: NSManagedObjectContext) -> UserEntity {
|
||||
|
||||
let fetchUserRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserEntity")
|
||||
fetchUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
|
||||
|
||||
do {
|
||||
let fetchedUser = try context.fetch(fetchUserRequest) as! [UserEntity]
|
||||
if fetchedUser.count == 1 {
|
||||
return fetchedUser[0]
|
||||
}
|
||||
} catch {
|
||||
return UserEntity(context: context)
|
||||
}
|
||||
return UserEntity(context: context)
|
||||
}
|
||||
|
||||
public func getWaypoint(id: Int64, context: NSManagedObjectContext) -> WaypointEntity {
|
||||
|
||||
let fetchWaypointRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "WaypointEntity")
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ func upsertDisplayConfigPacket(config: Config, nodeNum: Int64, context: NSManage
|
|||
}
|
||||
}
|
||||
|
||||
func upsertLoRaConfigPacket(config: Config, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertLoRaConfigPacket(config: Meshtastic.Config.LoRaConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.lora.config %@", comment: "LoRa config received: %@"), String(nodeNum))
|
||||
MeshLogger.log("📻 \(logString)")
|
||||
|
|
@ -320,33 +320,34 @@ func upsertLoRaConfigPacket(config: Config, nodeNum: Int64, context: NSManagedOb
|
|||
if fetchedNode[0].loRaConfig == nil {
|
||||
// No lora config for node, save a new lora config
|
||||
let newLoRaConfig = LoRaConfigEntity(context: context)
|
||||
newLoRaConfig.regionCode = Int32(config.lora.region.rawValue)
|
||||
newLoRaConfig.usePreset = config.lora.usePreset
|
||||
newLoRaConfig.modemPreset = Int32(config.lora.modemPreset.rawValue)
|
||||
newLoRaConfig.bandwidth = Int32(config.lora.bandwidth)
|
||||
newLoRaConfig.spreadFactor = Int32(config.lora.spreadFactor)
|
||||
newLoRaConfig.codingRate = Int32(config.lora.codingRate)
|
||||
newLoRaConfig.frequencyOffset = config.lora.frequencyOffset
|
||||
newLoRaConfig.hopLimit = Int32(config.lora.hopLimit)
|
||||
newLoRaConfig.txPower = Int32(config.lora.txPower)
|
||||
newLoRaConfig.txEnabled = config.lora.txEnabled
|
||||
newLoRaConfig.channelNum = Int32(config.lora.channelNum)
|
||||
newLoRaConfig.regionCode = Int32(config.region.rawValue)
|
||||
newLoRaConfig.usePreset = config.usePreset
|
||||
newLoRaConfig.modemPreset = Int32(config.modemPreset.rawValue)
|
||||
newLoRaConfig.bandwidth = Int32(config.bandwidth)
|
||||
newLoRaConfig.spreadFactor = Int32(config.spreadFactor)
|
||||
newLoRaConfig.codingRate = Int32(config.codingRate)
|
||||
newLoRaConfig.frequencyOffset = config.frequencyOffset
|
||||
newLoRaConfig.hopLimit = Int32(config.hopLimit)
|
||||
newLoRaConfig.txPower = Int32(config.txPower)
|
||||
newLoRaConfig.txEnabled = config.txEnabled
|
||||
newLoRaConfig.channelNum = Int32(config.channelNum)
|
||||
fetchedNode[0].loRaConfig = newLoRaConfig
|
||||
} else {
|
||||
fetchedNode[0].loRaConfig?.regionCode = Int32(config.lora.region.rawValue)
|
||||
fetchedNode[0].loRaConfig?.usePreset = config.lora.usePreset
|
||||
fetchedNode[0].loRaConfig?.modemPreset = Int32(config.lora.modemPreset.rawValue)
|
||||
fetchedNode[0].loRaConfig?.bandwidth = Int32(config.lora.bandwidth)
|
||||
fetchedNode[0].loRaConfig?.spreadFactor = Int32(config.lora.spreadFactor)
|
||||
fetchedNode[0].loRaConfig?.codingRate = Int32(config.lora.codingRate)
|
||||
fetchedNode[0].loRaConfig?.frequencyOffset = config.lora.frequencyOffset
|
||||
fetchedNode[0].loRaConfig?.hopLimit = Int32(config.lora.hopLimit)
|
||||
fetchedNode[0].loRaConfig?.txPower = Int32(config.lora.txPower)
|
||||
fetchedNode[0].loRaConfig?.txEnabled = config.lora.txEnabled
|
||||
fetchedNode[0].loRaConfig?.channelNum = Int32(config.lora.channelNum)
|
||||
fetchedNode[0].loRaConfig?.regionCode = Int32(config.region.rawValue)
|
||||
fetchedNode[0].loRaConfig?.usePreset = config.usePreset
|
||||
fetchedNode[0].loRaConfig?.modemPreset = Int32(config.modemPreset.rawValue)
|
||||
fetchedNode[0].loRaConfig?.bandwidth = Int32(config.bandwidth)
|
||||
fetchedNode[0].loRaConfig?.spreadFactor = Int32(config.spreadFactor)
|
||||
fetchedNode[0].loRaConfig?.codingRate = Int32(config.codingRate)
|
||||
fetchedNode[0].loRaConfig?.frequencyOffset = config.frequencyOffset
|
||||
fetchedNode[0].loRaConfig?.hopLimit = Int32(config.hopLimit)
|
||||
fetchedNode[0].loRaConfig?.txPower = Int32(config.txPower)
|
||||
fetchedNode[0].loRaConfig?.txEnabled = config.txEnabled
|
||||
fetchedNode[0].loRaConfig?.channelNum = Int32(config.channelNum)
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
context.refresh(fetchedNode[0], mergeChanges: true)
|
||||
print("💾 Updated LoRa Config for node number: \(String(nodeNum))")
|
||||
} catch {
|
||||
context.rollback()
|
||||
|
|
|
|||
|
|
@ -168,6 +168,10 @@ struct Config {
|
|||
/// Defaults to PIN_BUZZER if defined.
|
||||
var buzzerGpio: UInt32 = 0
|
||||
|
||||
///
|
||||
/// Sets the role of node
|
||||
var rebroadcastMode: Config.DeviceConfig.RebroadcastMode = .all
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
///
|
||||
|
|
@ -198,13 +202,13 @@ struct Config {
|
|||
|
||||
///
|
||||
/// Repeater device role
|
||||
/// Mesh packets will simply be rebroadcasted over this node. Nodes under this role node will not originate NodeInfo, Position, Telemetry
|
||||
/// or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factory, and coding rate.
|
||||
/// Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry
|
||||
/// or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate.
|
||||
case repeater // = 4
|
||||
|
||||
///
|
||||
/// Tracker device role
|
||||
/// Position Mesh packets for will be higher priority and sent more frequently by default.
|
||||
/// Position Mesh packets will be prioritized higher and sent more frequently by default.
|
||||
case tracker // = 5
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
|
|
@ -238,6 +242,51 @@ struct Config {
|
|||
|
||||
}
|
||||
|
||||
///
|
||||
/// Defines the device's behavior for how messages are rebroadcast
|
||||
enum RebroadcastMode: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// Default behavior.
|
||||
/// Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params.
|
||||
case all // = 0
|
||||
|
||||
///
|
||||
/// Same as behavior as ALL but skips packet decoding and simply rebroadcasts them.
|
||||
/// Only available in Repeater role. Setting this on any other roles will result in ALL behavior.
|
||||
case allSkipDecoding // = 1
|
||||
|
||||
///
|
||||
/// Ignores observed messages from foreign meshes that are open or those which it cannot decrypt.
|
||||
/// Only rebroadcasts message on the nodes local primary / secondary channels.
|
||||
case localOnly // = 2
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
self = .all
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .all
|
||||
case 1: self = .allSkipDecoding
|
||||
case 2: self = .localOnly
|
||||
default: self = .UNRECOGNIZED(rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .all: return 0
|
||||
case .allSkipDecoding: return 1
|
||||
case .localOnly: return 2
|
||||
case .UNRECOGNIZED(let i): return i
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
|
|
@ -905,6 +954,14 @@ struct Config {
|
|||
/// If true, sets RX boosted gain mode on SX126X based radios
|
||||
var sx126XRxBoostedGain: Bool = false
|
||||
|
||||
///
|
||||
/// This parameter is for advanced users and licensed HAM radio operators.
|
||||
/// Ignore Channel Calculation and use this frequency instead. The frequency_offset
|
||||
/// will still be applied. This will allow you to use out-of-band frequencies.
|
||||
/// Please respect your local laws and regulations. If you are a HAM, make sure you
|
||||
/// enable HAM mode and turn off encryption.
|
||||
var overrideFrequency: Float = 0
|
||||
|
||||
///
|
||||
/// For testing it is useful sometimes to force a node to never listen to
|
||||
/// particular other nodes (simulating radio out of range). All nodenums listed
|
||||
|
|
@ -1186,6 +1243,15 @@ extension Config.DeviceConfig.Role: CaseIterable {
|
|||
]
|
||||
}
|
||||
|
||||
extension Config.DeviceConfig.RebroadcastMode: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static var allCases: [Config.DeviceConfig.RebroadcastMode] = [
|
||||
.all,
|
||||
.allSkipDecoding,
|
||||
.localOnly,
|
||||
]
|
||||
}
|
||||
|
||||
extension Config.PositionConfig.PositionFlags: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static var allCases: [Config.PositionConfig.PositionFlags] = [
|
||||
|
|
@ -1303,6 +1369,7 @@ extension Config: @unchecked Sendable {}
|
|||
extension Config.OneOf_PayloadVariant: @unchecked Sendable {}
|
||||
extension Config.DeviceConfig: @unchecked Sendable {}
|
||||
extension Config.DeviceConfig.Role: @unchecked Sendable {}
|
||||
extension Config.DeviceConfig.RebroadcastMode: @unchecked Sendable {}
|
||||
extension Config.PositionConfig: @unchecked Sendable {}
|
||||
extension Config.PositionConfig.PositionFlags: @unchecked Sendable {}
|
||||
extension Config.PowerConfig: @unchecked Sendable {}
|
||||
|
|
@ -1491,6 +1558,7 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
3: .standard(proto: "debug_log_enabled"),
|
||||
4: .standard(proto: "button_gpio"),
|
||||
5: .standard(proto: "buzzer_gpio"),
|
||||
6: .standard(proto: "rebroadcast_mode"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
|
|
@ -1504,6 +1572,7 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
case 3: try { try decoder.decodeSingularBoolField(value: &self.debugLogEnabled) }()
|
||||
case 4: try { try decoder.decodeSingularUInt32Field(value: &self.buttonGpio) }()
|
||||
case 5: try { try decoder.decodeSingularUInt32Field(value: &self.buzzerGpio) }()
|
||||
case 6: try { try decoder.decodeSingularEnumField(value: &self.rebroadcastMode) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
|
@ -1525,6 +1594,9 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
if self.buzzerGpio != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.buzzerGpio, fieldNumber: 5)
|
||||
}
|
||||
if self.rebroadcastMode != .all {
|
||||
try visitor.visitSingularEnumField(value: self.rebroadcastMode, fieldNumber: 6)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
|
|
@ -1534,6 +1606,7 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
if lhs.debugLogEnabled != rhs.debugLogEnabled {return false}
|
||||
if lhs.buttonGpio != rhs.buttonGpio {return false}
|
||||
if lhs.buzzerGpio != rhs.buzzerGpio {return false}
|
||||
if lhs.rebroadcastMode != rhs.rebroadcastMode {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
@ -1550,6 +1623,14 @@ extension Config.DeviceConfig.Role: SwiftProtobuf._ProtoNameProviding {
|
|||
]
|
||||
}
|
||||
|
||||
extension Config.DeviceConfig.RebroadcastMode: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "ALL"),
|
||||
1: .same(proto: "ALL_SKIP_DECODING"),
|
||||
2: .same(proto: "LOCAL_ONLY"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Config.PositionConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = Config.protoMessageName + ".PositionConfig"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
|
|
@ -1987,6 +2068,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
11: .standard(proto: "channel_num"),
|
||||
12: .standard(proto: "override_duty_cycle"),
|
||||
13: .standard(proto: "sx126x_rx_boosted_gain"),
|
||||
14: .standard(proto: "override_frequency"),
|
||||
103: .standard(proto: "ignore_incoming"),
|
||||
]
|
||||
|
||||
|
|
@ -2009,6 +2091,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
case 11: try { try decoder.decodeSingularUInt32Field(value: &self.channelNum) }()
|
||||
case 12: try { try decoder.decodeSingularBoolField(value: &self.overrideDutyCycle) }()
|
||||
case 13: try { try decoder.decodeSingularBoolField(value: &self.sx126XRxBoostedGain) }()
|
||||
case 14: try { try decoder.decodeSingularFloatField(value: &self.overrideFrequency) }()
|
||||
case 103: try { try decoder.decodeRepeatedUInt32Field(value: &self.ignoreIncoming) }()
|
||||
default: break
|
||||
}
|
||||
|
|
@ -2055,6 +2138,9 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
if self.sx126XRxBoostedGain != false {
|
||||
try visitor.visitSingularBoolField(value: self.sx126XRxBoostedGain, fieldNumber: 13)
|
||||
}
|
||||
if self.overrideFrequency != 0 {
|
||||
try visitor.visitSingularFloatField(value: self.overrideFrequency, fieldNumber: 14)
|
||||
}
|
||||
if !self.ignoreIncoming.isEmpty {
|
||||
try visitor.visitPackedUInt32Field(value: self.ignoreIncoming, fieldNumber: 103)
|
||||
}
|
||||
|
|
@ -2075,6 +2161,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
if lhs.channelNum != rhs.channelNum {return false}
|
||||
if lhs.overrideDutyCycle != rhs.overrideDutyCycle {return false}
|
||||
if lhs.sx126XRxBoostedGain != rhs.sx126XRxBoostedGain {return false}
|
||||
if lhs.overrideFrequency != rhs.overrideFrequency {return false}
|
||||
if lhs.ignoreIncoming != rhs.ignoreIncoming {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -220,9 +220,34 @@ struct OEMStore {
|
|||
/// The default device encryption key, 16 or 32 byte
|
||||
var oemAesKey: Data = Data()
|
||||
|
||||
///
|
||||
/// A Preset LocalConfig to apply during factory reset
|
||||
var oemLocalConfig: LocalConfig {
|
||||
get {return _oemLocalConfig ?? LocalConfig()}
|
||||
set {_oemLocalConfig = newValue}
|
||||
}
|
||||
/// Returns true if `oemLocalConfig` has been explicitly set.
|
||||
var hasOemLocalConfig: Bool {return self._oemLocalConfig != nil}
|
||||
/// Clears the value of `oemLocalConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearOemLocalConfig() {self._oemLocalConfig = nil}
|
||||
|
||||
///
|
||||
/// A Preset LocalModuleConfig to apply during factory reset
|
||||
var oemLocalModuleConfig: LocalModuleConfig {
|
||||
get {return _oemLocalModuleConfig ?? LocalModuleConfig()}
|
||||
set {_oemLocalModuleConfig = newValue}
|
||||
}
|
||||
/// Returns true if `oemLocalModuleConfig` has been explicitly set.
|
||||
var hasOemLocalModuleConfig: Bool {return self._oemLocalModuleConfig != nil}
|
||||
/// Clears the value of `oemLocalModuleConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearOemLocalModuleConfig() {self._oemLocalModuleConfig = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _oemLocalConfig: LocalConfig? = nil
|
||||
fileprivate var _oemLocalModuleConfig: LocalModuleConfig? = nil
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
|
|
@ -413,6 +438,8 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
4: .standard(proto: "oem_font"),
|
||||
5: .standard(proto: "oem_text"),
|
||||
6: .standard(proto: "oem_aes_key"),
|
||||
7: .standard(proto: "oem_local_config"),
|
||||
8: .standard(proto: "oem_local_module_config"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
|
|
@ -427,12 +454,18 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
case 4: try { try decoder.decodeSingularEnumField(value: &self.oemFont) }()
|
||||
case 5: try { try decoder.decodeSingularStringField(value: &self.oemText) }()
|
||||
case 6: try { try decoder.decodeSingularBytesField(value: &self.oemAesKey) }()
|
||||
case 7: try { try decoder.decodeSingularMessageField(value: &self._oemLocalConfig) }()
|
||||
case 8: try { try decoder.decodeSingularMessageField(value: &self._oemLocalModuleConfig) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// 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.oemIconWidth != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.oemIconWidth, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -451,6 +484,12 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
if !self.oemAesKey.isEmpty {
|
||||
try visitor.visitSingularBytesField(value: self.oemAesKey, fieldNumber: 6)
|
||||
}
|
||||
try { if let v = self._oemLocalConfig {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 7)
|
||||
} }()
|
||||
try { if let v = self._oemLocalModuleConfig {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
|
|
@ -461,6 +500,8 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
if lhs.oemFont != rhs.oemFont {return false}
|
||||
if lhs.oemText != rhs.oemText {return false}
|
||||
if lhs.oemAesKey != rhs.oemAesKey {return false}
|
||||
if lhs._oemLocalConfig != rhs._oemLocalConfig {return false}
|
||||
if lhs._oemLocalModuleConfig != rhs._oemLocalModuleConfig {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ struct Connect: View {
|
|||
if isUnsetRegion {
|
||||
HStack {
|
||||
NavigationLink {
|
||||
LoRaConfig(node: node, connectedNode: node)
|
||||
LoRaConfig(node: node)
|
||||
} label: {
|
||||
Label("set.region", systemImage: "globe.americas.fill")
|
||||
.foregroundColor(.red)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ struct NodeMap: View {
|
|||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@EnvironmentObject var userSettings: UserSettings
|
||||
@AppStorage("meshMapType") var type: String = "hybrid"
|
||||
|
||||
@AppStorage("meshMapCustomTileServer") var customTileServer: String = "" {
|
||||
didSet {
|
||||
if customTileServer == "" {
|
||||
|
|
@ -39,7 +39,7 @@ struct NodeMap: View {
|
|||
), animation: .easeIn)
|
||||
private var waypoints: FetchedResults<WaypointEntity>
|
||||
|
||||
@State private var mapType: MKMapType = .standard
|
||||
@State private var mapType: MKMapType?
|
||||
@State var waypointCoordinate: CLLocationCoordinate2D = LocationHelper.DefaultLocation
|
||||
@State var editingWaypoint: Int = 0
|
||||
@State private var presentingWaypointForm = false
|
||||
|
|
@ -68,7 +68,9 @@ struct NodeMap: View {
|
|||
editingWaypoint = wpId
|
||||
presentingWaypointForm = true
|
||||
}
|
||||
}, positions: Array(positions), waypoints: Array(waypoints), mapViewType: mapType,
|
||||
}, positions: Array(positions),
|
||||
waypoints: Array(waypoints),
|
||||
mapViewType: mapType ?? MKMapType.standard,
|
||||
centerOnPositionsOnly: false,
|
||||
customMapOverlay: self.customMapOverlay,
|
||||
overlays: self.overlays
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ struct LoRaConfig: View {
|
|||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
var connectedNode: NodeInfoEntity?
|
||||
|
||||
@State var isPresentingSaveConfirm = false
|
||||
@State var hasChanges = false
|
||||
|
|
@ -81,13 +80,14 @@ struct LoRaConfig: View {
|
|||
let nodeName = node?.user?.longName ?? NSLocalizedString("unknown", comment: "Unknown")
|
||||
let buttonText = String.localizedStringWithFormat(NSLocalizedString("save.config %@", comment: "Save Config for %@"), nodeName)
|
||||
Button(buttonText) {
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
var lc = Config.LoRaConfig()
|
||||
lc.hopLimit = UInt32(hopLimit)
|
||||
lc.region = RegionCodes(rawValue: region)!.protoEnumValue()
|
||||
lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue()
|
||||
lc.usePreset = true
|
||||
lc.txEnabled = true
|
||||
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
// for now just disable the button after a successful save
|
||||
|
|
@ -116,9 +116,12 @@ struct LoRaConfig: View {
|
|||
self.hasChanges = false
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if connectedNode != nil && node?.loRaConfig == nil {
|
||||
if bleManager.connectedPeripheral != nil && node?.loRaConfig == nil {
|
||||
print("empty lora config")
|
||||
_ = bleManager.requestLoRaConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: region) { newRegion in
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ struct Settings: View {
|
|||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink {
|
||||
UserConfig(node: nodes.first(where: { $0.num == selectedNode }), connectedNode: nodes.first(where: { $0.num == connectedNodeNum }))
|
||||
UserConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
|
||||
Image(systemName: "person.crop.rectangle.fill")
|
||||
|
|
@ -116,14 +116,13 @@ struct Settings: View {
|
|||
.tag(SettingsSidebar.userConfig)
|
||||
|
||||
NavigationLink() {
|
||||
LoRaConfig(node: nodes.first(where: { $0.num == selectedNode }), connectedNode: nodes.first(where: { $0.num == connectedNodeNum }))
|
||||
LoRaConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
Image(systemName: "dot.radiowaves.left.and.right")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("lora")
|
||||
}
|
||||
.tag(SettingsSidebar.loraConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink() {
|
||||
Channels(node: nodes.first(where: { $0.num == connectedNodeNum }))
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ struct UserConfig: View {
|
|||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
var connectedNode: NodeInfoEntity?
|
||||
|
||||
@State private var isPresentingFactoryResetConfirm: Bool = false
|
||||
@State private var isPresentingSaveConfirm: Bool = false
|
||||
|
|
@ -86,10 +85,13 @@ struct UserConfig: View {
|
|||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Save User Config to \(node?.user?.longName ?? "Unknown")?") {
|
||||
|
||||
let connectedUser = getUser(id: bleManager.connectedPeripheral.num, context: context)
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
var u = User()
|
||||
u.shortName = shortName
|
||||
u.longName = longName
|
||||
let adminMessageId = bleManager.saveUser(config: u, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
let adminMessageId = bleManager.saveUser(config: u, fromUser: connectedUser, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
hasChanges = false
|
||||
goBack()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue