diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 6ac0a6d6..f8bf2053 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1575,7 +1575,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.7; + MARKETING_VERSION = 2.2.8; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1608,7 +1608,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.7; + MARKETING_VERSION = 2.2.8; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index de3c8ad0..351c899e 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -2070,6 +2070,72 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return false } + func storeAndForwardPacket(packet: MeshPacket, connectedNodeNum: Int64, context: NSManagedObjectContext) { + if let storeAndForwardMessage = try? StoreAndForward(serializedData: packet.decoded.payload) { + // Request Response + switch storeAndForwardMessage.rr { + case .unset: + MeshLogger.log("📮 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") + case .routerError: + MeshLogger.log("☠️ Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") + case .routerHeartbeat: + /// When we get a router heartbeat we know there is a store and forward node on the network + /// Check if it is the primary S&F Router + if (storeAndForwardMessage.heartbeat.secondary == 0) { + /// send a request for ClientHistory with a time period matching the heartbeat + var sfPacket = StoreAndForward() + sfPacket.rr = StoreAndForward.RequestResponse.clientHistory + sfPacket.history.window = storeAndForwardMessage.heartbeat.period + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(packet.from) + meshPacket.from = UInt32(connectedNodeNum) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. = NSFetchRequest.init(entityName: "MyInfoEntity") diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index de34943b..b01808fa 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -569,45 +569,6 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana } } -func storeAndForwardPacket(packet: MeshPacket, connectedNodeNum: Int64, context: NSManagedObjectContext) { - if let storeAndForwardMessage = try? StoreAndForward(serializedData: packet.decoded.payload) { - // Request Response - switch storeAndForwardMessage.rr { - case .unset: - MeshLogger.log("📮 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .routerError: - MeshLogger.log("☠️ Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .routerHeartbeat: - // Query any messages since the heartbeat.period. Send their ids to the store and forward node. - MeshLogger.log("💓 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .routerPing: - MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .routerPong: - MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .routerBusy: - MeshLogger.log("🐝 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .routerHistory: - MeshLogger.log("📜 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .routerStats: - MeshLogger.log("📊 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .clientError: - MeshLogger.log("☠️ Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .clientHistory: - MeshLogger.log("📜 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .clientStats: - MeshLogger.log("📊 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .clientPing: - MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .clientPong: - MeshLogger.log("🏓 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .clientAbort: - MeshLogger.log("🛑 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - case .UNRECOGNIZED: - MeshLogger.log("📮 Store and Forward \(storeAndForwardMessage.rr) message received \(storeAndForwardMessage)") - } - } -} - func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManagedObjectContext) { if let telemetryMessage = try? Telemetry(serializedData: packet.decoded.payload) { diff --git a/Meshtastic/Persistence/QueryCoreData.swift b/Meshtastic/Persistence/QueryCoreData.swift index c3e718f2..fa200d8a 100644 --- a/Meshtastic/Persistence/QueryCoreData.swift +++ b/Meshtastic/Persistence/QueryCoreData.swift @@ -25,6 +25,28 @@ public func getNodeInfo(id: Int64, context: NSManagedObjectContext) -> NodeInfoE return nil } +public func getStoreAndForwardMessageIds(seconds: Int, context: NSManagedObjectContext) -> [UInt32] { + + let time = seconds * -1 + let fetchMessagesRequest: NSFetchRequest = NSFetchRequest.init(entityName: "MessageEntity") + let timeRange = Calendar.current.date(byAdding: .minute, value: time, to: Date()) + let milleseconds = Int32(timeRange?.timeIntervalSince1970 ?? 0) + fetchMessagesRequest.predicate = NSPredicate(format: "receivedTimestamp >= %d", milleseconds) + + do { + guard let fetchedMessages = try context.fetch(fetchMessagesRequest) as? [MessageEntity] else { + return [] + } + if fetchedMessages.count == 1 { + return fetchedMessages.map { UInt32($0.messageId) } + } + } catch { + return [] + } + return [] +} + + public func getUser(id: Int64, context: NSManagedObjectContext) -> UserEntity { let fetchUserRequest: NSFetchRequest = NSFetchRequest.init(entityName: "UserEntity")