From d3ac782773a5b50e56c40e13119ff885e896247b Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 23 Feb 2022 20:11:02 -1000 Subject: [PATCH 1/5] Re-enable mesh map setting, fix nil node bug --- MeshtasticClient/Info.plist | 2 +- MeshtasticClient/Views/Nodes/NodeDetail.swift | 2 +- MeshtasticClient/Views/Settings/AppSettings.swift | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MeshtasticClient/Info.plist b/MeshtasticClient/Info.plist index 85d9e776..1a7b3ab5 100644 --- a/MeshtasticClient/Info.plist +++ b/MeshtasticClient/Info.plist @@ -40,7 +40,7 @@ LSRequiresIPhoneOS LSSupportsOpeningDocumentsInPlace - + NSBluetoothAlwaysUsageDescription We use bluetooth to connect to nearby Meshtastic Devices NSBluetoothPeripheralUsageDescription diff --git a/MeshtasticClient/Views/Nodes/NodeDetail.swift b/MeshtasticClient/Views/Nodes/NodeDetail.swift index a638828c..a32533c7 100644 --- a/MeshtasticClient/Views/Nodes/NodeDetail.swift +++ b/MeshtasticClient/Views/Nodes/NodeDetail.swift @@ -271,7 +271,7 @@ struct NodeDetail: View { .padding(1) } } - .navigationTitle(node != nil ? String(node.user!.longName ?? "Unknown") : "Unknown") + .navigationTitle((node != nil && node.user != nil) ? String(node.user!.longName ?? "Unknown") : "Unknown") .navigationBarTitleDisplayMode(.inline) .navigationBarItems(trailing: diff --git a/MeshtasticClient/Views/Settings/AppSettings.swift b/MeshtasticClient/Views/Settings/AppSettings.swift index 2978d565..6a5b9282 100644 --- a/MeshtasticClient/Views/Settings/AppSettings.swift +++ b/MeshtasticClient/Views/Settings/AppSettings.swift @@ -174,12 +174,12 @@ struct AppSettings: View { // TextField("Custom Tile Server", text: $userSettings.meshMapCustomTileServer) } Section(header: Text("DEBUG")) { - // Toggle(isOn: $userSettings.meshActivityLog) { + Toggle(isOn: $userSettings.meshActivityLog) { - // Label("Log all Mesh activity", systemImage: "network") - // } - // .toggleStyle(SwitchToggleStyle(tint: .accentColor)) - if true {// userSettings.meshActivityLog { + Label("Log all Mesh activity", systemImage: "network") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + if userSettings.meshActivityLog { NavigationLink(destination: MeshLog()) { Text("View Mesh Log") } From 543debbcce1e1fa797920aeb21c0b43e44b5253d Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 23 Feb 2022 23:05:47 -1000 Subject: [PATCH 2/5] Add acks and ack timestamp to messages --- MeshtasticClient/Helpers/BLEManager.swift | 25 ++++++++--- .../contents | 3 +- .../Views/Helpers/CircleText.swift | 2 +- .../Views/Messages/Contacts.swift | 6 ++- .../Views/Messages/UserMessageList.swift | 44 +++++++++++-------- MeshtasticClient/Views/Nodes/NodeDetail.swift | 2 +- .../Views/Settings/AppSettings.swift | 28 ++++++------ 7 files changed, 68 insertions(+), 42 deletions(-) diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index ce8f2753..bfb97ab5 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -742,7 +742,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph print("💾 Saved a new message for \(decodedInfo.packet.id)") if meshLoggingEnabled { MeshLogger.log("💾 Saved a new message for \(newMessage.messageId)") } - if newMessage.toUser!.num == self.broadcastNodeNum || self.connectedPeripheral != nil && self.connectedPeripheral.num == newMessage.toUser!.num { + if newMessage.toUser != nil && newMessage.toUser!.num == self.broadcastNodeNum || self.connectedPeripheral != nil && self.connectedPeripheral.num == newMessage.toUser!.num { // Create an iOS Notification for the received message and schedule it immediately let manager = LocalNotificationManager() @@ -895,9 +895,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if let routingMessage = try? Routing(serializedData: decodedInfo.packet.decoded.payload) { print(decodedInfo.packet.decoded.requestID) - print(routingMessage) + print(decodedInfo.packet.priority) //let mes = routingMessage. - let error = routingMessage.errorReason + //let error = routingMessage.errorReason //routingMessage.routeRequest } @@ -909,15 +909,26 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph do { - let fetchedMessage = try context?.fetch(fetchMessageRequest) as! [MessageEntity] + let fetchedMessage = try context?.fetch(fetchMessageRequest)[0] as? MessageEntity - if fetchedMessage.count > 0 { - + if fetchedMessage != nil { + fetchedMessage!.receivedACK = true + fetchedMessage!.ackTimestamp = Int32(Date().timeIntervalSince1970) } + try context!.save() + + if meshLoggingEnabled { + MeshLogger.log("💾 ACK Received and saved for MessageID \(decodedInfo.packet.id)") + } + print("💾 ACK Received and saved for MessageID \(decodedInfo.packet.id)") + } catch { - + context!.rollback() + + let nsError = error as NSError + print("💥 Error Saving ACK for message MessageID \(decodedInfo.packet.id) Error: \(nsError)") } } diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents index 6de78a4d..c9b0d9b9 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents @@ -1,6 +1,7 @@ + @@ -76,7 +77,7 @@ - + diff --git a/MeshtasticClient/Views/Helpers/CircleText.swift b/MeshtasticClient/Views/Helpers/CircleText.swift index c8b3c6ad..4ada7061 100644 --- a/MeshtasticClient/Views/Helpers/CircleText.swift +++ b/MeshtasticClient/Views/Helpers/CircleText.swift @@ -19,7 +19,7 @@ struct CircleText: View { Circle() .fill(color) .frame(width: circleSize, height: circleSize) - Text(text).textCase(.uppercase).font(font).foregroundColor(.white) + Text(text).textCase(.uppercase).font(font).foregroundColor(.white).fixedSize() .frame(width: circleSize, height: circleSize, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).offset(x: 0, y: 0) } } diff --git a/MeshtasticClient/Views/Messages/Contacts.swift b/MeshtasticClient/Views/Messages/Contacts.swift index 45131a60..66a20737 100644 --- a/MeshtasticClient/Views/Messages/Contacts.swift +++ b/MeshtasticClient/Views/Messages/Contacts.swift @@ -25,8 +25,11 @@ struct Contacts: View { List(users) { (user: UserEntity) in let allMessages = user.value(forKey: "allMessages") as! [MessageEntity] + let connectedNodeNum = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.num : 0 - NavigationLink(destination: UserMessageList(user: user)) { + if user.num != connectedNodeNum { + + NavigationLink(destination: UserMessageList(user: user)) { if allMessages.count > 0 { @@ -120,6 +123,7 @@ struct Contacts: View { }.padding() } } + } } .navigationTitle("Contacts") .navigationBarTitleDisplayMode(.inline) diff --git a/MeshtasticClient/Views/Messages/UserMessageList.swift b/MeshtasticClient/Views/Messages/UserMessageList.swift index b60c9956..1a6615fb 100644 --- a/MeshtasticClient/Views/Messages/UserMessageList.swift +++ b/MeshtasticClient/Views/Messages/UserMessageList.swift @@ -218,15 +218,9 @@ struct UserMessageList: View { VStack { - let time = Int32(message.messageTimestamp) - let messageDate = Date(timeIntervalSince1970: TimeInterval(time)) - - if time != 0 { - Text("Sent \(messageDate, style: .date) \(messageDate, style: .time)").font(.caption2).foregroundColor(.gray) - } else { - Text("Unknown").font(.caption2).foregroundColor(.gray) - } + let messageDate = Date(timeIntervalSince1970: TimeInterval(message.messageTimestamp)) + Text("Sent \(messageDate, style: .date) \(messageDate, style: .time)").font(.caption2).foregroundColor(.gray) } VStack { @@ -234,6 +228,13 @@ struct UserMessageList: View { Text("Received ACK: \(message.receivedACK ? "✔️" : "")") } + if message.receivedACK { + VStack { + + let ackDate = Date(timeIntervalSince1970: TimeInterval(message.ackTimestamp)) + Text("ACK \(ackDate, style: .date) \(ackDate, style: .time)").font(.caption2).foregroundColor(.gray) + } + } } Divider() Button(role: .destructive, action: { @@ -285,13 +286,6 @@ struct UserMessageList: View { let time = Int32(message.messageTimestamp) let messageDate = Date(timeIntervalSince1970: TimeInterval(time)) let showUntil = Date().addingTimeInterval(3600) - - if time != 0 { - // Text(messageDate, style: .date).font(.caption2).foregroundColor(.gray) - // Text(messageDate, style: .time).font(.caption2).foregroundColor(.gray) - } else { - // Text("Unknown").font(.caption2).foregroundColor(.gray) - } if messageDate <= showUntil && message.receivedACK { @@ -352,7 +346,7 @@ struct UserMessageList: View { let index = count - 1 - if index > 2 { + if index > 3 { scrollView.scrollTo(index, anchor: .bottom) } @@ -394,11 +388,25 @@ struct UserMessageList: View { sendPositionWithMessage = true if user.num == bleManager.broadcastNodeNum { - typingMessage = "📍 " + userLongName + " Has shared their position with the mesh." + if userSettings.meshtasticUsername.count > 0 { + + typingMessage = "📍 " + userSettings.meshtasticUsername + " has shared their position with the mesh from node " + userLongName + } else { + + typingMessage = "📍 " + userLongName + " has shared their position with the mesh." + + } } else { - typingMessage = "📍 " + userLongName + " Has shared their position with you." + if userSettings.meshtasticUsername.count > 0 { + + typingMessage = "📍 " + userSettings.meshtasticUsername + " has shared their position with you from node " + userLongName + + } else { + + typingMessage = "📍 " + userLongName + " has shared their position with you." + } } } label: { Image(systemName: "mappin.and.ellipse") diff --git a/MeshtasticClient/Views/Nodes/NodeDetail.swift b/MeshtasticClient/Views/Nodes/NodeDetail.swift index a32533c7..7dc1da84 100644 --- a/MeshtasticClient/Views/Nodes/NodeDetail.swift +++ b/MeshtasticClient/Views/Nodes/NodeDetail.swift @@ -43,7 +43,7 @@ struct NodeDetail: View { MapAnnotation( coordinate: location.coordinate, content: { - CircleText(text: node.user!.shortName ?? "???", color: .accentColor, circleSize: 33, fontSize: 16) + CircleText(text: node.user!.shortName ?? "???", color: .accentColor, circleSize: 32, fontSize: 14) } ) } diff --git a/MeshtasticClient/Views/Settings/AppSettings.swift b/MeshtasticClient/Views/Settings/AppSettings.swift index 6a5b9282..3b4f286b 100644 --- a/MeshtasticClient/Views/Settings/AppSettings.swift +++ b/MeshtasticClient/Views/Settings/AppSettings.swift @@ -54,11 +54,11 @@ enum MeshMapType: String, CaseIterable, Identifiable { } class UserSettings: ObservableObject { -// @Published var meshtasticUsername: String { -// didSet { -// UserDefaults.standard.set(meshtasticUsername, forKey: "meshtasticusername") -// } -// } + @Published var meshtasticUsername: String { + didSet { + UserDefaults.standard.set(meshtasticUsername, forKey: "meshtasticusername") + } + } @Published var preferredPeripheralName: String { didSet { UserDefaults.standard.set(preferredPeripheralName, forKey: "preferredPeripheralName") @@ -99,7 +99,7 @@ class UserSettings: ObservableObject { init() { - // self.meshtasticUsername = UserDefaults.standard.object(forKey: "meshtasticusername") as? String ?? "" + self.meshtasticUsername = UserDefaults.standard.object(forKey: "meshtasticusername") as? String ?? "" self.preferredPeripheralName = UserDefaults.standard.object(forKey: "preferredPeripheralName") as? String ?? "" self.preferredPeripheralId = UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" self.provideLocation = UserDefaults.standard.object(forKey: "provideLocation") as? Bool ?? false @@ -131,12 +131,14 @@ struct AppSettings: View { List { Section(header: Text("USER DETAILS")) { -// HStack { -// Label("Name", systemImage: "person.crop.rectangle.fill") -// TextField("Username", text: $userSettings.meshtasticUsername) -// .foregroundColor(.gray) -// } -// .listRowSeparator(.visible) + HStack { + Label("Name", systemImage: "person.crop.rectangle.fill") + TextField("Username", text: $userSettings.meshtasticUsername) + .foregroundColor(.gray) + } + .keyboardType(.asciiCapable) + .disableAutocorrection(true) + .listRowSeparator(.visible) Toggle(isOn: $userSettings.provideLocation) { Label("Provide location to mesh", systemImage: "location.circle.fill") @@ -173,7 +175,7 @@ struct AppSettings: View { .pickerStyle(DefaultPickerStyle()) // TextField("Custom Tile Server", text: $userSettings.meshMapCustomTileServer) } - Section(header: Text("DEBUG")) { + Section(header: Text("DEBUG OPTIONS")) { Toggle(isOn: $userSettings.meshActivityLog) { Label("Log all Mesh activity", systemImage: "network") From 3f92e527789e749e59e302b523d53898deff3bf7 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 24 Feb 2022 07:57:08 -1000 Subject: [PATCH 3/5] Update default location, don't send out empty or default location from the new Share position features --- Meshtastic Client.xcodeproj/project.pbxproj | 4 +- MeshtasticClient/Helpers/BLEManager.swift | 5 ++- MeshtasticClient/Helpers/LocationHelper.swift | 4 +- MeshtasticClient/Views/Nodes/NodeList.swift | 44 +++++++++---------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 39305a3c..7b156787 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -738,7 +738,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 11; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -769,7 +769,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 11; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index bfb97ab5..8ed430d1 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -897,7 +897,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph print(decodedInfo.packet.decoded.requestID) print(decodedInfo.packet.priority) //let mes = routingMessage. - //let error = routingMessage.errorReason + let error = routingMessage.errorReason //routingMessage.routeRequest } @@ -1111,7 +1111,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let fromNodeNum = connectedPeripheral.num - if fromNodeNum <= 0 { + if fromNodeNum <= 0 || (LocationHelper.currentLocation.latitude == LocationHelper.DefaultLocation.latitude && LocationHelper.currentLocation.longitude == LocationHelper.DefaultLocation.longitude) { return false } @@ -1199,6 +1199,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph // Send a position out to the mesh if "share location with the mesh" is enabled in settings if userSettings!.provideLocation { + let success = sendPosition(destNum: connectedPeripheral.num, wantResponse: false) if !success { diff --git a/MeshtasticClient/Helpers/LocationHelper.swift b/MeshtasticClient/Helpers/LocationHelper.swift index b3459ef7..7cea2ee3 100644 --- a/MeshtasticClient/Helpers/LocationHelper.swift +++ b/MeshtasticClient/Helpers/LocationHelper.swift @@ -4,8 +4,8 @@ class LocationHelper: NSObject, ObservableObject { static let shared = LocationHelper() - // Mount Rainier - static let DefaultLocation = CLLocationCoordinate2D(latitude: 46.879967, longitude: -121.726906) + // Apple Park ° N, 122.0090° W + static let DefaultLocation = CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090) static let DefaultAltitude = CLLocationDistance(integerLiteral: 0) diff --git a/MeshtasticClient/Views/Nodes/NodeList.swift b/MeshtasticClient/Views/Nodes/NodeList.swift index 9a73881c..3c043ea8 100644 --- a/MeshtasticClient/Views/Nodes/NodeList.swift +++ b/MeshtasticClient/Views/Nodes/NodeList.swift @@ -87,28 +87,28 @@ struct NodeList: View { } .padding([.leading, .top, .bottom]) } - .swipeActions { - - Button { - - context.delete(node) - - do { - - try context.save() - print("Successfully Deleted NodeInfoEntiy: \(node.num)") - - } catch { - - print("Failed to save context after deleting NodeInfoEntity Num: \(node.num)") - } - - } label: { - - Label("Delete from app", systemImage: "trash") - } - .tint(.red) - } +// .swipeActions { +// +// Button { +// +// context.delete(node) +// +// do { +// +// try context.save() +// print("Successfully Deleted NodeInfoEntiy: \(node.num)") +// +// } catch { +// +// print("Failed to save context after deleting NodeInfoEntity Num: \(node.num)") +// } +// +// } label: { +// +// Label("Delete from app", systemImage: "trash") +// } +// .tint(.red) +// } } } } From 89a7b3025f470620ee554559bf45de286a878bc1 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 24 Feb 2022 07:57:42 -1000 Subject: [PATCH 4/5] Update Build --- Meshtastic Client.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 7b156787..580ee094 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -738,7 +738,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 11; + CURRENT_PROJECT_VERSION = 12; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -769,7 +769,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 11; + CURRENT_PROJECT_VERSION = 12; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; From a6d287ee8026313c90763c5d14e99d0ed7ecb118 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 24 Feb 2022 08:28:08 -1000 Subject: [PATCH 5/5] Remove debug code --- MeshtasticClient/Helpers/BLEManager.swift | 11 ----------- MeshtasticClient/Helpers/LocationHelper.swift | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 8ed430d1..1a3831d8 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -891,17 +891,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph // MARK: Incoming ROUTING_APP Packet } else if decodedInfo.packet.decoded.portnum == PortNum.routingApp { - let currentNodeNum = self.connectedPeripheral.num - - if let routingMessage = try? Routing(serializedData: decodedInfo.packet.decoded.payload) { - print(decodedInfo.packet.decoded.requestID) - print(decodedInfo.packet.priority) - //let mes = routingMessage. - let error = routingMessage.errorReason - - //routingMessage.routeRequest - } - if decodedInfo.packet.priority == MeshPacket.Priority.ack { let fetchMessageRequest: NSFetchRequest = NSFetchRequest.init(entityName: "MessageEntity") diff --git a/MeshtasticClient/Helpers/LocationHelper.swift b/MeshtasticClient/Helpers/LocationHelper.swift index 7cea2ee3..3210680b 100644 --- a/MeshtasticClient/Helpers/LocationHelper.swift +++ b/MeshtasticClient/Helpers/LocationHelper.swift @@ -4,7 +4,7 @@ class LocationHelper: NSObject, ObservableObject { static let shared = LocationHelper() - // Apple Park ° N, 122.0090° W + // Apple Park static let DefaultLocation = CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090) static let DefaultAltitude = CLLocationDistance(integerLiteral: 0)