temp commit
This commit is contained in:
parent
3e8d7839c5
commit
d96fd7a5db
|
@ -190,14 +190,6 @@
|
|||
F8BECB05235CE5D80060DAE1 /* GlucoseChartManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8BECB04235CE5D80060DAE1 /* GlucoseChartManager.swift */; };
|
||||
F8BECB12235CEA9B0060DAE1 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8BECB11235CEA9B0060DAE1 /* TimeInterval.swift */; };
|
||||
F8C5EBE722F38F0E00563B5F /* Trace.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C5EBE622F38F0E00563B5F /* Trace.swift */; };
|
||||
F8DF765323E34F4500063910 /* DexcomG5+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF765223E34F4500063910 /* DexcomG5+CoreDataClass.swift */; };
|
||||
F8DF765523E34FD500063910 /* DexcomG5+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF765423E34FD500063910 /* DexcomG5+CoreDataProperties.swift */; };
|
||||
F8DF765C23E350B100063910 /* DexcomG5+BluetoothPeripheral.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF765B23E350B100063910 /* DexcomG5+BluetoothPeripheral.swift */; };
|
||||
F8DF766023E38FC100063910 /* BLEPeripheral+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF765F23E38FC100063910 /* BLEPeripheral+CoreDataClass.swift */; };
|
||||
F8DF766223E390D100063910 /* BLEPeripheral+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF766123E390D100063910 /* BLEPeripheral+CoreDataProperties.swift */; };
|
||||
F8DF766423E781C100063910 /* BLEPeripheralAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF766323E781C100063910 /* BLEPeripheralAccessor.swift */; };
|
||||
F8DF766823E782E400063910 /* DexcomG5Accessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF766723E782E400063910 /* DexcomG5Accessor.swift */; };
|
||||
F8DF766D23ED9B0900063910 /* DexcomG5BluetoothPeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DF766C23ED9B0900063910 /* DexcomG5BluetoothPeripheralViewModel.swift */; };
|
||||
F8E3A2A323D4E7E200E5E98A /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F8E3A2A223D4E7E200E5E98A /* Default-568h@2x.png */; };
|
||||
F8E3A2A523D78FBD00E5E98A /* SettingsViewAppleWatchSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E3A2A423D78FBD00E5E98A /* SettingsViewAppleWatchSettingsViewModel.swift */; };
|
||||
F8E3A2A923D906C200E5E98A /* WatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8E3A2A823D906C200E5E98A /* WatchManager.swift */; };
|
||||
|
@ -624,15 +616,6 @@
|
|||
F8C5EBED22F5A52400563B5F /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Common.strings"; sourceTree = "<group>"; };
|
||||
F8C5EBEE22F5A52800563B5F /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Common.strings; sourceTree = "<group>"; };
|
||||
F8DF764E23DCF64F00063910 /* xdrip v10.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "xdrip v10.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F8DF765123E34E6A00063910 /* xdrip v11.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "xdrip v11.xcdatamodel"; sourceTree = "<group>"; };
|
||||
F8DF765223E34F4500063910 /* DexcomG5+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexcomG5+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
F8DF765423E34FD500063910 /* DexcomG5+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DexcomG5+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
F8DF765B23E350B100063910 /* DexcomG5+BluetoothPeripheral.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DexcomG5+BluetoothPeripheral.swift"; sourceTree = "<group>"; };
|
||||
F8DF765F23E38FC100063910 /* BLEPeripheral+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BLEPeripheral+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
F8DF766123E390D100063910 /* BLEPeripheral+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BLEPeripheral+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
F8DF766323E781C100063910 /* BLEPeripheralAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BLEPeripheralAccessor.swift; sourceTree = "<group>"; };
|
||||
F8DF766723E782E400063910 /* DexcomG5Accessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomG5Accessor.swift; sourceTree = "<group>"; };
|
||||
F8DF766C23ED9B0900063910 /* DexcomG5BluetoothPeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DexcomG5BluetoothPeripheralViewModel.swift; sourceTree = "<group>"; };
|
||||
F8E3A2A223D4E7E200E5E98A /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||
F8E3A2A423D78FBD00E5E98A /* SettingsViewAppleWatchSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewAppleWatchSettingsViewModel.swift; sourceTree = "<group>"; };
|
||||
F8E3A2A823D906C200E5E98A /* WatchManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchManager.swift; sourceTree = "<group>"; };
|
||||
|
@ -1157,8 +1140,6 @@
|
|||
F8B3A815227DEC91004BA588 /* SensorsAccessor.swift */,
|
||||
F8F6226F233AA3B200BE8796 /* M5StackAccessor.swift */,
|
||||
F830992B23C694F4005741DF /* WatlaaAccessor.swift */,
|
||||
F8DF766323E781C100063910 /* BLEPeripheralAccessor.swift */,
|
||||
F8DF766723E782E400063910 /* DexcomG5Accessor.swift */,
|
||||
);
|
||||
path = accessors;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1294,46 +1275,6 @@
|
|||
path = Charts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8DF765923E350B100063910 /* Dexcom */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8DF765A23E350B100063910 /* G5 */,
|
||||
);
|
||||
path = Dexcom;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8DF765A23E350B100063910 /* G5 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8DF765B23E350B100063910 /* DexcomG5+BluetoothPeripheral.swift */,
|
||||
);
|
||||
path = G5;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8DF766923ED9AF100063910 /* CGM */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8DF766A23ED9AF100063910 /* Dexcom */,
|
||||
);
|
||||
path = CGM;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8DF766A23ED9AF100063910 /* Dexcom */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8DF766B23ED9AF100063910 /* DexcomG5 */,
|
||||
);
|
||||
path = Dexcom;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8DF766B23ED9AF100063910 /* DexcomG5 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8DF766C23ED9B0900063910 /* DexcomG5BluetoothPeripheralViewModel.swift */,
|
||||
);
|
||||
path = DexcomG5;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8E3A2A723D906B600E5E98A /* Watch */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1402,10 +1343,6 @@
|
|||
F804870B2336D90200EBDDB7 /* M5Stack+CoreDataProperties.swift */,
|
||||
F85DC2F121CFE3D400B9F74A /* Sensor+CoreDataClass.swift */,
|
||||
F85DC2E921CFE2F500B9F74A /* Sensor+CoreDataProperties.swift */,
|
||||
F8DF765223E34F4500063910 /* DexcomG5+CoreDataClass.swift */,
|
||||
F8DF765423E34FD500063910 /* DexcomG5+CoreDataProperties.swift */,
|
||||
F8DF765F23E38FC100063910 /* BLEPeripheral+CoreDataClass.swift */,
|
||||
F8DF766123E390D100063910 /* BLEPeripheral+CoreDataProperties.swift */,
|
||||
);
|
||||
path = classes;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1436,7 +1373,6 @@
|
|||
F8F971AE23A5914C00C3F17D /* CGM */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8DF765923E350B100063910 /* Dexcom */,
|
||||
);
|
||||
path = CGM;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1692,7 +1628,6 @@
|
|||
F8F9723623A5928D00C3F17D /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F8DF766923ED9AF100063910 /* CGM */,
|
||||
F830992423C32226005741DF /* watlaa */,
|
||||
F8F9723A23A5934300C3F17D /* M5StickC */,
|
||||
F8F9723723A5928D00C3F17D /* M5Stack */,
|
||||
|
@ -1925,7 +1860,6 @@
|
|||
F898EDF6234A8A5700BFB79B /* UInt32.swift in Sources */,
|
||||
F8F9723223A5915900C3F17D /* M5StackReadBlePassWordTxMessage.swift in Sources */,
|
||||
F8A54AAF22D686CD00934E7A /* NightScoutBgReading.swift in Sources */,
|
||||
F8DF765323E34F4500063910 /* DexcomG5+CoreDataClass.swift in Sources */,
|
||||
F8F9720F23A5915900C3F17D /* NSData+CRC.swift in Sources */,
|
||||
F8A1585722EDB754007F5B5D /* ConstantsCoreData.swift in Sources */,
|
||||
F821CF9022AB1068005C1E43 /* DatePickerViewData.swift in Sources */,
|
||||
|
@ -2004,9 +1938,7 @@
|
|||
F8F62270233AA3B200BE8796 /* M5StackAccessor.swift in Sources */,
|
||||
F830991C23C2909E005741DF /* Watlaa+CoreDataClass.swift in Sources */,
|
||||
F8A1586122EDB844007F5B5D /* ConstantsNotifications.swift in Sources */,
|
||||
F8DF765523E34FD500063910 /* DexcomG5+CoreDataProperties.swift in Sources */,
|
||||
F8F9720423A5915900C3F17D /* TransmitterVersionTxMessage.swift in Sources */,
|
||||
F8DF765C23E350B100063910 /* DexcomG5+BluetoothPeripheral.swift in Sources */,
|
||||
F8F9720323A5915900C3F17D /* CGMG5Transmitter.swift in Sources */,
|
||||
F8B3A81C227DEC92004BA588 /* AlertEntriesAccessor.swift in Sources */,
|
||||
F8A1585B22EDB7EA007F5B5D /* ConstantsDexcomG5.swift in Sources */,
|
||||
|
@ -2026,13 +1958,11 @@
|
|||
F8691888239CEEFA0065B607 /* BluetoothPeripheralViewModel.swift in Sources */,
|
||||
F8297F4F238DCAD800D74D66 /* BluetoothPeripheralNavigationController.swift in Sources */,
|
||||
F8A1585322EDB602007F5B5D /* ConstantsBloodGlucose.swift in Sources */,
|
||||
F8DF766023E38FC100063910 /* BLEPeripheral+CoreDataClass.swift in Sources */,
|
||||
F80ED2EE236F68F90005C035 /* SettingsViewM5StackWiFiSettingsViewModel.swift in Sources */,
|
||||
F8A389C823203E3E0010F405 /* ConstantsM5Stack.swift in Sources */,
|
||||
F898EDEA233F53BF00BFB79B /* UIButton.swift in Sources */,
|
||||
F81F9FF822861E6D0028C70F /* KeyValueObserverTimeKeeper.swift in Sources */,
|
||||
F8B3A858227F6971004BA588 /* UISwitch.swift in Sources */,
|
||||
F8DF766823E782E400063910 /* DexcomG5Accessor.swift in Sources */,
|
||||
F830990523B94ED7005741DF /* TimeScheduleViewController.swift in Sources */,
|
||||
F8F9722123A5915900C3F17D /* LibreSensorSerialNumber.swift in Sources */,
|
||||
F8A1586722EDB8BF007F5B5D /* ConstantsHomeView.swift in Sources */,
|
||||
|
@ -2065,7 +1995,6 @@
|
|||
F8F9721C23A5915900C3F17D /* LibreOOPResponse.swift in Sources */,
|
||||
F81F9FFC2288C7530028C70F /* NewAlertSettingsViewController.swift in Sources */,
|
||||
F898EDF2234A8A0500BFB79B /* UInt8.swift in Sources */,
|
||||
F8DF766423E781C100063910 /* BLEPeripheralAccessor.swift in Sources */,
|
||||
F81FA0002289E4990028C70F /* AlertSettingsViewControllerData.swift in Sources */,
|
||||
F856CE5B22EDC8E50083E436 /* ConstantsBluetoothPairing.swift in Sources */,
|
||||
F8F971B823A5914D00C3F17D /* BluetoothPeripheral.swift in Sources */,
|
||||
|
@ -2112,7 +2041,6 @@
|
|||
F8025C1321DA683400ECF0C0 /* Data.swift in Sources */,
|
||||
F8F9722023A5915900C3F17D /* LibreGlucoseSmoothing.swift in Sources */,
|
||||
F80859272364355F00F3829D /* ConstantsGlucoseChart.swift in Sources */,
|
||||
F8DF766D23ED9B0900063910 /* DexcomG5BluetoothPeripheralViewModel.swift in Sources */,
|
||||
F85DC2EF21CFE2F500B9F74A /* Sensor+CoreDataProperties.swift in Sources */,
|
||||
F8297F56238ED07700D74D66 /* BluetoothPeripheralManager.swift in Sources */,
|
||||
F8297F5A238EE14E00D74D66 /* TextsBluetoothPeripheralView.swift in Sources */,
|
||||
|
@ -2126,7 +2054,6 @@
|
|||
F8A1584F22ECB281007F5B5D /* SettingsViewInfoViewModel.swift in Sources */,
|
||||
F8B3A845227F090E004BA588 /* SettingsViewDexcomSettingsViewModel.swift in Sources */,
|
||||
F8F9720C23A5915900C3F17D /* SensorDataTxMessage.swift in Sources */,
|
||||
F8DF766223E390D100063910 /* BLEPeripheral+CoreDataProperties.swift in Sources */,
|
||||
F8A1585F22EDB81E007F5B5D /* ConstantsLog.swift in Sources */,
|
||||
F8A1586522EDB89D007F5B5D /* ConstantsDefaultAlertTypeSettings.swift in Sources */,
|
||||
);
|
||||
|
@ -2552,7 +2479,7 @@
|
|||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 3009;
|
||||
DEVELOPMENT_TEAM = 92C77A2942;
|
||||
DEVELOPMENT_TEAM = RNX44PP998;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/xdrip/Supporting Files/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -2580,7 +2507,7 @@
|
|||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 3009;
|
||||
DEVELOPMENT_TEAM = 92C77A2942;
|
||||
DEVELOPMENT_TEAM = RNX44PP998;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/xdrip/Supporting Files/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -2624,7 +2551,6 @@
|
|||
F8AC429F21B31F160078C348 /* xdrip.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
F8DF765123E34E6A00063910 /* xdrip v11.xcdatamodel */,
|
||||
F8DF764E23DCF64F00063910 /* xdrip v10.xcdatamodel */,
|
||||
F830991523C28E79005741DF /* xdrip v9.xcdatamodel */,
|
||||
F830990323B3928E005741DF /* xdrip v8.xcdatamodel */,
|
||||
|
@ -2636,7 +2562,7 @@
|
|||
F85C4A93233632EC00D6A86F /* xdrip v2.xcdatamodel */,
|
||||
F8AC42A021B31F160078C348 /* xdrip.xcdatamodel */,
|
||||
);
|
||||
currentVersion = F8DF765123E34E6A00063910 /* xdrip v11.xcdatamodel */;
|
||||
currentVersion = F8DF764E23DCF64F00063910 /* xdrip v10.xcdatamodel */;
|
||||
path = xdrip.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
versionGroupType = wrapper.xcdatamodel;
|
||||
|
|
|
@ -179,4 +179,21 @@ enum BluetoothPeripheralType: String, CaseIterable {
|
|||
|
||||
}
|
||||
|
||||
/// can a transmitter be reset ? For example Dexcom G5 (and G6) can be reset
|
||||
///
|
||||
/// can be used in UI stuff, if reset not possible then there's no need to show that option in the settings UI
|
||||
func resetPossible() -> Bool {
|
||||
|
||||
switch self {
|
||||
|
||||
case .M5StackType, .M5StickCType, .watlaaMaster:
|
||||
return false
|
||||
|
||||
case .DexcomG5Type:
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,9 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
|
|||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - name : if already connected before, then give here the name that was received during previous connect, if not give nil
|
||||
/// - transmitterID: expected transmitterID, 5 characters
|
||||
init(address:String?, name: String?, transmitterID:String, delegate:CGMTransmitterDelegate) {
|
||||
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) {
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: nil)
|
||||
if let address = address {
|
||||
|
@ -38,41 +40,17 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
|
|||
}
|
||||
|
||||
//assign CGMTransmitterDelegate
|
||||
cgmTransmitterDelegate = delegate
|
||||
self.cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
//assign transmitterId
|
||||
self.transmitterId = transmitterID
|
||||
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: CBUUID_Advertisement_G4, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_G4)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_G4, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_G4, startScanningAfterInit: CGMTransmitterType.dexcomG4.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: CBUUID_Advertisement_G4, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_G4)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_G4, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_G4, startScanningAfterInit: CGMTransmitterType.dexcomG4.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
// MARK: - MARK: CBCentralManager overriden functions
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
super.centralManager(central, didConnect: peripheral)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidConnect(address: deviceAddress, name: deviceName)
|
||||
|
||||
}
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
|
||||
|
@ -162,11 +140,6 @@ final class CGMG4xDripTransmitter: BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
/// to ask pairing - empty function because G4 doesn't need pairing
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
func initiatePairing() {}
|
||||
|
||||
/// to ask transmitter reset - empty function because G4 doesn't support reset
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
|
|
|
@ -4,13 +4,16 @@ import os
|
|||
|
||||
class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
||||
|
||||
// MARK: - properties
|
||||
// MARK: - public properties
|
||||
|
||||
/// G5 or G6 transmitter firmware version - only used internally, if nil then it was never received
|
||||
///
|
||||
/// created public because inheriting classes need it
|
||||
var firmwareVersion:String?
|
||||
var firmware:String?
|
||||
|
||||
/// CGMG5TransmitterDelegate
|
||||
public weak var cGMG5TransmitterDelegate: CGMG5TransmitterDelegate?
|
||||
|
||||
// MARK: UUID's
|
||||
|
||||
// advertisement
|
||||
|
@ -100,7 +103,10 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - name : if already connected before, then give here the name that was received during previous connect, if not give nil
|
||||
/// - transmitterID: expected transmitterID, 6 characters
|
||||
init(address:String?, name: String?, transmitterID:String, cGMTransmitterDelegate:CGMTransmitterDelegate) {
|
||||
/// - bluetoothTransmitterDelegate : a NluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
/// - cGMG5TransmitterDelegate : a CGMG5TransmitterDelegate
|
||||
init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG5TransmitterDelegate: CGMG5TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "DEXCOM" + transmitterID[transmitterID.index(transmitterID.startIndex, offsetBy: 4)..<transmitterID.endIndex])
|
||||
|
@ -124,11 +130,14 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
self.G5ResetRequested = false
|
||||
|
||||
// initialize - CBUUID_Receive_Authentication.rawValue and CBUUID_Write_Control.rawValue will probably not be used in the superclass
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: CBUUID_Advertisement_G5, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_G5)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_Receive_Authentication.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_Write_Control.rawValue, startScanningAfterInit: CGMTransmitterType.dexcomG5.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: CBUUID_Advertisement_G5, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_G5)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_Receive_Authentication.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_Write_Control.rawValue, startScanningAfterInit: CGMTransmitterType.dexcomG5.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
//assign CGMTransmitterDelegate
|
||||
self.cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
// assign cGMG5TransmitterDelegate
|
||||
self.cGMG5TransmitterDelegate = cGMG5TransmitterDelegate
|
||||
|
||||
// start scanning
|
||||
_ = startScanning()
|
||||
}
|
||||
|
@ -166,7 +175,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
}
|
||||
|
||||
// MARK: CBCentralManager overriden functions
|
||||
// MARK: BluetoothTransmitter overriden functions
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
|
@ -180,8 +189,12 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
}
|
||||
}
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
/// to ask pairing
|
||||
override func initiatePairing() {
|
||||
// assuming that the transmitter is effectively awaiting the pairing, otherwise this obviously won't work
|
||||
sendPairingRequest()
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
@ -193,12 +206,10 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
waitingPairingConfirmation = false
|
||||
|
||||
// inform delegate
|
||||
cgmTransmitterDelegate?.pairingFailed()
|
||||
bluetoothTransmitterDelegate.pairingFailed()
|
||||
|
||||
}
|
||||
|
||||
// inform delegate
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
@ -282,7 +293,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
sendKeepAliveMessage()
|
||||
|
||||
// delegate needs to be informed that pairing is needed
|
||||
cgmTransmitterDelegate?.cgmTransmitterNeedsPairing()
|
||||
bluetoothTransmitterDelegate.transmitterNeedsPairing(bluetoothTransmitter: self)
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -319,12 +330,12 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
// if this is the first sensorDataRx after a successful pairing, then inform delegate that pairing is finished
|
||||
if waitingPairingConfirmation {
|
||||
waitingPairingConfirmation = false
|
||||
cgmTransmitterDelegate?.successfullyPaired()
|
||||
bluetoothTransmitterDelegate.successfullyPaired()
|
||||
}
|
||||
|
||||
if let sensorDataRxMessage = SensorDataRxMessage(data: value) {
|
||||
|
||||
if firmwareVersion != nil {
|
||||
if firmware != nil {
|
||||
|
||||
// transmitterversion was already recceived, let's see if we need to get the batterystatus
|
||||
if Date() > Date(timeInterval: ConstantsDexcomG5.batteryReadPeriodInHours * 60 * 60, since: timeStampOfLastBatteryReading) {
|
||||
|
@ -359,7 +370,7 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
} else {
|
||||
timeStampOfLastG5Reading = Date()
|
||||
|
||||
let glucoseData = GlucoseData(timeStamp: sensorDataRxMessage.timestamp, glucoseLevelRaw: scaleRawValue(firmwareVersion: firmwareVersion, rawValue: sensorDataRxMessage.unfiltered), glucoseLevelFiltered: scaleRawValue(firmwareVersion: firmwareVersion, rawValue: sensorDataRxMessage.unfiltered))
|
||||
let glucoseData = GlucoseData(timeStamp: sensorDataRxMessage.timestamp, glucoseLevelRaw: scaleRawValue(firmwareVersion: firmware, rawValue: sensorDataRxMessage.unfiltered), glucoseLevelFiltered: scaleRawValue(firmwareVersion: firmware, rawValue: sensorDataRxMessage.unfiltered))
|
||||
|
||||
var glucoseDataArray = [glucoseData]
|
||||
|
||||
|
@ -489,12 +500,6 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
/// to ask pairing
|
||||
func initiatePairing() {
|
||||
// assuming that the transmitter is effectively awaiting the pairing, otherwise this obviously won't work
|
||||
sendPairingRequest()
|
||||
}
|
||||
|
||||
/// to ask transmitter reset
|
||||
func reset(requested:Bool) {
|
||||
G5ResetRequested = requested
|
||||
|
@ -548,10 +553,10 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
if let resetRxMessage = ResetRxMessage(data: value) {
|
||||
if resetRxMessage.status == 0 {
|
||||
trace("resetRxMessage status is 0, considering reset successful", log: log, category: ConstantsLog.categoryCGMG5, type: .info)
|
||||
cgmTransmitterDelegate?.reset(successful: true)
|
||||
bluetoothTransmitterDelegate.reset(successful: true)
|
||||
} else {
|
||||
trace("resetRxMessage status is %{public}d, considering reset failed", log: log, category: ConstantsLog.categoryCGMG5, type: .info, resetRxMessage.status)
|
||||
cgmTransmitterDelegate?.reset(successful: false)
|
||||
bluetoothTransmitterDelegate.reset(successful: false)
|
||||
}
|
||||
} else {
|
||||
trace("resetRxMessage is nil", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
|
||||
|
@ -567,16 +572,23 @@ class CGMG5Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
}
|
||||
|
||||
private func processTransmitterVersionRxMessage(value:Data) {
|
||||
|
||||
if let transmitterVersionRxMessage = TransmitterVersionRxMessage(data: value) {
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &emptyArray, transmitterBatteryInfo: nil, sensorState: nil, sensorTimeInMinutes: nil, firmware: transmitterVersionRxMessage.firmwareVersion.hexEncodedString(), hardware: nil, hardwareSerialNumber: nil, bootloader: nil, sensorSerialNumber: nil)
|
||||
|
||||
// assign transmitterVersion
|
||||
firmwareVersion = transmitterVersionRxMessage.firmwareVersion.hexEncodedString()
|
||||
firmware = transmitterVersionRxMessage.firmwareVersion.hexEncodedString()
|
||||
|
||||
// send to delegate
|
||||
cGMG5TransmitterDelegate?.received(firmware: firmware!, cGMG5Transmitter: self)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &emptyArray, transmitterBatteryInfo: nil, sensorState: nil, sensorTimeInMinutes: nil, firmware: firmware, hardware: nil, hardwareSerialNumber: nil, bootloader: nil, sensorSerialNumber: nil)
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
trace("transmitterVersionRxMessage is nil", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
|
||||
trace("transmitterVersionRxMessage is nil or firmware to hex is nil", log: log, category: ConstantsLog.categoryCGMG5, type: .error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// calculates encryptionkey
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import Foundation
|
||||
|
||||
protocol CGMG5TransmitterDelegate: AnyObject {
|
||||
|
||||
/// received firmware from CGMG5Transmitter
|
||||
func received(firmware: String, cGMG5Transmitter: CGMG5Transmitter)
|
||||
|
||||
}
|
||||
|
|
@ -8,10 +8,12 @@ class CGMG6Transmitter: CGMG5Transmitter {
|
|||
/// - parameters:
|
||||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - transmitterID: expected transmitterID, 6 characters
|
||||
override init(address:String?, name: String?, transmitterID:String, cGMTransmitterDelegate delegate:CGMTransmitterDelegate) {
|
||||
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
override init(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMG5TransmitterDelegate: CGMG5TransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) {
|
||||
|
||||
// call super.init
|
||||
super.init(address: address, name: name, transmitterID: transmitterID, cGMTransmitterDelegate: delegate)
|
||||
super.init(address: address, name: name, transmitterID: transmitterID, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate, cGMG5TransmitterDelegate: cGMG5TransmitterDelegate, cGMTransmitterDelegate: cGMTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,41 +1,9 @@
|
|||
import Foundation
|
||||
import CoreBluetooth
|
||||
|
||||
/// defines functions that every cgm transmitter should conform to, mainly used by rootviewcontroller
|
||||
///
|
||||
/// Most of the functions are already defined by BlueToothTransmitter.swift - so most of these functions don't need re-implementation in CGMTransmitter classes that conform to this protocol.
|
||||
///
|
||||
/// An exception is for example initiatePairing, which is implemented in CGMG5Transmitter.swift, because that transmitter needs to send a message to the transmitter that will cause the app to request the user to accept the pairing
|
||||
/// defines functions that every cgm transmitter should conform to
|
||||
protocol CGMTransmitter:AnyObject {
|
||||
|
||||
/// get device name, cgmtransmitters should also derive from BlueToothTransmitter, hence no need to implement this function
|
||||
///
|
||||
/// this function is implemented in class BluetoothTransmitter.swift, it's not necessary for transmitter types to implement this function (as new transmitterType class conform to protocol CGMTransmitter but also extend the BluetoothTransmitter class
|
||||
func name() -> String?
|
||||
|
||||
/// start scanning, cgmtransmitters should also derive from BlueToothTransmitter, hence no need to implement this function
|
||||
/// - returns:
|
||||
/// the scanning result
|
||||
///
|
||||
/// this function is implemented in class BluetoothTransmitter.swift, it's not necessary for transmitter types to implement this function (as new transmitterType class conform to protocol CGMTransmitter but also extend the BluetoothTransmitter class
|
||||
func startScanning() -> BluetoothTransmitter.startScanningResult
|
||||
|
||||
/// get connection status, nil if peripheral not yet known, ie never connected or discovered the transmitter
|
||||
///
|
||||
/// this function is implemented in class BluetoothTransmitter.swift, it's not necessary for transmitter types to implement this function (as new transmitterType class conform to protocol CGMTransmitter but also extend the BluetoothTransmitter class
|
||||
func getConnectionStatus() -> CBPeripheralState?
|
||||
|
||||
/// to ask transmitter that it initiates pairing
|
||||
///
|
||||
/// for transmitter types that don't need pairing, or that don't need pairing initiated by user/view controller, this will be an empty function. Only G5 (and in future maybe G6) will use it. The others can define an empty body
|
||||
func initiatePairing()
|
||||
|
||||
/// to reset the transmitter
|
||||
/// - parameters:
|
||||
/// - requested : if true then transmitter must be reset
|
||||
/// for transmitter types that don't support resetting, this will be an empty function. Only G5 (and in future maybe G6) will use it. The others can define an empty body
|
||||
func reset(requested:Bool)
|
||||
|
||||
/// to set webOOPEnabled - called when user change the setting
|
||||
///
|
||||
/// for transmitters who don't support webOOP, there's no need to implemented this function<br>
|
||||
|
@ -88,39 +56,6 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
/// watlaa
|
||||
case watlaa = "Watlaa (under development)"
|
||||
|
||||
/// does the transmitter need a transmitter id ?
|
||||
///
|
||||
/// can be used in UI stuff, if reset not possible then there's no need to show that option in the settings UI
|
||||
func needsTransmitterId() -> Bool {
|
||||
switch self {
|
||||
|
||||
case .dexcomG4:
|
||||
return true
|
||||
|
||||
case .dexcomG5, .dexcomG6:
|
||||
return true
|
||||
|
||||
case .miaomiao, .Bubble:
|
||||
return false
|
||||
|
||||
case .GNSentry:
|
||||
return false
|
||||
|
||||
case .Blucon:
|
||||
return true
|
||||
|
||||
case .Droplet1:
|
||||
return false
|
||||
|
||||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// if true, then a class conforming to the protocol CGMTransmitterDelegate will call newSensorDetected if it detects a new sensor is placed. Means there's no need to let the user start and stop a sensor
|
||||
///
|
||||
/// example MiaoMiao can detect new sensor, implementation should return true, Dexcom transmitter's can't
|
||||
|
@ -242,40 +177,6 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
}
|
||||
}
|
||||
|
||||
/// if true, then scanning can start automatically as soon as an instance of the CGM transmitter is created. This is typical for eg Dexcom G5, where an individual transitter can be idenfied via the transmitter id. Also the case for Blucon. For MiaoMiao and G4 xdrip this is different.
|
||||
///
|
||||
/// for this type of devices, there's no need to give an option in the UI to manually start scanning.
|
||||
func startScanningAfterInit() -> Bool {
|
||||
|
||||
switch self {
|
||||
|
||||
case .dexcomG4:
|
||||
return false
|
||||
|
||||
case .dexcomG5, .dexcomG6:
|
||||
return true
|
||||
|
||||
case .miaomiao, .Bubble:
|
||||
return false
|
||||
|
||||
case .GNSentry:
|
||||
return false
|
||||
|
||||
case .Blucon:
|
||||
return true
|
||||
|
||||
case .Droplet1:
|
||||
return false
|
||||
|
||||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// what unit to use for battery level, like '%', Volt, or nothing at all
|
||||
///
|
||||
/// to be used for UI stuff
|
||||
|
@ -307,34 +208,4 @@ enum CGMTransmitterType:String, CaseIterable {
|
|||
}
|
||||
}
|
||||
|
||||
/// can a transmitter be reset ? For example Dexcom G5 (and G6) can be reset
|
||||
///
|
||||
/// can be used in UI stuff, if reset not possible then there's no need to show that option in the settings UI
|
||||
func resetPossible() -> Bool {
|
||||
|
||||
switch self {
|
||||
|
||||
case .dexcomG4:
|
||||
return false
|
||||
|
||||
case .dexcomG5, .dexcomG6:
|
||||
return true
|
||||
|
||||
case .miaomiao, .Bubble, .Droplet1:
|
||||
return false
|
||||
|
||||
case .GNSentry:
|
||||
return false
|
||||
|
||||
case .Blucon:
|
||||
return false
|
||||
|
||||
case .blueReader:
|
||||
return false
|
||||
|
||||
case .watlaa:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,17 +4,6 @@ import CoreBluetooth
|
|||
/// to be implemented for anyone who needs to receive information from a specific type of cgm transmitter
|
||||
protocol CGMTransmitterDelegate:AnyObject {
|
||||
|
||||
/// transmitter reaches final connection status
|
||||
///
|
||||
/// example in CGMG4xDripTransmitter, the function is called only when subscription to read characteristic has succeeded, whereas for other like MiaoMiao, the function is called as soon as real connection is made
|
||||
func cgmTransmitterDidConnect(address:String?, name:String?)
|
||||
|
||||
/// transmitter did disconnect
|
||||
func cgmTransmitterDidDisconnect()
|
||||
|
||||
/// the ios device did change bluetooth status
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState)
|
||||
|
||||
/// will only happen for MiaoMiao transmitter, anyway we can do the stuff for any type of transmitter which means restart the sensor, ask calibration blablabla
|
||||
func newSensorDetected()
|
||||
|
||||
|
@ -34,24 +23,12 @@ protocol CGMTransmitterDelegate:AnyObject {
|
|||
/// - sensorSerialNumber : serial number of the sensor, only applicable for Libre transmitters (MiaoMiao, Blucon, ...)
|
||||
func cgmTransmitterInfoReceived(glucoseData:inout [GlucoseData], transmitterBatteryInfo:TransmitterBatteryInfo?, sensorState:LibreSensorState?, sensorTimeInMinutes:Int?, firmware:String?, hardware:String?, hardwareSerialNumber:String?, bootloader:String?, sensorSerialNumber:String?)
|
||||
|
||||
/// transmitter needs bluetooth pairing
|
||||
func cgmTransmitterNeedsPairing()
|
||||
|
||||
/// transmitter successfully paired
|
||||
func successfullyPaired()
|
||||
|
||||
/// transmitter pairing failed
|
||||
func pairingFailed()
|
||||
|
||||
/// transmitter reset result
|
||||
func reset(successful: Bool)
|
||||
/// temporary function till all cgm transmitters have moved to bluetooth tab. - this function returns the currently assigned cgmTransmiter
|
||||
func getCGMTransmitter() -> CGMTransmitter?
|
||||
|
||||
/// to pass some text error message, delegate can decide to show to user, log, ...
|
||||
func error(message: String)
|
||||
|
||||
/// temporary function till all cgm transmitters have moved to bluetooth tab. - this function returns the currently assigned cgmTransmiter
|
||||
func getCGMTransmitter() -> CGMTransmitter?
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,9 +69,11 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - name: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - transmitterID: expected transmitterID
|
||||
/// - delegate : CGMTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : CGMTransmitterDelegate
|
||||
/// - sensorSerialNumber : is needed to allow detection of a new sensor.
|
||||
init?(address:String?, name: String?, transmitterID:String, delegate:CGMTransmitterDelegate, timeStampLastBgReading:Date, sensorSerialNumber:String?) {
|
||||
/// - bluetoothTransmitterDelegate : a NluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init?(address:String?, name: String?, transmitterID:String, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, timeStampLastBgReading:Date, sensorSerialNumber:String?) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
// start by using expected device name
|
||||
|
@ -91,10 +93,10 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
rxBuffer = Data()
|
||||
|
||||
// initialize
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_BluconService)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Blucon, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Blucon, startScanningAfterInit: CGMTransmitterType.Blucon.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_BluconService)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Blucon, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Blucon, startScanningAfterInit: CGMTransmitterType.Blucon.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
//assign CGMTransmitterDelegate
|
||||
cgmTransmitterDelegate = delegate
|
||||
cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
}
|
||||
|
||||
|
@ -134,7 +136,7 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
/// process new historic data block received from Blucon, one block is the contents when receiving multipleBlockResponseIndex, inclusive the opcode - this is used if we ask all Libre data from the transmitter, which includes sensorTime and sensorStatus
|
||||
/// - returns:
|
||||
/// - did receive all data yes or no, if yes, then blucon can go to sleep
|
||||
/// also calls delegate with result of new readings
|
||||
/// also calls cGMTransmitterDelegate with result of new readings
|
||||
private func handleNewHistoricData(block: Data) -> Bool {
|
||||
|
||||
//check if buffer needs to be reset
|
||||
|
@ -163,7 +165,7 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
|
||||
}
|
||||
|
||||
//get readings from buffer and send to delegate
|
||||
//get readings from buffer and send to cGMTransmitterDelegate
|
||||
var result = LibreDataParser.parse(libreData: rxBuffer, timeStampLastBgReading: timeStampLastBgReading)
|
||||
|
||||
//TODO: sort glucosedata before calling newReadingsReceived
|
||||
|
@ -230,32 +232,6 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
super.centralManager(central, didConnect: peripheral)
|
||||
|
||||
trace("in centralManagerDidConnect", log: log, category: ConstantsLog.categoryBlucon, type: .info)
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidConnect(address: deviceAddress, name: deviceName)
|
||||
|
||||
}
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
||||
trace("in centralManagerDidDisconnectPeripheral", log: log, category: ConstantsLog.categoryBlucon, type: .info)
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateNotificationStateFor: characteristic, error: error)
|
||||
|
@ -267,16 +243,19 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
|
||||
// no need to log the error, it's already logged in BluetoothTransmitter
|
||||
|
||||
// check if it's an encryption error, if so call delegate
|
||||
// check if it's an encryption error, if so call cGMTransmitterDelegate
|
||||
if error.localizedDescription.uppercased().contains(find: "ENCRYPTION IS INSUFFICIENT") {
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterNeedsPairing()
|
||||
|
||||
|
||||
// inform delegate
|
||||
bluetoothTransmitterDelegate.transmitterNeedsPairing(bluetoothTransmitter: self)
|
||||
|
||||
waitingSuccessfulPairing = true
|
||||
}
|
||||
} else {
|
||||
if waitingSuccessfulPairing {
|
||||
cgmTransmitterDelegate?.successfullyPaired()
|
||||
// inform delegate
|
||||
bluetoothTransmitterDelegate.pairingFailed()
|
||||
waitingSuccessfulPairing = false
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +271,7 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
|
||||
// this is only applicable the very first time that blucon connects and pairing is done
|
||||
if waitingSuccessfulPairing {
|
||||
cgmTransmitterDelegate?.successfullyPaired()
|
||||
bluetoothTransmitterDelegate.successfullyPaired()
|
||||
waitingSuccessfulPairing = false
|
||||
}
|
||||
|
||||
|
@ -341,7 +320,7 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
|
||||
case .sensorNotDetected:
|
||||
|
||||
// Blucon didn't detect sensor, call delegate
|
||||
// Blucon didn't detect sensor, call cGMTransmitterDelegate
|
||||
cgmTransmitterDelegate?.sensorNotDetected()
|
||||
|
||||
// and send Blucon to sleep
|
||||
|
@ -352,14 +331,14 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
// get serial number
|
||||
let newSerialNumber = BluconUtilities.decodeSerialNumber(input: value)
|
||||
|
||||
// verify serial number and if changed inform delegate
|
||||
// verify serial number and if changed inform cGMTransmitterDelegate
|
||||
if newSerialNumber != sensorSerialNumber {
|
||||
|
||||
trace(" new sensor detected : %{public}@", log: log, category: ConstantsLog.categoryBlucon, type: .info, newSerialNumber)
|
||||
|
||||
sensorSerialNumber = newSerialNumber
|
||||
|
||||
// inform delegate about new sensor detected
|
||||
// inform cGMTransmitterDelegate about new sensor detected
|
||||
cgmTransmitterDelegate?.newSensorDetected()
|
||||
|
||||
// also reset timestamp last reading, to be sure that if new sensor is started, we get historic data
|
||||
|
@ -386,7 +365,7 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
|
||||
}
|
||||
|
||||
// inform delegate about sensorSerialNumber and sensorState
|
||||
// inform cGMTransmitterDelegate about sensorSerialNumber and sensorState
|
||||
cgmTransmitterDelegate?.cgmTransmitterInfoReceived(glucoseData: &emptyArray, transmitterBatteryInfo: nil, sensorState: sensorState, sensorTimeInMinutes: nil, firmware: nil, hardware: nil, hardwareSerialNumber: nil, bootloader: nil, sensorSerialNumber: sensorSerialNumber)
|
||||
|
||||
return
|
||||
|
@ -542,11 +521,6 @@ class CGMBluconTransmitter: BluetoothTransmitter {
|
|||
|
||||
extension CGMBluconTransmitter: CGMTransmitter {
|
||||
|
||||
func initiatePairing() {
|
||||
// nothing to do, Blucon keeps on reconnecting, resulting in continous pairing request
|
||||
return
|
||||
}
|
||||
|
||||
func reset(requested: Bool) {
|
||||
// no reset supported for blucon
|
||||
return
|
||||
|
|
|
@ -28,7 +28,9 @@ class CGMBlueReaderTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
/// - parameters:
|
||||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - name : if already connected before, then give here the name that was received during previous connect, if not give nil
|
||||
init(address:String?, name: String?, delegate:CGMTransmitterDelegate) {
|
||||
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "blueReader")
|
||||
|
@ -37,38 +39,14 @@ class CGMBlueReaderTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
}
|
||||
|
||||
// assign CGMTransmitterDelegate
|
||||
cgmTransmitterDelegate = delegate
|
||||
cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_BlueReader)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_BlueReader, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_BlueReader, startScanningAfterInit: CGMTransmitterType.blueReader.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_BlueReader)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_BlueReader, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_BlueReader, startScanningAfterInit: CGMTransmitterType.blueReader.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
super.centralManager(central, didConnect: peripheral)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidConnect(address: deviceAddress, name: deviceName)
|
||||
|
||||
}
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateNotificationStateFor: characteristic, error: error)
|
||||
|
@ -135,11 +113,6 @@ class CGMBlueReaderTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
/// to ask pairing - empty function because Bubble doesn't need pairing
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
func initiatePairing() {}
|
||||
|
||||
/// to ask transmitter reset - empty function because Bubble doesn't support reset
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
|
|
|
@ -59,7 +59,9 @@ class CGMBubbleTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
/// - webOOPEnabled : enabled or not
|
||||
/// - oopWebSite : oop web site url to use, only used in case webOOPEnabled = true
|
||||
/// - oopWebToken : oop web token to use, only used in case webOOPEnabled = true
|
||||
init(address:String?, name: String?, delegate:CGMTransmitterDelegate, timeStampLastBgReading:Date, sensorSerialNumber:String?, webOOPEnabled: Bool, oopWebSite: String, oopWebToken: String) {
|
||||
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, timeStampLastBgReading:Date, sensorSerialNumber:String?, webOOPEnabled: Bool, oopWebSite: String, oopWebToken: String) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: expectedDeviceNameBubble)
|
||||
|
@ -71,7 +73,7 @@ class CGMBubbleTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
self.sensorSerialNumber = sensorSerialNumber
|
||||
|
||||
// assign CGMTransmitterDelegate
|
||||
cgmTransmitterDelegate = delegate
|
||||
self.cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
// initialize rxbuffer
|
||||
rxBuffer = Data()
|
||||
|
@ -87,7 +89,7 @@ class CGMBubbleTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
self.oopWebToken = oopWebToken
|
||||
self.oopWebSite = oopWebSite
|
||||
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_Bubble)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Bubble, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Bubble, startScanningAfterInit: CGMTransmitterType.Bubble.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_Bubble)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Bubble, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Bubble, startScanningAfterInit: CGMTransmitterType.Bubble.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
|
@ -104,30 +106,6 @@ class CGMBubbleTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
super.centralManager(central, didConnect: peripheral)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidConnect(address: deviceAddress, name: deviceName)
|
||||
|
||||
}
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateNotificationStateFor: characteristic, error: error)
|
||||
|
@ -222,11 +200,6 @@ class CGMBubbleTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
/// to ask pairing - empty function because Bubble doesn't need pairing
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
func initiatePairing() {}
|
||||
|
||||
/// to ask transmitter reset - empty function because Bubble doesn't support reset
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
|
|
|
@ -28,7 +28,9 @@ class CGMDroplet1Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
/// - parameters:
|
||||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - name : if already connected before, then give here the name that was received during previous connect, if not give nil
|
||||
init(address:String?, name: String?, delegate:CGMTransmitterDelegate) {
|
||||
/// - bluetoothTransmitterDelegate : a NluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "limitter")
|
||||
|
@ -37,38 +39,14 @@ class CGMDroplet1Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
}
|
||||
|
||||
// assign CGMTransmitterDelegate
|
||||
cgmTransmitterDelegate = delegate
|
||||
self.cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_Droplet)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Droplet, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Droplet, startScanningAfterInit: CGMTransmitterType.Droplet1.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_Droplet)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_Droplet, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_Droplet, startScanningAfterInit: CGMTransmitterType.Droplet1.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
super.centralManager(central, didConnect: peripheral)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidConnect(address: deviceAddress, name: deviceName)
|
||||
|
||||
}
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
|
||||
|
@ -137,11 +115,6 @@ class CGMDroplet1Transmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
/// to ask pairing - empty function because Bubble doesn't need pairing
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
func initiatePairing() {}
|
||||
|
||||
/// to ask transmitter reset - empty function because Bubble doesn't support reset
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
|
|
|
@ -93,7 +93,9 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
/// - parameters:
|
||||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - name: if already connected before, then give here the name that was received during previous connect, if not give nil
|
||||
init?(address:String?, name: String?, delegate:CGMTransmitterDelegate, timeStampLastBgReading:Date) {
|
||||
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init?(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, timeStampLastBgReading:Date) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: "GNSentry")
|
||||
|
@ -105,39 +107,15 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
self.timeStampLastBgReadingInMinutes = timeStampLastBgReading.toMillisecondsAsDouble()/1000/60
|
||||
|
||||
// initialize
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_GNWService), CBUUID(string: CBUUID_BatteryService), CBUUID(string: CBUUID_DeviceInformationService)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Notify.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Write.rawValue, startScanningAfterInit: CGMTransmitterType.GNSentry.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_GNWService), CBUUID(string: CBUUID_BatteryService), CBUUID(string: CBUUID_DeviceInformationService)], CBUUID_ReceiveCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Notify.rawValue, CBUUID_WriteCharacteristic: CBUUID_Characteristic_UUID.CBUUID_GNW_Write.rawValue, startScanningAfterInit: CGMTransmitterType.GNSentry.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
//assign CGMTransmitterDelegate
|
||||
cgmTransmitterDelegate = delegate
|
||||
self.cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
}
|
||||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
super.centralManager(central, didConnect: peripheral)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidConnect(address: deviceAddress, name: deviceName)
|
||||
|
||||
}
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
|
||||
|
@ -258,11 +236,6 @@ class CGMGNSEntryTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
/// to ask pairing - empty function because GNSEntry doesn't need pairing
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
func initiatePairing() {}
|
||||
|
||||
/// to ask transmitter reset - empty function because GNSEntry doesn't support reset
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
|
|
|
@ -56,12 +56,13 @@ class CGMMiaoMiaoTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
/// - parameters:
|
||||
/// - address: if already connected before, then give here the address that was received during previous connect, if not give nil
|
||||
/// - name : if already connected before, then give here the name that was received during previous connect, if not give nil
|
||||
/// - delegate : CGMTransmitterDelegate intance
|
||||
/// - timeStampLastBgReading : timestamp of last bgReading
|
||||
/// - webOOPEnabled : enabled or not
|
||||
/// - oopWebSite : oop web site url to use, only used in case webOOPEnabled = true
|
||||
/// - oopWebToken : oop web token to use, only used in case webOOPEnabled = true
|
||||
init(address:String?, name: String?, delegate:CGMTransmitterDelegate, timeStampLastBgReading:Date, webOOPEnabled: Bool, oopWebSite: String, oopWebToken: String) {
|
||||
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
|
||||
/// - cGMTransmitterDelegate : a CGMTransmitterDelegate
|
||||
init(address:String?, name: String?, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate, cGMTransmitterDelegate:CGMTransmitterDelegate, timeStampLastBgReading:Date, webOOPEnabled: Bool, oopWebSite: String, oopWebToken: String) {
|
||||
|
||||
// assign addressname and name or expected devicename
|
||||
var newAddressAndName:BluetoothTransmitter.DeviceAddressAndName = BluetoothTransmitter.DeviceAddressAndName.notYetConnected(expectedName: expectedDeviceNameMiaoMiao)
|
||||
|
@ -70,7 +71,7 @@ class CGMMiaoMiaoTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
}
|
||||
|
||||
// assign CGMTransmitterDelegate
|
||||
cgmTransmitterDelegate = delegate
|
||||
self.cgmTransmitterDelegate = cGMTransmitterDelegate
|
||||
|
||||
// initialize rxbuffer
|
||||
rxBuffer = Data()
|
||||
|
@ -86,7 +87,7 @@ class CGMMiaoMiaoTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
self.oopWebToken = oopWebToken
|
||||
self.oopWebSite = oopWebSite
|
||||
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_MiaoMiao)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_MiaoMiao, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_MiaoMiao, startScanningAfterInit: CGMTransmitterType.miaomiao.startScanningAfterInit(), bluetoothTransmitterDelegate: nil)
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service_MiaoMiao)], CBUUID_ReceiveCharacteristic: CBUUID_ReceiveCharacteristic_MiaoMiao, CBUUID_WriteCharacteristic: CBUUID_WriteCharacteristic_MiaoMiao, startScanningAfterInit: CGMTransmitterType.miaomiao.startScanningAfterInit(), bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
|
@ -103,30 +104,6 @@ class CGMMiaoMiaoTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: - overriden BluetoothTransmitter functions
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
|
||||
super.centralManager(central, didConnect: peripheral)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidConnect(address: deviceAddress, name: deviceName)
|
||||
|
||||
}
|
||||
|
||||
override func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
|
||||
super.centralManagerDidUpdateState(central)
|
||||
|
||||
cgmTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state)
|
||||
|
||||
}
|
||||
|
||||
override func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
|
||||
super.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
|
||||
|
||||
cgmTransmitterDelegate?.cgmTransmitterDidDisconnect()
|
||||
|
||||
}
|
||||
|
||||
override func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
|
||||
super.peripheral(peripheral, didUpdateNotificationStateFor: characteristic, error: error)
|
||||
|
@ -236,11 +213,6 @@ class CGMMiaoMiaoTransmitter:BluetoothTransmitter, CGMTransmitter {
|
|||
|
||||
// MARK: CGMTransmitter protocol functions
|
||||
|
||||
/// to ask pairing - empty function because G4 doesn't need pairing
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
func initiatePairing() {}
|
||||
|
||||
/// to ask transmitter reset - empty function because MiaoMiao doesn't support reset
|
||||
///
|
||||
/// this function is not implemented in BluetoothTransmitter.swift, otherwise it might be forgotten to look at in future CGMTransmitter developments
|
||||
|
|
|
@ -10,7 +10,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
// MARK: - public properties
|
||||
|
||||
/// variable : it can get a new value during app run, will be used by rootviewcontroller's that want to receive info
|
||||
public weak var variableBluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
public var bluetoothTransmitterDelegate: BluetoothTransmitterDelegate
|
||||
|
||||
// MARK: - private properties
|
||||
|
||||
|
@ -65,9 +65,6 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
/// should the app try to reconnect after disconnect?
|
||||
private var reconnectAfterDisconnect:Bool = true
|
||||
|
||||
/// fixed : it will be set during init and not change, there's also a variable one, named variableBluetoothTransmitterDelegate
|
||||
private(set) weak var fixedBluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
/// - parameters:
|
||||
|
@ -79,8 +76,8 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
/// - servicesCBUUIDs: service uuid's
|
||||
/// - CBUUID_ReceiveCharacteristic: receive characteristic uuid
|
||||
/// - CBUUID_WriteCharacteristic: write characteristic uuid
|
||||
/// - delegate : a
|
||||
init(addressAndName:BluetoothTransmitter.DeviceAddressAndName, CBUUID_Advertisement:String?, servicesCBUUIDs:[CBUUID], CBUUID_ReceiveCharacteristic:String, CBUUID_WriteCharacteristic:String, startScanningAfterInit:Bool, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate?) {
|
||||
/// - bluetoothTransmitterDelegate : a BluetoothTransmitterDelegate
|
||||
init(addressAndName:BluetoothTransmitter.DeviceAddressAndName, CBUUID_Advertisement:String?, servicesCBUUIDs:[CBUUID], CBUUID_ReceiveCharacteristic:String, CBUUID_WriteCharacteristic:String, startScanningAfterInit:Bool, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate) {
|
||||
|
||||
switch addressAndName {
|
||||
|
||||
|
@ -105,8 +102,8 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
//initialize timeStampLastStatusUpdate
|
||||
timeStampLastStatusUpdate = Date()
|
||||
|
||||
// assign delegate
|
||||
self.fixedBluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
// assign bluetoothTransmitterDelegate
|
||||
self.bluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -367,8 +364,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
|
||||
trace("connected to peripheral with name %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'")
|
||||
|
||||
fixedBluetoothTransmitterDelegate?.didConnectTo(bluetoothTransmitter: self)
|
||||
variableBluetoothTransmitterDelegate?.didConnectTo(bluetoothTransmitter: self)
|
||||
bluetoothTransmitterDelegate.didConnectTo(bluetoothTransmitter: self)
|
||||
|
||||
peripheral.discoverServices(servicesCBUUIDs)
|
||||
|
||||
|
@ -394,8 +390,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
|
||||
trace("in centralManagerDidUpdateState, for peripheral with name %{public}@, new state is %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info, deviceName ?? "'unknown'", "\(central.state.toString())")
|
||||
|
||||
fixedBluetoothTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state, bluetoothTransmitter: self)
|
||||
variableBluetoothTransmitterDelegate?.deviceDidUpdateBluetoothState(state: central.state, bluetoothTransmitter: self)
|
||||
bluetoothTransmitterDelegate.deviceDidUpdateBluetoothState(state: central.state, bluetoothTransmitter: self)
|
||||
|
||||
/// in case status changed to powered on and if device address known then try either to retrieveperipherals, or if that doesn't succeed, start scanning
|
||||
if central.state == .poweredOn, reconnectAfterDisconnect {
|
||||
|
@ -415,8 +410,7 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
|
||||
trace(" didDisconnect peripheral with name %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .info , deviceName ?? "'unknown'")
|
||||
|
||||
fixedBluetoothTransmitterDelegate?.didDisconnectFrom(bluetoothTransmitter: self)
|
||||
variableBluetoothTransmitterDelegate?.didDisconnectFrom(bluetoothTransmitter: self)
|
||||
bluetoothTransmitterDelegate.didDisconnectFrom(bluetoothTransmitter: self)
|
||||
|
||||
if let error = error {
|
||||
trace(" error: %{public}@", log: log, category: ConstantsLog.categoryBlueToothTransmitter, type: .error , error.localizedDescription)
|
||||
|
@ -520,7 +514,13 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/// to ask transmitter that it initiates pairing
|
||||
///
|
||||
/// to be overriden. For transmitter types that don't need pairing, or that don't need pairing initiated by user/view controller, this function does not need to be overriden
|
||||
func initiatePairing() {return}
|
||||
|
||||
|
||||
// MARK: methods to get address and name
|
||||
|
||||
/// read device name
|
||||
|
|
|
@ -17,4 +17,19 @@ protocol BluetoothTransmitterDelegate: AnyObject {
|
|||
/// the ios device did change bluetooth status
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState, bluetoothTransmitter: BluetoothTransmitter)
|
||||
|
||||
/// transmitter needs bluetooth pairing, this to allow to notify the user about the fact that pairing is needed
|
||||
func transmitterNeedsPairing(bluetoothTransmitter: BluetoothTransmitter)
|
||||
|
||||
/// transmitter successfully paired
|
||||
func successfullyPaired()
|
||||
|
||||
/// transmitter pairing failed
|
||||
func pairingFailed()
|
||||
|
||||
/// transmitter reset result
|
||||
func reset(successful: Bool)
|
||||
|
||||
/// to pass some text error message, delegate can decide to show to user, log, ...
|
||||
func error(message: String)
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
/// possible rotation values, , the value is how it will be sent to the M5Stack but not how it's stored in the M5Stack object - In the M5Stack object we store an Int value which is used as index in rotationValues and rotationStrings
|
||||
private let rotationValues: [UInt16] = [ 1, 2, 3, 0]
|
||||
|
||||
public weak var m5StackBluetoothTransmitterDelegate: M5StackBluetoothTransmitterDelegate?
|
||||
|
||||
// MARK: - initializer
|
||||
|
||||
/// - parameters:
|
||||
|
@ -61,6 +63,9 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
// assign bluetoothPeripheralType
|
||||
self.bluetoothPeripheralType = bluetoothPeripheralType
|
||||
|
||||
// assign m5StackBluetoothTransmitterDelegate
|
||||
self.m5StackBluetoothTransmitterDelegate = m5StackBluetoothTransmitterDelegate
|
||||
|
||||
// call super
|
||||
super.init(addressAndName: newAddressAndName, CBUUID_Advertisement: nil, servicesCBUUIDs: [CBUUID(string: CBUUID_Service)], CBUUID_ReceiveCharacteristic: CBUUID_TxRxCharacteristic, CBUUID_WriteCharacteristic: CBUUID_TxRxCharacteristic, startScanningAfterInit: false, bluetoothTransmitterDelegate: bluetoothTransmitterDelegate)
|
||||
|
||||
|
@ -351,8 +356,7 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
|
||||
self.blePassword = newBlePassword
|
||||
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)? .newBlePassWord(newBlePassword: newBlePassword, m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.newBlePassWord(newBlePassword: newBlePassword, m5StackBluetoothTransmitter: self)
|
||||
m5StackBluetoothTransmitterDelegate?.newBlePassWord(newBlePassword: newBlePassword, m5StackBluetoothTransmitter: self)
|
||||
|
||||
}
|
||||
|
||||
|
@ -364,8 +368,7 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
trace(" successfully authenticated", log: log, category: ConstantsLog.categoryM5StackBluetoothTransmitter, type: .error)
|
||||
|
||||
// inform delegates
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.authentication(success: true, m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.authentication(success: true, m5StackBluetoothTransmitter: self)
|
||||
m5StackBluetoothTransmitterDelegate?.authentication(success: true, m5StackBluetoothTransmitter: self)
|
||||
|
||||
// final steps after successful communication
|
||||
finalizeConnectionSetup()
|
||||
|
@ -373,18 +376,13 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
case .authenticateFailureRx:
|
||||
// received authentication failure, inform delegates
|
||||
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.authentication(success: false, m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.authentication(success: false, m5StackBluetoothTransmitter: self)
|
||||
m5StackBluetoothTransmitterDelegate?.authentication(success: false, m5StackBluetoothTransmitter: self)
|
||||
|
||||
case .readBlePassWordError1Rx:
|
||||
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.blePasswordMissing(m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.blePasswordMissing(m5StackBluetoothTransmitter: self)
|
||||
m5StackBluetoothTransmitterDelegate?.blePasswordMissing(m5StackBluetoothTransmitter: self)
|
||||
|
||||
case .readBlePassWordError2Rx:
|
||||
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.m5StackResetRequired(m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.m5StackResetRequired(m5StackBluetoothTransmitter: self)
|
||||
m5StackBluetoothTransmitterDelegate?.m5StackResetRequired(m5StackBluetoothTransmitter: self)
|
||||
|
||||
case .readTimeStampRx:
|
||||
|
||||
|
@ -394,8 +392,7 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
case .readAllParametersRx:
|
||||
|
||||
// M5Stack is asking for all parameters
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.isAskingForAllParameters(m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.isAskingForAllParameters(m5StackBluetoothTransmitter: self)
|
||||
m5StackBluetoothTransmitterDelegate?.isAskingForAllParameters(m5StackBluetoothTransmitter: self)
|
||||
|
||||
case .readBatteryLevelRx:
|
||||
|
||||
|
@ -408,8 +405,7 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
let receivedBatteryLevel = Int(value[1])
|
||||
|
||||
// M5Stack is sending batteryLevel, which is in the second byte
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.receivedBattery(level: receivedBatteryLevel, m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.receivedBattery(level: receivedBatteryLevel, m5StackBluetoothTransmitter: self)
|
||||
m5StackBluetoothTransmitterDelegate?.receivedBattery(level: receivedBatteryLevel, m5StackBluetoothTransmitter: self)
|
||||
|
||||
}
|
||||
|
||||
|
@ -545,8 +541,8 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter {
|
|||
|
||||
// this is the time when the M5stack is ready to receive readings or parameter updates
|
||||
isReadyToReceiveData = true
|
||||
(fixedBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.isReadyToReceiveData(m5StackBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? M5StackBluetoothTransmitterDelegate)?.isReadyToReceiveData(m5StackBluetoothTransmitter: self)
|
||||
|
||||
m5StackBluetoothTransmitterDelegate?.isReadyToReceiveData(m5StackBluetoothTransmitter: self)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
protocol M5StackBluetoothTransmitterDelegate {
|
||||
protocol M5StackBluetoothTransmitterDelegate: AnyObject {
|
||||
|
||||
/// will be called if M5StackBluetoothTransmitter is connected and ready to receive data
|
||||
func isReadyToReceiveData(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
protocol WatlaaBluetoothTransmitterDelegate {
|
||||
protocol WatlaaBluetoothTransmitterDelegate: AnyObject {
|
||||
|
||||
/// will be called if WatlaaBluetoothTransmitter is connected and ready to receive data, as soon as this is received, xdrip can request for example battery level
|
||||
func isReadyToReceiveData(watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster)
|
||||
|
|
|
@ -2,10 +2,6 @@ import Foundation
|
|||
|
||||
extension WatlaaBluetoothTransmitterMaster: CGMTransmitter {
|
||||
|
||||
func initiatePairing() {
|
||||
// no pairing needed for watlaa
|
||||
}
|
||||
|
||||
func reset(requested: Bool) {
|
||||
// no reset need for watlaa
|
||||
}
|
||||
|
|
|
@ -4,7 +4,11 @@ import CoreBluetooth
|
|||
|
||||
final class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
||||
|
||||
// MARK: UUID's
|
||||
// MARK: - public properties
|
||||
|
||||
public weak var watlaaBluetoothTransmitterDelegate: WatlaaBluetoothTransmitterDelegate?
|
||||
|
||||
// MARK: - UUID's
|
||||
|
||||
/// Glucose Data Service UUID
|
||||
let CBUUID_Data_Service = "00001010-1212-EFDE-0137-875F45AC0113"
|
||||
|
@ -111,6 +115,9 @@ final class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
|||
//assign CGMTransmitterDelegate
|
||||
self.cgmTransmitterDelegate = cgmTransmitterDelegate
|
||||
|
||||
// assign watlaaBluetoothTransmitterDelegate
|
||||
self.watlaaBluetoothTransmitterDelegate = watlaaBluetoothTransmitterDelegate
|
||||
|
||||
//initialize timeStampLastBgReading
|
||||
timeStampLastBgReading = Date(timeIntervalSince1970: 0)
|
||||
|
||||
|
@ -243,8 +250,7 @@ final class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
|||
// Watlaa is sending batteryLevel, which is in the first byte
|
||||
let receivedBatteryLevel = Int(value[0])
|
||||
|
||||
(fixedBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.receivedBattery(level: receivedBatteryLevel, watlaaBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.receivedBattery(level: receivedBatteryLevel, watlaaBluetoothTransmitter: self)
|
||||
watlaaBluetoothTransmitterDelegate?.receivedBattery(level: receivedBatteryLevel, watlaaBluetoothTransmitter: self)
|
||||
|
||||
}
|
||||
|
||||
|
@ -271,8 +277,7 @@ final class WatlaaBluetoothTransmitterMaster: BluetoothTransmitter {
|
|||
}
|
||||
|
||||
// here all characteristics should be known, we can call isReadyToReceiveData
|
||||
(fixedBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.isReadyToReceiveData(watlaaBluetoothTransmitter: self)
|
||||
(variableBluetoothTransmitterDelegate as? WatlaaBluetoothTransmitterDelegate)?.isReadyToReceiveData(watlaaBluetoothTransmitter: self)
|
||||
watlaaBluetoothTransmitterDelegate?.isReadyToReceiveData(watlaaBluetoothTransmitter: self)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
import UIKit
|
||||
import CoreBluetooth
|
||||
import AVFoundation
|
||||
import AudioToolbox
|
||||
|
||||
extension BluetoothPeripheralManager: BluetoothTransmitterDelegate {
|
||||
|
||||
/// because extension dont allow var's, this is a workaround as explained here https://medium.com/@valv0/computed-properties-and-extensions-a-pure-swift-approach-64733768112c
|
||||
private struct PropertyHolder {
|
||||
|
||||
/// timestamp of last notification for pairing
|
||||
static var timeStampLastNotificationForPairing:Date?
|
||||
|
||||
/// timer used when asking the transmitter to initiate pairing. The user is waiting for the response, if the response from the transmitter doesn't come within a few seconds, then we'll inform the user
|
||||
static var transmitterPairingResponseTimer:Timer?
|
||||
|
||||
/// constant for key in ApplicationManager.shared.addClosureToRunWhenAppWillEnterForeground - initiate pairing
|
||||
static let applicationManagerKeyInitiatePairing = "RootViewController-InitiatePairing"
|
||||
|
||||
}
|
||||
|
||||
/// Transmitter is calling this delegate function to indicate that bluetooth pairing is needed. If the app is in the background, the user will be informed, after opening the app a pairing request will be initiated. if the app is in the foreground, the pairing request will be initiated immediately
|
||||
func transmitterNeedsPairing(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
trace("transmitter needs pairing", log: log, category: ConstantsLog.categoryRootView, type: .info)
|
||||
|
||||
if let timeStampLastNotificationForPairing = PropertyHolder.timeStampLastNotificationForPairing {
|
||||
|
||||
// check timestamp of last notification, if too soon then return
|
||||
if Int(abs(timeStampLastNotificationForPairing.timeIntervalSinceNow)) < ConstantsBluetoothPairing.minimumTimeBetweenTwoPairingNotificationsInSeconds {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// set timeStampLastNotificationForPairing
|
||||
PropertyHolder.timeStampLastNotificationForPairing = Date()
|
||||
|
||||
// remove existing notification if any
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing])
|
||||
|
||||
// Create Notification Content
|
||||
let notificationContent = UNMutableNotificationContent()
|
||||
|
||||
// Configure NnotificationContent title
|
||||
notificationContent.title = Texts_Common.warning
|
||||
|
||||
notificationContent.body = Texts_HomeView.transmitterNotPaired
|
||||
|
||||
// add sound
|
||||
notificationContent.sound = UNNotificationSound.init(named: UNNotificationSoundName.init(""))
|
||||
|
||||
// Create Notification Request
|
||||
let notificationRequest = UNNotificationRequest(identifier: ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing, content: notificationContent, trigger: nil)
|
||||
|
||||
// Add Request to User Notification Center
|
||||
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
|
||||
if let error = error {
|
||||
trace("Unable add notification request : transmitter needs pairing Notification Request, error : %{public}@", log: self.log, category: ConstantsLog.categoryRootView, type: .error, error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
// vibrate
|
||||
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||
|
||||
// add closure to ApplicationManager.shared.addClosureToRunWhenAppWillEnterForeground so that if user opens the app, the pairing request will be initiated. This can be done only if the app is opened within 60 seconds.
|
||||
// If the app is already in the foreground, then userNotificationCenter willPresent will be called, in this function the closure will be removed immediately, and the pairing request will be called. As a result, if the app is in the foreground, the user will not see (or hear) any notification, but the pairing will be initiated
|
||||
|
||||
// max timestamp when notification was fired - connection stays open for 1 minute, taking 1 second as d
|
||||
let maxTimeUserCanOpenApp = Date(timeIntervalSinceNow: TimeInterval(ConstantsDexcomG5.maxTimeToAcceptPairingInSeconds - 1))
|
||||
|
||||
// we will not just count on it that the user will click the notification to open the app (assuming the app is in the background, if the app is in the foreground, then we come in another flow)
|
||||
// whenever app comes from-back to foreground, updateLabelsAndChart needs to be called
|
||||
ApplicationManager.shared.addClosureToRunWhenAppWillEnterForeground(key: PropertyHolder.applicationManagerKeyInitiatePairing, closure: {
|
||||
|
||||
// first of all reremove from application key manager
|
||||
ApplicationManager.shared.removeClosureToRunWhenAppWillEnterForeground(key: PropertyHolder.applicationManagerKeyInitiatePairing)
|
||||
|
||||
// first remove existing notification if any
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing])
|
||||
|
||||
// if it was too long since notification was fired, then forget about it - inform user that it's too late
|
||||
if Date() > maxTimeUserCanOpenApp {
|
||||
trace("in cgmTransmitterNeedsPairing, user opened the app too late", log: self.log, category: ConstantsLog.categoryRootView, type: .error)
|
||||
let alert = UIAlertController(title: Texts_Common.warning, message: Texts_HomeView.transmitterPairingTooLate, actionHandler: nil)
|
||||
|
||||
self.uIViewController.present(alert, animated: true, completion: nil)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// initiate the pairing
|
||||
self.initiateTransmitterPairing(bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func successfullyPaired() {
|
||||
|
||||
// remove existing notification if any
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing])
|
||||
|
||||
// invalidate transmitterPairingResponseTimer
|
||||
if let transmitterPairingResponseTimer = PropertyHolder.transmitterPairingResponseTimer {
|
||||
transmitterPairingResponseTimer.invalidate()
|
||||
}
|
||||
|
||||
// inform user
|
||||
let alert = UIAlertController(title: Texts_HomeView.info, message: Texts_HomeView.transmitterPairingSuccessful, actionHandler: nil)
|
||||
|
||||
uIViewController.present(alert, animated: true, completion: nil)
|
||||
|
||||
}
|
||||
|
||||
|
||||
func pairingFailed() {
|
||||
// this should be the consequence of the user not accepting the pairing request, there's no need to inform the user
|
||||
// invalidate transmitterPairingResponseTimer
|
||||
if let transmitterPairingResponseTimer = PropertyHolder.transmitterPairingResponseTimer {
|
||||
transmitterPairingResponseTimer.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
func reset(successful: Bool) {
|
||||
|
||||
// reset setting to false
|
||||
UserDefaults.standard.transmitterResetRequired = false
|
||||
|
||||
// Create Notification Content to give info about reset result of reset attempt
|
||||
let notificationContent = UNMutableNotificationContent()
|
||||
|
||||
// Configure NnotificationContent title
|
||||
notificationContent.title = successful ? Texts_HomeView.info : Texts_Common.warning
|
||||
|
||||
notificationContent.body = Texts_HomeView.transmitterResetResult + " : " + (successful ? Texts_HomeView.success : Texts_HomeView.failed)
|
||||
|
||||
// Create Notification Request
|
||||
let notificationRequest = UNNotificationRequest(identifier: ConstantsNotifications.NotificationIdentifierForResetResult.transmitterResetResult, content: notificationContent, trigger: nil)
|
||||
|
||||
// Add Request to User Notification Center
|
||||
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
|
||||
if let error = error {
|
||||
trace("Unable add notification request : transmitter reset result, error: %{public}@", log: self.log, category: ConstantsLog.categoryRootView, type: .error, error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// temporary, till all cgm's are moved to second tab
|
||||
if bluetoothTransmitter is CGMTransmitter {
|
||||
onCGMTransmitterCreation((bluetoothTransmitter as! CGMTransmitter))
|
||||
}
|
||||
|
||||
// if tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is nil, then this is a connection to an already known/stored BluetoothTransmitter. BluetoothPeripheralManager is not interested in this info.
|
||||
guard let tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral else {
|
||||
trace("in didConnect, tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is nil, no further processing", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
return
|
||||
}
|
||||
|
||||
// check that address and name are not nil, otherwise this looks like a coding error
|
||||
guard let deviceAddressNewTransmitter = bluetoothTransmitter.deviceAddress, let deviceNameNewTransmitter = bluetoothTransmitter.deviceName else {
|
||||
trace("in didConnect, address or name of new transmitter is nil, looks like a coding error", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
return
|
||||
}
|
||||
|
||||
// check that tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral and the bluetoothTransmitter to which connection is made are actually the same objects, otherwise it's a connection that is made to a already known/stored BluetoothTransmitter
|
||||
guard tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral == bluetoothTransmitter else {
|
||||
trace("in didConnect, tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is not nil and not equal to bluetoothTransmitter", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
return
|
||||
}
|
||||
|
||||
// check that it's a peripheral for which we don't know yet the address
|
||||
for buetoothPeripheral in bluetoothPeripherals {
|
||||
|
||||
if buetoothPeripheral.blePeripheral.address == deviceAddressNewTransmitter {
|
||||
|
||||
trace("in didConnect, transmitter address already known. This is not a new device, will disconnect", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// it's an already known BluetoothTransmitter, not storing this, on the contrary disconnecting because maybe it's a bluetoothTransmitter already known for which user has preferred not to connect to
|
||||
// If we're actually waiting for a new scan result, then there's an instance of BluetoothTransmitter stored in tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral - but this one stopped scanning, so let's recreate an instance of BluetoothTransmitter
|
||||
self.tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = createNewTransmitter(type: getTransmitterType(for: bluetoothTransmitter), transmitterId: buetoothPeripheral.blePeripheral.transmitterId)
|
||||
|
||||
_ = self.tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral?.startScanning()
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// it's a new peripheral that we will store. No need to continue scanning
|
||||
bluetoothTransmitter.stopScanning()
|
||||
|
||||
// create bluetoothPeripheral
|
||||
let newBluetoothPeripheral = getTransmitterType(for: tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral).createNewBluetoothPeripheral(withAddress: deviceAddressNewTransmitter, withName: deviceNameNewTransmitter, nsManagedObjectContext: coreDataManager.mainManagedObjectContext)
|
||||
|
||||
bluetoothPeripherals.append(newBluetoothPeripheral)
|
||||
bluetoothTransmitters.append(bluetoothTransmitter)
|
||||
|
||||
// call the callback function
|
||||
if let callBackAfterDiscoveringDevice = callBackAfterDiscoveringDevice {
|
||||
callBackAfterDiscoveringDevice(newBluetoothPeripheral)
|
||||
self.callBackAfterDiscoveringDevice = nil
|
||||
}
|
||||
|
||||
// assign tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral to nil here
|
||||
self.tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = nil
|
||||
}
|
||||
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState, bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
trace("in deviceDidUpdateBluetoothState, no further action", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
if bluetoothTransmitter.deviceAddress == nil {
|
||||
/// this bluetoothTransmitter is created to start scanning for a new, unknown M5Stack, so start scanning
|
||||
_ = bluetoothTransmitter.startScanning()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func error(message: String) {
|
||||
|
||||
trace("received error = %{public}@", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info, message)
|
||||
|
||||
}
|
||||
|
||||
func didDisconnectFrom(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
// no further action, This is for UIViewcontroller's that also receive this info, means info can only be shown if this happens while user has one of the UIViewcontrollers open
|
||||
trace("in didDisconnectFrom", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
}
|
||||
|
||||
/// will call bluetoothTransmitter.initiatePairing() - also sets timer, if no successful pairing within a few seconds, then info will be given to user asking to wait another few minutes
|
||||
private func initiateTransmitterPairing(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// initiate the pairing
|
||||
bluetoothTransmitter.initiatePairing()
|
||||
|
||||
// invalide the timer, if it exists
|
||||
if let transmitterPairingResponseTimer = PropertyHolder.transmitterPairingResponseTimer {
|
||||
transmitterPairingResponseTimer.invalidate()
|
||||
}
|
||||
|
||||
// create and schedule timer
|
||||
PropertyHolder.transmitterPairingResponseTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(informUserThatPairingTimedOut), userInfo: nil, repeats: false)
|
||||
|
||||
}
|
||||
|
||||
// inform user that pairing request timed out
|
||||
@objc private func informUserThatPairingTimedOut() {
|
||||
|
||||
let alert = UIAlertController(title: Texts_Common.warning, message: "time out", actionHandler: nil)
|
||||
|
||||
uIViewController.present(alert, animated: true, completion: nil)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import Foundation
|
||||
|
||||
extension BluetoothPeripheralManager: CGMG5TransmitterDelegate {
|
||||
|
||||
func received(firmware: String, cGMG5Transmitter: CGMG5Transmitter) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: cGMG5Transmitter), let dexcomG5 = bluetoothPeripherals[index] as? DexcomG5 else {return}
|
||||
|
||||
dexcomG5.firmwareVersion = firmware
|
||||
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
import Foundation
|
||||
|
||||
// MARK: - conform to M5StackBluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: M5StackBluetoothTransmitterDelegate {
|
||||
|
||||
func receivedBattery(level: Int, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
m5Stack.batteryLevel = level
|
||||
|
||||
}
|
||||
|
||||
/// did the app successfully authenticate towards M5Stack, if no, then disconnect will be done
|
||||
func authentication(success: Bool, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in authentication with success = %{public}@", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info, success.description)
|
||||
|
||||
// if authentication not successful then disconnect and don't reconnect, user should verify password or reset the M5Stack, disconnect and set shouldconnect to false, permenantly (ie store in core data)
|
||||
// disconnection is done because maybe another device is trying to connect to the M5Stack, need to make it free
|
||||
// also set shouldConnect to false (note that this is also done in M5StackViewController if an instance of that exists, no issue, shouldConnect will be set to false two times
|
||||
if !success {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// don't try to reconnect after disconnecting
|
||||
m5Stack.blePeripheral.shouldconnect = false
|
||||
|
||||
// store in core data
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
// disconnect
|
||||
disconnect(fromBluetoothPeripheral: m5Stack)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// there's no ble password set, user should set it in the settings - disconnect will be called, shouldconnect is set to false
|
||||
func blePasswordMissing(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in blePasswordMissing", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// don't try to reconnect after disconnecting
|
||||
m5Stack.blePeripheral.shouldconnect = false
|
||||
|
||||
// store in core data
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
// disconnect
|
||||
disconnect(fromBluetoothPeripheral: m5Stack)
|
||||
|
||||
}
|
||||
|
||||
/// if a new ble password is received from M5Stack
|
||||
func newBlePassWord(newBlePassword: String, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in newBlePassWord, storing the password in M5Stack", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and also the bluetoothPeripheral and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// possibily this is a new scanned m5stack, calling coreDataManager.saveChanges() but still the user may be in M5stackviewcontroller and decide not to save the m5stack, bad luck
|
||||
m5Stack.blepassword = newBlePassword
|
||||
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
}
|
||||
|
||||
/// it's an M5Stack without password configured in the ini file. xdrip app has been requesting temp password to M5Stack but this was already done once. M5Stack needs to be reset. - disconnect will be called, shouldconnect is set to false
|
||||
func m5StackResetRequired(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in m5StackResetRequired", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// should not try to reconnect, wait till user decide to push the "always connect button"
|
||||
m5Stack.blePeripheral.shouldconnect = false
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
// disconnect
|
||||
disconnect(fromBluetoothPeripheral: m5Stack)
|
||||
|
||||
}
|
||||
|
||||
/// M5Stack is asking for an update of all parameters, send them
|
||||
func isAskingForAllParameters(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter) else {
|
||||
trace("in isAskingForAllParameters, could not find index of bluetoothTransmitter, looks like a coding error", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
return
|
||||
}
|
||||
|
||||
// send all parameters, if successful,then for this m5Stack we can set parameterUpdateNeeded to false
|
||||
if sendAllParametersToM5Stack(to: m5StackBluetoothTransmitter) {
|
||||
(bluetoothPeripherals[index] as? M5Stack)?.blePeripheral.parameterUpdateNeededAtNextConnect = false
|
||||
} else {
|
||||
// failed, so we need to set parameterUpdateNeeded to true, so that next time it connects we will send all parameters
|
||||
(bluetoothPeripherals[index] as? M5Stack)?.blePeripheral.parameterUpdateNeededAtNextConnect = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// will be called if M5Stack is connected, and authentication was successful, BluetoothPeripheralManager can start sending data like parameter updates or bgreadings
|
||||
func isReadyToReceiveData(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// if the M5Stack needs new parameters, then send them
|
||||
if m5Stack.blePeripheral.parameterUpdateNeededAtNextConnect {
|
||||
|
||||
// send all parameters
|
||||
if sendAllParametersToM5Stack(to: m5StackBluetoothTransmitter) {
|
||||
m5Stack.blePeripheral.parameterUpdateNeededAtNextConnect = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// send latest reading
|
||||
sendLatestReading(to: m5Stack)
|
||||
|
||||
}
|
||||
|
||||
// MARK: - private functions related to M5Stack
|
||||
|
||||
/// send all parameters to m5Stack
|
||||
/// - parameters:
|
||||
/// - to : m5StackBluetoothTransmitter to send all parameters
|
||||
/// - returns:
|
||||
/// successfully written all parameters or not
|
||||
private func sendAllParametersToM5Stack(to m5StackBluetoothTransmitter : M5StackBluetoothTransmitter) -> Bool {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return false}
|
||||
|
||||
// M5Stack must be ready to receive data
|
||||
guard m5StackBluetoothTransmitter.isReadyToReceiveData else {
|
||||
trace("in sendAllParameters, bluetoothTransmitter is not ready to receive data", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
return false
|
||||
}
|
||||
|
||||
// initialise returnValue, result
|
||||
var success = true
|
||||
|
||||
// send bloodglucoseunit
|
||||
if !m5StackBluetoothTransmitter.writeBloodGlucoseUnit(isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl) {success = false}
|
||||
|
||||
// send textColor
|
||||
if !m5StackBluetoothTransmitter.writeTextColor(textColor: M5StackColor(forUInt16: UInt16(m5Stack.textcolor)) ?? UserDefaults.standard.m5StackTextColor ?? ConstantsM5Stack.defaultTextColor) {success = false}
|
||||
|
||||
// send backGroundColor
|
||||
if !m5StackBluetoothTransmitter.writeBackGroundColor(backGroundColor: M5StackColor(forUInt16: UInt16(m5Stack.backGroundColor)) ?? ConstantsM5Stack.defaultBackGroundColor ) {success = false}
|
||||
|
||||
// send rotation
|
||||
if !m5StackBluetoothTransmitter.writeRotation(rotation: Int(m5Stack.rotation)) {success = false}
|
||||
|
||||
// send connectToWiFi
|
||||
if !m5StackBluetoothTransmitter.writeConnectToWiFi(connect: m5Stack.connectToWiFi) {success = false}
|
||||
|
||||
// send WiFiSSID's
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 1) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 2) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send WiFiPasswords
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 1) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 2) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout url
|
||||
if let url = UserDefaults.standard.nightScoutUrl {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutUrl(url: url) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout token
|
||||
if let token = UserDefaults.standard.nightScoutAPIKey {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutAPIKey(apiKey: token) {success = false}
|
||||
}
|
||||
|
||||
// return success
|
||||
return success
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import Foundation
|
||||
|
||||
extension BluetoothPeripheralManager: WatlaaBluetoothTransmitterDelegate {
|
||||
|
||||
func isReadyToReceiveData(watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
|
||||
// request battery level
|
||||
watlaaBluetoothTransmitter.readBatteryLevel()
|
||||
|
||||
}
|
||||
|
||||
func receivedBattery(level: Int, watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: watlaaBluetoothTransmitter), let watlaa = bluetoothPeripherals[index] as? Watlaa else {return}
|
||||
|
||||
watlaa.batteryLevel = level
|
||||
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -2,53 +2,55 @@ import Foundation
|
|||
import os
|
||||
import CoreBluetooth
|
||||
import CoreData
|
||||
import UIKit
|
||||
|
||||
class BluetoothPeripheralManager: NSObject {
|
||||
|
||||
// MARK: - public properties
|
||||
|
||||
/// all currently known BluetoothPeripheral's (MStacks, cgmtransmitters, watlaa , ...)
|
||||
public var bluetoothPeripherals: [BluetoothPeripheral] = []
|
||||
|
||||
/// the bluetoothTransmitter's, array must have the same size as bluetoothPeripherals. For each element in bluetoothPeripherals, there's an element at the same index in bluetoothTransmitters, which may be nil. nil value means user selected not to connect
|
||||
public var bluetoothTransmitters: [BluetoothTransmitter?] = []
|
||||
|
||||
/// for logging
|
||||
public var log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryBluetoothPeripheralManager)
|
||||
|
||||
/// when xdrip connects to a BluetoothTransmitter that is also CGMTransmitter, then we'll call this function with the BluetoothTransmitter as argument. This is to let the cgmTransmitterDelegate know what is the CGMTransmitter
|
||||
public var onCGMTransmitterCreation: (CGMTransmitter?) -> ()
|
||||
|
||||
/// if scan is called, an instance of M5StackBluetoothTransmitter is created with address and name. The new instance will be assigned to this variable, temporary, until a connection is made
|
||||
public var tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral: BluetoothTransmitter?
|
||||
|
||||
/// if scan is called, and a connection is successfully made to a new device, then a new M5Stack must be created, and this function will be called. It is owned by the UIViewController that calls the scan function
|
||||
public var callBackAfterDiscoveringDevice: ((BluetoothPeripheral) -> Void)?
|
||||
|
||||
/// will be used to present alerts, for example pairing failed
|
||||
public let uIViewController: UIViewController
|
||||
|
||||
// MARK: - private properties
|
||||
|
||||
/// CoreDataManager to use
|
||||
private let coreDataManager:CoreDataManager
|
||||
public let coreDataManager:CoreDataManager
|
||||
|
||||
/// for logging
|
||||
private var log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryBluetoothPeripheralManager)
|
||||
|
||||
/// dictionary with key = an instance of BluetoothPeripheral, and value an instance of BluetoothTransmitter. Value can be nil in which case we found a BluetoothPeripheral in the coredata but shouldconnect == false so we don't instanstiate a BluetoothTransmitter
|
||||
//private var m5StacksBlueToothTransmitters = [BluetoothPeripheral : BluetoothTransmitter?]()
|
||||
|
||||
/// all currently known BluetoothPeripheral's (MStacks, cgmtransmitters, watlaa , ...)
|
||||
private var bluetoothPeripherals: [BluetoothPeripheral] = []
|
||||
|
||||
/// the bluetoothTransmitter's, array must have the same size as bluetoothPeripherals. For each element in bluetoothPeripherals, there's an element at the same index in bluetoothTransmitters, which may be nil. nil value means user selected not to connect
|
||||
private var bluetoothTransmitters: [BluetoothTransmitter?] = []
|
||||
|
||||
|
||||
/// reference to BgReadingsAccessor
|
||||
private var bgReadingsAccessor: BgReadingsAccessor
|
||||
|
||||
/// reference to BLEPeripheralAccessor
|
||||
private var bLEPeripheralAccessor: BLEPeripheralAccessor
|
||||
|
||||
/// if scan is called, and a connection is successfully made to a new device, then a new M5Stack must be created, and this function will be called. It is owned by the UIViewController that calls the scan function
|
||||
private var callBackAfterDiscoveringDevice: ((BluetoothPeripheral) -> Void)?
|
||||
|
||||
/// if scan is called, an instance of M5StackBluetoothTransmitter is created with address and name. The new instance will be assigned to this variable, temporary, until a connection is made
|
||||
private var tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral: BluetoothTransmitter?
|
||||
|
||||
/// to solve problem that sometemes UserDefaults key value changes is triggered twice for just one change
|
||||
private let keyValueObserverTimeKeeper:KeyValueObserverTimeKeeper = KeyValueObserverTimeKeeper()
|
||||
|
||||
/// will be used to pass back bluetooth and cgm related events, probably temporary ?
|
||||
private(set) weak var cgmTransmitterDelegate:CGMTransmitterDelegate?
|
||||
|
||||
/// when xdrip connects to a BluetoothTransmitter that is also CGMTransmitter, then we'll call this function with the BluetoothTransmitter as argument. This is to let the cgmTransmitterDelegate know what is the CGMTransmitter
|
||||
private var onCGMTransmitterCreation: (CGMTransmitter?) -> ()
|
||||
|
||||
// MARK: - initializer
|
||||
|
||||
/// - parameters:
|
||||
/// - onCGMTransmitterCreation : to be called when cgmtransmitter is created
|
||||
init(coreDataManager: CoreDataManager, cgmTransmitterDelegate: CGMTransmitterDelegate, onCGMTransmitterCreation: @escaping (CGMTransmitter?) -> ()) {
|
||||
init(coreDataManager: CoreDataManager, cgmTransmitterDelegate: CGMTransmitterDelegate, uIViewController: UIViewController, onCGMTransmitterCreation: @escaping (CGMTransmitter?) -> ()) {
|
||||
|
||||
// initialize properties
|
||||
self.coreDataManager = coreDataManager
|
||||
|
@ -56,6 +58,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
self.cgmTransmitterDelegate = cgmTransmitterDelegate
|
||||
self.onCGMTransmitterCreation = onCGMTransmitterCreation
|
||||
self.bLEPeripheralAccessor = BLEPeripheralAccessor(coreDataManager: coreDataManager)
|
||||
self.uIViewController = uIViewController
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -125,7 +128,7 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
// create an instance of WatlaaBluetoothTransmitter, WatlaaBluetoothTransmitter will automatically try to connect to the watlaa with the address that is stored in watlaa
|
||||
// add it to the array of bluetoothTransmitters
|
||||
bluetoothTransmitters.append(CGMG5Transmitter(address: dexcomG5.blePeripheral.address, name: dexcomG5.blePeripheral.name, transmitterID: transmitterId, cGMTransmitterDelegate: cgmTransmitterDelegate))
|
||||
bluetoothTransmitters.append(CGMG5Transmitter(address: dexcomG5.blePeripheral.address, name: dexcomG5.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate))
|
||||
|
||||
}
|
||||
|
||||
|
@ -200,6 +203,148 @@ class BluetoothPeripheralManager: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
/// disconnect from bluetoothPeripheral - and don't reconnect - set shouldconnect to false
|
||||
public func disconnect(fromBluetoothPeripheral bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
||||
// device should not reconnect after disconnecting
|
||||
bluetoothPeripheral.blePeripheral.shouldconnect = false
|
||||
|
||||
// save in coredata
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
if let bluetoothTransmitter = getBluetoothTransmitter(for: bluetoothPeripheral, createANewOneIfNecesssary: false) {
|
||||
|
||||
_ = bluetoothTransmitter.disconnect(reconnectAfterDisconnect: false)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// returns the bluetoothTransmitter for the bluetoothPeripheral
|
||||
/// - parameters:
|
||||
/// - forBluetoothPeripheral : the bluetoothPeripheral for which bluetoothTransmitter should be returned
|
||||
/// - createANewOneIfNecesssary : if bluetoothTransmitter is nil, then should one be created ?
|
||||
public func getBluetoothTransmitter(for bluetoothPeripheral: BluetoothPeripheral, createANewOneIfNecesssary: Bool) -> BluetoothTransmitter? {
|
||||
|
||||
if let index = firstIndexInBluetoothPeripherals(bluetoothPeripheral: bluetoothPeripheral) {
|
||||
|
||||
if let bluetoothTransmitter = bluetoothTransmitters[index] {
|
||||
return bluetoothTransmitter
|
||||
}
|
||||
|
||||
if createANewOneIfNecesssary {
|
||||
|
||||
var newTransmitter: BluetoothTransmitter? = nil
|
||||
|
||||
switch bluetoothPeripheral.bluetoothPeripheralType() {
|
||||
|
||||
case .M5StackType, .M5StickCType:
|
||||
|
||||
if let m5Stack = bluetoothPeripheral as? M5Stack {
|
||||
|
||||
// blePassword : first check if m5Stack has a blepassword configured. If not then user blepassword from userDefaults, which can also still be nil
|
||||
var blePassword = m5Stack.blepassword
|
||||
if blePassword == nil {
|
||||
blePassword = UserDefaults.standard.m5StackBlePassword
|
||||
}
|
||||
|
||||
newTransmitter = M5StackBluetoothTransmitter(address: m5Stack.blePeripheral.address, name: m5Stack.blePeripheral.name, bluetoothTransmitterDelegate: self, m5StackBluetoothTransmitterDelegate: self, blePassword: blePassword, bluetoothPeripheralType: bluetoothPeripheral.bluetoothPeripheralType())
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
if let watlaa = bluetoothPeripheral as? Watlaa {
|
||||
|
||||
newTransmitter = WatlaaBluetoothTransmitterMaster(address: watlaa.blePeripheral.address, name: watlaa.blePeripheral.name, cgmTransmitterDelegate: cgmTransmitterDelegate, bluetoothTransmitterDelegate: self, watlaaBluetoothTransmitterDelegate: self, bluetoothPeripheralType: .watlaaMaster)
|
||||
|
||||
}
|
||||
|
||||
case .DexcomG5Type:
|
||||
|
||||
if let dexcomG5 = bluetoothPeripheral as? DexcomG5 {
|
||||
|
||||
if let transmitterId = dexcomG5.blePeripheral.transmitterId, let cgmTransmitterDelegate = cgmTransmitterDelegate {
|
||||
|
||||
newTransmitter = CGMG5Transmitter(address: dexcomG5.blePeripheral.address, name: dexcomG5.blePeripheral.name, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate)
|
||||
|
||||
} else {
|
||||
|
||||
trace("in getBluetoothTransmitter, case DexcomG5Type but transmitterId is nil or cgmTransmitterDelegate is nil, looks like a coding error ", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bluetoothTransmitters[index] = newTransmitter
|
||||
|
||||
return newTransmitter
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
public func getTransmitterType(for bluetoothTransmitter:BluetoothTransmitter) -> BluetoothPeripheralType {
|
||||
|
||||
for bluetoothPeripheralType in BluetoothPeripheralType.allCases {
|
||||
|
||||
// using switch through all cases, to make sure that new future types are supported
|
||||
switch bluetoothPeripheralType {
|
||||
|
||||
case .M5StackType, .M5StickCType:
|
||||
|
||||
if let bluetoothTransmitter = bluetoothTransmitter as? M5StackBluetoothTransmitter {
|
||||
return bluetoothTransmitter.bluetoothPeripheralType
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
if bluetoothTransmitter is WatlaaBluetoothTransmitterMaster {
|
||||
return .watlaaMaster
|
||||
}
|
||||
|
||||
case .DexcomG5Type:
|
||||
if bluetoothTransmitter is CGMG5Transmitter {
|
||||
return .DexcomG5Type
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// normally we shouldn't get here, but we need to return a value
|
||||
fatalError("BluetoothPeripheralManager : getTransmitterType did not find a valid type")
|
||||
|
||||
}
|
||||
|
||||
/// transmitterId only for transmitter types that need it (at the moment only Dexcom and Blucon)
|
||||
public func createNewTransmitter(type: BluetoothPeripheralType, transmitterId: String?) -> BluetoothTransmitter? {
|
||||
|
||||
switch type {
|
||||
|
||||
case .M5StackType, .M5StickCType:
|
||||
|
||||
return M5StackBluetoothTransmitter(address: nil, name: nil, bluetoothTransmitterDelegate: self, m5StackBluetoothTransmitterDelegate: self, blePassword: UserDefaults.standard.m5StackBlePassword, bluetoothPeripheralType: type)
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
return WatlaaBluetoothTransmitterMaster(address: nil, name: nil, cgmTransmitterDelegate: cgmTransmitterDelegate, bluetoothTransmitterDelegate: self, watlaaBluetoothTransmitterDelegate: self, bluetoothPeripheralType: type)
|
||||
|
||||
case .DexcomG5Type:
|
||||
|
||||
guard let transmitterId = transmitterId, let cgmTransmitterDelegate = cgmTransmitterDelegate else {
|
||||
trace("in createNewTransmitter, transmitterId is nil or cgmTransmitterDelegate is nil", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
return nil
|
||||
}
|
||||
|
||||
return CGMG5Transmitter(address: nil, name: nil, transmitterID: transmitterId, bluetoothTransmitterDelegate: self, cGMG5TransmitterDelegate: self, cGMTransmitterDelegate: cgmTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - private functions
|
||||
|
||||
/// check if transmitter in bluetoothTransmitters with index, is the cgmtransmitter currently assigned to delegate, if so set cgmtransmitter at delegate to nil - This should be temporary till cgm transmitters have moved to bluetooth tab
|
||||
|
@ -234,86 +379,10 @@ class BluetoothPeripheralManager: NSObject {
|
|||
|
||||
}
|
||||
|
||||
/// disconnect from bluetoothPeripheral - and don't reconnect - set shouldconnect to false
|
||||
private func disconnect(fromBluetoothPeripheral bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
||||
// device should not reconnect after disconnecting
|
||||
bluetoothPeripheral.blePeripheral.shouldconnect = false
|
||||
|
||||
// save in coredata
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
if let bluetoothTransmitter = getBluetoothTransmitter(for: bluetoothPeripheral, createANewOneIfNecesssary: false) {
|
||||
|
||||
_ = bluetoothTransmitter.disconnect(reconnectAfterDisconnect: false)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func firstIndexInBluetoothPeripherals(bluetoothPeripheral: BluetoothPeripheral) -> Int? {
|
||||
public func firstIndexInBluetoothPeripherals(bluetoothPeripheral: BluetoothPeripheral) -> Int? {
|
||||
return bluetoothPeripherals.firstIndex(where: {$0.blePeripheral.address == bluetoothPeripheral.blePeripheral.address})
|
||||
}
|
||||
|
||||
/// transmitterId only for transmitter types that need it (at the moment only Dexcom and Blucon)
|
||||
private func createNewTransmitter(type: BluetoothPeripheralType, transmitterId: String?) -> BluetoothTransmitter? {
|
||||
|
||||
switch type {
|
||||
|
||||
case .M5StackType, .M5StickCType:
|
||||
|
||||
return M5StackBluetoothTransmitter(address: nil, name: nil, bluetoothTransmitterDelegate: self, m5StackBluetoothTransmitterDelegate: self, blePassword: UserDefaults.standard.m5StackBlePassword, bluetoothPeripheralType: type)
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
return WatlaaBluetoothTransmitterMaster(address: nil, name: nil, cgmTransmitterDelegate: cgmTransmitterDelegate, bluetoothTransmitterDelegate: self, watlaaBluetoothTransmitterDelegate: self, bluetoothPeripheralType: type)
|
||||
|
||||
case .DexcomG5Type:
|
||||
|
||||
guard let transmitterId = transmitterId, let cgmTransmitterDelegate = cgmTransmitterDelegate else {
|
||||
trace("in createNewTransmitter, transmitterId is nil or cgmTransmitterDelegate is nil", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
return nil
|
||||
}
|
||||
|
||||
return CGMG5Transmitter(address: nil, name: nil, transmitterID: transmitterId, cGMTransmitterDelegate: cgmTransmitterDelegate)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func getTransmitterType(for bluetoothTransmitter:BluetoothTransmitter) -> BluetoothPeripheralType {
|
||||
|
||||
for bluetoothPeripheralType in BluetoothPeripheralType.allCases {
|
||||
|
||||
// using switch through all cases, to make sure that new future types are supported
|
||||
switch bluetoothPeripheralType {
|
||||
|
||||
case .M5StackType, .M5StickCType:
|
||||
|
||||
if let bluetoothTransmitter = bluetoothTransmitter as? M5StackBluetoothTransmitter {
|
||||
return bluetoothTransmitter.bluetoothPeripheralType
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
if bluetoothTransmitter is WatlaaBluetoothTransmitterMaster {
|
||||
return .watlaaMaster
|
||||
}
|
||||
|
||||
case .DexcomG5Type:
|
||||
if bluetoothTransmitter is CGMG5Transmitter {
|
||||
return .DexcomG5Type
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// normally we shouldn't get here, but we need to return a value
|
||||
fatalError("BluetoothPeripheralManager : getTransmitterType did not find a valid type")
|
||||
|
||||
}
|
||||
|
||||
// MARK:- override observe function
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
|
@ -440,7 +509,7 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
if !type.transmitterStartsScanningAfterInit() {
|
||||
_ = tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral?.startScanning()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// stops scanning for new device
|
||||
|
@ -477,7 +546,7 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
let transmitter = getBluetoothTransmitter(for: bluetoothPeripheral, createANewOneIfNecesssary: true)
|
||||
|
||||
transmitter?.connect()
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// returns the BluetoothPeripheral for the specified BluetoothTransmitter
|
||||
|
@ -493,75 +562,9 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
|
||||
}
|
||||
|
||||
/// returns the bluetoothTransmitter for the bluetoothPeripheral
|
||||
/// - parameters:
|
||||
/// - forBluetoothPeripheral : the bluetoothPeripheral for which bluetoothTransmitter should be returned
|
||||
/// - createANewOneIfNecesssary : if bluetoothTransmitter is nil, then should one be created ?
|
||||
func getBluetoothTransmitter(for bluetoothPeripheral: BluetoothPeripheral, createANewOneIfNecesssary: Bool) -> BluetoothTransmitter? {
|
||||
|
||||
if let index = firstIndexInBluetoothPeripherals(bluetoothPeripheral: bluetoothPeripheral) {
|
||||
|
||||
if let bluetoothTransmitter = bluetoothTransmitters[index] {
|
||||
return bluetoothTransmitter
|
||||
}
|
||||
|
||||
if createANewOneIfNecesssary {
|
||||
|
||||
var newTransmitter: BluetoothTransmitter? = nil
|
||||
|
||||
switch bluetoothPeripheral.bluetoothPeripheralType() {
|
||||
|
||||
case .M5StackType, .M5StickCType:
|
||||
|
||||
if let m5Stack = bluetoothPeripheral as? M5Stack {
|
||||
|
||||
// blePassword : first check if m5Stack has a blepassword configured. If not then user blepassword from userDefaults, which can also still be nil
|
||||
var blePassword = m5Stack.blepassword
|
||||
if blePassword == nil {
|
||||
blePassword = UserDefaults.standard.m5StackBlePassword
|
||||
}
|
||||
|
||||
newTransmitter = M5StackBluetoothTransmitter(address: m5Stack.blePeripheral.address, name: m5Stack.blePeripheral.name, bluetoothTransmitterDelegate: self, m5StackBluetoothTransmitterDelegate: self, blePassword: blePassword, bluetoothPeripheralType: bluetoothPeripheral.bluetoothPeripheralType())
|
||||
}
|
||||
|
||||
case .watlaaMaster:
|
||||
|
||||
if let watlaa = bluetoothPeripheral as? Watlaa {
|
||||
|
||||
newTransmitter = WatlaaBluetoothTransmitterMaster(address: watlaa.blePeripheral.address, name: watlaa.blePeripheral.name, cgmTransmitterDelegate: cgmTransmitterDelegate, bluetoothTransmitterDelegate: self, watlaaBluetoothTransmitterDelegate: self, bluetoothPeripheralType: .watlaaMaster)
|
||||
|
||||
}
|
||||
|
||||
case .DexcomG5Type:
|
||||
|
||||
if let dexcomG5 = bluetoothPeripheral as? DexcomG5 {
|
||||
|
||||
if let transmitterId = dexcomG5.blePeripheral.transmitterId, let cgmTransmitterDelegate = cgmTransmitterDelegate {
|
||||
|
||||
newTransmitter = CGMG5Transmitter(address: dexcomG5.blePeripheral.address, name: dexcomG5.blePeripheral.name, transmitterID: transmitterId, cGMTransmitterDelegate: cgmTransmitterDelegate)
|
||||
|
||||
} else {
|
||||
|
||||
trace("in getBluetoothTransmitter, case DexcomG5Type but transmitterId is nil or cgmTransmitterDelegate is nil, looks like a coding error ", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bluetoothTransmitters[index] = newTransmitter
|
||||
|
||||
return newTransmitter
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// deletes the BluetoothPeripheral in coredata, and also the corresponding BluetoothTransmitter if there is one will be deleted
|
||||
func deleteBluetoothPeripheral(bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
||||
|
||||
// find the bluetoothPeripheral in array bluetoothPeripherals, if it's not there then this looks like a coding error
|
||||
guard let index = firstIndexInBluetoothPeripherals(bluetoothPeripheral: bluetoothPeripheral) else {
|
||||
trace("in deleteBluetoothPeripheral but bluetoothPeripheral not found in bluetoothPeripherals, looks like a coding error ", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
|
@ -570,10 +573,10 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
|
||||
// check if transmitter being deleted is assigned to cgmTransmitterDelegate, if so we need to set it also to nil, otherwise the bluetoothTransmitter deinit function wouldn't get called
|
||||
setCGMTransmitterToNilAtDelegate(withIndexInBluetoothTransmitters: index)
|
||||
|
||||
|
||||
// set bluetoothTransmitter to nil, this will also initiate a disconnect
|
||||
bluetoothTransmitters[index] = nil
|
||||
|
||||
|
||||
// delete in coredataManager
|
||||
coreDataManager.mainManagedObjectContext.delete(bluetoothPeripherals[index] as! NSManagedObject)
|
||||
|
||||
|
@ -607,7 +610,7 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
return bluetoothTransmitters
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// bluetoothtransmitter for this bluetoothPeripheral will be deleted, as a result this will also disconnect the bluetoothPeripheral
|
||||
func setBluetoothTransmitterToNil(forBluetoothPeripheral bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
||||
|
@ -615,322 +618,12 @@ extension BluetoothPeripheralManager: BluetoothPeripheralManaging {
|
|||
|
||||
// check if transmitter being deleted is assigned to cgmTransmitterDelegate, if so we need to set it also to nil, otherwise the bluetoothTransmitter deinit function wouldn't get called
|
||||
setCGMTransmitterToNilAtDelegate(withIndexInBluetoothTransmitters: index)
|
||||
|
||||
|
||||
bluetoothTransmitters[index] = nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to BluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: BluetoothTransmitterDelegate {
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// temporary, till all cgm's are moved to second tab
|
||||
if bluetoothTransmitter is CGMTransmitter {
|
||||
onCGMTransmitterCreation((bluetoothTransmitter as! CGMTransmitter))
|
||||
}
|
||||
|
||||
// if tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is nil, then this is a connection to an already known/stored BluetoothTransmitter. BluetoothPeripheralManager is not interested in this info.
|
||||
guard let tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral else {
|
||||
trace("in didConnect, tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is nil, no further processing", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
return
|
||||
}
|
||||
|
||||
// check that address and name are not nil, otherwise this looks like a coding error
|
||||
guard let deviceAddressNewTransmitter = bluetoothTransmitter.deviceAddress, let deviceNameNewTransmitter = bluetoothTransmitter.deviceName else {
|
||||
trace("in didConnect, address or name of new transmitter is nil, looks like a coding error", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
return
|
||||
}
|
||||
|
||||
// check that tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral and the bluetoothTransmitter to which connection is made are actually the same objects, otherwise it's a connection that is made to a already known/stored BluetoothTransmitter
|
||||
guard tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral == bluetoothTransmitter else {
|
||||
trace("in didConnect, tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral is not nil and not equal to bluetoothTransmitter", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
return
|
||||
}
|
||||
|
||||
// check that it's a peripheral for which we don't know yet the address
|
||||
for buetoothPeripheral in bluetoothPeripherals {
|
||||
|
||||
if buetoothPeripheral.blePeripheral.address == deviceAddressNewTransmitter {
|
||||
|
||||
trace("in didConnect, transmitter address already known. This is not a new device, will disconnect", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// it's an already known BluetoothTransmitter, not storing this, on the contrary disconnecting because maybe it's a bluetoothTransmitter already known for which user has preferred not to connect to
|
||||
// If we're actually waiting for a new scan result, then there's an instance of BluetoothTransmitter stored in tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral - but this one stopped scanning, so let's recreate an instance of BluetoothTransmitter
|
||||
self.tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = createNewTransmitter(type: getTransmitterType(for: bluetoothTransmitter), transmitterId: buetoothPeripheral.blePeripheral.transmitterId)
|
||||
|
||||
_ = self.tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral?.startScanning()
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// it's a new peripheral that we will store. No need to continue scanning
|
||||
bluetoothTransmitter.stopScanning()
|
||||
|
||||
// create bluetoothPeripheral
|
||||
let newBluetoothPeripheral = getTransmitterType(for: tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral).createNewBluetoothPeripheral(withAddress: deviceAddressNewTransmitter, withName: deviceNameNewTransmitter, nsManagedObjectContext: coreDataManager.mainManagedObjectContext)
|
||||
|
||||
bluetoothPeripherals.append(newBluetoothPeripheral)
|
||||
bluetoothTransmitters.append(bluetoothTransmitter)
|
||||
|
||||
// call the callback function
|
||||
if let callBackAfterDiscoveringDevice = callBackAfterDiscoveringDevice {
|
||||
callBackAfterDiscoveringDevice(newBluetoothPeripheral)
|
||||
self.callBackAfterDiscoveringDevice = nil
|
||||
}
|
||||
|
||||
// assign tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral to nil here
|
||||
self.tempBlueToothTransmitterWhileScanningForNewBluetoothPeripheral = nil
|
||||
}
|
||||
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState, bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
trace("in deviceDidUpdateBluetoothState, no further action", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
if bluetoothTransmitter.deviceAddress == nil {
|
||||
/// this bluetoothTransmitter is created to start scanning for a new, unknown M5Stack, so start scanning
|
||||
_ = bluetoothTransmitter.startScanning()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func error(message: String) {
|
||||
trace("in error, no further action", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
}
|
||||
|
||||
func didDisconnectFrom(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
// no further action, This is for UIViewcontroller's that also receive this info, means info can only be shown if this happens while user has one of the UIViewcontrollers open
|
||||
trace("in didDisconnectFrom", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to WatlaaBluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: WatlaaBluetoothTransmitterDelegate {
|
||||
|
||||
func isReadyToReceiveData(watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
|
||||
// request battery level
|
||||
watlaaBluetoothTransmitter.readBatteryLevel()
|
||||
|
||||
}
|
||||
|
||||
func receivedBattery(level: Int, watlaaBluetoothTransmitter: WatlaaBluetoothTransmitterMaster) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: watlaaBluetoothTransmitter), let watlaa = bluetoothPeripherals[index] as? Watlaa else {return}
|
||||
|
||||
watlaa.batteryLevel = level
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - conform to M5StackBluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralManager: M5StackBluetoothTransmitterDelegate {
|
||||
|
||||
func receivedBattery(level: Int, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
m5Stack.batteryLevel = level
|
||||
|
||||
}
|
||||
|
||||
/// did the app successfully authenticate towards M5Stack, if no, then disconnect will be done
|
||||
func authentication(success: Bool, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in authentication with success = %{public}@", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info, success.description)
|
||||
|
||||
// if authentication not successful then disconnect and don't reconnect, user should verify password or reset the M5Stack, disconnect and set shouldconnect to false, permenantly (ie store in core data)
|
||||
// disconnection is done because maybe another device is trying to connect to the M5Stack, need to make it free
|
||||
// also set shouldConnect to false (note that this is also done in M5StackViewController if an instance of that exists, no issue, shouldConnect will be set to false two times
|
||||
if !success {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// don't try to reconnect after disconnecting
|
||||
m5Stack.blePeripheral.shouldconnect = false
|
||||
|
||||
// store in core data
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
// disconnect
|
||||
disconnect(fromBluetoothPeripheral: m5Stack)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// there's no ble password set, user should set it in the settings - disconnect will be called, shouldconnect is set to false
|
||||
func blePasswordMissing(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in blePasswordMissing", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// don't try to reconnect after disconnecting
|
||||
m5Stack.blePeripheral.shouldconnect = false
|
||||
|
||||
// store in core data
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
// disconnect
|
||||
disconnect(fromBluetoothPeripheral: m5Stack)
|
||||
|
||||
}
|
||||
|
||||
/// if a new ble password is received from M5Stack
|
||||
func newBlePassWord(newBlePassword: String, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in newBlePassWord, storing the password in M5Stack", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and also the bluetoothPeripheral and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// possibily this is a new scanned m5stack, calling coreDataManager.saveChanges() but still the user may be in M5stackviewcontroller and decide not to save the m5stack, bad luck
|
||||
m5Stack.blepassword = newBlePassword
|
||||
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
}
|
||||
|
||||
/// it's an M5Stack without password configured in the ini file. xdrip app has been requesting temp password to M5Stack but this was already done once. M5Stack needs to be reset. - disconnect will be called, shouldconnect is set to false
|
||||
func m5StackResetRequired(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
trace("in m5StackResetRequired", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// should not try to reconnect, wait till user decide to push the "always connect button"
|
||||
m5Stack.blePeripheral.shouldconnect = false
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
// disconnect
|
||||
disconnect(fromBluetoothPeripheral: m5Stack)
|
||||
|
||||
}
|
||||
|
||||
/// M5Stack is asking for an update of all parameters, send them
|
||||
func isAskingForAllParameters(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter) else {
|
||||
trace("in isAskingForAllParameters, could not find index of bluetoothTransmitter, looks like a coding error", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .error)
|
||||
return
|
||||
}
|
||||
|
||||
// send all parameters, if successful,then for this m5Stack we can set parameterUpdateNeeded to false
|
||||
if sendAllParametersToM5Stack(to: m5StackBluetoothTransmitter) {
|
||||
(bluetoothPeripherals[index] as? M5Stack)?.blePeripheral.parameterUpdateNeededAtNextConnect = false
|
||||
} else {
|
||||
// failed, so we need to set parameterUpdateNeeded to true, so that next time it connects we will send all parameters
|
||||
(bluetoothPeripherals[index] as? M5Stack)?.blePeripheral.parameterUpdateNeededAtNextConnect = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// will be called if M5Stack is connected, and authentication was successful, BluetoothPeripheralManager can start sending data like parameter updates or bgreadings
|
||||
func isReadyToReceiveData(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return}
|
||||
|
||||
// if the M5Stack needs new parameters, then send them
|
||||
if m5Stack.blePeripheral.parameterUpdateNeededAtNextConnect {
|
||||
|
||||
// send all parameters
|
||||
if sendAllParametersToM5Stack(to: m5StackBluetoothTransmitter) {
|
||||
m5Stack.blePeripheral.parameterUpdateNeededAtNextConnect = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// send latest reading
|
||||
sendLatestReading(to: m5Stack)
|
||||
|
||||
}
|
||||
|
||||
// MARK: - private functions related to M5Stack
|
||||
|
||||
/// send all parameters to m5Stack
|
||||
/// - parameters:
|
||||
/// - to : m5StackBluetoothTransmitter to send all parameters
|
||||
/// - returns:
|
||||
/// successfully written all parameters or not
|
||||
private func sendAllParametersToM5Stack(to m5StackBluetoothTransmitter : M5StackBluetoothTransmitter) -> Bool {
|
||||
|
||||
// should find the m5StackBluetoothTransmitter in bluetoothTransmitters and it should be an M5Stack
|
||||
guard let index = bluetoothTransmitters.firstIndex(of: m5StackBluetoothTransmitter), let m5Stack = bluetoothPeripherals[index] as? M5Stack else {return false}
|
||||
|
||||
// M5Stack must be ready to receive data
|
||||
guard m5StackBluetoothTransmitter.isReadyToReceiveData else {
|
||||
trace("in sendAllParameters, bluetoothTransmitter is not ready to receive data", log: log, category: ConstantsLog.categoryBluetoothPeripheralManager, type: .info)
|
||||
return false
|
||||
}
|
||||
|
||||
// initialise returnValue, result
|
||||
var success = true
|
||||
|
||||
// send bloodglucoseunit
|
||||
if !m5StackBluetoothTransmitter.writeBloodGlucoseUnit(isMgDl: UserDefaults.standard.bloodGlucoseUnitIsMgDl) {success = false}
|
||||
|
||||
// send textColor
|
||||
if !m5StackBluetoothTransmitter.writeTextColor(textColor: M5StackColor(forUInt16: UInt16(m5Stack.textcolor)) ?? UserDefaults.standard.m5StackTextColor ?? ConstantsM5Stack.defaultTextColor) {success = false}
|
||||
|
||||
// send backGroundColor
|
||||
if !m5StackBluetoothTransmitter.writeBackGroundColor(backGroundColor: M5StackColor(forUInt16: UInt16(m5Stack.backGroundColor)) ?? ConstantsM5Stack.defaultBackGroundColor ) {success = false}
|
||||
|
||||
// send rotation
|
||||
if !m5StackBluetoothTransmitter.writeRotation(rotation: Int(m5Stack.rotation)) {success = false}
|
||||
|
||||
// send connectToWiFi
|
||||
if !m5StackBluetoothTransmitter.writeConnectToWiFi(connect: m5Stack.connectToWiFi) {success = false}
|
||||
|
||||
// send WiFiSSID's
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 1) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 2) {success = false}
|
||||
}
|
||||
if let wifiName = UserDefaults.standard.m5StackWiFiName3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiName(name: wifiName, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send WiFiPasswords
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword1 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 1) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword2 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 2) {success = false}
|
||||
}
|
||||
if let wifiPassword = UserDefaults.standard.m5StackWiFiPassword3 {
|
||||
if !m5StackBluetoothTransmitter.writeWifiPassword(password: wifiPassword, number: 3) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout url
|
||||
if let url = UserDefaults.standard.nightScoutUrl {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutUrl(url: url) {success = false}
|
||||
}
|
||||
|
||||
// send nightscout token
|
||||
if let token = UserDefaults.standard.nightScoutAPIKey {
|
||||
if !m5StackBluetoothTransmitter.writeNightScoutAPIKey(apiKey: token) {success = false}
|
||||
}
|
||||
|
||||
// return success
|
||||
return success
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
|
||||
/// action for cancelbutton
|
||||
@IBAction func cancelButtonAction(_ sender: UIBarButtonItem) {
|
||||
cancel()
|
||||
cancelButtonAction()
|
||||
}
|
||||
|
||||
/// outlet for scanButton, to set the text in the scanButton
|
||||
|
@ -107,7 +107,11 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
/// needed to support the bluetooth peripheral type specific attributes
|
||||
private var bluetoothPeripheralViewModel: BluetoothPeripheralViewModel!
|
||||
|
||||
/// BluetoothPeripheralType for which this viewcontroller is created
|
||||
private var expectedBluetoothPeripheralType: BluetoothPeripheralType?
|
||||
|
||||
/// temp storage of assigned BluetoothTransmitterDelegate
|
||||
private weak var previouslyAssignedBluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
|
||||
// MARK:- public functions
|
||||
|
||||
|
@ -134,6 +138,17 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
|
||||
}
|
||||
|
||||
/// sets shouldconnect for bluetoothPeripheral to false
|
||||
public func setShouldConnectToFalse(for bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
||||
bluetoothPeripheral.blePeripheral.shouldconnect = false
|
||||
|
||||
coreDataManager?.saveChanges()
|
||||
|
||||
self.setConnectButtonLabelText()
|
||||
|
||||
}
|
||||
|
||||
// MARK: - View Life Cycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
|
@ -146,21 +161,41 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
bluetoothPeripheralViewModel = expectedBluetoothPeripheralType?.viewModel()
|
||||
|
||||
// configure the bluetoothPeripheralViewModel
|
||||
bluetoothPeripheralViewModel?.configure(bluetoothPeripheral: bluetoothPeripheralAsNSObject, bluetoothPeripheralManager: self.bluetoothPeripheralManager, tableView: tableView, bluetoothPeripheralViewController: self, bluetoothTransmitterDelegate: self)
|
||||
bluetoothPeripheralViewModel?.configure(bluetoothPeripheral: bluetoothPeripheralAsNSObject, bluetoothPeripheralManager: self.bluetoothPeripheralManager, tableView: tableView, bluetoothPeripheralViewController: self)
|
||||
|
||||
// still need to assign the delegate in the transmitter object
|
||||
if let bluetoothPeripheralASNSObject = bluetoothPeripheralAsNSObject {
|
||||
if let bluetoothPeripheralASNSObject = bluetoothPeripheralAsNSObject, let bluetoothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralASNSObject, createANewOneIfNecesssary: false) {
|
||||
|
||||
// set bluetoothPeripheralViewModel as delegate in bluetoothTransmitter
|
||||
if let bluetoothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralASNSObject, createANewOneIfNecesssary: false) {
|
||||
bluetoothTransmitter.variableBluetoothTransmitterDelegate = self
|
||||
}
|
||||
// this will store the current value of the bluetoothTransitterDelegate, and assign self as new delegate
|
||||
assignPreviouslyAssignedBluetoothTransmitterDelegateAndSetSelfAsDelegate(bluetoothTransmitter: bluetoothTransmitter, assignDelegateTo: self)
|
||||
|
||||
// this will internally store the BluetoothTransmitter type specific delegate
|
||||
bluetoothPeripheralViewModel.assignBluetoothTransmitterDelegate(to: bluetoothTransmitter)
|
||||
|
||||
}
|
||||
|
||||
setupView()
|
||||
|
||||
}
|
||||
|
||||
// MARK: - De-initialization
|
||||
|
||||
deinit {
|
||||
|
||||
// to be sure that previouslyAssignedBluetoothTransmitterDelegate is reassigned although it's probably already done for example in doneButtonHandler
|
||||
|
||||
if let bluetoothPeripheralAsNSObject = bluetoothPeripheralAsNSObject, let previouslyAssignedBluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate, let bluetoothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralAsNSObject, createANewOneIfNecesssary: false) {
|
||||
|
||||
// this will internally reset the BluetoothTransmitter delegate to the original value
|
||||
bluetoothPeripheralViewModel.reAssignBluetoothTransmitterDelegateToOriginal(for: bluetoothTransmitter)
|
||||
|
||||
// reassign delegate
|
||||
bluetoothTransmitter.bluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - other overriden functions
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
|
@ -253,10 +288,16 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
/// user cliks done button
|
||||
public func doneButtonHandler() {
|
||||
|
||||
if let bluetoothPeripheralAsNSObject = bluetoothPeripheralAsNSObject, let coreDataManager = coreDataManager {
|
||||
if let bluetoothPeripheralAsNSObject = bluetoothPeripheralAsNSObject, let coreDataManager = coreDataManager, let bluetoothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralAsNSObject, createANewOneIfNecesssary: false) {
|
||||
|
||||
// set variable delegate in bluetoothPeripheralASNSObject to nil, no need anymore to receive info
|
||||
bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralAsNSObject, createANewOneIfNecesssary: false)?.variableBluetoothTransmitterDelegate = nil
|
||||
// no need anymore to receive info from BluetoothTransmitter, reassign previouslyAssignedBluetoothTransmitterDelegate
|
||||
// previouslyAssignedBluetoothTransmitterDelegate must be non nil here. Otherwise there's a coding error.
|
||||
guard let previouslyAssignedBluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate else {
|
||||
fatalError("BluetoothPeripheralViewController, doneButtonHandler, previouslyAssignedBluetoothTransmitterDelegate is nil")
|
||||
}
|
||||
|
||||
// reassign previouslyAssignedBluetoothTransmitterDelegate as delegate in BluetoothTransmitter
|
||||
bluetoothTransmitter.bluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate
|
||||
|
||||
// set alias temp value, possibly this is a nil value
|
||||
bluetoothPeripheralAsNSObject.blePeripheral.alias = aliasTemporaryValue
|
||||
|
@ -266,13 +307,16 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
|
||||
// temp values stored by viewmodel needs to be written to bluetoothPeripheralASNSObject
|
||||
bluetoothPeripheralViewModel.writeTempValues(to: bluetoothPeripheralAsNSObject)
|
||||
|
||||
|
||||
// this will internally reset the BluetoothTransmitter delegate to the original value
|
||||
bluetoothPeripheralViewModel.reAssignBluetoothTransmitterDelegateToOriginal(for: bluetoothTransmitter)
|
||||
|
||||
// save all changes now
|
||||
coreDataManager.saveChanges()
|
||||
|
||||
}
|
||||
|
||||
// don't delete the BluetoothPeripheral when going back to prevous viewcontroller
|
||||
// don't delete the BluetoothPeripheral when going back to previous viewcontroller
|
||||
self.deleteBluetoothPeripheralWhenClosingViewController = false
|
||||
|
||||
// return to BluetoothPeripheralsViewController
|
||||
|
@ -314,8 +358,15 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
// if user goes back to previous screen via the back button, then delete the newly discovered BluetoothPeripheral
|
||||
self.deleteBluetoothPeripheralWhenClosingViewController = true
|
||||
|
||||
// set self as delegate in the bluetoothTransmitter
|
||||
self.bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheral, createANewOneIfNecesssary: false)?.variableBluetoothTransmitterDelegate = self
|
||||
// set self as delegate in the bluetoothTransmitter, and assign currently assigned BluetoothTransmitterDelegate to previouslyAssignedBluetoothTransmitterDelegate
|
||||
if let bluetoothTransmitter = self.bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheral, createANewOneIfNecesssary: false) {
|
||||
|
||||
self.assignPreviouslyAssignedBluetoothTransmitterDelegateAndSetSelfAsDelegate(bluetoothTransmitter: bluetoothTransmitter, assignDelegateTo: self)
|
||||
|
||||
// this will internally reset the BluetoothTransmitter delegate to the original value
|
||||
self.bluetoothPeripheralViewModel.assignBluetoothTransmitterDelegate(to: bluetoothTransmitter)
|
||||
|
||||
}
|
||||
|
||||
// reload the full screen , all rows in all sections in the tableView
|
||||
self.tableView.reloadData()
|
||||
|
@ -365,9 +416,10 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
// let's first check if bluetoothPeripheral exists, it should because otherwise connectButton should be disabled
|
||||
guard let bluetoothPeripheralASNSObject = bluetoothPeripheralAsNSObject else {return}
|
||||
|
||||
// user clicked connectbutton. Check first the current value of shouldconnect and change
|
||||
if bluetoothPeripheralASNSObject.blePeripheral.shouldconnect {
|
||||
|
||||
// device should not automaticaly connect, which means, each time the app restarts, it will not try to connect to this bluetoothPeripheral
|
||||
// device should not automaticaly connect in future, which means, each time the app restarts, it will not try to connect to this bluetoothPeripheral
|
||||
bluetoothPeripheralASNSObject.blePeripheral.shouldconnect = false
|
||||
|
||||
// save the update in coredata
|
||||
|
@ -376,11 +428,14 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
// update the connect button text
|
||||
setConnectButtonLabelText()
|
||||
|
||||
// normally there should be a bluetoothTransmitter
|
||||
if let bluetoothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralASNSObject, createANewOneIfNecesssary: false) {
|
||||
// disconnecting means also deleting the bluetoothTransmitter (which as a consequence also disconnects). Also reassign previouslyAssignedBluetoothTransmitterDelegate, although this is probably not necessary as the bluetoothTransmitter will be set to nil
|
||||
if let bluetoothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralASNSObject, createANewOneIfNecesssary: false), let previouslyAssignedBluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate {
|
||||
|
||||
// set delegate in bluetoothtransmitter to nil, as we're going to disconnect permenantly, so not interested anymore to receive info
|
||||
bluetoothTransmitter.variableBluetoothTransmitterDelegate = nil
|
||||
bluetoothTransmitter.bluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate
|
||||
|
||||
// this will internally reset the BluetoothTransmitter delegate to the original value
|
||||
self.bluetoothPeripheralViewModel.reAssignBluetoothTransmitterDelegateToOriginal(for: bluetoothTransmitter)
|
||||
|
||||
// this will also set bluetoothTransmitter to nil and also disconnect the peripheral
|
||||
bluetoothPeripheralManager.setBluetoothTransmitterToNil(forBluetoothPeripheral: bluetoothPeripheralASNSObject)
|
||||
|
@ -398,12 +453,14 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
// get bluetoothTransmitter
|
||||
if let bluetoothTransmitter = bluetoothPeripheralManager.getBluetoothTransmitter(for: bluetoothPeripheralASNSObject, createANewOneIfNecesssary: true) {
|
||||
|
||||
// set delegate
|
||||
bluetoothTransmitter.variableBluetoothTransmitterDelegate = self
|
||||
assignPreviouslyAssignedBluetoothTransmitterDelegateAndSetSelfAsDelegate(bluetoothTransmitter: bluetoothTransmitter, assignDelegateTo: self)
|
||||
|
||||
// connect
|
||||
bluetoothTransmitter.connect()
|
||||
|
||||
|
||||
// this will internally store the BluetoothTransmitter type specific delegate
|
||||
bluetoothPeripheralViewModel.assignBluetoothTransmitterDelegate(to: bluetoothTransmitter)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -442,7 +499,7 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
}
|
||||
|
||||
/// user clicked cancel button
|
||||
private func cancel() {
|
||||
private func cancelButtonAction() {
|
||||
|
||||
// just in case scanning for a new device is still ongoing, call stopscanning
|
||||
bluetoothPeripheralManager.stopScanningForNewDevice()
|
||||
|
@ -452,14 +509,14 @@ class BluetoothPeripheralViewController: UIViewController {
|
|||
|
||||
}
|
||||
|
||||
/// sets shouldconnect for bluetoothPeripheral to false
|
||||
public func setShouldConnectToFalse(for bluetoothPeripheral: BluetoothPeripheral) {
|
||||
|
||||
bluetoothPeripheral.blePeripheral.shouldconnect = false
|
||||
/// assign current delegate in bluetoothTransmitter to previouslyAssignedBluetoothTransmitterDelegate, and set delegate in to to self
|
||||
private func assignPreviouslyAssignedBluetoothTransmitterDelegateAndSetSelfAsDelegate(bluetoothTransmitter: BluetoothTransmitter, assignDelegateTo bluetoothTransmitterDelegate: BluetoothTransmitterDelegate) {
|
||||
|
||||
coreDataManager?.saveChanges()
|
||||
// assign previouslyAssignedBluetoothTransmitterDelegate
|
||||
previouslyAssignedBluetoothTransmitterDelegate = bluetoothTransmitter.bluetoothTransmitterDelegate
|
||||
|
||||
self.setConnectButtonLabelText()
|
||||
// assign self as BluetoothTransmitterDelegate
|
||||
bluetoothTransmitter.bluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
|
||||
}
|
||||
|
||||
|
@ -703,25 +760,68 @@ extension BluetoothPeripheralViewController: UITableViewDataSource, UITableViewD
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extension BluetoothTransmitterDelegate
|
||||
|
||||
extension BluetoothPeripheralViewController: BluetoothTransmitterDelegate {
|
||||
|
||||
func transmitterNeedsPairing(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.transmitterNeedsPairing(bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
func successfullyPaired() {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.successfullyPaired()
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
func pairingFailed() {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.pairingFailed()
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
func reset(successful: Bool) {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.reset(successful: successful)
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
tableView.reloadRows(at: [IndexPath(row: Setting.connectionStatus.rawValue, section: 0)], with: .none)
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.didConnectTo(bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
tableView.reloadRows(at: [IndexPath(row: Setting.connectionStatus.rawValue, section: 0)], with: .none)
|
||||
|
||||
}
|
||||
|
||||
func didDisconnectFrom(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
tableView.reloadRows(at: [IndexPath(row: Setting.connectionStatus.rawValue, section: 0)], with: .none)
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.didDisconnectFrom(bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
tableView.reloadRows(at: [IndexPath(row: Setting.connectionStatus.rawValue, section: 0)], with: .none)
|
||||
|
||||
}
|
||||
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState, bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// when bluetooth status changes to powered off, the device, if connected, will disconnect, however didDisConnect doesn't get call (looks like an error in iOS) - so let's reload the cell that shows the connection status, this will refresh the cell
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.deviceDidUpdateBluetoothState(state: state, bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
// when bluetooth status changes to powered off, the device, if connected, will disconnect, however didDisConnect doesn't get call (looks like an error in iOS) - so let's reload the cell that shows the connection status, this will refresh the cell
|
||||
// do this whenever the bluetooth status changes
|
||||
tableView.reloadRows(at: [IndexPath(row: Setting.connectionStatus.rawValue, section: 0)], with: .none)
|
||||
|
||||
|
@ -729,6 +829,9 @@ extension BluetoothPeripheralViewController: BluetoothTransmitterDelegate {
|
|||
|
||||
func error(message: String) {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.error(message: message)
|
||||
|
||||
let alert = UIAlertController(title: Texts_Common.warning, message: message, actionHandler: nil)
|
||||
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
|
|
@ -5,12 +5,11 @@ protocol BluetoothPeripheralViewModel {
|
|||
|
||||
/// to be called before opening the actual viewcontroller or after discovering a new bluetoothperipheral
|
||||
/// - parameters :
|
||||
/// - bluetoothTransmitterDelegate : usually the uiViewController
|
||||
/// - bluetoothPeripheral : if nil then the viewcontroller is opened to scan for a new peripheral
|
||||
/// - bluetoothPeripheralManager : reference to bluetoothPeripheralManaging object
|
||||
/// - tableView : needed to intiate refresh of row
|
||||
/// - bluetoothPeripheralViewController : BluetoothPeripheralViewController
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate)
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController)
|
||||
|
||||
/// screen title for uiviewcontroller
|
||||
func screenTitle() -> String
|
||||
|
@ -37,4 +36,10 @@ protocol BluetoothPeripheralViewModel {
|
|||
/// used when user clicks done button in uiviewcontroller
|
||||
func writeTempValues(to bluetoothPeripheral: BluetoothPeripheral)
|
||||
|
||||
/// used in BluetoothPeripheralViewController which is unaware of types of transmitters (M5Stack, Watlaa, ...). This to handle that there can be multiple delegates listening for example M5StackBluetoothTransmitter changes. The function assignBluetoothTransmitterDelegate will temporary store the value of the existing delegate (example M5StackBluetoothTransmitterDelegate) and assign itself (ie the viewmodel) as delegate. It should also handle the calling of the functions in the stored delegate (look at an example to understand :) )
|
||||
func assignBluetoothTransmitterDelegate(to bluetoothTransmitter: BluetoothTransmitter)
|
||||
|
||||
/// see explanation assignBluetoothTransmitterDelegate
|
||||
func reAssignBluetoothTransmitterDelegateToOriginal(for bluetoothTransmitter: BluetoothTransmitter)
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ class DexcomG5BluetoothPeripheralViewModel {
|
|||
/// reference to BluetoothPeripheralViewController that will own this WatlaaMasterBluetoothPeripheralViewModel - needed to present stuff etc
|
||||
private weak var bluetoothPeripheralViewController: BluetoothPeripheralViewController?
|
||||
|
||||
private weak var bluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
/// temporary stores CGMG5TransmitterDelegate
|
||||
private weak var previouslyAssignedcGMG5TransmitterDelegate: CGMG5TransmitterDelegate?
|
||||
|
||||
}
|
||||
|
||||
|
@ -32,7 +33,31 @@ class DexcomG5BluetoothPeripheralViewModel {
|
|||
|
||||
extension DexcomG5BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
||||
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate) {
|
||||
func assignBluetoothTransmitterDelegate(to bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
guard let cGMG5Transmitter = bluetoothTransmitter as? CGMG5Transmitter else {fatalError("DexcomG5BluetoothPeripheralViewModel: BluetoothPeripheralViewModel, assignBluetoothTransmitterDelegate, not a CGMG5Transmitter")}
|
||||
|
||||
previouslyAssignedcGMG5TransmitterDelegate = cGMG5Transmitter.cGMG5TransmitterDelegate
|
||||
|
||||
cGMG5Transmitter.cGMG5TransmitterDelegate = self
|
||||
|
||||
}
|
||||
|
||||
func reAssignBluetoothTransmitterDelegateToOriginal(for bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
guard let cGMG5Transmitter = bluetoothTransmitter as? CGMG5Transmitter else {fatalError("DexcomG5BluetoothPeripheralViewModel: BluetoothPeripheralViewModel, reAssignBluetoothTransmitterDelegateToOriginal, not a WatlaaBluetoothTransmitterMaster")}
|
||||
|
||||
guard let previouslyAssignedcGMG5TransmitterDelegate = previouslyAssignedcGMG5TransmitterDelegate else {
|
||||
|
||||
fatalError("DexcomG5BluetoothPeripheralViewModel: BluetoothPeripheralViewModel, reAssignBluetoothTransmitterDelegateToOriginal, previouslyAssignedcGMG5TransmitterDelegate is nil")
|
||||
return
|
||||
}
|
||||
|
||||
cGMG5Transmitter.cGMG5TransmitterDelegate = previouslyAssignedcGMG5TransmitterDelegate
|
||||
|
||||
}
|
||||
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController) {
|
||||
|
||||
self.bluetoothPeripheralManager = bluetoothPeripheralManager
|
||||
|
||||
|
@ -40,8 +65,6 @@ extension DexcomG5BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
|||
|
||||
self.bluetoothPeripheralViewController = bluetoothPeripheralViewController
|
||||
|
||||
self.bluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
|
||||
if let dexcomG5 = bluetoothPeripheral as? DexcomG5 {
|
||||
|
||||
storeTempValues(from: dexcomG5)
|
||||
|
@ -147,3 +170,16 @@ extension DexcomG5BluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension DexcomG5BluetoothPeripheralViewModel: CGMG5TransmitterDelegate {
|
||||
|
||||
func received(firmware: String, cGMG5Transmitter: CGMG5Transmitter) {
|
||||
|
||||
previouslyAssignedcGMG5TransmitterDelegate?.received(firmware: firmware, cGMG5Transmitter: cGMG5Transmitter)
|
||||
|
||||
// firmware should get updated in DexcomG5 object by bluetoothPeripheralManager, here's the trigger to update the table
|
||||
tableView?.reloadRows(at: [IndexPath(row: Settings.firmWareVersion.rawValue, section: 1)], with: .none)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -111,7 +111,8 @@ class M5StackBluetoothPeripheralViewModel {
|
|||
/// reference to BluetoothPeripheralViewController that will own this M5StackBluetoothPeripheralViewModel - needed to present stuff etc
|
||||
private(set) weak var bluetoothPeripheralViewController: BluetoothPeripheralViewController?
|
||||
|
||||
private weak var bluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
/// temporary stores M5StackBluetoothTransmitterDelegate
|
||||
private weak var previouslyAssignedM5StackBluetoothTransmitterDelegate: M5StackBluetoothTransmitterDelegate?
|
||||
|
||||
// MARK: - public functions
|
||||
|
||||
|
@ -497,21 +498,30 @@ extension M5StackBluetoothPeripheralViewModel: M5StackBluetoothTransmitterDelega
|
|||
|
||||
func receivedBattery(level: Int, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate?.receivedBattery(level: level, m5StackBluetoothTransmitter: m5StackBluetoothTransmitter)
|
||||
|
||||
// batteryLevel should get updated in M5Stack object by bluetoothPeripheralManager, here's the trigger to update the table
|
||||
tableView?.reloadRows(at: [IndexPath(row: SpecificM5StackSettings.batteryLevel.rawValue, section: M5StackSections.allCases.count)], with: .none)
|
||||
|
||||
}
|
||||
|
||||
func isAskingForAllParameters(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate?.isAskingForAllParameters(m5StackBluetoothTransmitter: m5StackBluetoothTransmitter)
|
||||
|
||||
// viewcontroller doesn't use this
|
||||
}
|
||||
|
||||
func isReadyToReceiveData(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate?.isReadyToReceiveData(m5StackBluetoothTransmitter: m5StackBluetoothTransmitter)
|
||||
|
||||
// viewcontroller doesn't use this
|
||||
}
|
||||
|
||||
func newBlePassWord(newBlePassword: String, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate?.newBlePassWord(newBlePassword: newBlePassword, m5StackBluetoothTransmitter: m5StackBluetoothTransmitter)
|
||||
|
||||
// note : blePassword is also saved in BluetoothPeripheralManager, it will be saved two times
|
||||
if let m5StackPeripheral = bluetoothPeripheralManager?.getBluetoothPeripheral(for: m5StackBluetoothTransmitter) as? M5Stack {
|
||||
|
||||
|
@ -525,6 +535,8 @@ extension M5StackBluetoothPeripheralViewModel: M5StackBluetoothTransmitterDelega
|
|||
|
||||
func authentication(success: Bool, m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate?.authentication(success: success, m5StackBluetoothTransmitter: m5StackBluetoothTransmitter)
|
||||
|
||||
if !success, let m5StackPeripheral = bluetoothPeripheralManager?.getBluetoothPeripheral(for: m5StackBluetoothTransmitter) as? M5Stack {
|
||||
|
||||
// show warning, inform that user should set password or reset M5Stack
|
||||
|
@ -541,6 +553,8 @@ extension M5StackBluetoothPeripheralViewModel: M5StackBluetoothTransmitterDelega
|
|||
|
||||
func blePasswordMissing(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate?.blePasswordMissing(m5StackBluetoothTransmitter: m5StackBluetoothTransmitter)
|
||||
|
||||
guard let m5StackPeripheral = bluetoothPeripheralManager?.getBluetoothPeripheral(for: m5StackBluetoothTransmitter) as? M5Stack else {return}
|
||||
|
||||
// show warning, inform that user should set password
|
||||
|
@ -557,6 +571,8 @@ extension M5StackBluetoothPeripheralViewModel: M5StackBluetoothTransmitterDelega
|
|||
|
||||
func m5StackResetRequired(m5StackBluetoothTransmitter: M5StackBluetoothTransmitter) {
|
||||
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate?.m5StackResetRequired(m5StackBluetoothTransmitter: m5StackBluetoothTransmitter)
|
||||
|
||||
guard let m5StackBluetoothPeripheral = bluetoothPeripheralManager?.getBluetoothPeripheral(for: m5StackBluetoothTransmitter) as? M5Stack else {return}
|
||||
|
||||
// show warning, inform that user should reset M5Stack
|
||||
|
@ -573,10 +589,34 @@ extension M5StackBluetoothPeripheralViewModel: M5StackBluetoothTransmitterDelega
|
|||
|
||||
}
|
||||
|
||||
// MARK: - extension BluetoothPeripheralViewModelProtocol
|
||||
// MARK: - conform to BluetoothPeripheralViewModel
|
||||
|
||||
extension M5StackBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
||||
|
||||
func assignBluetoothTransmitterDelegate(to bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
guard let m5StackBluetoothTransmitter = bluetoothTransmitter as? M5StackBluetoothTransmitter else {fatalError("M5StackBluetoothPeripheralViewModel: BluetoothPeripheralViewModel, assignBluetoothTransmitterDelegate, not a m5StackBluetoothTransmitter")}
|
||||
|
||||
previouslyAssignedM5StackBluetoothTransmitterDelegate = m5StackBluetoothTransmitter.m5StackBluetoothTransmitterDelegate
|
||||
|
||||
m5StackBluetoothTransmitter.m5StackBluetoothTransmitterDelegate = self
|
||||
|
||||
}
|
||||
|
||||
func reAssignBluetoothTransmitterDelegateToOriginal(for bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
guard let m5StackBluetoothTransmitter = bluetoothTransmitter as? M5StackBluetoothTransmitter else {fatalError("M5StackBluetoothPeripheralViewModel: BluetoothPeripheralViewModel, reAssignBluetoothTransmitterDelegateToOriginal, not a m5StackBluetoothTransmitter")}
|
||||
|
||||
guard let previouslyAssignedM5StackBluetoothTransmitter = previouslyAssignedM5StackBluetoothTransmitterDelegate else {
|
||||
|
||||
fatalError("M5StackBluetoothPeripheralViewModel: BluetoothPeripheralViewModel, reAssignBluetoothTransmitterDelegateToOriginal, previouslyAssignedM5StackBluetoothTransmitter is nil")
|
||||
return
|
||||
}
|
||||
|
||||
m5StackBluetoothTransmitter.m5StackBluetoothTransmitterDelegate = previouslyAssignedM5StackBluetoothTransmitter
|
||||
|
||||
}
|
||||
|
||||
func numberOfSections() -> Int {
|
||||
return numberOfM5Sections()
|
||||
}
|
||||
|
@ -720,7 +760,7 @@ extension M5StackBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
|||
/// - bluetoothPeripheralManager : reference to bluetoothPeripheralManaging object
|
||||
/// - tableView : needed to intiate refresh of row
|
||||
/// - bluetoothPeripheralViewController : BluetoothPeripheralViewController
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate) {
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController) {
|
||||
|
||||
self.bluetoothPeripheralManager = bluetoothPeripheralManager
|
||||
|
||||
|
@ -728,8 +768,6 @@ extension M5StackBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
|||
|
||||
self.bluetoothPeripheralViewController = bluetoothPeripheralViewController
|
||||
|
||||
self.bluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
|
||||
if let m5Stack = bluetoothPeripheral as? M5Stack {
|
||||
|
||||
storeTempValues(from: m5Stack)
|
||||
|
|
|
@ -22,8 +22,8 @@ class WatlaaMasterBluetoothPeripheralViewModel {
|
|||
/// reference to BluetoothPeripheralViewController that will own this WatlaaMasterBluetoothPeripheralViewModel - needed to present stuff etc
|
||||
private weak var bluetoothPeripheralViewController: BluetoothPeripheralViewController?
|
||||
|
||||
private weak var bluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
|
||||
/// temporary stores WatlaaBluetoothTransmitterDelegate
|
||||
private weak var previouslyAssignedWatlaaBluetoothTransmitterDelegate: WatlaaBluetoothTransmitterDelegate?
|
||||
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,31 @@ class WatlaaMasterBluetoothPeripheralViewModel {
|
|||
|
||||
extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel {
|
||||
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController, bluetoothTransmitterDelegate: BluetoothTransmitterDelegate) {
|
||||
func assignBluetoothTransmitterDelegate(to bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
guard let watlaaBluetoothTransmitter = bluetoothTransmitter as? WatlaaBluetoothTransmitterMaster else {fatalError("WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel, assignBluetoothTransmitterDelegate, not a WatlaaBluetoothTransmitterMaster")}
|
||||
|
||||
previouslyAssignedWatlaaBluetoothTransmitterDelegate = watlaaBluetoothTransmitter.watlaaBluetoothTransmitterDelegate
|
||||
|
||||
watlaaBluetoothTransmitter.watlaaBluetoothTransmitterDelegate = self
|
||||
|
||||
}
|
||||
|
||||
func reAssignBluetoothTransmitterDelegateToOriginal(for bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
guard let watlaaBluetoothTransmitter = bluetoothTransmitter as? WatlaaBluetoothTransmitterMaster else {fatalError("WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel, reAssignBluetoothTransmitterDelegateToOriginal, not a WatlaaBluetoothTransmitterMaster")}
|
||||
|
||||
guard let previouslyAssignedWatlaaBluetoothTransmitterDelegate = previouslyAssignedWatlaaBluetoothTransmitterDelegate else {
|
||||
|
||||
fatalError("WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel, reAssignBluetoothTransmitterDelegateToOriginal, previouslyAssignedWatlaaBluetoothTransmitterDelegate is nil")
|
||||
return
|
||||
}
|
||||
|
||||
watlaaBluetoothTransmitter.watlaaBluetoothTransmitterDelegate = previouslyAssignedWatlaaBluetoothTransmitterDelegate
|
||||
|
||||
}
|
||||
|
||||
func configure(bluetoothPeripheral: BluetoothPeripheral?, bluetoothPeripheralManager: BluetoothPeripheralManaging, tableView: UITableView, bluetoothPeripheralViewController: BluetoothPeripheralViewController) {
|
||||
|
||||
self.bluetoothPeripheralManager = bluetoothPeripheralManager
|
||||
|
||||
|
@ -39,8 +63,6 @@ extension WatlaaMasterBluetoothPeripheralViewModel: BluetoothPeripheralViewModel
|
|||
|
||||
self.bluetoothPeripheralViewController = bluetoothPeripheralViewController
|
||||
|
||||
self.bluetoothTransmitterDelegate = bluetoothTransmitterDelegate
|
||||
|
||||
if let watlaaPeripheral = bluetoothPeripheral as? Watlaa {
|
||||
|
||||
storeTempValues(from: watlaaPeripheral)
|
||||
|
|
|
@ -29,6 +29,9 @@ final class BluetoothPeripheralsViewController: UIViewController {
|
|||
/// a bluetoothPeripheralManager
|
||||
private weak var bluetoothPeripheralManager: BluetoothPeripheralManaging!
|
||||
|
||||
/// temp storage of assigned BluetoothTransmitterDelegate
|
||||
private weak var previouslyAssignedBluetoothTransmitterDelegate: BluetoothTransmitterDelegate?
|
||||
|
||||
// MARK: public functions
|
||||
|
||||
/// configure
|
||||
|
@ -41,6 +44,25 @@ final class BluetoothPeripheralsViewController: UIViewController {
|
|||
|
||||
}
|
||||
|
||||
// MARK: - De-initialization
|
||||
|
||||
deinit {
|
||||
|
||||
// to be sure that previouslyAssignedBluetoothTransmitterDelegate is reassigned to every existing BluetoothTransmistter
|
||||
|
||||
if let previouslyAssignedBluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate {
|
||||
|
||||
for bluetoothTransmitter in bluetoothPeripheralManager.getBluetoothTransmitters() {
|
||||
|
||||
// assign self as BluetoothTransmitterDelegate
|
||||
bluetoothTransmitter.bluetoothTransmitterDelegate = previouslyAssignedBluetoothTransmitterDelegate
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: overrides
|
||||
|
||||
override func viewDidLoad() {
|
||||
|
@ -152,9 +174,14 @@ final class BluetoothPeripheralsViewController: UIViewController {
|
|||
/// - sets the delegates of each transmitter to self
|
||||
private func initializeBluetoothPeripherals() {
|
||||
|
||||
for bluetoothtTransmitter in bluetoothPeripheralManager.getBluetoothTransmitters() {
|
||||
for bluetoothTransmitter in bluetoothPeripheralManager.getBluetoothTransmitters() {
|
||||
|
||||
bluetoothtTransmitter.variableBluetoothTransmitterDelegate = self
|
||||
// assign previously assigned BluetoothTransmitterDelegate, we will still pass all info to that delegate also
|
||||
// every bluetoothTransmitter may in theory have a different bluetoothTransmitterDelegate, so we should create an array of BluetoothTransmitterDelegate, however in practice it will always be the same bluetoothPeripheralManager
|
||||
previouslyAssignedBluetoothTransmitterDelegate = bluetoothTransmitter.bluetoothTransmitterDelegate
|
||||
|
||||
// assign self as BluetoothTransmitterDelegate
|
||||
bluetoothTransmitter.bluetoothTransmitterDelegate = self
|
||||
|
||||
}
|
||||
|
||||
|
@ -217,20 +244,72 @@ extension BluetoothPeripheralsViewController: UITableViewDataSource, UITableView
|
|||
|
||||
extension BluetoothPeripheralsViewController: BluetoothTransmitterDelegate {
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
func transmitterNeedsPairing(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.transmitterNeedsPairing(bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
func successfullyPaired() {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.successfullyPaired()
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
func pairingFailed() {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.pairingFailed()
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
|
||||
}
|
||||
|
||||
func reset(successful: Bool) {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.reset(successful: successful)
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
}
|
||||
|
||||
func error(message: String) {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.error(message: message)
|
||||
|
||||
// handled in BluetoothPeripheralManager
|
||||
}
|
||||
|
||||
func didConnectTo(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.didConnectTo(bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
updateRow(for: bluetoothPeripheralManager.getBluetoothPeripheral(for: bluetoothTransmitter))
|
||||
|
||||
}
|
||||
|
||||
func didDisconnectFrom(bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.didDisconnectFrom(bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
updateRow(for: bluetoothPeripheralManager.getBluetoothPeripheral(for: bluetoothTransmitter))
|
||||
|
||||
}
|
||||
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState, bluetoothTransmitter: BluetoothTransmitter) {
|
||||
|
||||
|
||||
// need to inform also other delegates
|
||||
previouslyAssignedBluetoothTransmitterDelegate?.deviceDidUpdateBluetoothState(state: state, bluetoothTransmitter: bluetoothTransmitter)
|
||||
|
||||
// when bluetooth status changes to powered off, the device, if connected, will disconnect, however didDisConnect doesn't get call (looks like an error in iOS) - so let's reload the cell that shows the connection status, this will refresh the cell
|
||||
if state == CBManagerState.poweredOff {
|
||||
updateRow(for: bluetoothPeripheralManager.getBluetoothPeripheral(for: bluetoothTransmitter))
|
||||
|
|
|
@ -3,11 +3,9 @@ import CoreData
|
|||
import os
|
||||
import CoreBluetooth
|
||||
import UserNotifications
|
||||
import AVFoundation
|
||||
import AudioToolbox
|
||||
import SwiftCharts
|
||||
import HealthKitUI
|
||||
|
||||
|
||||
/// viewcontroller for the home screen
|
||||
final class RootViewController: UIViewController {
|
||||
|
||||
|
@ -132,9 +130,6 @@ final class RootViewController: UIViewController {
|
|||
/// constant for key in ApplicationManager.shared.addClosureToRunWhenAppDidEnterBackground - updateLabels
|
||||
private let applicationManagerKeyUpdateLabelsAndChart = "RootViewController-UpdateLabelsAndChart"
|
||||
|
||||
/// constant for key in ApplicationManager.shared.addClosureToRunWhenAppWillEnterForeground - initiate pairing
|
||||
private let applicationManagerKeyInitiatePairing = "RootViewController-InitiatePairing"
|
||||
|
||||
/// constant for key in ApplicationManager.shared.addClosureToRunWhenAppWillEnterForeground - initial calibration
|
||||
private let applicationManagerKeyInitialCalibration = "RootViewController-InitialCalibration"
|
||||
|
||||
|
@ -182,24 +177,15 @@ final class RootViewController: UIViewController {
|
|||
/// WatchManager instance
|
||||
private var watchManager: WatchManager?
|
||||
|
||||
/// timer used when asking the transmitter to initiate pairing. The user is waiting for the response, if the response from the transmitter doesn't come within a few seconds, then we'll inform the user
|
||||
private var transmitterPairingResponseTimer:Timer?
|
||||
|
||||
/// healthkit manager instance
|
||||
private var healthKitManager:HealthKitManager?
|
||||
|
||||
/// reference to activeSensor
|
||||
private var activeSensor:Sensor?
|
||||
|
||||
/// if true, user manually started scanning for a device, when connection is made, we'll inform the user, see cgmTransmitterDidConnect
|
||||
private var userDidInitiateScanning = false
|
||||
|
||||
/// reference to bgReadingSpeaker
|
||||
private var bgReadingSpeaker:BGReadingSpeaker?
|
||||
|
||||
/// timestamp of last notification for pairing
|
||||
private var timeStampLastNotificationForPairing:Date?
|
||||
|
||||
/// manages bluetoothPeripherals that this app knows
|
||||
private var bluetoothPeripheralManager: BluetoothPeripheralManager?
|
||||
|
||||
|
@ -422,7 +408,7 @@ final class RootViewController: UIViewController {
|
|||
})
|
||||
|
||||
// setup bluetoothPeripheralManager
|
||||
bluetoothPeripheralManager = BluetoothPeripheralManager(coreDataManager: coreDataManager, cgmTransmitterDelegate: self, onCGMTransmitterCreation: {
|
||||
bluetoothPeripheralManager = BluetoothPeripheralManager(coreDataManager: coreDataManager, cgmTransmitterDelegate: self, uIViewController: self, onCGMTransmitterCreation: {
|
||||
(cgmTransmitter: CGMTransmitter?) in
|
||||
|
||||
self.cgmTransmitter = cgmTransmitter
|
||||
|
@ -630,15 +616,6 @@ final class RootViewController: UIViewController {
|
|||
|
||||
// MARK: - private helper functions
|
||||
|
||||
// inform user that pairing request timed out
|
||||
@objc private func informUserThatPairingTimedOut() {
|
||||
|
||||
let alert = UIAlertController(title: Texts_Common.warning, message: "time out", actionHandler: nil)
|
||||
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
||||
}
|
||||
|
||||
/// will update the chart with endDate = currentDate
|
||||
private func updateChartWithResetEndDate() {
|
||||
|
||||
|
@ -646,22 +623,6 @@ final class RootViewController: UIViewController {
|
|||
|
||||
}
|
||||
|
||||
/// will call cgmTransmitter.initiatePairing() - also sets timer, if no successful pairing within a few seconds, then info will be given to user asking to wait another few minutes
|
||||
private func initiateTransmitterPairing() {
|
||||
|
||||
// initiate the pairing
|
||||
cgmTransmitter?.initiatePairing()
|
||||
|
||||
// invalide the timer, if it exists
|
||||
if let transmitterPairingResponseTimer = transmitterPairingResponseTimer {
|
||||
transmitterPairingResponseTimer.invalidate()
|
||||
}
|
||||
|
||||
// create and schedule timer
|
||||
transmitterPairingResponseTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(informUserThatPairingTimedOut), userInfo: nil, repeats: false)
|
||||
|
||||
}
|
||||
|
||||
/// launches timer that will do regular screen updates - and adds closure to ApplicationManager : when going to background, stop the timer, when coming to foreground, restart the timer
|
||||
///
|
||||
/// should be called only once immediately after app start, ie in viewdidload
|
||||
|
@ -812,35 +773,35 @@ final class RootViewController: UIViewController {
|
|||
|
||||
case .dexcomG4:
|
||||
if let currentTransmitterId = UserDefaults.standard.transmitterId {
|
||||
cgmTransmitter = CGMG4xDripTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId, delegate:self)
|
||||
cgmTransmitter = CGMG4xDripTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId)
|
||||
}
|
||||
|
||||
case .dexcomG5:
|
||||
if let currentTransmitterId = UserDefaults.standard.transmitterId {
|
||||
cgmTransmitter = CGMG5Transmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId, cGMTransmitterDelegate: self)
|
||||
cgmTransmitter = CGMG5Transmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId, bluetoothTransmitterDelegate: self, cGMTransmitterDelegate: self)
|
||||
}
|
||||
|
||||
case .dexcomG6:
|
||||
if let currentTransmitterId = UserDefaults.standard.transmitterId {
|
||||
cgmTransmitter = CGMG6Transmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId, cGMTransmitterDelegate: self)
|
||||
cgmTransmitter = CGMG6Transmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId, bluetoothTransmitterDelegate: self, cGMTransmitterDelegate: self)
|
||||
}
|
||||
|
||||
case .miaomiao:
|
||||
cgmTransmitter = CGMMiaoMiaoTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, delegate: self, timeStampLastBgReading: Date(timeIntervalSince1970: 0), webOOPEnabled: UserDefaults.standard.webOOPEnabled, oopWebSite: UserDefaults.standard.webOOPSite ?? ConstantsLibreOOP.site, oopWebToken: UserDefaults.standard.webOOPtoken ?? ConstantsLibreOOP.token)
|
||||
cgmTransmitter = CGMMiaoMiaoTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, bluetoothTransmitterDelegate: <#BluetoothTransmitterDelegate#>, timeStampLastBgReading: Date(timeIntervalSince1970: 0), webOOPEnabled: UserDefaults.standard.webOOPEnabled, oopWebSite: UserDefaults.standard.webOOPSite ?? ConstantsLibreOOP.site, oopWebToken: UserDefaults.standard.webOOPtoken ?? ConstantsLibreOOP.token)
|
||||
|
||||
case .Bubble:
|
||||
cgmTransmitter = CGMBubbleTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, delegate: self, timeStampLastBgReading: Date(timeIntervalSince1970: 0), sensorSerialNumber: UserDefaults.standard.sensorSerialNumber, webOOPEnabled: UserDefaults.standard.webOOPEnabled, oopWebSite: UserDefaults.standard.webOOPSite ?? ConstantsLibreOOP.site, oopWebToken: UserDefaults.standard.webOOPtoken ?? ConstantsLibreOOP.token)
|
||||
cgmTransmitter = CGMBubbleTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, bluetoothTransmitterDelegate: <#BluetoothTransmitterDelegate#>, timeStampLastBgReading: Date(timeIntervalSince1970: 0), sensorSerialNumber: UserDefaults.standard.sensorSerialNumber, webOOPEnabled: UserDefaults.standard.webOOPEnabled, oopWebSite: UserDefaults.standard.webOOPSite ?? ConstantsLibreOOP.site, oopWebToken: UserDefaults.standard.webOOPtoken ?? ConstantsLibreOOP.token)
|
||||
|
||||
case .GNSentry:
|
||||
cgmTransmitter = CGMGNSEntryTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, delegate: self, timeStampLastBgReading: Date(timeIntervalSince1970: 0))
|
||||
cgmTransmitter = CGMGNSEntryTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, bluetoothTransmitterDelegate: <#BluetoothTransmitterDelegate#>, timeStampLastBgReading: Date(timeIntervalSince1970: 0))
|
||||
|
||||
case .Blucon:
|
||||
if let currentTransmitterId = UserDefaults.standard.transmitterId {
|
||||
cgmTransmitter = CGMBluconTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId, delegate: self, timeStampLastBgReading: Date(timeIntervalSince1970: 0), sensorSerialNumber: UserDefaults.standard.sensorSerialNumber)
|
||||
cgmTransmitter = CGMBluconTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, transmitterID: currentTransmitterId, bluetoothTransmitterDelegate: <#BluetoothTransmitterDelegate#>, timeStampLastBgReading: Date(timeIntervalSince1970: 0), sensorSerialNumber: UserDefaults.standard.sensorSerialNumber)
|
||||
}
|
||||
|
||||
case .Droplet1:
|
||||
cgmTransmitter = CGMDroplet1Transmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, delegate: self)
|
||||
cgmTransmitter = CGMDroplet1Transmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName)
|
||||
|
||||
case .blueReader:
|
||||
cgmTransmitter = CGMBlueReaderTransmitter(address: UserDefaults.standard.cgmTransmitterDeviceAddress, name: UserDefaults.standard.cgmTransmitterDeviceName, delegate: self)
|
||||
|
@ -1381,186 +1342,6 @@ extension RootViewController:CGMTransmitterDelegate {
|
|||
|
||||
}
|
||||
|
||||
func reset(successful: Bool) {
|
||||
|
||||
// reset setting to false
|
||||
UserDefaults.standard.transmitterResetRequired = false
|
||||
|
||||
// Create Notification Content to give info about reset result of reset attempt
|
||||
let notificationContent = UNMutableNotificationContent()
|
||||
|
||||
// Configure NnotificationContent title
|
||||
notificationContent.title = successful ? Texts_HomeView.info : Texts_Common.warning
|
||||
|
||||
notificationContent.body = Texts_HomeView.transmitterResetResult + " : " + (successful ? Texts_HomeView.success : Texts_HomeView.failed)
|
||||
|
||||
// Create Notification Request
|
||||
let notificationRequest = UNNotificationRequest(identifier: ConstantsNotifications.NotificationIdentifierForResetResult.transmitterResetResult, content: notificationContent, trigger: nil)
|
||||
|
||||
// Add Request to User Notification Center
|
||||
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
|
||||
if let error = error {
|
||||
trace("Unable add notification request : transmitter reset result, error: %{public}@", log: self.log, category: ConstantsLog.categoryRootView, type: .error, error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func pairingFailed() {
|
||||
// this should be the consequence of the user not accepting the pairing request, there's no need to inform the user
|
||||
// invalidate transmitterPairingResponseTimer
|
||||
if let transmitterPairingResponseTimer = transmitterPairingResponseTimer {
|
||||
transmitterPairingResponseTimer.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
func successfullyPaired() {
|
||||
|
||||
// remove existing notification if any
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing])
|
||||
|
||||
// invalidate transmitterPairingResponseTimer
|
||||
if let transmitterPairingResponseTimer = transmitterPairingResponseTimer {
|
||||
transmitterPairingResponseTimer.invalidate()
|
||||
}
|
||||
|
||||
// inform user
|
||||
let alert = UIAlertController(title: Texts_HomeView.info, message: Texts_HomeView.transmitterPairingSuccessful, actionHandler: nil)
|
||||
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
||||
}
|
||||
|
||||
func cgmTransmitterDidConnect(address:String?, name:String?) {
|
||||
// store address and name, if this is the first connect to a specific device, then this address and name will be used in the future to reconnect to the same device, without having to scan
|
||||
if let address = address, let name = name {
|
||||
UserDefaults.standard.cgmTransmitterDeviceAddress = address
|
||||
UserDefaults.standard.cgmTransmitterDeviceName = name
|
||||
}
|
||||
|
||||
// if the connect is a result of a user initiated start scanning, then display message that connection was successful
|
||||
if userDidInitiateScanning {
|
||||
userDidInitiateScanning = false
|
||||
// additional info for the user
|
||||
let alert = UIAlertController(title: Texts_HomeView.scanBluetoothDeviceActionTitle, message: Texts_HomeView.bluetoothDeviceConnectedInfo, actionHandler: nil)
|
||||
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func cgmTransmitterDidDisconnect() {
|
||||
// set disconnect timestamp
|
||||
UserDefaults.standard.lastdisConnectTimestamp = Date()
|
||||
}
|
||||
|
||||
func deviceDidUpdateBluetoothState(state: CBManagerState) {
|
||||
|
||||
switch state {
|
||||
|
||||
case .unknown:
|
||||
break
|
||||
case .resetting:
|
||||
break
|
||||
case .unsupported:
|
||||
break
|
||||
case .unauthorized:
|
||||
break
|
||||
case .poweredOff:
|
||||
UserDefaults.standard.lastdisConnectTimestamp = Date()
|
||||
case .poweredOn:
|
||||
// user changes device bluetooth status to on
|
||||
|
||||
if UserDefaults.standard.cgmTransmitterDeviceAddress == nil, let cgmTransmitter = cgmTransmitter, let transmitterType = UserDefaults.standard.transmitterType, transmitterType.startScanningAfterInit() {
|
||||
// bluetoothDeviceAddress = nil, means app hasn't connected before to the transmitter
|
||||
// cgmTransmitter != nil, means user has configured transmitter type and transmitterid
|
||||
// transmitterType.startScanningAfterInit() gives true, means it's ok to start the scanning
|
||||
// possibly scanning is already running, but that's ok if we call the startScanning function again
|
||||
_ = cgmTransmitter.startScanning()
|
||||
}
|
||||
|
||||
@unknown default:
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Transmitter is calling this delegate function to indicate that bluetooth pairing is needed. If the app is in the background, the user will be informed, after opening the app a pairing request will be initiated. if the app is in the foreground, the pairing request will be initiated immediately
|
||||
func cgmTransmitterNeedsPairing() {
|
||||
|
||||
trace("transmitter needs pairing", log: log, category: ConstantsLog.categoryRootView, type: .info)
|
||||
|
||||
if let timeStampLastNotificationForPairing = timeStampLastNotificationForPairing {
|
||||
|
||||
// check timestamp of last notification, if too soon then return
|
||||
if Int(abs(timeStampLastNotificationForPairing.timeIntervalSinceNow)) < ConstantsBluetoothPairing.minimumTimeBetweenTwoPairingNotificationsInSeconds {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// set timeStampLastNotificationForPairing
|
||||
timeStampLastNotificationForPairing = Date()
|
||||
|
||||
// remove existing notification if any
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing])
|
||||
|
||||
// Create Notification Content
|
||||
let notificationContent = UNMutableNotificationContent()
|
||||
|
||||
// Configure NnotificationContent title
|
||||
notificationContent.title = Texts_Common.warning
|
||||
|
||||
notificationContent.body = Texts_HomeView.transmitterNotPaired
|
||||
|
||||
// add sound
|
||||
notificationContent.sound = UNNotificationSound.init(named: UNNotificationSoundName.init(""))
|
||||
|
||||
// Create Notification Request
|
||||
let notificationRequest = UNNotificationRequest(identifier: ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing, content: notificationContent, trigger: nil)
|
||||
|
||||
// Add Request to User Notification Center
|
||||
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
|
||||
if let error = error {
|
||||
trace("Unable add notification request : transmitter needs pairing Notification Request, error : %{public}@", log: self.log, category: ConstantsLog.categoryRootView, type: .error, error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
// vibrate
|
||||
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||
|
||||
// add closure to ApplicationManager.shared.addClosureToRunWhenAppWillEnterForeground so that if user opens the app, the pairing request will be initiated. This can be done only if the app is opened within 60 seconds.
|
||||
// If the app is already in the foreground, then userNotificationCenter willPresent will be called, in this function the closure will be removed immediately, and the pairing request will be called. As a result, if the app is in the foreground, the user will not see (or hear) any notification, but the pairing will be initiated
|
||||
|
||||
// max timestamp when notification was fired - connection stays open for 1 minute, taking 1 second as d
|
||||
let maxTimeUserCanOpenApp = Date(timeIntervalSinceNow: TimeInterval(ConstantsDexcomG5.maxTimeToAcceptPairingInSeconds - 1))
|
||||
|
||||
// we will not just count on it that the user will click the notification to open the app (assuming the app is in the background, if the app is in the foreground, then we come in another flow)
|
||||
// whenever app comes from-back to foreground, updateLabelsAndChart needs to be called
|
||||
ApplicationManager.shared.addClosureToRunWhenAppWillEnterForeground(key: applicationManagerKeyInitiatePairing, closure: {
|
||||
|
||||
// first of all reremove from application key manager
|
||||
ApplicationManager.shared.removeClosureToRunWhenAppWillEnterForeground(key: self.applicationManagerKeyInitiatePairing)
|
||||
|
||||
// first remove existing notification if any
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [ConstantsNotifications.NotificationIdentifierForTransmitterNeedsPairing.transmitterNeedsPairing])
|
||||
|
||||
// if it was too long since notification was fired, then forget about it
|
||||
if Date() > maxTimeUserCanOpenApp {
|
||||
trace("in cgmTransmitterNeedsPairing, user opened the app too late", log: self.log, category: ConstantsLog.categoryRootView, type: .error)
|
||||
let alert = UIAlertController(title: Texts_Common.warning, message: Texts_HomeView.transmitterPairingTooLate, actionHandler: nil)
|
||||
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// initiate the pairing
|
||||
self.cgmTransmitter?.initiatePairing()
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Only MioaMiao will call this
|
||||
func newSensorDetected() {
|
||||
trace("new sensor detected", log: log, category: ConstantsLog.categoryRootView, type: .info)
|
||||
|
|
Loading…
Reference in New Issue