From 8da5e9f9d01a67f4b582b63b87af4d47246bb503 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 12 Oct 2022 22:15:15 -0700 Subject: [PATCH 1/4] Assorted cleanup --- Meshtastic/Helpers/BLEManager.swift | 98 +++---------------- Meshtastic/Helpers/MeshPackets.swift | 9 +- Meshtastic/MeshtasticApp.swift | 2 +- .../Views/Settings/SaveChannelQRCode.swift | 30 ++---- 4 files changed, 24 insertions(+), 115 deletions(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 1fa33d52..d1501259 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -235,7 +235,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph self.isConnecting = false self.isConnected = true - if userSettings?.preferredPeripheralId.count ?? 0 < 1 { self.userSettings?.preferredPeripheralId = peripheral.identifier.uuidString self.preferredPeripheral = true @@ -244,41 +243,32 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } else { print("Trying to connect a non prefered peripheral") } - // Invalidate and reset connection timer count, remove any connection errors self.lastConnectionError = "" self.timeoutTimerCount = 0 if self.timeoutTimer != nil { - self.timeoutTimer!.invalidate() } - // Map the peripheral to the connectedPeripheral ObservedObjects connectedPeripheral = peripherals.filter({ $0.peripheral.identifier == peripheral.identifier }).first - if connectedPeripheral != nil { - connectedPeripheral.peripheral.delegate = self } else { - // we are null just disconnect and start over self.lastConnectionError = "Bluetooth connection error, please try again." self.disconnectPeripheral() return } - // Discover Services peripheral.discoverServices([meshtasticServiceCBUUID, DFUSERVICE_UUID]) - if meshLoggingEnabled { MeshLogger.log("✅ BLE Connected: \(peripheral.name ?? "Unknown")") } - + MeshLogger.log("✅ BLE Connected: \(peripheral.name ?? "Unknown")") } // Called when a Peripheral fails to connect func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { - - if meshLoggingEnabled { MeshLogger.log("đŸšĢ BLE Failed to Connect: \(peripheral.name ?? "Unknown")") } disconnectPeripheral() + MeshLogger.log("đŸšĢ BLE Failed to Connect: \(peripheral.name ?? "Unknown")") } // Disconnect Peripheral Event @@ -287,83 +277,53 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph self.startScanning() self.connectedPeripheral = nil self.isConnecting = false - if let e = error { - // https://developer.apple.com/documentation/corebluetooth/cberror/code let errorCode = (e as NSError).code - // unknown = 0, - if errorCode == 6 { // CBError.Code.connectionTimeout The connection has timed out unexpectedly. - // Happens when device is manually reset / powered off // We will try and re-connect to this device lastConnectionError = "🚨 \(e.localizedDescription) The app will automatically reconnect to the preferred radio if it reappears within one minute." if peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" { - if meshLoggingEnabled { MeshLogger.log("â„šī¸ BLE Reconnecting: \(peripheral.name ?? "Unknown")") } self.connectTo(peripheral: peripheral) + MeshLogger.log("â„šī¸ BLE Reconnecting: \(peripheral.name ?? "Unknown")") } - } else if errorCode == 7 { // CBError.Code.peripheralDisconnected The specified device has disconnected from us. - // Seems to be what is received when a tbeam sleeps, immediately recconnecting does not work. lastConnectionError = e.localizedDescription - - if meshLoggingEnabled { MeshLogger.log("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)") } + MeshLogger.log("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)") } else if errorCode == 14 { // Peer removed pairing information - // Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that lastConnectionError = "🚨 \(e.localizedDescription) This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re-connecting to the radio." - - if meshLoggingEnabled { MeshLogger.log("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(lastConnectionError)") } - + MeshLogger.log("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(lastConnectionError)") } else { - lastConnectionError = e.localizedDescription - - if meshLoggingEnabled { MeshLogger.log("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)") } + MeshLogger.log("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)") } } else { - // Disconnected without error which indicates user intent to disconnect // Happens when swiping to disconnect - if meshLoggingEnabled { MeshLogger.log("â„šī¸ BLE Disconnected: \(peripheral.name ?? "Unknown"): User Initiated Disconnect") } + MeshLogger.log("â„šī¸ BLE Disconnected: \(peripheral.name ?? "Unknown"): User Initiated Disconnect") } } // MARK: Peripheral Services functions func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { - if let e = error { - print("đŸšĢ Discover Services error \(e)") } - guard let services = peripheral.services else { return } - for service in services { - if service.uuid == meshtasticServiceCBUUID { - - if meshLoggingEnabled { MeshLogger.log("✅ BLE Service for Meshtastic discovered by \(peripheral.name ?? "Unknown")") } - //peripheral.discoverCharacteristics(nil, for: service) peripheral.discoverCharacteristics([TORADIO_UUID, FROMRADIO_UUID, FROMNUM_UUID], for: service) - + MeshLogger.log("✅ BLE Service for Meshtastic discovered by \(peripheral.name ?? "Unknown")") } else if (service.uuid == DFUSERVICE_UUID) { - - print("✅ Meshtastic DFU service discovered OK") - if meshLoggingEnabled { MeshLogger.log("✅ BLE Service for Meshtastic DFU discovered by \(peripheral.name ?? "Unknown")") } - peripheral.discoverCharacteristics([DFUDATA_UUID, DFUSIZE_UUID, DFUREGION_UUID, DFURESULT_UUID, DFUCRC32_UUID], for: service) - + peripheral.discoverCharacteristics([DFUDATA_UUID, DFUSIZE_UUID, DFUREGION_UUID, DFURESULT_UUID, DFUCRC32_UUID], for: service) + MeshLogger.log("✅ BLE Service for Meshtastic DFU discovered by \(peripheral.name ?? "Unknown")") } } } - - func peripheral(_ peripheral: CBPeripheral, didModifyServices invalidatedServices: [CBService]) { - - print(invalidatedServices) - } // MARK: Discover Characteristics Event func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { @@ -658,19 +618,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph case .adminApp: adminAppPacket(packet: decodedInfo.packet, meshLogging: meshLoggingEnabled, context: context!) case .replyApp: - if meshLoggingEnabled { MeshLogger.log("â„šī¸ MESH PACKET received for Reply App UNHANDLED \(try! decodedInfo.packet.jsonString())") } + MeshLogger.log("â„šī¸ MESH PACKET received for Reply App UNHANDLED \(try! decodedInfo.packet.jsonString())") case .ipTunnelApp: - if meshLoggingEnabled { MeshLogger.log("â„šī¸ MESH PACKET received for IP Tunnel App UNHANDLED \(try! decodedInfo.packet.jsonString())") } + MeshLogger.log("â„šī¸ MESH PACKET received for IP Tunnel App UNHANDLED \(try! decodedInfo.packet.jsonString())") case .serialApp: - if meshLoggingEnabled { MeshLogger.log("â„šī¸ MESH PACKET received for Serial App UNHANDLED \(try! decodedInfo.packet.jsonString())") } + MeshLogger.log("â„šī¸ MESH PACKET received for Serial App UNHANDLED \(try! decodedInfo.packet.jsonString())") case .storeForwardApp: - if meshLoggingEnabled { MeshLogger.log("â„šī¸ MESH PACKET received for Store Forward App UNHANDLED \(try! decodedInfo.packet.jsonString())") } + MeshLogger.log("â„šī¸ MESH PACKET received for Store Forward App UNHANDLED \(try! decodedInfo.packet.jsonString())") case .rangeTestApp: if meshLoggingEnabled { MeshLogger.log("â„šī¸ MESH PACKET received for Range Test App UNHANDLED \(try! decodedInfo.packet.jsonString())") } case .telemetryApp: if !invalidVersion { - + telemetryPacket(packet: decodedInfo.packet, meshLogging: meshLoggingEnabled, context: context!) } case .textMessageCompressedApp: @@ -687,7 +647,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if meshLoggingEnabled { MeshLogger.log("â„šī¸ MESH PACKET received for Other App UNHANDLED \(try! decodedInfo.packet.jsonString())") } case .max: print("MAX PORT NUM OF 511") - } // MARK: Check for an All / Broadcast User @@ -696,7 +655,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph do { let fetchedUser = try context?.fetch(fetchBCUserRequest) as! [UserEntity] - if fetchedUser.isEmpty { // Save the broadcast user if it does not exist let bcu: UserEntity = UserEntity(context: context!) @@ -709,7 +667,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } } catch { - print("đŸ’Ĩ Error Saving the All - Broadcast User") } @@ -717,7 +674,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph // Use context to pass the radio name with the timer // Use a RunLoop to prevent the timer from running on the main UI thread if userSettings?.provideLocation ?? false { - if self.positionTimer != nil { self.positionTimer!.invalidate() @@ -728,40 +684,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } if decodedInfo.configCompleteID != 0 && decodedInfo.configCompleteID == configNonce { - invalidVersion = false lastConnectionError = "" - if meshLoggingEnabled { MeshLogger.log("🤜 BLE Config Complete Packet Id: \(decodedInfo.configCompleteID)") } self.connectedPeripheral.subscribed = true peripherals.removeAll(where: { $0.peripheral.state == CBPeripheralState.disconnected }) // Config conplete returns so we don't read the characteristic again 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 : - - print("đŸ—žī¸ BLE FROMNUM (Notify) characteristic, value will be read next") - + print("đŸ—žī¸ BLE (Notify) characteristic, value will be read next") default: - print("🚨 Unhandled Characteristic UUID: \(characteristic.uuid)") } diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index fac17e9d..bf65b3ec 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -818,7 +818,7 @@ func myInfoPacket (myInfo: MyNodeInfo, meshLogging: Bool, context: NSManagedObje return nil } -func channelPacket (channel: Channel, fromNum: Int64, meshLogging: Bool, context: NSManagedObjectContext) -> NodeInfoEntity? { +func channelPacket (channel: Channel, fromNum: Int64, meshLogging: Bool, context: NSManagedObjectContext) { if channel.isInitialized && channel.hasSettings { @@ -864,13 +864,6 @@ func channelPacket (channel: Channel, fromNum: Int64, meshLogging: Bool, context print("đŸ’Ĩ Error Saving MyInfo Channel from ADMIN_APP \(nsError)") } } - //} - - - - - return nil - } func nodeInfoPacket (nodeInfo: NodeInfo, meshLogging: Bool, context: NSManagedObjectContext) -> NodeInfoEntity? { diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index 96d1f899..a15663e4 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -25,7 +25,7 @@ struct MeshtasticAppleApp: App { .environmentObject(userSettings) .sheet(isPresented: $saveChannels) { - SaveChannelQRCode(channelHash: channelSettings ?? "Empty Channel URL", validUrl: true) + SaveChannelQRCode(channelHash: channelSettings ?? "Empty Channel URL") .presentationDetents([.medium, .large]) .presentationDragIndicator(.visible) } diff --git a/Meshtastic/Views/Settings/SaveChannelQRCode.swift b/Meshtastic/Views/Settings/SaveChannelQRCode.swift index feacdb70..b3ecffc7 100644 --- a/Meshtastic/Views/Settings/SaveChannelQRCode.swift +++ b/Meshtastic/Views/Settings/SaveChannelQRCode.swift @@ -12,34 +12,16 @@ struct SaveChannelQRCode: View { var body: some View { VStack { - if validUrl { - Text("Save Channel Settings?") - .font(.title) - Text("These settings will replace the current settings on your radio.") - .foregroundColor(.gray) - .font(.callout) - .padding() - - Text(channelHash) - .font(.caption2) - .padding() - - } else { - Text("Invalid Channel Settings Url") - .font(.title) - - Text("Error Message") - .font(.callout) - .foregroundColor(.red) - .padding() - } + Text("Save Channel Settings?") + .font(.title) + Text("These settings will replace the current LoRa Config and Channel Settings on your radio.") + .foregroundColor(.gray) + .font(.callout) + .padding() } .onChange(of: channelHash) { newSettings in - var decodedString = newSettings.base64urlToBase64() - if let decodedData = Data(base64Encoded: decodedString) { - decodedString = String(data: decodedData, encoding: .utf8)! do { var channelSet: ChannelSet = try ChannelSet(serializedData: decodedData) print(channelSet) From 8aa94f5e0fbbc27fa40525f3687ee95674cb43c5 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 12 Oct 2022 22:15:51 -0700 Subject: [PATCH 2/4] Remove valid url bool --- Meshtastic/Views/Settings/SaveChannelQRCode.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Meshtastic/Views/Settings/SaveChannelQRCode.swift b/Meshtastic/Views/Settings/SaveChannelQRCode.swift index b3ecffc7..82b38bd6 100644 --- a/Meshtastic/Views/Settings/SaveChannelQRCode.swift +++ b/Meshtastic/Views/Settings/SaveChannelQRCode.swift @@ -8,7 +8,6 @@ import SwiftUI struct SaveChannelQRCode: View { var channelHash: String - var validUrl: Bool var body: some View { VStack { From acd7d4e2790e44f6a4ca822aa1d49abeb3c14921 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 13 Oct 2022 07:45:23 -0700 Subject: [PATCH 3/4] Bump version --- Meshtastic.xcodeproj/project.pbxproj | 4 +- .../Enums/CannedMessagesConfigEnums.swift | 55 +++++++++---------- .../Config/Module/CannedMessagesConfig.swift | 20 +++---- .../Views/Settings/SaveChannelQRCode.swift | 17 +++++- 4 files changed, 54 insertions(+), 42 deletions(-) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 298891c0..93583250 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -964,7 +964,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.3.43; + MARKETING_VERSION = 1.3.44; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -996,7 +996,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.3.43; + MARKETING_VERSION = 1.3.44; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; diff --git a/Meshtastic/Enums/CannedMessagesConfigEnums.swift b/Meshtastic/Enums/CannedMessagesConfigEnums.swift index a3268956..0864e5d4 100644 --- a/Meshtastic/Enums/CannedMessagesConfigEnums.swift +++ b/Meshtastic/Enums/CannedMessagesConfigEnums.swift @@ -10,9 +10,8 @@ enum ConfigPresets : Int, CaseIterable, Identifiable { case unset = 0 case rakRotaryEncoder = 1 - case tbeamThreeButtonScreen = 2 - case cardKB = 3 - case facesKB = 4 + case cardKB = 2 + case facesKB = 3 var id: Int { self.rawValue } var description: String { @@ -23,8 +22,6 @@ enum ConfigPresets : Int, CaseIterable, Identifiable { return "Manual Configuration" case .rakRotaryEncoder: return "RAK Rotary Encoder Module" - case .tbeamThreeButtonScreen: - return "TBEAM 3 Button OLED Screen" case .cardKB: return "M5 Stack Card KeyBoard" case .facesKB: @@ -37,35 +34,35 @@ enum ConfigPresets : Int, CaseIterable, Identifiable { // Default of 0 is off enum InputEventChars: Int, CaseIterable, Identifiable { - case keyNone = 0 - case keyUp = 17 - case keyDown = 18 - case keyLeft = 19 - case keyRight = 20 - case keySelect = 10 - case keyBack = 27 - case keyCancel = 24 + case none = 0 + case up = 17 + case down = 18 + case left = 19 + case right = 20 + case select = 10 + case back = 27 + case cancel = 24 var id: Int { self.rawValue } var description: String { get { switch self { - case .keyNone: + case .none: return "None" - case .keyUp: + case .up: return "Up" - case .keyDown: + case .down: return "Down" - case .keyLeft: + case .left: return "Left" - case .keyRight: + case .right: return "Right" - case .keySelect: + case .select: return "Select" - case .keyBack: + case .back: return "Back" - case .keyCancel: + case .cancel: return "Cancel" } } @@ -74,21 +71,21 @@ enum InputEventChars: Int, CaseIterable, Identifiable { switch self { - case .keyNone: + case .none: return ModuleConfig.CannedMessageConfig.InputEventChar.none - case .keyUp: + case .up: return ModuleConfig.CannedMessageConfig.InputEventChar.up - case .keyDown: + case .down: return ModuleConfig.CannedMessageConfig.InputEventChar.down - case .keyLeft: + case .left: return ModuleConfig.CannedMessageConfig.InputEventChar.left - case .keyRight: + case .right: return ModuleConfig.CannedMessageConfig.InputEventChar.right - case .keySelect: + case .select: return ModuleConfig.CannedMessageConfig.InputEventChar.select - case .keyBack: + case .back: return ModuleConfig.CannedMessageConfig.InputEventChar.back - case .keyCancel: + case .cancel: return ModuleConfig.CannedMessageConfig.InputEventChar.cancel } } diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index ea8560dc..9f7efe1d 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -244,7 +244,7 @@ struct CannedMessagesConfig: View { } else if updown1Enabled { - cmc.allowInputSource = "upDownEnc1" + cmc.allowInputSource = "_any" } else { @@ -313,12 +313,12 @@ struct CannedMessagesConfig: View { // RAK Rotary Encoder updown1Enabled = false rotary1Enabled = false - inputbrokerPinA = 32 - inputbrokerPinB = 38 - inputbrokerPinPress = 37 - inputbrokerEventCw = InputEventChars.keyUp.rawValue - inputbrokerEventCcw = InputEventChars.keyDown.rawValue - inputbrokerEventPress = InputEventChars.keySelect.rawValue + inputbrokerPinA = 4 + inputbrokerPinB = 10 + inputbrokerPinPress = 9 + inputbrokerEventCw = InputEventChars.down.rawValue + inputbrokerEventCcw = InputEventChars.up.rawValue + inputbrokerEventPress = InputEventChars.select.rawValue } else if newPreset == 2 { @@ -328,9 +328,9 @@ struct CannedMessagesConfig: View { inputbrokerPinA = 25 inputbrokerPinB = 39 inputbrokerPinPress = 36 - inputbrokerEventCw = InputEventChars.keyUp.rawValue - inputbrokerEventCcw = InputEventChars.keyDown.rawValue - inputbrokerEventPress = InputEventChars.keySelect.rawValue + inputbrokerEventCw = InputEventChars.up.rawValue + inputbrokerEventCcw = InputEventChars.down.rawValue + inputbrokerEventPress = InputEventChars.select.rawValue } hasChanges = true diff --git a/Meshtastic/Views/Settings/SaveChannelQRCode.swift b/Meshtastic/Views/Settings/SaveChannelQRCode.swift index 82b38bd6..8d5e3f5c 100644 --- a/Meshtastic/Views/Settings/SaveChannelQRCode.swift +++ b/Meshtastic/Views/Settings/SaveChannelQRCode.swift @@ -13,10 +13,25 @@ struct SaveChannelQRCode: View { VStack { Text("Save Channel Settings?") .font(.title) - Text("These settings will replace the current LoRa Config and Channel Settings on your radio.") + Text("These settings will replace the current LoRa Config and Channel Settings on your radio. After everything saves your device will reboot.") .foregroundColor(.gray) .font(.callout) .padding() + Text(channelHash) + .font(.caption2) + .foregroundColor(.gray) + .padding() + + Button { + + } label: { + + Label("Save", systemImage: "square.and.arrow.down") + } + .buttonStyle(.bordered) + .buttonBorderShape(.capsule) + .controlSize(.large) + .padding() } .onChange(of: channelHash) { newSettings in var decodedString = newSettings.base64urlToBase64() From 9d4fa3b163b09b82dba683789807ce0c6659a54e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 13 Oct 2022 14:08:36 -0700 Subject: [PATCH 4/4] Consistant UUID formatting --- Meshtastic/Helpers/BLEManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index d1501259..41c726ed 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -54,7 +54,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let meshtasticServiceCBUUID = CBUUID(string: "0x6BA1B218-15A8-461F-9FA8-5DCAE273EAFD") let TORADIO_UUID = CBUUID(string: "0xF75C76D2-129E-4DAD-A1DD-7866124401E7") - let FROMRADIO_UUID = CBUUID(string: "2c55e69e-4993-11ed-b878-0242ac120002") + let FROMRADIO_UUID = CBUUID(string: "0x2C55E69E-4993-11ED-B878-0242AC120002") let EOL_FROMRADIO_UUID = CBUUID(string: "0x8BA2BCC2-EE02-4A55-A531-C525C5E454D5") let FROMNUM_UUID = CBUUID(string: "0xED9DA18C-A800-4F66-A670-AA7547E34453")