More 1.3 Photo updates

This commit is contained in:
Garth Vander Houwen 2022-04-02 06:02:21 -07:00
parent 832241e1f3
commit 0ba625fa88
9 changed files with 67 additions and 140 deletions

View file

@ -513,6 +513,12 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
let newNode = NodeInfoEntity(context: context!)
newNode.id = Int64(decodedInfo.nodeInfo.num)
newNode.num = Int64(decodedInfo.nodeInfo.num)
if decodedInfo.nodeInfo.hasDeviceMetrics {
newNode.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel)
newNode.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage
}
if decodedInfo.nodeInfo.lastHeard > 0 {
newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.lastHeard)))
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="21E230" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="21E258" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="MessageEntity" representedClassName="MessageEntity" syncable="YES" codeGenerationType="class">
<attribute name="ackSNR" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="ackTimestamp" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
@ -23,10 +23,12 @@
</entity>
<entity name="MyInfoEntity" representedClassName="MyInfoEntity" syncable="YES" codeGenerationType="class">
<attribute name="airUtilTx" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="bitrate" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="bleName" optional="YES" attributeType="String"/>
<attribute name="channelUtilization" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="firmwareVersion" attributeType="String"/>
<attribute name="hasGps" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="hasWifi" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="maxChannels" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="messageTimeoutMsec" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="minAppVersion" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
@ -39,11 +41,13 @@
</uniquenessConstraints>
</entity>
<entity name="NodeInfoEntity" representedClassName="NodeInfoEntity" syncable="YES" codeGenerationType="class">
<attribute name="batteryLevel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="bleName" optional="YES" attributeType="String"/>
<attribute name="id" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="lastHeard" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="voltage" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<relationship name="myInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="myInfoNode" inverseEntity="MyInfoEntity"/>
<relationship name="positions" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PositionEntity" inverseName="nodePosition" inverseEntity="PositionEntity"/>
<relationship name="user" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="userNode" inverseEntity="UserEntity"/>
@ -78,8 +82,8 @@
</entity>
<elements>
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="215"/>
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="179"/>
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="149"/>
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="209"/>
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="179"/>
<element name="PositionEntity" positionX="-54" positionY="54" width="128" height="119"/>
<element name="UserEntity" positionX="0" positionY="144" width="128" height="200"/>
</elements>

View file

@ -7,25 +7,6 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
///
/// Meshtastic protobufs
///
/// For more information on protobufs (and tools to use them with the language of your choice) see
/// https://developers.google.com/protocol-buffers/docs/proto3
///
/// We are not placing any of these defs inside a package, because if you do the
/// resulting nanopb version is super verbose package mesh.
///
/// Protobuf build instructions:
///
/// To build java classes for reading writing:
/// protoc -I=. --java_out /tmp mesh.proto
///
/// To generate Nanopb c code:
/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto
///
/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0
import Foundation
import SwiftProtobuf

View file

@ -7,25 +7,6 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
///
/// Meshtastic protobufs
///
/// For more information on protobufs (and tools to use them with the language of your choice) see
/// https://developers.google.com/protocol-buffers/docs/proto3
///
/// We are not placing any of these defs inside a package, because if you do the
/// resulting nanopb version is super verbose package mesh.
///
/// Protobuf build instructions:
///
/// To build java classes for reading writing:
/// protoc -I=. --java_out /tmp mesh.proto
///
/// To generate Nanopb c code:
/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto
///
/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0
import Foundation
import SwiftProtobuf
@ -56,7 +37,6 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
/// users COULD type in a channel name and be able to talk.
/// Y is a lower case letter from a-z that represents the channel 'speed' settings
/// (for some future definition of speed)
///
/// FIXME: Add description of multi-channel support and how primary vs secondary channels are used.
/// FIXME: explain how apps use channels for security.
/// explain how remote settings and remote gpio are managed as an example
@ -285,12 +265,10 @@ struct Channel {
///
/// How this channel is being used (or not).
///
/// Note: this field is an enum to give us options for the future.
/// In particular, someday we might make a 'SCANNING' option.
/// SCANNING channels could have different frequencies and the radio would
/// occasionally check that freq to see if anything is being transmitted.
///
/// For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow
/// cross band routing as needed.
/// If a device has only a single radio (the common case) only one channel can be PRIMARY at a time

View file

@ -7,25 +7,6 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
///
/// Meshtastic protobufs
///
/// For more information on protobufs (and tools to use them with the language of your choice) see
/// https://developers.google.com/protocol-buffers/docs/proto3
///
/// We are not placing any of these defs inside a package, because if you do the
/// resulting nanopb version is super verbose package mesh.
///
/// Protobuf build instructions:
///
/// To build java classes for reading writing:
/// protoc -I=. --java_out /tmp mesh.proto
///
/// To generate Nanopb c code:
/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto
///
/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0
import Foundation
import SwiftProtobuf
@ -425,7 +406,6 @@ extension Constants: CaseIterable {
///
/// Error codes for critical errors
///
/// The device might report these fault codes on the screen.
/// If you encounter a fault code, please post on the meshtastic.discourse.group
/// and we'll try to help.
@ -665,7 +645,6 @@ struct Position {
///
/// Ground speed in m/s and True North TRACK in 1/100 degrees
///
/// Clarification of terms:
/// - "track" is the direction of motion (measured in horizontal plane)
/// - "heading" is where the fuselage points (measured in horizontal plane)
@ -868,24 +847,20 @@ extension Position.AltSource: CaseIterable {
/// Broadcast when a newly powered mesh node wants to find a node num it can use
/// Sent from the phone over bluetooth to set the user id for the owner of this node.
/// Also sent from nodes to each other when a new node signs on (so all clients can have this info)
///
/// The algorithm is as follows:
/// when a node starts up, it broadcasts their user and the normal flow is for all
/// other nodes to reply with their User as well (so the new node can build its nodedb)
/// If a node ever receives a User (not just the first broadcast) message where
/// the sender node number equals our node number, that indicates a collision has
/// occurred and the following steps should happen:
///
/// If the receiving node (that was already in the mesh)'s macaddr is LOWER than the
/// new User who just tried to sign in: it gets to keep its nodenum.
/// We send a broadcast message of OUR User (we use a broadcast so that the other node can
/// receive our message, considering we have the same id - it also serves to let
/// observers correct their nodedb) - this case is rare so it should be okay.
///
/// If any node receives a User where the macaddr is GTE than their local macaddr,
/// they have been vetoed and should pick a new random nodenum (filtering against
/// whatever it knows about the nodedb) and rebroadcast their User.
///
/// A few nodenums are reserved and will never be requested:
/// 0xff - broadcast
/// 0 through 3 - for future use
@ -1453,11 +1428,8 @@ struct MeshPacket {
/// This field is never sent over the air, it is only used internally inside of a local device node.
/// API clients (either on the local node or connected directly to the node)
/// can set this parameter if necessary.
///
/// (values must be <= 127 to keep protobuf field to one byte in size.
///
/// Detailed background on this field:
///
/// I noticed a funny side effect of lora being so slow: Usually when making
/// a protocol there isnt much need to use message priority to change the order
/// of transmission (because interfaces are fairly fast).
@ -1466,7 +1438,6 @@ struct MeshPacket {
/// In the case of meshtastic that means we want to send protocol acks as soon as possible
/// (to prevent unneeded retransmissions), we want routing messages to be sent next,
/// then messages marked as reliable and finally background packets like periodic position updates.
///
/// So I bit the bullet and implemented a new (internal - not sent over the air)
/// field in MeshPacket called priority.
/// And the transmission queue in the router object is now a priority queue.
@ -1612,16 +1583,12 @@ extension MeshPacket.Delayed: CaseIterable {
///
/// The bluetooth to device link:
///
/// Old BTLE protocol docs from TODO, merge in above and make real docs...
///
/// use protocol buffers, and NanoPB
///
/// messages from device to phone:
/// POSITION_UPDATE (..., time)
/// TEXT_RECEIVED(from, text, time)
/// OPAQUE_RECEIVED(from, payload, time) (for signal messages or other applications)
///
/// messages from phone to device:
/// SET_MYID(id, human readable long, human readable short) (send down the unique ID
/// string used for this node, a human readable string shown for that id, and a very
@ -1630,7 +1597,6 @@ extension MeshPacket.Delayed: CaseIterable {
/// nodes() (returns list of nodes, with full info, last time seen, loc, battery
/// level etc) SET_CONFIG (switches device to a new set of radio params and
/// preshared key, drops all existing nodes, force our node to rejoin this new group)
///
/// Full information about a node on the mesh
struct NodeInfo {
// SwiftProtobuf.Message conformance is added in an extension below. See the
@ -1683,15 +1649,15 @@ struct NodeInfo {
}
///
/// The latest device telemetry data for the node.
var telemetry: Telemetry {
get {return _storage._telemetry ?? Telemetry()}
set {_uniqueStorage()._telemetry = newValue}
/// The latest device metrics for the node.
var deviceMetrics: DeviceMetrics {
get {return _storage._deviceMetrics ?? DeviceMetrics()}
set {_uniqueStorage()._deviceMetrics = newValue}
}
/// Returns true if `telemetry` has been explicitly set.
var hasTelemetry: Bool {return _storage._telemetry != nil}
/// Clears the value of `telemetry`. Subsequent reads from it will return its default value.
mutating func clearTelemetry() {_uniqueStorage()._telemetry = nil}
/// Returns true if `deviceMetrics` has been explicitly set.
var hasDeviceMetrics: Bool {return _storage._deviceMetrics != nil}
/// Clears the value of `deviceMetrics`. Subsequent reads from it will return its default value.
mutating func clearDeviceMetrics() {_uniqueStorage()._deviceMetrics = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
@ -1856,7 +1822,6 @@ struct MyNodeInfo {
///
/// Debug output from the device.
///
/// To minimize the size of records inside the device code, if a time/source/level is not set
/// on the message it is assumed to be a continuation of the previously sent message.
/// This allows the device code to use fixed maxlen 64 byte strings for messages,
@ -3197,7 +3162,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
3: .same(proto: "position"),
4: .same(proto: "snr"),
5: .standard(proto: "last_heard"),
6: .same(proto: "telemetry"),
6: .standard(proto: "device_metrics"),
]
fileprivate class _StorageClass {
@ -3206,7 +3171,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
var _position: Position? = nil
var _snr: Float = 0
var _lastHeard: UInt32 = 0
var _telemetry: Telemetry? = nil
var _deviceMetrics: DeviceMetrics? = nil
static let defaultInstance = _StorageClass()
@ -3218,7 +3183,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
_position = source._position
_snr = source._snr
_lastHeard = source._lastHeard
_telemetry = source._telemetry
_deviceMetrics = source._deviceMetrics
}
}
@ -3242,7 +3207,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
case 3: try { try decoder.decodeSingularMessageField(value: &_storage._position) }()
case 4: try { try decoder.decodeSingularFloatField(value: &_storage._snr) }()
case 5: try { try decoder.decodeSingularFixed32Field(value: &_storage._lastHeard) }()
case 6: try { try decoder.decodeSingularMessageField(value: &_storage._telemetry) }()
case 6: try { try decoder.decodeSingularMessageField(value: &_storage._deviceMetrics) }()
default: break
}
}
@ -3270,7 +3235,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
if _storage._lastHeard != 0 {
try visitor.visitSingularFixed32Field(value: _storage._lastHeard, fieldNumber: 5)
}
try { if let v = _storage._telemetry {
try { if let v = _storage._deviceMetrics {
try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
} }()
}
@ -3287,7 +3252,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
if _storage._position != rhs_storage._position {return false}
if _storage._snr != rhs_storage._snr {return false}
if _storage._lastHeard != rhs_storage._lastHeard {return false}
if _storage._telemetry != rhs_storage._telemetry {return false}
if _storage._deviceMetrics != rhs_storage._deviceMetrics {return false}
return true
}
if !storagesAreEqual {return false}

View file

@ -23,19 +23,14 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
///
/// For any new 'apps' that run on the device or via sister apps on phones/PCs they should pick and use a
/// unique 'portnum' for their application.
///
/// If you are making a new app using meshtastic, please send in a pull request to add your 'portnum' to this
/// master table.
/// PortNums should be assigned in the following range:
///
/// 0-63 Core Meshtastic use, do not use for third party apps
/// 64-127 Registered 3rd party apps, send in a pull request that adds a new entry to portnums.proto to register your application
/// 256-511 Use one of these portnums for your private applications that you don't want to register publically
///
/// All other values are reserved.
///
/// Note: This was formerly a Type enum named 'typ' with the same id #
///
/// We have change to this 'portnum' based scheme for specifying app handlers for particular payloads.
/// This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically.
enum PortNum: SwiftProtobuf.Enum {

View file

@ -7,25 +7,6 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
///
/// Meshtastic protobufs
///
/// For more information on protobufs (and tools to use them with the language of your choice) see
/// https://developers.google.com/protocol-buffers/docs/proto3
///
/// We are not placing any of these defs inside a package, because if you do the
/// resulting nanopb version is super verbose package mesh.
///
/// Protobuf build instructions:
///
/// To build java classes for reading writing:
/// protoc -I=. --java_out /tmp mesh.proto
///
/// To generate Nanopb c code:
/// /home/kevinh/packages/nanopb-0.4.0-linux-x86/generator-bin/protoc --nanopb_out=/tmp -I=app/src/main/proto mesh.proto
///
/// Nanopb binaries available here: https://jpa.kapsi.fi/nanopb/download/ use nanopb 0.4.0
import Foundation
import SwiftProtobuf
@ -41,10 +22,8 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
///
/// The frequency/regulatory region the user has selected.
///
/// Note: In 1.0 builds (which must still be supported by the android app for a
/// long time) this field will be unpopulated.
///
/// If firmware is ever upgraded from an old 1.0ish build, the old
/// MyNodeInfo.region string will be used to set UserPreferences.region and the
/// old value will be no longer set.
@ -175,37 +154,57 @@ extension RegionCode: CaseIterable {
/// Defines the device's role on the Mesh network
/// unset
/// Behave normally.
///
/// Router
/// Functions as a router
enum Role: SwiftProtobuf.Enum {
typealias RawValue = Int
///
/// Default device role
case `default` // = 0
/// Client device role
case client // = 0
///
/// Router device role
case router // = 1
/// ClientMute device role
/// This is like the client but packets will not hop over this node. Would be
/// useful if you want to save power by not contributing to the mesh.
case clientMute // = 1
///
/// Router device role.
/// Uses an agressive algirithem for the flood networking so packets will
/// prefer to be routed over this node. Also assume that this will be generally
/// unattended and so will turn off the wifi/ble radio as well as the oled screen.
case router // = 2
///
/// RouterClient device role
/// Uses an agressive algirithem for the flood networking so packets will
/// prefer to be routed over this node. Similiar power management as a regular
/// client, so the RouterClient can be used as both a Router and a Client. Useful
/// as a well placed base station that you could also use to send messages.
case routerClient // = 3
case UNRECOGNIZED(Int)
init() {
self = .default
self = .client
}
init?(rawValue: Int) {
switch rawValue {
case 0: self = .default
case 1: self = .router
case 0: self = .client
case 1: self = .clientMute
case 2: self = .router
case 3: self = .routerClient
default: self = .UNRECOGNIZED(rawValue)
}
}
var rawValue: Int {
switch self {
case .default: return 0
case .router: return 1
case .client: return 0
case .clientMute: return 1
case .router: return 2
case .routerClient: return 3
case .UNRECOGNIZED(let i): return i
}
}
@ -217,8 +216,10 @@ enum Role: SwiftProtobuf.Enum {
extension Role: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
static var allCases: [Role] = [
.default,
.client,
.clientMute,
.router,
.routerClient,
]
}
@ -465,7 +466,6 @@ extension GpsCoordinateFormat: CaseIterable {
/// Bit field of boolean configuration options, indicating which optional
/// fields to include when assembling POSITION messages
/// Longitude and latitude are always included (also time if GPS-synced)
///
/// NOTE: the more fields are included, the larger the message will be -
/// leading to longer airtime and a higher risk of packet loss
enum PositionFlags: SwiftProtobuf.Enum {
@ -1338,7 +1338,6 @@ struct RadioConfig {
/// Whether to send encrypted or decrypted packets to MQTT.
/// This parameter is only honoured if you also set mqtt_server
/// (the default official mqtt.meshtastic.org server can handle encrypted packets)
///
/// Decrypted packets may be useful for external systems that want to consume meshtastic packets
var mqttEncryptionEnabled: Bool {
get {return _storage._mqttEncryptionEnabled}
@ -1633,8 +1632,10 @@ extension RegionCode: SwiftProtobuf._ProtoNameProviding {
extension Role: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "Default"),
1: .same(proto: "Router"),
0: .same(proto: "Client"),
1: .same(proto: "ClientMute"),
2: .same(proto: "Router"),
3: .same(proto: "RouterClient"),
]
}
@ -1842,7 +1843,7 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes
var _wifiApMode: Bool = false
var _region: RegionCode = .unset
var _chargeCurrent: ChargeCurrent = .maunset
var _role: Role = .default
var _role: Role = .client
var _isLowPower: Bool = false
var _fixedPosition: Bool = false
var _serialDisabled: Bool = false
@ -2161,7 +2162,7 @@ extension RadioConfig.UserPreferences: SwiftProtobuf.Message, SwiftProtobuf._Mes
if _storage._positionBroadcastSmartDisabled != false {
try visitor.visitSingularBoolField(value: _storage._positionBroadcastSmartDisabled, fieldNumber: 17)
}
if _storage._role != .default {
if _storage._role != .client {
try visitor.visitSingularEnumField(value: _storage._role, fieldNumber: 18)
}
if _storage._locationShareDisabled != false {

View file

@ -23,12 +23,9 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
///
/// An example app to show off the module system. This message is used for
/// REMOTE_HARDWARE_APP PortNums.
///
/// Also provides easy remote access to any GPIO.
///
/// In the future other remote hardware operations can be added based on user interest
/// (i.e. serial output, spi/i2c input/output).
///
/// FIXME - currently this feature is turned on by default which is dangerous
/// because no security yet (beyond the channel mechanism).
/// It should be off by default and then protected based on some TBD mechanism

View file

@ -24,7 +24,7 @@ struct Connect: View {
var body: some View {
let firmwareVersion = bleManager.lastConnnectionVersion
let minimumVersion = "1.2.52"
let minimumVersion = "1.3.0"
let supportedVersion = firmwareVersion == "0.0.0" || minimumVersion.compare(firmwareVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(firmwareVersion, options: .numeric) == .orderedSame
NavigationView {