mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #64 from meshtastic/feature/project_cleanup
Hook up Mesh Logging and remove ad hoc position data save
This commit is contained in:
commit
eadc435b9a
4 changed files with 106 additions and 99 deletions
|
|
@ -730,7 +730,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
CURRENT_PROJECT_VERSION = 20;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = GCH7VS5Y9R;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
|
|
@ -761,7 +761,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
CURRENT_PROJECT_VERSION = 20;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = GCH7VS5Y9R;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
|
|
|
|||
|
|
@ -52,13 +52,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let FROMRADIO_UUID = CBUUID(string: "0x8BA2BCC2-EE02-4A55-A531-C525C5E454D5")
|
||||
let FROMNUM_UUID = CBUUID(string: "0xED9DA18C-A800-4F66-A670-AA7547E34453")
|
||||
|
||||
private var meshLoggingEnabled: Bool = true
|
||||
private var meshLoggingEnabled: Bool = false
|
||||
let meshLog = documentsFolder.appendingPathComponent("meshlog.txt")
|
||||
|
||||
// MARK: init BLEManager
|
||||
override init() {
|
||||
|
||||
self.meshLoggingEnabled = true // UserDefaults.standard.object(forKey: "meshActivityLog") as? Bool ?? false
|
||||
self.meshLoggingEnabled = UserDefaults.standard.object(forKey: "meshActivityLog") as? Bool ?? false
|
||||
self.lastConnectionError = ""
|
||||
self.lastConnnectionVersion = "0.0.0"
|
||||
super.init()
|
||||
|
|
@ -624,17 +624,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
}
|
||||
|
||||
let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet
|
||||
mutablePositions.add(position)
|
||||
|
||||
// if position.coordinate == nil {
|
||||
// var newPostions = [PositionEntity]()
|
||||
// newPostions.append(position)
|
||||
// fetchedNode[0].positions? = NSOrderedSet(array: newPostions)
|
||||
//
|
||||
// } else {
|
||||
|
||||
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
|
||||
// }
|
||||
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
|
||||
|
||||
// Look for a MyInfo
|
||||
let fetchMyInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
|
||||
|
|
@ -845,28 +836,27 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
}
|
||||
fetchedNode[0].snr = decodedInfo.packet.rxSnr
|
||||
|
||||
|
||||
if let positionMessage = try? Position(serializedData: decodedInfo.packet.decoded.payload) {
|
||||
|
||||
let position = PositionEntity(context: context!)
|
||||
position.latitudeI = positionMessage.latitudeI
|
||||
position.longitudeI = positionMessage.longitudeI
|
||||
position.altitude = positionMessage.altitude
|
||||
position.batteryLevel = positionMessage.batteryLevel
|
||||
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time)))
|
||||
|
||||
if positionMessage.time == 0 {
|
||||
|
||||
position.time = Date()
|
||||
|
||||
} else {
|
||||
|
||||
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time)))
|
||||
}
|
||||
let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet
|
||||
mutablePositions.add(position)
|
||||
|
||||
if position.coordinate == nil {
|
||||
var newPostions = [PositionEntity]()
|
||||
newPostions.append(position)
|
||||
fetchedNode[0].positions? = NSOrderedSet(array: newPostions)
|
||||
|
||||
} else {
|
||||
|
||||
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
|
||||
}
|
||||
|
||||
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -895,45 +885,88 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
}
|
||||
// MARK: Incoming ROUTING_APP Packet
|
||||
} else if decodedInfo.packet.decoded.portnum == PortNum.routingApp {
|
||||
|
||||
|
||||
if let routingMessage = try? Routing(serializedData: decodedInfo.packet.decoded.payload) {
|
||||
print(decodedInfo.packet.decoded.requestID)
|
||||
print(routingMessage)
|
||||
|
||||
let fetchMessageRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MessageEntity")
|
||||
fetchMessageRequest.predicate = NSPredicate(format: "messageId == %lld", Int64(decodedInfo.packet.decoded.requestID))
|
||||
|
||||
do {
|
||||
|
||||
let fetchedMessage = try context?.fetch(fetchMessageRequest)[0] as? MessageEntity
|
||||
let error = routingMessage.errorReason
|
||||
|
||||
if fetchedMessage != nil {
|
||||
|
||||
|
||||
fetchedMessage!.receivedACK = true
|
||||
fetchedMessage!.ackSNR = decodedInfo.packet.rxSnr
|
||||
if decodedInfo.packet.rxTime <= 0 {
|
||||
fetchedMessage!.ackTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
} else {
|
||||
fetchedMessage!.ackTimestamp = Int32(decodedInfo.packet.rxTime)
|
||||
}
|
||||
|
||||
fetchedMessage!.objectWillChange.send()
|
||||
} else {
|
||||
var errorExplanation = "Unknown Routing Error"
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Routing App UNHANDLED \(try decodedInfo.packet.jsonString())") }
|
||||
print("ℹ️ MESH PACKET received for Routing App UNHANDLED \(try decodedInfo.packet.jsonString())")
|
||||
switch error {
|
||||
case Routing.Error.none:
|
||||
errorExplanation = "This message is not a failure"
|
||||
case Routing.Error.noRoute:
|
||||
errorExplanation = "Our node doesn't have a route to the requested destination anymore."
|
||||
case Routing.Error.gotNak:
|
||||
errorExplanation = "We received a nak while trying to forward on your behalf"
|
||||
case Routing.Error.timeout:
|
||||
errorExplanation = "Timeout"
|
||||
case Routing.Error.noInterface:
|
||||
errorExplanation = "No suitable interface could be found for delivering this packet"
|
||||
case Routing.Error.maxRetransmit:
|
||||
errorExplanation = "We reached the max retransmission count (typically for naive flood routing)"
|
||||
case Routing.Error.noChannel:
|
||||
errorExplanation = "No suitable channel was found for sending this packet (i.e. was requested channel index disabled?)"
|
||||
case Routing.Error.tooLarge:
|
||||
errorExplanation = "The packet was too big for sending (exceeds interface MTU after encoding)"
|
||||
case Routing.Error.noResponse:
|
||||
errorExplanation = "The request had want_response set, the request reached the destination node, but no service on that node wants to send a response (possibly due to bad channel permissions)"
|
||||
case Routing.Error.badRequest:
|
||||
errorExplanation = "The application layer service on the remote node received your request, but considered your request somehow invalid"
|
||||
case Routing.Error.notAuthorized:
|
||||
errorExplanation = "The application layer service on the remote node received your request, but considered your request not authorized (i.e you did not send the request on the required bound channel)"
|
||||
fallthrough
|
||||
default:
|
||||
print(error)
|
||||
}
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled {
|
||||
MeshLogger.log("💾 ACK Received and saved for MessageID \(decodedInfo.packet.decoded.requestID)")
|
||||
}
|
||||
print("💾 ACK Received and saved for MessageID \(decodedInfo.packet.decoded.requestID)")
|
||||
if meshLoggingEnabled { MeshLogger.log("🕸️ ROUTING PACKET received for RequestID: \(decodedInfo.packet.decoded.requestID) Error: \(errorExplanation)") }
|
||||
print("🕸️ ROUTING PACKET received for RequestID: \(decodedInfo.packet.decoded.requestID) Error: \(errorExplanation)")
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
if routingMessage.errorReason == Routing.Error.none {
|
||||
|
||||
print("Priority ACK no Error")
|
||||
|
||||
let fetchMessageRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MessageEntity")
|
||||
fetchMessageRequest.predicate = NSPredicate(format: "messageId == %lld", Int64(decodedInfo.packet.decoded.requestID))
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Saving ACK for message MessageID \(decodedInfo.packet.id) Error: \(nsError)")
|
||||
do {
|
||||
|
||||
let fetchedMessage = try context?.fetch(fetchMessageRequest)[0] as? MessageEntity
|
||||
|
||||
if fetchedMessage != nil {
|
||||
|
||||
|
||||
fetchedMessage!.receivedACK = true
|
||||
fetchedMessage!.ackSNR = decodedInfo.packet.rxSnr
|
||||
if decodedInfo.packet.rxTime <= 0 {
|
||||
fetchedMessage!.ackTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
} else {
|
||||
fetchedMessage!.ackTimestamp = Int32(decodedInfo.packet.rxTime)
|
||||
}
|
||||
|
||||
fetchedMessage!.objectWillChange.send()
|
||||
}
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled {
|
||||
MeshLogger.log("💾 ACK Received and saved for MessageID \(decodedInfo.packet.decoded.requestID)")
|
||||
}
|
||||
print("💾 ACK Received and saved for MessageID \(decodedInfo.packet.decoded.requestID)")
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Saving ACK for message MessageID \(decodedInfo.packet.id) Error: \(nsError)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if decodedInfo.packet.decoded.portnum == PortNum.environmentalMeasurementApp {
|
||||
|
|
@ -972,7 +1005,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
}
|
||||
|
||||
default:
|
||||
if meshLoggingEnabled { MeshLogger.log("🚨 Unhandled Characteristic UUID: \(characteristic.uuid)") }
|
||||
// Likely FROMNUM_UUID
|
||||
print("🚨 Unhandled Characteristic UUID: \(characteristic.uuid)")
|
||||
}
|
||||
peripheral.readValue(for: FROMRADIO_characteristic)
|
||||
|
|
@ -1104,8 +1137,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return success
|
||||
}
|
||||
|
||||
// Send Message
|
||||
public func sendPosition(destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func sendPosition(destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
|
||||
var success = false
|
||||
|
||||
|
|
@ -1124,6 +1156,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let fetchedNode = try context?.fetch(fetchNode) as! [NodeInfoEntity]
|
||||
|
||||
if fetchedNode.count == 1 {
|
||||
|
||||
var positionPacket = Position()
|
||||
positionPacket.latitudeI = Int32(LocationHelper.currentLocation.latitude * 1e7)
|
||||
positionPacket.longitudeI = Int32(LocationHelper.currentLocation.longitude * 1e7)
|
||||
|
|
@ -1142,51 +1175,25 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
dataMessage.portnum = PortNum.positionApp
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let position = PositionEntity(context: context!)
|
||||
position.latitudeI = positionPacket.latitudeI
|
||||
position.longitudeI = positionPacket.longitudeI
|
||||
position.altitude = positionPacket.altitude
|
||||
position.batteryLevel = positionPacket.batteryLevel
|
||||
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(positionPacket.time)))
|
||||
|
||||
let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet
|
||||
mutablePositions.add(position)
|
||||
|
||||
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
|
||||
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("📍 Sent a Position Packet for node: \(fromNodeNum)") }
|
||||
print("📍 Sent a Position Packet for node: \(fromNodeNum)")
|
||||
if meshLoggingEnabled { MeshLogger.log("📍 Sent a Position Packet from the phone to the device for node: \(fromNodeNum)") }
|
||||
print("📍 Sent a Position Packet from the phone to the device for node: \(fromNodeNum)")
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
print("💾 Saved a new position for the connected node: \(fromNodeNum)")
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new position for the connected node: \(fromNodeNum)") }
|
||||
success = true
|
||||
|
||||
} catch {
|
||||
|
||||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("🚫 Unresolved Core Data error in Send Position Function \(nsError)")
|
||||
if meshLoggingEnabled { MeshLogger.log("🚫 Unresolved Core Data error in Send Position Function \(nsError)") }
|
||||
success = false
|
||||
}
|
||||
|
||||
success = true
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch {
|
||||
|
||||
success = false
|
||||
}
|
||||
|
||||
return success
|
||||
|
|
|
|||
|
|
@ -344,9 +344,9 @@ struct UserMessageList: View {
|
|||
scrollView.scrollTo(allMessages.firstIndex(of: allMessages.last! ), anchor: .bottom)
|
||||
}
|
||||
})
|
||||
.onChange(of: allMessages, perform: { message in
|
||||
.onChange(of: allMessages.count, perform: { count in
|
||||
|
||||
if allMessages.count > 1 {
|
||||
if count > 1 {
|
||||
|
||||
scrollView.scrollTo(allMessages.firstIndex(of: allMessages.last! ), anchor: .bottom)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ struct NodeDetail: View {
|
|||
|
||||
VStack {
|
||||
|
||||
if node.positions?.count ?? 0 > 0 {
|
||||
if node.positions?.count ?? 0 >= 1 {
|
||||
|
||||
let mostRecent = node.positions?.lastObject as! PositionEntity
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ struct NodeDetail: View {
|
|||
.padding(5)
|
||||
}
|
||||
|
||||
if node.positions!.count > 0 {
|
||||
if node.positions?.count ?? 0 >= 1 {
|
||||
|
||||
let mostRecent = node.positions?.lastObject as! PositionEntity
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ struct NodeDetail: View {
|
|||
}
|
||||
.padding()
|
||||
|
||||
if node.positions?.count ?? 0 > 1 {
|
||||
if node.positions?.count ?? 0 >= 1 {
|
||||
|
||||
Divider()
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ struct NodeDetail: View {
|
|||
.padding(1)
|
||||
}
|
||||
}
|
||||
.navigationTitle((node != nil && node.user != nil) ? String(node.user!.longName ?? "Unknown") : "Unknown")
|
||||
.navigationTitle((node.user != nil) ? String(node.user!.longName ?? "Unknown") : "Unknown")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarItems(trailing:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue