mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
UpdateCoreData.updateAnyPacketFrom: mirror firmware's lastHeard/snr/rssi/hopsAway update logic from NodeDB::updateFrom (#1492)
This commit is contained in:
parent
b57ba1557c
commit
c19c810749
2 changed files with 62 additions and 25 deletions
|
|
@ -493,6 +493,14 @@ class AccessoryManager: ObservableObject, MqttClientProxyManagerDelegate {
|
|||
handleMyInfo(myNodeInfo)
|
||||
|
||||
case .packet(let packet):
|
||||
// All received packets get passed through updateAnyPacketFrom to update lastHeard, rxSnr, etc. (like firmware's NodeDB::updateFrom).
|
||||
if let connectedNodeNum = self.activeDeviceNum {
|
||||
updateAnyPacketFrom(packet: packet, activeDeviceNum: connectedNodeNum, context: context)
|
||||
} else {
|
||||
Logger.mesh.error("🕸️ Unable to determine connectedNodeNum for updateAnyPacketFrom. Skipping.")
|
||||
}
|
||||
|
||||
// Dispatch based on packet contents.
|
||||
if case let .decoded(data) = packet.payloadVariant {
|
||||
switch data.portnum {
|
||||
case .textMessageApp, .detectionSensorApp, .alertApp:
|
||||
|
|
|
|||
|
|
@ -165,6 +165,60 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes
|
|||
}
|
||||
}
|
||||
|
||||
func updateAnyPacketFrom (packet: MeshPacket, activeDeviceNum: Int64, context: NSManagedObjectContext) {
|
||||
// Update NodeInfoEntity for any packet received. This mirrors the firmware's NodeDB::updateFrom, which sniffs ALL received packets and updates the radio's nodeDB with packet.from's:
|
||||
// - last_heard (from rxTime)
|
||||
// - snr
|
||||
// - via_mqtt
|
||||
// - hops_away
|
||||
|
||||
// However, unlike the firmware, this function will NOT create a new NodeInfoEntity if we don't have it already. We'll leave that to the existing code paths.
|
||||
|
||||
// We do NOT update fetchedNode[0].channel, because we may hear a node over multiple channels, and only some packet types should update what we consider the node's channel to be. (Example: primary private channel, secondary public channel. A text message on the secondary public channel should NOT change fetchedNode[0].channel.)
|
||||
|
||||
guard packet.from > 0 else { return }
|
||||
guard packet.from != activeDeviceNum else { return } // Ignore if packet is from our own node
|
||||
|
||||
let fetchNodeInfoAppRequest = NodeInfoEntity.fetchRequest()
|
||||
fetchNodeInfoAppRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
|
||||
|
||||
do {
|
||||
let fetchedNode = try context.fetch(fetchNodeInfoAppRequest)
|
||||
if fetchedNode.count >= 1 {
|
||||
fetchedNode[0].id = Int64(packet.from)
|
||||
fetchedNode[0].num = Int64(packet.from)
|
||||
|
||||
if packet.rxTime > 0 {
|
||||
fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
|
||||
Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(packet.from.toHex(), privacy: .public) lastHeard from rxTime=\(packet.rxTime)")
|
||||
} else {
|
||||
fetchedNode[0].lastHeard = Date()
|
||||
Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(packet.from.toHex(), privacy: .public) lastHeard to now (rxTime==0)")
|
||||
}
|
||||
|
||||
fetchedNode[0].snr = packet.rxSnr
|
||||
fetchedNode[0].rssi = packet.rxRssi
|
||||
fetchedNode[0].viaMqtt = packet.viaMqtt
|
||||
|
||||
if packet.hopStart != 0 && packet.hopLimit <= packet.hopStart {
|
||||
fetchedNode[0].hopsAway = Int32(packet.hopStart - packet.hopLimit)
|
||||
Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(packet.from.toHex(), privacy: .public) hopsAway=\(fetchedNode[0].hopsAway)")
|
||||
}
|
||||
|
||||
do {
|
||||
try context.save()
|
||||
Logger.data.info("💾 [updateAnyPacketFrom] Updating node \(fetchedNode[0].num.toHex(), privacy: .public) snr=\(fetchedNode[0].snr), rssi=\(fetchedNode[0].rssi) from packet \(packet.id.toHex(), privacy: .public)")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
Logger.data.error("💥 [updateAnyPacketFrom] Error Saving node \(fetchedNode[0].num.toHex(), privacy: .public) from packet \(packet.id.toHex(), privacy: .public) \(nsError, privacy: .public)")
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Logger.data.error("💥 [updateAnyPacketFrom] fetch data error")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertNodeInfoPacket (packet: MeshPacket, favorite: Bool = false, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("[NodeInfo] received for: %@".localized, packet.from.toHex())
|
||||
|
|
@ -316,16 +370,6 @@ func upsertNodeInfoPacket (packet: MeshPacket, favorite: Bool = false, context:
|
|||
|
||||
} else {
|
||||
// Update an existing node
|
||||
fetchedNode[0].id = Int64(packet.from)
|
||||
fetchedNode[0].num = Int64(packet.from)
|
||||
if packet.rxTime > 0 {
|
||||
fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
|
||||
} else {
|
||||
fetchedNode[0].lastHeard = Date()
|
||||
}
|
||||
fetchedNode[0].snr = packet.rxSnr
|
||||
fetchedNode[0].rssi = packet.rxRssi
|
||||
fetchedNode[0].viaMqtt = packet.viaMqtt
|
||||
if packet.to == Constants.maximumNodeNum || packet.to == UserDefaults.preferredPeripheralNum {
|
||||
fetchedNode[0].channel = Int32(packet.channel)
|
||||
}
|
||||
|
|
@ -463,22 +507,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
mutablePositions.removeAllObjects()
|
||||
}
|
||||
mutablePositions.add(position)
|
||||
fetchedNode[0].id = Int64(packet.from)
|
||||
fetchedNode[0].num = Int64(packet.from)
|
||||
|
||||
// Update the node's lastHeard.
|
||||
// Some misconfigured nodes will broadcast position packets that claim GPS timestamps in the future. When updating lastHeard, don't use any future timestamps: fallback to using rxTime or Date() instead.
|
||||
if positionMessage.time > 0 && (Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time))) <= Date()) {
|
||||
fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time)))
|
||||
} else if packet.rxTime > 0 {
|
||||
fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
|
||||
} else {
|
||||
fetchedNode[0].lastHeard = Date()
|
||||
}
|
||||
|
||||
fetchedNode[0].snr = packet.rxSnr
|
||||
fetchedNode[0].rssi = packet.rxRssi
|
||||
fetchedNode[0].viaMqtt = packet.viaMqtt
|
||||
fetchedNode[0].channel = Int32(packet.channel)
|
||||
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue