diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index a6ef687e..c25dffe7 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -27,6 +27,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { @Published var invalidVersion = false @Published var preferredPeripheral = false @Published var isSwitchedOn: Bool = false + @Published var automaticallyReconnect: Bool = true public var minimumVersion = "1.3.48" public var connectedVersion: String @@ -123,6 +124,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { DispatchQueue.main.async { self.isConnecting = true self.lastConnectionError = "" + self.automaticallyReconnect = true } if connectedPeripheral != nil { print("ℹ️ BLE Disconnecting from: \(connectedPeripheral.name) to connect to \(peripheral.name ?? "Unknown")") @@ -142,9 +144,10 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { } // Disconnect Connected Peripheral - func disconnectPeripheral() { + func disconnectPeripheral(reconnect: Bool = true) { guard let connectedPeripheral = connectedPeripheral else { return } + automaticallyReconnect = reconnect centralManager?.cancelPeripheralConnection(connectedPeripheral.peripheral) FROMRADIO_characteristic = nil isConnected = false @@ -393,7 +396,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { comment: "Please try connecting again and check the PIN carefully."), e.localizedDescription) print("🚨 \(e.localizedDescription) Please try connecting again and check the PIN carefully.") - self.centralManager?.cancelPeripheralConnection(peripheral) + self.disconnectPeripheral(reconnect: false) } } @@ -566,11 +569,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { do { let fetchedUser = try context?.fetch(fetchBCUserRequest) as! [UserEntity] if fetchedUser.count > 0 { - context?.delete(fetchedUser[0]) print("🗑️ Deleted the All - Broadcast User") } - } catch { print("💥 Error Deleting the All - Broadcast User") } @@ -942,6 +943,32 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { return success } + public func getChannel(channel: Channel, fromUser: UserEntity, toUser: UserEntity) -> Int64 { + + var adminPacket = AdminMessage() + adminPacket.getChannelRequest = UInt32(channel.index + 1) + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(toUser.num) + meshPacket.from = 0 //UInt32(fromUser.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Int64 { var adminPacket = AdminMessage() @@ -956,13 +983,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject { var dataMessage = DataMessage() dataMessage.payload = try! adminPacket.serializedData() dataMessage.portnum = PortNum.adminApp - + dataMessage.wantResponse = true meshPacket.decoded = dataMessage let messageDescription = "Saved Channel \(channel.index) for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) { - return Int64(meshPacket.id) } @@ -1567,7 +1593,7 @@ extension BLEManager: CBCentralManagerDelegate { // Called each time a peripheral is discovered func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { - if timeoutTimerRuns < 2 && peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" { + if self.automaticallyReconnect && timeoutTimerRuns < 2 && peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" { self.connectTo(peripheral: peripheral) print("ℹ️ BLE Reconnecting to prefered peripheral: \(peripheral.name ?? "Unknown")") } diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index ec5fcca6..fb21e3fc 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -985,34 +985,37 @@ func nodeInfoAppPacket (packet: MeshPacket, context: NSManagedObjectContext) { } func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) { - - let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.cannedmessages.messages.received %@", comment: "Canned Messages Messages Received For: %@"), String(packet.from)) - MeshLogger.log("🥫 \(logString)") - + if let cmmc = try? CannedMessageModuleConfig(serializedData: packet.decoded.payload) { - - let fetchNodeRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") - fetchNodeRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from)) - - do { - let fetchedNode = try context.fetch(fetchNodeRequest) as! [NodeInfoEntity] - if fetchedNode.count == 1 { - let messages = String(cmmc.textFormatString()) - .replacingOccurrences(of: "11: ", with: "") - .replacingOccurrences(of: "\"", with: "") - .trimmingCharacters(in: .whitespacesAndNewlines) - fetchedNode[0].cannedMessageConfig?.messages = messages - do { - try context.save() - print("💾 Updated Canned Messages Messages For: \(fetchedNode[0].num)") - } catch { - context.rollback() - let nsError = error as NSError - print("💥 Error Saving NodeInfoEntity from POSITION_APP \(nsError)") + + if !cmmc.messages.isEmpty { + + let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.cannedmessages.messages.received %@", comment: "Canned Messages Messages Received For: %@"), String(packet.from)) + MeshLogger.log("🥫 \(logString)") + + let fetchNodeRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") + fetchNodeRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from)) + + do { + let fetchedNode = try context.fetch(fetchNodeRequest) as! [NodeInfoEntity] + if fetchedNode.count == 1 { + let messages = String(cmmc.textFormatString()) + .replacingOccurrences(of: "11: ", with: "") + .replacingOccurrences(of: "\"", with: "") + .trimmingCharacters(in: .whitespacesAndNewlines) + fetchedNode[0].cannedMessageConfig?.messages = messages + do { + try context.save() + print("💾 Updated Canned Messages Messages For: \(fetchedNode[0].num)") + } catch { + context.rollback() + let nsError = error as NSError + print("💥 Error Saving NodeInfoEntity from POSITION_APP \(nsError)") + } } + } catch { + print("💥 Error Deserializing POSITION_APP packet.") } - } catch { - print("💥 Error Deserializing POSITION_APP packet.") } } } diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 7094441d..817c19d5 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -88,7 +88,7 @@ struct Connect: View { Button(role: .destructive) { if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == CBPeripheralState.connected { - bleManager.disconnectPeripheral() + bleManager.disconnectPeripheral(reconnect: false) isPreferredRadio = false } } label: { @@ -287,6 +287,6 @@ struct Connect: View { }) } func didDismissSheet() { - bleManager.disconnectPeripheral() + bleManager.disconnectPeripheral(reconnect: false) } } diff --git a/Meshtastic/Views/Settings/Channels.swift b/Meshtastic/Views/Settings/Channels.swift index 4a6bb4a5..7d115fc6 100644 --- a/Meshtastic/Views/Settings/Channels.swift +++ b/Meshtastic/Views/Settings/Channels.swift @@ -240,22 +240,25 @@ struct Channels: View { var channel = Channel() channel.index = channelIndex - channel.settings.id = UInt32(channelIndex) - channel.settings.name = channelName - channel.settings.psk = Data(base64Encoded: channelKey) ?? Data() channel.role = ChannelRoles(rawValue: channelRole)?.protoEnumValue() ?? .secondary - channel.settings.uplinkEnabled = uplink - channel.settings.downlinkEnabled = downlink + if channel.role != Channel.Role.disabled { + channel.settings.id = UInt32(channelIndex) + channel.settings.name = channelName + channel.settings.psk = Data(base64Encoded: channelKey) ?? Data() + channel.settings.uplinkEnabled = uplink + channel.settings.downlinkEnabled = downlink + } let adminMessageId = bleManager.saveChannel(channel: channel, fromUser: node!.user!, toUser: node!.user!) if adminMessageId > 0 { // Should show a saved successfully alert once I know that to be true - // for now just disable the button after a successful save + // for now just disable the button after a successful save. + // Would rather send a getChannel but I can't seem to tell what admin message it is + bleManager.sendWantConfig() channelName = "" hasChanges = false isPresentingEditView = false - bleManager.disconnectPeripheral() } } } diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 01d51a62..c7966528 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -74,7 +74,7 @@ struct CannedMessagesConfig: View { HStack { Label("Messages", systemImage: "message.fill") - TextField("Messages seperate with |", text: $messages) + TextField("Messages seperate with |", text: $messages, axis: .vertical) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) @@ -256,7 +256,7 @@ struct CannedMessagesConfig: View { // for now just disable the button after a successful save hasMessagesChanges = false if !hasChanges { - bleManager.sendReboot(fromUser: node!.user!, toUser: node!.user!) + bleManager.sendWantConfig() goBack() } }