Get share channels loading from real channel data

This commit is contained in:
Garth Vander Houwen 2022-10-09 18:32:21 -07:00
parent 61f862f2c8
commit 4318794c08
8 changed files with 239 additions and 183 deletions

View file

@ -459,7 +459,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
MeshLogger.log(" Requesting Device Metadata for \(connectedPeripheral!.peripheral.name ?? "Unknown")")
var adminPacket = AdminMessage()
adminPacket.getDeviceMetadataRequest = 0
adminPacket.getDeviceMetadataRequest = true
var meshPacket: MeshPacket = MeshPacket()
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
@ -616,6 +616,12 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
}
}
}
// Channels
if decodedInfo.channel.isInitialized {
nowKnown = true
channelPacket(channel: decodedInfo.channel, fromNum: connectedPeripheral.num, meshLogging: meshLoggingEnabled, context: context!)
}
// Config
if decodedInfo.config.isInitialized && !invalidVersion {
@ -743,27 +749,25 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
self.connectedPeripheral.subscribed = true
peripherals.removeAll(where: { $0.peripheral.state == CBPeripheralState.disconnected })
// Config conplete returns so we don't read the characteristic again
// Get all the channels
var i: UInt32 = 1;
let max: Int32 = self.connectedPeripheral.maxChannels
Timer.scheduledTimer(withTimeInterval: 0.4, repeats: true) { timer in
if i == (max + 1) {
timer.invalidate() // invalidate the timer
} else {
if self.connectedPeripheral != nil {
_ = self.getChannel(channelIndex: i, nodeNum: self.connectedPeripheral.num, wantResponse: true)
i+=1;
}
}
}
return
// Get all the channels
// var i: UInt32 = 1;
// let max: Int32 = self.connectedPeripheral.maxChannels
//
// Timer.scheduledTimer(withTimeInterval: 0.4, repeats: true) { timer in
//
// if i == (max + 1) {
// timer.invalidate() // invalidate the timer
// } else {
//
// if self.connectedPeripheral != nil {
//
// _ = self.getChannel(channelIndex: i, nodeNum: self.connectedPeripheral.num, wantResponse: true)
// i+=1;
// }
// }
// }
}
case FROMNUM_UUID :
@ -1447,7 +1451,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
meshPacket.decoded = dataMessage
let messageDescription = "Saved Canned Message Module Messages for \(toUser.longName ?? "Unknown")"
let messageDescription = "💾 Saved Canned Message Module Messages for \(toUser.longName ?? "Unknown")"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
@ -1457,13 +1461,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
return 0
}
public func getChannel(channelIndex: UInt32, nodeNum: Int64, wantResponse: Bool) -> Bool {
public func getChannel(channelIndex: UInt32, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Bool {
var adminPacket = AdminMessage()
adminPacket.getChannelRequest = channelIndex
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(nodeNum)
meshPacket.to = UInt32(toUser.num)
meshPacket.from = 0 //UInt32(cnodeNum)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
@ -1475,19 +1479,12 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
var toRadio: ToRadio!
toRadio = ToRadio()
toRadio.packet = meshPacket
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
if meshLoggingEnabled { MeshLogger.log("🛎️ Send Get Channel \(channelIndex) Request Admin Message for node: \(String(connectedPeripheral.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
return true
let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(String(connectedPeripheral.num))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
return true
}
return false
@ -1521,22 +1518,10 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
do {
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a Canned Messages Module Get Messages Request Admin Message for node: \(String(destNum))") }
if meshLoggingEnabled { MeshLogger.log("✈️ Sent a Canned Messages Module Get Messages Request Admin Message for node: \(String(destNum))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
return true
} catch {
context!.rollback()
let nsError = error as NSError
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
}
}
return false

View file

@ -820,6 +820,78 @@ func myInfoPacket (myInfo: MyNodeInfo, meshLogging: Bool, context: NSManagedObje
return nil
}
func channelPacket (channel: Channel, fromNum: Int64, meshLogging: Bool, context: NSManagedObjectContext) -> NodeInfoEntity? {
print(try! channel.jsonString())
if channel.isInitialized {
let fetchedMyInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
fetchedMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", fromNum)
do {
let fetchedMyInfo = try context.fetch(fetchedMyInfoRequest) as! [MyInfoEntity]
if fetchedMyInfo.count == 1 {
// Update
if fetchedMyInfo[0].channels?.count ?? 0 >= 1 {
let newChannel = ChannelEntity(context: context)
newChannel.index = Int32(channel.index)
newChannel.uplinkEnabled = channel.settings.uplinkEnabled
newChannel.downlinkEnabled = channel.settings.downlinkEnabled
newChannel.name = channel.settings.name
newChannel.role = Int32(channel.role.rawValue)
let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as! NSMutableOrderedSet
mutableChannels.add(newChannel)
fetchedMyInfo[0].channels = mutableChannels.copy() as? NSOrderedSet
} else {
let newChannel = ChannelEntity(context: context)
newChannel.index = Int32(channel.index)
newChannel.uplinkEnabled = channel.settings.uplinkEnabled
newChannel.downlinkEnabled = channel.settings.downlinkEnabled
newChannel.name = channel.settings.name
newChannel.role = Int32(channel.role.rawValue)
var newChannels = [ChannelEntity]()
newChannels.append(newChannel)
fetchedMyInfo[0].channels! = NSOrderedSet(array: newChannels)
}
} else {
print("💥 Trying to save a channel to a MyInfo that does not exist: \(fromNum)")
}
try context.save()
if meshLogging {
MeshLogger.log("💾 Updated MyInfo channel \(channel.settings.channelNum + 1) from Channel App Packet For: \(fetchedMyInfo[0].myNodeNum)")
}
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Saving MyInfo Channel from ADMIN_APP \(nsError)")
}
}
//}
return nil
}
func nodeInfoPacket (nodeInfo: NodeInfo, meshLogging: Bool, context: NSManagedObjectContext) -> NodeInfoEntity? {
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
@ -1012,6 +1084,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, meshLogging: Bool, context: NSManagedOb
return nil
}
func nodeInfoAppPacket (packet: MeshPacket, meshLogging: Bool, context: NSManagedObjectContext) {
let fetchNodeInfoAppRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
@ -1076,71 +1149,7 @@ func nodeInfoAppPacket (packet: MeshPacket, meshLogging: Bool, context: NSManage
func adminAppPacket (packet: MeshPacket, meshLogging: Bool, context: NSManagedObjectContext) {
if let channelMessage = try? Channel(serializedData: packet.decoded.payload) {
if channelMessage.hasSettings {
let fetchedMyInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
fetchedMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(packet.from))
do {
let fetchedMyInfo = try context.fetch(fetchedMyInfoRequest) as! [MyInfoEntity]
if fetchedMyInfo.count == 1 {
// Update
if fetchedMyInfo[0].channels?.count ?? 0 >= 1 {
let newChannel = ChannelEntity(context: context)
newChannel.index = Int32(channelMessage.settings.channelNum)
newChannel.uplinkEnabled = channelMessage.settings.uplinkEnabled
newChannel.downlinkEnabled = channelMessage.settings.downlinkEnabled
newChannel.name = channelMessage.settings.name
newChannel.role = Int32(channelMessage.role.rawValue)
let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as! NSMutableOrderedSet
mutableChannels.add(newChannel)
fetchedMyInfo[0].channels = mutableChannels.copy() as? NSOrderedSet
} else {
let newChannel = ChannelEntity(context: context)
newChannel.index = Int32(channelMessage.settings.channelNum)
newChannel.uplinkEnabled = channelMessage.settings.uplinkEnabled
newChannel.downlinkEnabled = channelMessage.settings.downlinkEnabled
newChannel.name = channelMessage.settings.name
newChannel.role = Int32(channelMessage.role.rawValue)
var newChannels = [ChannelEntity]()
newChannels.append(newChannel)
fetchedMyInfo[0].channels! = NSOrderedSet(array: newChannels)
}
} else {
print("💥 Trying to save a channel to a MyInfo that does not exist: \(packet.from)")
}
try context.save()
if meshLogging {
MeshLogger.log("💾 Updated MyInfo channel \(channelMessage.settings.channelNum + 1) from Channel App Packet For: \(fetchedMyInfo[0].myNodeNum)")
}
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Saving MyInfo Channel from ADMIN_APP \(nsError)")
}
}
} else {
print(try! packet.decoded.jsonString())
}
}

View file

@ -11,8 +11,8 @@ struct MeshtasticAppleApp: App {
@ObservedObject private var bleManager: BLEManager = BLEManager.shared
@ObservedObject private var userSettings: UserSettings = UserSettings()
@State var saveQR = false
@State var channelUrl: URL?
@State var saveChannels = false
@State var incomingUrl: URL?
@Environment(\.scenePhase) var scenePhase
@ -25,32 +25,30 @@ struct MeshtasticAppleApp: App {
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
print("QR Code URL received from the Camera \(userActivity)")
channelUrl = userActivity.webpageURL
if channelUrl!.absoluteString.lowercased().contains("https://meshtastic.org/e/#") {
saveQR = true
print("URL received \(userActivity)")
incomingUrl = userActivity.webpageURL
if incomingUrl!.absoluteString.lowercased().contains("https://meshtastic.org/e/#") {
saveChannels = true
}
if saveChannels {
print("User wants to open Channel Settings URL: \(String(describing: incomingUrl!.relativeString))")
}
print("User wants to open URL: \(String(describing: channelUrl?.relativeString))")
}
.sheet(isPresented: $saveQR) {
SaveChannelQRCode(channelHash: channelUrl?.absoluteString ?? "Empty Channel URL")
.sheet(isPresented: $saveChannels) {
SaveChannelQRCode(channelHash: incomingUrl?.absoluteString ?? "Empty Channel URL")
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
}
.onOpenURL(perform: { (url) in
print("Some sort of URL was received \(url)")
channelUrl = url
incomingUrl = url
if url.absoluteString.lowercased().contains("https://meshtastic.org/e/#") {
saveQR = true
print("User wants to open a Channel Settings URL: \(channelUrl?.absoluteString ?? "No QR Code Link")")
saveChannels = true
print("User wants to open a Channel Settings URL: \(incomingUrl?.absoluteString ?? "No QR Code Link")")
} else {
print("User wants to import a MBTILES offline map file: \(channelUrl?.absoluteString ?? "No Tiles link")")
print("User wants to import a MBTILES offline map file: \(incomingUrl?.absoluteString ?? "No Tiles link")")
}
//we are expecting a .mbtiles map file that contains raster data

View file

@ -114,16 +114,6 @@ struct AdminMessage {
set {payloadVariant = .getModuleConfigResponse(newValue)}
}
///
/// Send all channels in the response to this message
var getAllChannelRequest: Bool {
get {
if case .getAllChannelRequest(let v)? = payloadVariant {return v}
return false
}
set {payloadVariant = .getAllChannelRequest(newValue)}
}
///
/// Get the Canned Message Module messages in the response to this message.
var getCannedMessageModuleMessagesRequest: Bool {
@ -146,10 +136,10 @@ struct AdminMessage {
///
/// Request the node to send device metadata (firmware, protobuf version, etc)
var getDeviceMetadataRequest: UInt32 {
var getDeviceMetadataRequest: Bool {
get {
if case .getDeviceMetadataRequest(let v)? = payloadVariant {return v}
return 0
return false
}
set {payloadVariant = .getDeviceMetadataRequest(newValue)}
}
@ -261,6 +251,17 @@ struct AdminMessage {
set {payloadVariant = .confirmSetRadio(newValue)}
}
///
/// Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
/// Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
var rebootOtaSeconds: Int32 {
get {
if case .rebootOtaSeconds(let v)? = payloadVariant {return v}
return 0
}
set {payloadVariant = .rebootOtaSeconds(newValue)}
}
///
/// This message is only supported for the simulator porduino build.
/// If received the simulator will exit successfully.
@ -343,9 +344,6 @@ struct AdminMessage {
/// Send the current Config in the response to this message.
case getModuleConfigResponse(ModuleConfig)
///
/// Send all channels in the response to this message
case getAllChannelRequest(Bool)
///
/// Get the Canned Message Module messages in the response to this message.
case getCannedMessageModuleMessagesRequest(Bool)
///
@ -353,7 +351,7 @@ struct AdminMessage {
case getCannedMessageModuleMessagesResponse(String)
///
/// Request the node to send device metadata (firmware, protobuf version, etc)
case getDeviceMetadataRequest(UInt32)
case getDeviceMetadataRequest(Bool)
///
/// Device metadata response
case getDeviceMetadataResponse(DeviceMetadata)
@ -392,6 +390,10 @@ struct AdminMessage {
/// TODO: REPLACE
case confirmSetRadio(Bool)
///
/// Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
/// Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
case rebootOtaSeconds(Int32)
///
/// This message is only supported for the simulator porduino build.
/// If received the simulator will exit successfully.
case exitSimulator(Bool)
@ -446,10 +448,6 @@ struct AdminMessage {
guard case .getModuleConfigResponse(let l) = lhs, case .getModuleConfigResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getAllChannelRequest, .getAllChannelRequest): return {
guard case .getAllChannelRequest(let l) = lhs, case .getAllChannelRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getCannedMessageModuleMessagesRequest, .getCannedMessageModuleMessagesRequest): return {
guard case .getCannedMessageModuleMessagesRequest(let l) = lhs, case .getCannedMessageModuleMessagesRequest(let r) = rhs else { preconditionFailure() }
return l == r
@ -502,6 +500,10 @@ struct AdminMessage {
guard case .confirmSetRadio(let l) = lhs, case .confirmSetRadio(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.rebootOtaSeconds, .rebootOtaSeconds): return {
guard case .rebootOtaSeconds(let l) = lhs, case .rebootOtaSeconds(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.exitSimulator, .exitSimulator): return {
guard case .exitSimulator(let l) = lhs, case .exitSimulator(let r) = rhs else { preconditionFailure() }
return l == r
@ -713,7 +715,6 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
6: .standard(proto: "get_config_response"),
7: .standard(proto: "get_module_config_request"),
8: .standard(proto: "get_module_config_response"),
9: .standard(proto: "get_all_channel_request"),
10: .standard(proto: "get_canned_message_module_messages_request"),
11: .standard(proto: "get_canned_message_module_messages_response"),
12: .standard(proto: "get_device_metadata_request"),
@ -727,6 +728,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
65: .standard(proto: "confirm_set_module_config"),
66: .standard(proto: "confirm_set_channel"),
67: .standard(proto: "confirm_set_radio"),
95: .standard(proto: "reboot_ota_seconds"),
96: .standard(proto: "exit_simulator"),
97: .standard(proto: "reboot_seconds"),
98: .standard(proto: "shutdown_seconds"),
@ -824,14 +826,6 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
self.payloadVariant = .getModuleConfigResponse(v)
}
}()
case 9: try {
var v: Bool?
try decoder.decodeSingularBoolField(value: &v)
if let v = v {
if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
self.payloadVariant = .getAllChannelRequest(v)
}
}()
case 10: try {
var v: Bool?
try decoder.decodeSingularBoolField(value: &v)
@ -849,8 +843,8 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
}
}()
case 12: try {
var v: UInt32?
try decoder.decodeSingularUInt32Field(value: &v)
var v: Bool?
try decoder.decodeSingularBoolField(value: &v)
if let v = v {
if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
self.payloadVariant = .getDeviceMetadataRequest(v)
@ -961,6 +955,14 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
self.payloadVariant = .confirmSetRadio(v)
}
}()
case 95: try {
var v: Int32?
try decoder.decodeSingularInt32Field(value: &v)
if let v = v {
if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
self.payloadVariant = .rebootOtaSeconds(v)
}
}()
case 96: try {
var v: Bool?
try decoder.decodeSingularBoolField(value: &v)
@ -1044,10 +1046,6 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
guard case .getModuleConfigResponse(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
}()
case .getAllChannelRequest?: try {
guard case .getAllChannelRequest(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularBoolField(value: v, fieldNumber: 9)
}()
case .getCannedMessageModuleMessagesRequest?: try {
guard case .getCannedMessageModuleMessagesRequest(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularBoolField(value: v, fieldNumber: 10)
@ -1058,7 +1056,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
}()
case .getDeviceMetadataRequest?: try {
guard case .getDeviceMetadataRequest(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 12)
try visitor.visitSingularBoolField(value: v, fieldNumber: 12)
}()
case .getDeviceMetadataResponse?: try {
guard case .getDeviceMetadataResponse(let v)? = self.payloadVariant else { preconditionFailure() }
@ -1100,6 +1098,10 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
guard case .confirmSetRadio(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularBoolField(value: v, fieldNumber: 67)
}()
case .rebootOtaSeconds?: try {
guard case .rebootOtaSeconds(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularInt32Field(value: v, fieldNumber: 95)
}()
case .exitSimulator?: try {
guard case .exitSimulator(let v)? = self.payloadVariant else { preconditionFailure() }
try visitor.visitSingularBoolField(value: v, fieldNumber: 96)

View file

@ -675,7 +675,7 @@ struct Config {
///
/// The denominator of the coding rate.
/// ie for 4/8, the value is 8. 5/8 the value is 5.
/// ie for 4/5, the value is 5. 4/8 the value is 8.
var codingRate: UInt32 = 0
///

View file

@ -1850,6 +1850,16 @@ struct FromRadio {
set {_uniqueStorage()._payloadVariant = .moduleConfig(newValue)}
}
///
/// One packet is sent for each channel
var channel: Channel {
get {
if case .channel(let v)? = _storage._payloadVariant {return v}
return Channel()
}
set {_uniqueStorage()._payloadVariant = .channel(newValue)}
}
var unknownFields = SwiftProtobuf.UnknownStorage()
///
@ -1887,6 +1897,9 @@ struct FromRadio {
///
/// Include module config
case moduleConfig(ModuleConfig)
///
/// One packet is sent for each channel
case channel(Channel)
#if !swift(>=4.1)
static func ==(lhs: FromRadio.OneOf_PayloadVariant, rhs: FromRadio.OneOf_PayloadVariant) -> Bool {
@ -1926,6 +1939,10 @@ struct FromRadio {
guard case .moduleConfig(let l) = lhs, case .moduleConfig(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.channel, .channel): return {
guard case .channel(let l) = lhs, case .channel(let r) = rhs else { preconditionFailure() }
return l == r
}()
default: return false
}
}
@ -3244,6 +3261,7 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
7: .standard(proto: "config_complete_id"),
8: .same(proto: "rebooted"),
9: .same(proto: "moduleConfig"),
10: .same(proto: "channel"),
]
fileprivate class _StorageClass {
@ -3370,6 +3388,19 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
_storage._payloadVariant = .moduleConfig(v)
}
}()
case 10: try {
var v: Channel?
var hadOneofValue = false
if let current = _storage._payloadVariant {
hadOneofValue = true
if case .channel(let m) = current {v = m}
}
try decoder.decodeSingularMessageField(value: &v)
if let v = v {
if hadOneofValue {try decoder.handleConflictingOneOf()}
_storage._payloadVariant = .channel(v)
}
}()
default: break
}
}
@ -3418,6 +3449,10 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
guard case .moduleConfig(let v)? = _storage._payloadVariant else { preconditionFailure() }
try visitor.visitSingularMessageField(value: v, fieldNumber: 9)
}()
case .channel?: try {
guard case .channel(let v)? = _storage._payloadVariant else { preconditionFailure() }
try visitor.visitSingularMessageField(value: v, fieldNumber: 10)
}()
case nil: break
}
}

View file

@ -60,6 +60,14 @@ enum TelemetrySensorType: SwiftProtobuf.Enum {
///
/// High accuracy pressure
case lps22 // = 8
///
/// 3-Axis magnetic sensor
case qmc6310 // = 9
///
/// 6-Axis inertial measurement sensor
case qmi8658 // = 10
case UNRECOGNIZED(Int)
init() {
@ -77,6 +85,8 @@ enum TelemetrySensorType: SwiftProtobuf.Enum {
case 6: self = .bmp280
case 7: self = .shtc3
case 8: self = .lps22
case 9: self = .qmc6310
case 10: self = .qmi8658
default: self = .UNRECOGNIZED(rawValue)
}
}
@ -92,6 +102,8 @@ enum TelemetrySensorType: SwiftProtobuf.Enum {
case .bmp280: return 6
case .shtc3: return 7
case .lps22: return 8
case .qmc6310: return 9
case .qmi8658: return 10
case .UNRECOGNIZED(let i): return i
}
}
@ -112,6 +124,8 @@ extension TelemetrySensorType: CaseIterable {
.bmp280,
.shtc3,
.lps22,
.qmc6310,
.qmi8658,
]
}
@ -272,6 +286,8 @@ extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding {
6: .same(proto: "BMP280"),
7: .same(proto: "SHTC3"),
8: .same(proto: "LPS22"),
9: .same(proto: "QMC6310"),
10: .same(proto: "QMI8658"),
]
}

View file

@ -34,15 +34,17 @@ struct ShareChannels: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var userSettings: UserSettings
@State var initialLoad: Bool = true
@State var channels: [ChannelEntity] = [ChannelEntity]()
@State var includeChannel0 = true
@State var includeChannel1 = true
@State var includeChannel2 = true
@State var includeChannel1 = false
@State var includeChannel2 = false
@State var includeChannel3 = false
@State var includeChannel4 = false
@State var includeChannel5 = false
@State var includeChannel6 = false
@State var includeChannel7 = true
@State var includeChannel7 = false
var node: NodeInfoEntity?
@ -76,56 +78,60 @@ struct ShareChannels: View {
}
Divider()
ForEach(node!.myInfo!.channels?.array.sorted(by: { ($0 as! ChannelEntity).index < ($1 as! ChannelEntity).index }) as! [ChannelEntity], id: \.self) { (channel: ChannelEntity) in
ForEach(node!.myInfo!.channels?.array as! [ChannelEntity], id: \.self) { (channel: ChannelEntity) in
GridRow {
Spacer()
if channel.index == 0 {
Toggle("Channel 0 Included", isOn: $includeChannel0)
.toggleStyle(.switch)
.labelsHidden()
.disabled(true)
Text("Primary Channel")
Text((channel.name!.isEmpty ? "Primary Channel" : channel.name) ?? "Primary Channel")
} else if channel.index == 1 {
Toggle("Channel 1 Included", isOn: $includeChannel1)
.toggleStyle(.switch)
.labelsHidden()
Text("Public Channel")
.disabled(channel.role == 0)
Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)")
} else if channel.index == 2 {
Toggle("Channel 2 Included", isOn: $includeChannel2)
.toggleStyle(.switch)
.labelsHidden()
.disabled(channel.role == 0)
Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)")
} else if channel.index == 3 {
Toggle("Channel 3 Included", isOn: $includeChannel3)
.toggleStyle(.switch)
.labelsHidden()
.disabled(channel.role == 0)
Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)")
} else if channel.index == 4 {
Toggle("Channel 4 Included", isOn: $includeChannel4)
.toggleStyle(.switch)
.labelsHidden()
.disabled(true)
.disabled(channel.role == 0)
Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)")
} else if channel.index == 5 {
Toggle("Channel 5 Included", isOn: $includeChannel5)
.toggleStyle(.switch)
.labelsHidden()
.disabled(true)
.disabled(channel.role == 0)
Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)")
} else if channel.index == 6 {
Toggle("Channel 6 Included", isOn: $includeChannel6)
.toggleStyle(.switch)
.labelsHidden()
.disabled(true)
.disabled(channel.role == 0)
Text((channel.name!.isEmpty ? "Channel \(channel.index)" : channel.name) ?? "Channel \(channel.index)")
} else if channel.index == 7 {
Toggle("Channel 7 Included", isOn: $includeChannel7)
.toggleStyle(.switch)
.labelsHidden()
Text("Admin Channel")
}
if channel.index > 1 && channel.index < 4{
Text("Private Chat - \(channel.index)")
}
if channel.index > 3 && channel.index < 7{
Text("Channel - \(channel.index)")
.disabled(channel.role == 0)
Text((channel.name!.isEmpty ? "Admin Channel" : channel.name) ?? "Admin Channel")
}
Spacer()
}
@ -171,7 +177,12 @@ struct ShareChannels: View {
})
.onAppear {
self.bleManager.context = context
if self.initialLoad{
self.bleManager.context = context
self.initialLoad = false
}
}
}
.navigationViewStyle(StackNavigationViewStyle())