Merge pull request #136 from meshtastic/1_3_30_upgrades

1 3 30 upgrades
This commit is contained in:
Garth Vander Houwen 2022-08-04 20:25:52 -07:00 committed by GitHub
commit f01cf6c8e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 113 additions and 62 deletions

View file

@ -1214,6 +1214,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
dataMessage.wantResponse = wantResponse
meshPacket.decoded = dataMessage

View file

@ -243,10 +243,16 @@ func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectCont
let nsError = error as NSError
print("💥 Error Updating Core Data LoRaConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in core data matching connected node number \(nodeNum)")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data LoRaConfigEntity failed: \(nsError)")
}
}
@ -1312,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<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MessageEntity")
fetchMessageRequest.predicate = NSPredicate(format: "messageId == %lld", Int64(packet.decoded.requestID))
let fetchMessageRequest: NSFetchRequest<NSFetchRequestResult> = 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)")
}
}
}
@ -1422,7 +1430,7 @@ func textMessageAppPacket(packet: MeshPacket, connectedNode: Int64, meshLogging:
if let messageText = String(bytes: packet.decoded.payload, encoding: .utf8) {
if meshLogging { MeshLogger.log("💬 Message received for text message app \(messageText)") }
if meshLogging { MeshLogger.log("💬 Message received for text message app") }
let messageUsers: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserEntity")
messageUsers.predicate = NSPredicate(format: "num IN %@", [packet.to, packet.from])
@ -1496,7 +1504,7 @@ func textMessageAppPacket(packet: MeshPacket, connectedNode: Int64, meshLogging:
]
manager.schedule()
if meshLogging { MeshLogger.log("💬 iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown") \(messageText)") }
if meshLogging { MeshLogger.log("💬 iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown")") }
}
} catch {

View file

@ -47,6 +47,7 @@
<relationship name="loRaConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="loRaConfig" inverseEntity="NodeInfoEntity"/>
</entity>
<entity name="MessageEntity" representedClassName="MessageEntity" syncable="YES" codeGenerationType="class">
<attribute name="ackError" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="ackSNR" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="ackTimestamp" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="admin" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
@ -194,6 +195,7 @@
<entity name="WiFiConfigEntity" representedClassName="WiFiConfigEntity" syncable="YES" codeGenerationType="class">
<attribute name="apHidden" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="apMode" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="password" optional="YES" attributeType="String" minValueString="0" maxValueString="60"/>
<attribute name="ssid" optional="YES" attributeType="String" minValueString="0" maxValueString="30"/>
@ -205,7 +207,7 @@
<element name="DisplayConfigEntity" positionX="54" positionY="153" width="128" height="104"/>
<element name="ExternalNotificationConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
<element name="LoRaConfigEntity" positionX="45" positionY="144" width="128" height="119"/>
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="230"/>
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="245"/>
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="209"/>
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="314"/>
<element name="PositionConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
@ -215,6 +217,6 @@
<element name="TelemetryConfigEntity" positionX="72" positionY="171" width="128" height="134"/>
<element name="TelemetryEntity" positionX="160" positionY="192" width="128" height="209"/>
<element name="UserEntity" positionX="0" positionY="144" width="128" height="230"/>
<element name="WiFiConfigEntity" positionX="45" positionY="144" width="128" height="119"/>
<element name="WiFiConfigEntity" positionX="45" positionY="144" width="128" height="134"/>
</elements>
</model>

View file

@ -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<D: SwiftProtobuf.Decoder>(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
}

View file

@ -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"),
]
}

View file

@ -22,7 +22,7 @@ struct Connect: View {
@State var isPreferredRadio: Bool = false
@State var firmwareVersion = "0.0.0"
@State var minimumVersion = "1.3.28"
@State var minimumVersion = "1.3.30"
@State var invalidVersion = false

View file

@ -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 {

View file

@ -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<NodeInfoEntity>
@ -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"
// }
// }
}
}
}

View file

@ -177,7 +177,7 @@ struct TelemetryLog: View {
Spacer()
Text("Device Metrics")
.font(.title)
.font(.title3)
Spacer()
}
@ -234,7 +234,6 @@ struct TelemetryLog: View {
} else if tel.metricsType == 1 {
// Environment Metrics
let tempReadingType = (!(node.telemetryConfig?.environmentDisplayFahrenheit ?? true)) ? "°C" : "°F"

View file

@ -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 {

View file

@ -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)

View file

@ -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,21 @@ 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)
.padding()
Form {
Section(header: Text("SSID & Password")) {
Text("Enabling WiFi will disable the bluetooth connection to the app.")
.font(.title3)
Section(header: Text("Options")) {
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
@ -87,24 +94,25 @@ struct WiFiConfig: View {
.disableAutocorrection(true)
}
Section(header: Text("AP Settings")) {
Section(header: Text("Sofware Access Point")) {
Text("WiFi uses client mode by default, if Software Access Point(AP) is on the SSID and password will be used to access the AP at meshtastic.local.")
.font(.caption)
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 SSID", systemImage: "eye.slash")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Text("If set the SSID for the AP will be hidden.")
.font(.caption)
}
}
.disabled(!(node != nil && node!.myInfo?.hasWifi ?? false))
@ -130,6 +138,7 @@ struct WiFiConfig: View {
Button("Save WiFI Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
var wifi = Config.WiFiConfig()
wifi.enabled = self.enabled
wifi.ssid = self.ssid
wifi.psk = self.password
wifi.apMode = self.apMode
@ -162,6 +171,7 @@ struct WiFiConfig: View {
self.bleManager.context = context
self.enabled = (node!.wiFiConfig?.enabled ?? false)
self.ssid = node!.wiFiConfig?.ssid ?? ""
self.password = node!.wiFiConfig?.password ?? ""
self.apMode = (node!.wiFiConfig?.apMode ?? false)
@ -171,6 +181,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 {