mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Get share channels loading from real channel data
This commit is contained in:
parent
61f862f2c8
commit
4318794c08
8 changed files with 239 additions and 183 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue