From c3010bacc7d77c141d4ba1fcf8ec45b3a033604e Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 14 Jan 2023 17:36:58 +0000 Subject: [PATCH 1/7] Fixes #195. Develop branch version bumped to v2.2.0 Signed-off-by: Adam Fowler --- Herald-for-iOS.xcodeproj/project.pbxproj | 4 ++-- Herald.podspec | 2 +- Herald/Herald.xcodeproj/project.pbxproj | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Herald-for-iOS.xcodeproj/project.pbxproj b/Herald-for-iOS.xcodeproj/project.pbxproj index 884d12f..a10e5ab 100644 --- a/Herald-for-iOS.xcodeproj/project.pbxproj +++ b/Herald-for-iOS.xcodeproj/project.pbxproj @@ -399,7 +399,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.2.0; PRODUCT_BUNDLE_IDENTIFIER = io.heraldprox.herald.app; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -420,7 +420,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.2.0; PRODUCT_BUNDLE_IDENTIFIER = io.heraldprox.herald.app; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/Herald.podspec b/Herald.podspec index 91d2840..98d3653 100644 --- a/Herald.podspec +++ b/Herald.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |spec| spec.name = "Herald" - spec.version = "2.1.0" + spec.version = "2.2.0" spec.summary = "Reliable Bluetooth communication library for iOS" spec.description = <<-DESC diff --git a/Herald/Herald.xcodeproj/project.pbxproj b/Herald/Herald.xcodeproj/project.pbxproj index c60623f..9db00c0 100644 --- a/Herald/Herald.xcodeproj/project.pbxproj +++ b/Herald/Herald.xcodeproj/project.pbxproj @@ -840,7 +840,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.2.0; PRODUCT_BUNDLE_IDENTIFIER = io.heraldprox.herald; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; @@ -868,7 +868,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.2.0; PRODUCT_BUNDLE_IDENTIFIER = io.heraldprox.herald; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; From f66afd4d37e2d4d75e9e57d01c6ae33abf29a26b Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Tue, 7 Feb 2023 20:18:57 +0000 Subject: [PATCH 2/7] Added support for older iPhone builds for testing (Requires XCode < v14) Signed-off-by: Adam Fowler --- Herald-for-iOS.xcodeproj/project.pbxproj | 10 ++++++++++ Herald/Herald.xcodeproj/project.pbxproj | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/Herald-for-iOS.xcodeproj/project.pbxproj b/Herald-for-iOS.xcodeproj/project.pbxproj index a10e5ab..73a0267 100644 --- a/Herald-for-iOS.xcodeproj/project.pbxproj +++ b/Herald-for-iOS.xcodeproj/project.pbxproj @@ -389,6 +389,11 @@ B692CAA824CADA7A00F45AEE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7, + armv7s, + ); ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; @@ -410,6 +415,11 @@ B692CAA924CADA7A00F45AEE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7, + armv7s, + ); ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; diff --git a/Herald/Herald.xcodeproj/project.pbxproj b/Herald/Herald.xcodeproj/project.pbxproj index 9db00c0..65a853c 100644 --- a/Herald/Herald.xcodeproj/project.pbxproj +++ b/Herald/Herald.xcodeproj/project.pbxproj @@ -704,6 +704,11 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7, + armv7s, + ); CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -768,6 +773,11 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ( + "$(ARCHS_STANDARD)", + armv7, + armv7s, + ); CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; From aa72bbeda5778d7bc275873bf246ac426f2e8cdc Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Tue, 7 Feb 2023 20:19:43 +0000 Subject: [PATCH 3/7] Added explicit support for custom Herald service UUIDs Signed-off-by: Adam Fowler --- Herald/Herald/Sensor/BLE/BLEDatabase.swift | 5 +- Herald/Herald/Sensor/BLE/BLEReceiver.swift | 80 ++++++++++++++---- Herald/Herald/Sensor/BLE/BLESensor.swift | 82 ++++++++++++++++--- Herald/Herald/Sensor/BLE/BLETransmitter.swift | 24 ++++-- Herald/Herald/Sensor/SensorArray.swift | 7 +- 5 files changed, 160 insertions(+), 38 deletions(-) diff --git a/Herald/Herald/Sensor/BLE/BLEDatabase.swift b/Herald/Herald/Sensor/BLE/BLEDatabase.swift index 4df97ad..27ebcb4 100644 --- a/Herald/Herald/Sensor/BLE/BLEDatabase.swift +++ b/Herald/Herald/Sensor/BLE/BLEDatabase.swift @@ -579,9 +579,10 @@ class BLEPseudoDeviceAddress { return nil } // HERALD pseudo device address - if (manufacturerId == BLESensorConfiguration.linuxFoundationManufacturerIdForSensor || + if ( (BLESensorConfiguration.standardHeraldServiceDetectionEnabled && manufacturerId == BLESensorConfiguration.linuxFoundationManufacturerIdForSensor) || + (BLESensorConfiguration.customServiceDetectionEnabled && 0 != BLESensorConfiguration.customManufacturerIdForSensor && manufacturerId == BLESensorConfiguration.customManufacturerIdForSensor) || (BLESensorConfiguration.legacyHeraldServiceDetectionEnabled && manufacturerId == BLESensorConfiguration.legacyHeraldManufacturerIdForSensor) - ) && manufacturerData.count == 8 { + ) && manufacturerData.count >= 8 { self.init(data: Data(manufacturerData.subdata(in: 2..<8))) } // Legacy pseudo device address diff --git a/Herald/Herald/Sensor/BLE/BLEReceiver.swift b/Herald/Herald/Sensor/BLE/BLEReceiver.swift index 4240b04..f33a4c6 100644 --- a/Herald/Herald/Sensor/BLE/BLEReceiver.swift +++ b/Herald/Herald/Sensor/BLE/BLEReceiver.swift @@ -257,7 +257,23 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral */ private func taskScanForPeripherals() { // Scan for peripherals -> didDiscover - var scanForServices: [CBUUID] = [BLESensorConfiguration.linuxFoundationServiceUUID] + var scanForServices: [CBUUID] = [] + var solicitedKeys: [CBUUID] = [] + if BLESensorConfiguration.standardHeraldServiceDetectionEnabled { + scanForServices.append(BLESensorConfiguration.linuxFoundationServiceUUID) + solicitedKeys.append(BLESensorConfiguration.linuxFoundationServiceUUID) + } + if BLESensorConfiguration.customServiceDetectionEnabled { + if let csuuid = BLESensorConfiguration.customServiceUUID { + scanForServices.append(csuuid) + solicitedKeys.append(csuuid) + } + if let casuuids = BLESensorConfiguration.customAdditionalServiceUUIDs { + for suuid in BLESensorConfiguration.customServiceUUID { + scanForServices.append(suuid) + } + } + } // Optionally, include the old Herald service UUID (prior to v2.1.0) if BLESensorConfiguration.legacyHeraldServiceDetectionEnabled { scanForServices.append(BLESensorConfiguration.legacyHeraldServiceUUID) @@ -272,26 +288,41 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral } central.scanForPeripherals( withServices: scanForServices, - options: [CBCentralManagerScanOptionSolicitedServiceUUIDsKey: [BLESensorConfiguration.linuxFoundationServiceUUID]]) + options: [CBCentralManagerScanOptionSolicitedServiceUUIDsKey: solicitedKeys]) } /** Register all connected peripherals advertising the sensor service as a device. */ private func taskRegisterConnectedPeripherals() { - var services: [CBUUID] = [BLESensorConfiguration.linuxFoundationServiceUUID] + var services: [CBUUID] = [] + if BLESensorConfiguration.standardHeraldServiceDetectionEnabled { + services.append(BLESensorConfiguration.linuxFoundationServiceUUID) + } + if BLESensorConfiguration.customServiceDetectionEnabled { + if let csuuid = BLESensorConfiguration.customServiceUUID { + services.append(csuuid) + } + if let casuuids = BLESensorConfiguration.customAdditionalServiceUUIDs { + for suuid in BLESensorConfiguration.customServiceUUID { + services.append(suuid) + } + } + } // Optionally, include the old Herald service UUID (prior to v2.1.0) if BLESensorConfiguration.legacyHeraldServiceDetectionEnabled { services.append(BLESensorConfiguration.legacyHeraldServiceUUID) } - central.retrieveConnectedPeripherals(withServices: services).forEach() { peripheral in -// let targetIdentifier = TargetIdentifier(peripheral: peripheral) - let device = database.device(peripheral, delegate: self) - logger.debug("taskRegisterConnectedPeripherals (device=\(device))") -// if device.peripheral == nil || device.peripheral != peripheral { -// logger.debug("taskRegisterConnectedPeripherals (device=\(device))") -// _ = database.device(peripheral, delegate: self) -// } + if !services.isEmpty { + central.retrieveConnectedPeripherals(withServices: services).forEach() { peripheral in + // let targetIdentifier = TargetIdentifier(peripheral: peripheral) + let device = database.device(peripheral, delegate: self) + logger.debug("taskRegisterConnectedPeripherals (device=\(device))") + // if device.peripheral == nil || device.peripheral != peripheral { + // logger.debug("taskRegisterConnectedPeripherals (device=\(device))") + // _ = database.device(peripheral, delegate: self) + // } + } } } @@ -794,7 +825,20 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral return } queue.async { - var services: [CBUUID] = [BLESensorConfiguration.linuxFoundationServiceUUID] + var services: [CBUUID] = [] + if BLESensorConfiguration.standardHeraldServiceDetectionEnabled { + services.append(BLESensorConfiguration.linuxFoundationServiceUUID) + } + if BLESensorConfiguration.customServiceDetectionEnabled { + if let csuuid = BLESensorConfiguration.customServiceUUID { + services.append(csuuid) + } + if let casuuids = BLESensorConfiguration.customAdditionalServiceUUIDs { + for suuid in BLESensorConfiguration.customServiceUUID { + services.append(suuid) + } + } + } // Optionally, include the old Herald service UUID (prior to v2.1.0) if BLESensorConfiguration.legacyHeraldServiceDetectionEnabled { services.append(BLESensorConfiguration.legacyHeraldServiceUUID) @@ -1033,13 +1077,17 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral return } for service in services { - if (service.uuid == BLESensorConfiguration.linuxFoundationServiceUUID) || - (BLESensorConfiguration.legacyHeraldServiceDetectionEnabled && service.uuid == BLESensorConfiguration.legacyHeraldServiceUUID) { - logger.debug("didDiscoverServices, found sensor service (device=\(device))") + if (BLESensorConfiguration.standardHeraldServiceDetectionEnabled && service.uuid == BLESensorConfiguration.linuxFoundationServiceUUID) || + (BLESensorConfiguration.customServiceDetectionEnabled && ( + (nil != BLESensorConfiguration.customServiceUUID && service.uuid == BLESensorConfiguration.customServiceUUID) || + (nil != BLESensorConfiguration.customAdditionalServiceUUIDs && BLESensorConfiguration.customAdditionalServiceUUIDs.contains(service.uuid)) + ) || + (BLESensorConfiguration.legacyHeraldServiceDetectionEnabled && service.uuid == BLESensorConfiguration.legacyHeraldServiceUUID) { + logger.debug("didDiscoverServices, found sensor service (device=\(device),service=\(service.uuid.uuidString))") queue.async { peripheral.discoverCharacteristics(nil, for: service) } return } else if BLESensorConfiguration.interopOpenTraceEnabled, service.uuid == BLESensorConfiguration.interopOpenTraceServiceUUID { - logger.debug("didDiscoverServices, found legacy service (device=\(device))") + logger.debug("didDiscoverServices, found legacy service (device=\(device),service=\(service.uuid.uuidString))") queue.async { peripheral.discoverCharacteristics(nil, for: service) } return } diff --git a/Herald/Herald/Sensor/BLE/BLESensor.swift b/Herald/Herald/Sensor/BLE/BLESensor.swift index 1e150e8..9ef6596 100644 --- a/Herald/Herald/Sensor/BLE/BLESensor.swift +++ b/Herald/Herald/Sensor/BLE/BLESensor.swift @@ -7,6 +7,7 @@ import Foundation import CoreBluetooth +import CoreFoundation protocol BLESensor : Sensor { } @@ -20,9 +21,9 @@ public struct BLESensorConfiguration { /// then discover services to identify actual beacons. /// - Service and characteristic UUIDs are V4 UUIDs that have been randomly generated and tested /// for uniqueness by conducting web searches to ensure it returns no results. - public static var legacyHeraldServiceUUID: CBUUID = CBUUID(string: "428132af-4746-42d3-801e-4572d65bfd9b") + public static let legacyHeraldServiceUUID: CBUUID = CBUUID(string: "428132af-4746-42d3-801e-4572d65bfd9b") /// The legacy unregistered manufacturer ID that was used by Herald until Oct 2022 - public static var legacyHeraldManufacturerIdForSensor: UInt16 = UInt16(65530) + public static let legacyHeraldManufacturerIdForSensor: UInt16 = UInt16(65530) /// Detect the old legacy (unregistered) 128 bit Herald service ID /// Since v2.1.0 (Oct 2022) /// Deprecated. Support will be removed by Oct 2023. May be changed to false by default before then. @@ -30,25 +31,82 @@ public struct BLESensorConfiguration { /// The Service UUID (Short) used by Herald since v2.1.0 (Oct 2022) /// See legacyHeraldServiceDetectionEnabled and legacyHeraldServiceUUID for the prior service support - public static var linuxFoundationServiceUUID: CBUUID = CBUUID(string: "0000FCF6-0000-1000-8000-00805F9B34FB") + public static let linuxFoundationServiceUUID: CBUUID = CBUUID(string: "0000FCF6-0000-1000-8000-00805F9B34FB") /// Manufacturer data is being used on Android to store pseudo device address /// - This is now the dedicated Linux Foundation manufacturer ID (decimal 1521, hex 0x05F1) /// See legacyHeraldManufacturerIdForSensor for previous version - public static var linuxFoundationManufacturerIdForSensor: UInt16 = UInt16(1521) // aka 0x05F1 + public static let linuxFoundationManufacturerIdForSensor: UInt16 = UInt16(1521) // aka 0x05F1 + + /** + * Enables detection of the current standard Herald service UUID. + * Enabled by default + * @since v2.2 February 2023 + */ + public static var standardHeraldServiceDetectionEnabled: Bool = true; + + /** + * Enables advertising of the current standard Herald service UUID. + * Enabled by default + * @since v2.2 February 2023 + */ + public static var standardHeraldServiceAdvertisingEnabled: Bool = true; /// Signaling characteristic for controlling connection between peripheral and central, e.g. keep each other from suspend state /// - Characteristic UUID is randomly generated V4 UUIDs that has been tested for uniqueness by conducting web searches to ensure it returns no results. - public static var androidSignalCharacteristicUUID: CBUUID = CBUUID(string: "f617b813-092e-437a-8324-e09a80821a11") + public static let androidSignalCharacteristicUUID: CBUUID = CBUUID(string: "f617b813-092e-437a-8324-e09a80821a11") /// Signaling characteristic for controlling connection between peripheral and central, e.g. keep each other from suspend state /// - Characteristic UUID is randomly generated V4 UUIDs that has been tested for uniqueness by conducting web searches to ensure it returns no results. - public static var iosSignalCharacteristicUUID: CBUUID = CBUUID(string: "0eb0d5f2-eae4-4a9a-8af3-a4adb02d4363") + public static let iosSignalCharacteristicUUID: CBUUID = CBUUID(string: "0eb0d5f2-eae4-4a9a-8af3-a4adb02d4363") /// Primary payload characteristic (read) for distributing payload data from peripheral to central, e.g. identity data /// - Characteristic UUID is randomly generated V4 UUIDs that has been tested for uniqueness by conducting web searches to ensure it returns no results. - public static var payloadCharacteristicUUID: CBUUID = CBUUID(string: "3e98c0f8-8f05-4829-a121-43e38f8933e7") + public static let payloadCharacteristicUUID: CBUUID = CBUUID(string: "3e98c0f8-8f05-4829-a121-43e38f8933e7") /// Secured Payload exchange registered UUID /// Since v2.1.0 (Not used until a future version TBD) - public static var securedPayloadCharacteristicUUID: CBUUID = CBUUID(string: "ae9f88ca-6ea6-494d-bd3f-09ffa3380340") + public static let securedPayloadCharacteristicUUID: CBUUID = CBUUID(string: "ae9f88ca-6ea6-494d-bd3f-09ffa3380340") + // MARK:- Custom Service UUID interoperability - Since v2.2 + /** + * A custom service UUID to use for a Herald service. Required for custom apps (without Herald interop). + * + * @since v2.2 February 2023 + * @note Requires customHeraldServiceDetectionEnabled to be set to true to enable. + */ + public static var customServiceUUID: UUID = null; + /** + * Whether to detect a custom service UUID. Disabled by default. + * Doesn't affect advertising. + * in preference to the default Linux Foundation Herald UUID if specified. + * Only takes effect if customServiceUUID is set to a valid non-null UUID. + * + * @since v2.2 February 2023 + */ + public static var customServiceDetectionEnabled: Bool = false; + /** + * Whether to advertise using the main customServiceUUID instead of the standard Herald + * Service UUID. + * + * @since v2.2 February 2023 + */ + public static var customServiceAdvertisingEnabled: Bool = false; + /** + * Additional UUIDs beyond just customServiceUUID to detect. Useful for 'legacy' custom + * application detections. You do not have to include customServiceUUID in this list. + * + * @since v2.2 February 2023 + * @note Requires customHeraldServiceDetectionEnabled to be set to true to enable. + */ + public static var customAdditionalServiceUUIDs: [UUID] = null; + /** + * The custom manufacturer ID to use. Note this MUST be a Bluetooth SIG registered ID to + * ensure there is no interference. + * Note that if this is not specified, then the default Linux Foundation Herald service + * manufacturer ID will be used. + * + * @since v2.2 February 2023 + * @note Requires customHeraldServiceDetectionEnabled to be set to true to enable. + * @note Requires pseudoDeviceAddress to be enabled. + */ + static var customManufacturerIdForSensor: Int = 0; // MARK:- Interoperability with OpenTrace @@ -89,13 +147,13 @@ public struct BLESensorConfiguration { // MARK:- BLE signal characteristic action codes /// Signal characteristic action code for write payload, expect 1 byte action code followed by 2 byte little-endian Int16 integer value for payload data length, then payload data - public static var signalCharacteristicActionWritePayload: UInt8 = UInt8(1) + public static let signalCharacteristicActionWritePayload: UInt8 = UInt8(1) /// Signal characteristic action code for write RSSI, expect 1 byte action code followed by 4 byte little-endian Int32 integer value for RSSI value - public static var signalCharacteristicActionWriteRSSI: UInt8 = UInt8(2) + public static let signalCharacteristicActionWriteRSSI: UInt8 = UInt8(2) /// Signal characteristic action code for write payload, expect 1 byte action code followed by 2 byte little-endian Int16 integer value for payload sharing data length, then payload sharing data - public static var signalCharacteristicActionWritePayloadSharing: UInt8 = UInt8(3) + public static let signalCharacteristicActionWritePayloadSharing: UInt8 = UInt8(3) /// Signal characteristic action code for arbitrary immediate write - public static var signalCharacteristicActionWriteImmediate: UInt8 = UInt8(4) + public static let signalCharacteristicActionWriteImmediate: UInt8 = UInt8(4) // MARK:- BLE event timing diff --git a/Herald/Herald/Sensor/BLE/BLETransmitter.swift b/Herald/Herald/Sensor/BLE/BLETransmitter.swift index 5ef663c..515fad7 100644 --- a/Herald/Herald/Sensor/BLE/BLETransmitter.swift +++ b/Herald/Herald/Sensor/BLE/BLETransmitter.swift @@ -127,7 +127,11 @@ class ConcreteBLETransmitter : NSObject, BLETransmitter, CBPeripheralManagerDele } else { queue.async { self.peripheral.stopAdvertising() - self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.linuxFoundationServiceUUID]]) + if BLESensorConfiguration.customServiceAdvertisingEnabled && nil != BLESensorConfiguration.customServiceUUID { + self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.customServiceUUID]]) + } else if BLESensorConfiguration.standardHeraldServiceAdvertisingEnabled { + self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.linuxFoundationServiceUUID]]) + } } } } else { @@ -148,20 +152,26 @@ class ConcreteBLETransmitter : NSObject, BLETransmitter, CBPeripheralManagerDele payloadCharacteristic = CBMutableCharacteristic(type: BLESensorConfiguration.payloadCharacteristicUUID, properties: [.read], value: nil, permissions: [.readable]) legacyPayloadCharacteristic = (BLESensorConfiguration.interopOpenTraceEnabled ? CBMutableCharacteristic(type: BLESensorConfiguration.interopOpenTracePayloadCharacteristicUUID, properties: [.read, .write, .writeWithoutResponse], value: nil, permissions: [.readable, .writeable]) : nil) } - let service = CBMutableService(type: BLESensorConfiguration.linuxFoundationServiceUUID, primary: true) signalCharacteristic?.value = nil payloadCharacteristic?.value = nil - if let legacyPayloadCharacteristic = legacyPayloadCharacteristic { + if let legacyPayloadCharacteristic = legacyPayloadCharacteristic { legacyPayloadCharacteristic.value = nil service.characteristics = [signalCharacteristic!, payloadCharacteristic!, legacyPayloadCharacteristic] - } else { + } else { service.characteristics = [signalCharacteristic!, payloadCharacteristic!] - } + } queue.async { self.peripheral.stopAdvertising() self.peripheral.removeAllServices() - self.peripheral.add(service) - self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.linuxFoundationServiceUUID]]) + if BLESensorConfiguration.customServiceAdvertisingEnabled && nil != BLESensorConfiguration.customServiceUUID { + let service = CBMutableService(type: BLESensorConfiguration.customServiceUUID, primary: true) + self.peripheral.add(service) + self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.customServiceUUID]]) + } else if BLESensorConfiguration.standardHeraldServiceAdvertisingEnabled { + let service = CBMutableService(type: BLESensorConfiguration.linuxFoundationServiceUUID, primary: true) + self.peripheral.add(service) + self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.linuxFoundationServiceUUID]]) + } } } diff --git a/Herald/Herald/Sensor/SensorArray.swift b/Herald/Herald/Sensor/SensorArray.swift index c2ca9a7..fc8fa65 100644 --- a/Herald/Herald/Sensor/SensorArray.swift +++ b/Herald/Herald/Sensor/SensorArray.swift @@ -25,7 +25,12 @@ public class SensorArray : NSObject, Sensor { // but enabling location sensor will enable direct iOS-iOS detection in background. // - Please note, the actual location is not used or recorded by HERALD. if let mobilitySensorResolution = BLESensorConfiguration.mobilitySensorEnabled { - sensorArray.append(ConcreteMobilitySensor(resolution: mobilitySensorResolution, rangeForBeacon: UUID(uuidString: BLESensorConfiguration.linuxFoundationServiceUUID.uuidString))) + if BLESensorConfiguration.standardHeraldServiceDetectionEnabled { + sensorArray.append(ConcreteMobilitySensor(resolution: mobilitySensorResolution, rangeForBeacon: UUID(uuidString: BLESensorConfiguration.linuxFoundationServiceUUID.uuidString))) + } + if BLESensorConfiguration.customServiceDetectionEnabled && nil != BLESensorConfiguration.customServiceUUID { + sensorArray.append(ConcreteMobilitySensor(resolution: mobilitySensorResolution, rangeForBeacon: UUID(uuidString: BLESensorConfiguration.customServiceUUID.uuidString))) + } } // BLE sensor for detecting and tracking proximity concreteBle = ConcreteBLESensor(payloadDataSupplier) From 37e12c82b7fe2c4b5e332029e24927b67c504b9f Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sun, 12 Feb 2023 13:45:54 +0000 Subject: [PATCH 4/7] Added basic Activity classes. Fixed compilation and license issues. Signed-off-by: Adam Fowler --- Herald/Herald.xcodeproj/project.pbxproj | 16 ++++ Herald/Herald/Sensor/Analysis/Mobility.swift | 4 +- Herald/Herald/Sensor/BLE/BLEReceiver.swift | 36 ++++---- Herald/Herald/Sensor/BLE/BLESensor.swift | 11 ++- Herald/Herald/Sensor/BLE/BLETransmitter.swift | 27 +++--- Herald/Herald/Sensor/Data/EventLog.swift | 4 +- .../Sensor/Data/PayloadDataFormatter.swift | 4 +- Herald/Herald/Sensor/Engine/Activities.swift | 88 +++++++++++++++++++ Herald/Herald/Sensor/Engine/Coordinator.swift | 61 +++++++++++++ .../Sensor/Extensions/DataExtensions.swift | 4 +- .../Sensor/Location/MobilitySensor.swift | 7 +- .../Herald/Sensor/Motion/InertiaSensor.swift | 9 +- Herald/Herald/Sensor/Sensor.swift | 5 +- Herald/Herald/Sensor/SensorArray.swift | 13 ++- 14 files changed, 242 insertions(+), 47 deletions(-) create mode 100644 Herald/Herald/Sensor/Engine/Activities.swift create mode 100644 Herald/Herald/Sensor/Engine/Coordinator.swift diff --git a/Herald/Herald.xcodeproj/project.pbxproj b/Herald/Herald.xcodeproj/project.pbxproj index 65a853c..df2a5ac 100644 --- a/Herald/Herald.xcodeproj/project.pbxproj +++ b/Herald/Herald.xcodeproj/project.pbxproj @@ -92,6 +92,8 @@ B6F7460A255714C2003567B7 /* SimplePayloadDataMatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F74606255714C2003567B7 /* SimplePayloadDataMatcherTests.swift */; }; B6F7460B255714C2003567B7 /* BloomFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F74607255714C2003567B7 /* BloomFilterTests.swift */; }; B6F7460C255714C2003567B7 /* InteractionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F74608255714C2003567B7 /* InteractionsTests.swift */; }; + D1FA72CF2999233C00F2F784 /* Activities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1FA72CE2999233C00F2F784 /* Activities.swift */; }; + D1FA72D12999234800F2F784 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1FA72D02999234800F2F784 /* Coordinator.swift */; }; D301023D25B8DD8300598DF4 /* ExtendedDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D301023C25B8DD8300598DF4 /* ExtendedDataTests.swift */; }; D32988E425C34AE20066D9D4 /* PayloadDataFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D32988E325C34AE20066D9D4 /* PayloadDataFormatter.swift */; }; /* End PBXBuildFile section */ @@ -196,6 +198,8 @@ B6F74606255714C2003567B7 /* SimplePayloadDataMatcherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimplePayloadDataMatcherTests.swift; sourceTree = ""; }; B6F74607255714C2003567B7 /* BloomFilterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BloomFilterTests.swift; sourceTree = ""; }; B6F74608255714C2003567B7 /* InteractionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InteractionsTests.swift; sourceTree = ""; }; + D1FA72CE2999233C00F2F784 /* Activities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Activities.swift; path = herald/Sensor/Engine/Activities.swift; sourceTree = SOURCE_ROOT; }; + D1FA72D02999234800F2F784 /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Coordinator.swift; path = herald/Sensor/Engine/Coordinator.swift; sourceTree = SOURCE_ROOT; }; D301023C25B8DD8300598DF4 /* ExtendedDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedDataTests.swift; sourceTree = ""; }; D32988E325C34AE20066D9D4 /* PayloadDataFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PayloadDataFormatter.swift; path = herald/Sensor/Data/PayloadDataFormatter.swift; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ @@ -267,6 +271,7 @@ B637EF5C251E56320072D238 /* Sensor */ = { isa = PBXGroup; children = ( + D13665722992EA8A00F2B4FC /* Engine */, B6EEC24425B5BC2B00D1CDF9 /* Extensions */, B6599D0125A4EAE600AC306D /* Motion */, B6F745EE255713C2003567B7 /* Analysis */, @@ -484,6 +489,15 @@ path = Analysis; sourceTree = ""; }; + D13665722992EA8A00F2B4FC /* Engine */ = { + isa = PBXGroup; + children = ( + D1FA72CE2999233C00F2F784 /* Activities.swift */, + D1FA72D02999234800F2F784 /* Coordinator.swift */, + ); + path = Engine; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -633,6 +647,7 @@ B6F40DC52658FAD40088B098 /* Encryption.swift in Sources */, B6DA10B325A78AF50071C08E /* CalibrationLog.swift in Sources */, B637EF8E251E56320072D238 /* SensorDelegate.swift in Sources */, + D1FA72CF2999233C00F2F784 /* Activities.swift in Sources */, B637EF86251E56320072D238 /* SensorArray.swift in Sources */, B637EF8D251E56320072D238 /* StatisticsLog.swift in Sources */, 6FE142FB2565C39A0084A59C /* Device.swift in Sources */, @@ -653,6 +668,7 @@ B637EF87251E56320072D238 /* PayloadDataSupplier.swift in Sources */, B65235BB26308DF6007321B8 /* Sample.swift in Sources */, B6EEC24625B5BC4400D1CDF9 /* DataExtensions.swift in Sources */, + D1FA72D12999234800F2F784 /* Coordinator.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Herald/Herald/Sensor/Analysis/Mobility.swift b/Herald/Herald/Sensor/Analysis/Mobility.swift index 5c25a92..33bf11e 100644 --- a/Herald/Herald/Sensor/Analysis/Mobility.swift +++ b/Herald/Herald/Sensor/Analysis/Mobility.swift @@ -1,8 +1,8 @@ // // Mobility.swift // -// Copyright 2021 Herald Project Contributors -// SPDX-License-Identifier: MIT +// Copyright 2021-2023 Herald Project Contributors +// SPDX-License-Identifier: Apache-2.0 // import Foundation diff --git a/Herald/Herald/Sensor/BLE/BLEReceiver.swift b/Herald/Herald/Sensor/BLE/BLEReceiver.swift index f33a4c6..92a0779 100644 --- a/Herald/Herald/Sensor/BLE/BLEReceiver.swift +++ b/Herald/Herald/Sensor/BLE/BLEReceiver.swift @@ -1,7 +1,7 @@ // // BLEReceiver.swift // -// Copyright 2020-2021 Herald Project Contributors +// Copyright 2020-2023 Herald Project Contributors // SPDX-License-Identifier: Apache-2.0 // @@ -119,6 +119,11 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral } } + public func coordinationProvider() -> CoordinationProvider? { + // TODO implement BLE Coordination Provider + return nil + } + func immediateSend(data: Data, _ targetIdentifier: TargetIdentifier) -> Bool { logger.debug("immediateSend (targetIdentifier=\(targetIdentifier))") let device = database.device(targetIdentifier) @@ -268,10 +273,8 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral scanForServices.append(csuuid) solicitedKeys.append(csuuid) } - if let casuuids = BLESensorConfiguration.customAdditionalServiceUUIDs { - for suuid in BLESensorConfiguration.customServiceUUID { - scanForServices.append(suuid) - } + for suuid in BLESensorConfiguration.customAdditionalServiceUUIDs { + scanForServices.append(suuid) } } // Optionally, include the old Herald service UUID (prior to v2.1.0) @@ -303,10 +306,8 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral if let csuuid = BLESensorConfiguration.customServiceUUID { services.append(csuuid) } - if let casuuids = BLESensorConfiguration.customAdditionalServiceUUIDs { - for suuid in BLESensorConfiguration.customServiceUUID { - services.append(suuid) - } + for suuid in BLESensorConfiguration.customAdditionalServiceUUIDs { + services.append(suuid) } } // Optionally, include the old Herald service UUID (prior to v2.1.0) @@ -833,10 +834,8 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral if let csuuid = BLESensorConfiguration.customServiceUUID { services.append(csuuid) } - if let casuuids = BLESensorConfiguration.customAdditionalServiceUUIDs { - for suuid in BLESensorConfiguration.customServiceUUID { - services.append(suuid) - } + for suuid in BLESensorConfiguration.customAdditionalServiceUUIDs { + services.append(suuid) } } // Optionally, include the old Herald service UUID (prior to v2.1.0) @@ -1078,11 +1077,12 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral } for service in services { if (BLESensorConfiguration.standardHeraldServiceDetectionEnabled && service.uuid == BLESensorConfiguration.linuxFoundationServiceUUID) || - (BLESensorConfiguration.customServiceDetectionEnabled && ( - (nil != BLESensorConfiguration.customServiceUUID && service.uuid == BLESensorConfiguration.customServiceUUID) || - (nil != BLESensorConfiguration.customAdditionalServiceUUIDs && BLESensorConfiguration.customAdditionalServiceUUIDs.contains(service.uuid)) - ) || - (BLESensorConfiguration.legacyHeraldServiceDetectionEnabled && service.uuid == BLESensorConfiguration.legacyHeraldServiceUUID) { + (BLESensorConfiguration.customServiceDetectionEnabled && (( + (((nil != BLESensorConfiguration.customServiceUUID) && (service.uuid == BLESensorConfiguration.customServiceUUID!)) || + (BLESensorConfiguration.customAdditionalServiceUUIDs.contains(service.uuid)) + )))) || + (BLESensorConfiguration.legacyHeraldServiceDetectionEnabled && (service.uuid == BLESensorConfiguration.legacyHeraldServiceUUID) + ) { logger.debug("didDiscoverServices, found sensor service (device=\(device),service=\(service.uuid.uuidString))") queue.async { peripheral.discoverCharacteristics(nil, for: service) } return diff --git a/Herald/Herald/Sensor/BLE/BLESensor.swift b/Herald/Herald/Sensor/BLE/BLESensor.swift index 9ef6596..3de7785 100644 --- a/Herald/Herald/Sensor/BLE/BLESensor.swift +++ b/Herald/Herald/Sensor/BLE/BLESensor.swift @@ -1,7 +1,7 @@ // // BLESensor.swift // -// Copyright 2020-2021 Herald Project Contributors +// Copyright 2020-2023 Herald Project Contributors // SPDX-License-Identifier: Apache-2.0 // @@ -71,7 +71,7 @@ public struct BLESensorConfiguration { * @since v2.2 February 2023 * @note Requires customHeraldServiceDetectionEnabled to be set to true to enable. */ - public static var customServiceUUID: UUID = null; + public static var customServiceUUID: CBUUID? = nil; /** * Whether to detect a custom service UUID. Disabled by default. * Doesn't affect advertising. @@ -95,7 +95,7 @@ public struct BLESensorConfiguration { * @since v2.2 February 2023 * @note Requires customHeraldServiceDetectionEnabled to be set to true to enable. */ - public static var customAdditionalServiceUUIDs: [UUID] = null; + public static var customAdditionalServiceUUIDs: [CBUUID] = []; /** * The custom manufacturer ID to use. Note this MUST be a Bluetooth SIG registered ID to * ensure there is no interference. @@ -251,6 +251,11 @@ class ConcreteBLESensor : NSObject, BLESensor, BLEDatabaseDelegate { database.add(delegate: self) } + public func coordinationProvider() -> CoordinationProvider? { + // ConcreteBLESensor does not have a coordination provider + return nil + } + func start() { logger.debug("start") receiver.start() diff --git a/Herald/Herald/Sensor/BLE/BLETransmitter.swift b/Herald/Herald/Sensor/BLE/BLETransmitter.swift index 515fad7..dc93672 100644 --- a/Herald/Herald/Sensor/BLE/BLETransmitter.swift +++ b/Herald/Herald/Sensor/BLE/BLETransmitter.swift @@ -1,7 +1,7 @@ // // BLETransmitter.swift // -// Copyright 2020-2021 Herald Project Contributors +// Copyright 2020-2023 Herald Project Contributors // SPDX-License-Identifier: Apache-2.0 // @@ -86,6 +86,11 @@ class ConcreteBLETransmitter : NSObject, BLETransmitter, CBPeripheralManagerDele } } + public func coordinationProvider() -> CoordinationProvider? { + // BLETransmitter does not have a coordination provider + return nil + } + func add(delegate: SensorDelegate) { delegates.append(delegate) } @@ -154,19 +159,21 @@ class ConcreteBLETransmitter : NSObject, BLETransmitter, CBPeripheralManagerDele } signalCharacteristic?.value = nil payloadCharacteristic?.value = nil - if let legacyPayloadCharacteristic = legacyPayloadCharacteristic { - legacyPayloadCharacteristic.value = nil - service.characteristics = [signalCharacteristic!, payloadCharacteristic!, legacyPayloadCharacteristic] - } else { - service.characteristics = [signalCharacteristic!, payloadCharacteristic!] - } + legacyPayloadCharacteristic?.value = nil + // We do characteristics via GATT only now +// if let legacyPayloadCharacteristic = legacyPayloadCharacteristic { +// legacyPayloadCharacteristic.value = nil +// service.characteristics = [signalCharacteristic!, payloadCharacteristic!, legacyPayloadCharacteristic] +// } else { +// service.characteristics = [signalCharacteristic!, payloadCharacteristic!] +// } queue.async { self.peripheral.stopAdvertising() self.peripheral.removeAllServices() - if BLESensorConfiguration.customServiceAdvertisingEnabled && nil != BLESensorConfiguration.customServiceUUID { - let service = CBMutableService(type: BLESensorConfiguration.customServiceUUID, primary: true) + if let csuuid = BLESensorConfiguration.customServiceUUID, BLESensorConfiguration.customServiceAdvertisingEnabled { + let service = CBMutableService(type: csuuid, primary: true) self.peripheral.add(service) - self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.customServiceUUID]]) + self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [csuuid]]) } else if BLESensorConfiguration.standardHeraldServiceAdvertisingEnabled { let service = CBMutableService(type: BLESensorConfiguration.linuxFoundationServiceUUID, primary: true) self.peripheral.add(service) diff --git a/Herald/Herald/Sensor/Data/EventLog.swift b/Herald/Herald/Sensor/Data/EventLog.swift index 74c238a..8452eb5 100644 --- a/Herald/Herald/Sensor/Data/EventLog.swift +++ b/Herald/Herald/Sensor/Data/EventLog.swift @@ -1,8 +1,8 @@ // // EventLog.swift // -// Copyright 2021 Herald Project Contributors -// SPDX-License-Identifier: MIT +// Copyright 2021-2023 Herald Project Contributors +// SPDX-License-Identifier: Apache-2.0 // import Foundation diff --git a/Herald/Herald/Sensor/Data/PayloadDataFormatter.swift b/Herald/Herald/Sensor/Data/PayloadDataFormatter.swift index c30945d..28e2faa 100644 --- a/Herald/Herald/Sensor/Data/PayloadDataFormatter.swift +++ b/Herald/Herald/Sensor/Data/PayloadDataFormatter.swift @@ -1,8 +1,8 @@ // // PayloadDataFormatter.swift // -// Copyright 2021 Herald Project Contributors -// SPDX-License-Identifier: MIT +// Copyright 2021-2023 Herald Project Contributors +// SPDX-License-Identifier: Apache-2.0 // import Foundation diff --git a/Herald/Herald/Sensor/Engine/Activities.swift b/Herald/Herald/Sensor/Engine/Activities.swift new file mode 100644 index 0000000..f24252e --- /dev/null +++ b/Herald/Herald/Sensor/Engine/Activities.swift @@ -0,0 +1,88 @@ +// +// Activities.swift +// +// Copyright 2023 Herald Project Contributors +// SPDX-License-Identifier: Apache-2.0 +// +// Created by Adam Fowler on 07/02/2023. +// + +import Foundation + +public typealias FeatureTag = Data + +public let HeraldBluetoothProtocolConnection: FeatureTag = FeatureTag(repeating: UInt8(0x01), count: 1) + +public typealias Priority = UInt8 + +public let CriticalPriority: Priority = Priority(200) +public let HighPriority: Priority = Priority(150) +public let DefaultPriority: Priority = Priority(100) +public let LowPriority: Priority = Priority(50) + +public class Prerequisite { + private var feature: FeatureTag + private var relatedTo: TargetIdentifier? = nil + + init(required: FeatureTag) { + feature = required + } + + init(required: FeatureTag, toward: TargetIdentifier) { + feature = required + relatedTo = toward + } + + func getRelatedTo() -> TargetIdentifier? { + return relatedTo + } + + func getFeature() -> FeatureTag { + return feature + } +} + +public class PrioritisedPrerequisite: Prerequisite { + private var priority: Priority = DefaultPriority + + override init(required: FeatureTag) { + super.init(required: required) + } + + override init(required: FeatureTag, toward: TargetIdentifier) { + super.init(required: required, toward: toward) + } + + init(required: FeatureTag, priority: Priority) { + super.init(required: required) + self.priority = priority + } + + init(required: FeatureTag, toward: TargetIdentifier, priority: Priority) { + super.init(required: required, toward: toward) + self.priority = priority + } +} + +public struct ActivityDescription { + var priority: Priority + var name: String + var prerequisities: [Prerequisite] +} + + +public protocol ActivityProvider { + func executeActivity(activity: ActivityDescription) +} + +public struct Activity { + var description: ActivityDescription + var executor: ActivityProvider +} + +public protocol CoordinationProvider { + func connectionsProvided() -> [FeatureTag] + func provision(prereqs: [PrioritisedPrerequisite]) -> [PrioritisedPrerequisite] + func requiredConnections() -> [PrioritisedPrerequisite] + func requiredActivities() -> [Activity] +} diff --git a/Herald/Herald/Sensor/Engine/Coordinator.swift b/Herald/Herald/Sensor/Engine/Coordinator.swift new file mode 100644 index 0000000..6b0556a --- /dev/null +++ b/Herald/Herald/Sensor/Engine/Coordinator.swift @@ -0,0 +1,61 @@ +// +// Coordinator.swift +// +// Copyright 2023 Herald Project Contributors +// SPDX-License-Identifier: Apache-2.0 +// +// Created by Adam Fowler on 07/02/2023. +// + +import Foundation + +/// +/// Provides timed action collection and coordination based upon the concept of Features and Providers +/// +//class Coordinator: NSObject { +// private let logger = ConcreteSensorLogger(subsystem: "Sensor", category: "Engine.Coordinator") +// private var running: Bool = false +// private var providers: [CoordinationProvider] = [] +// private var featureProviders: [FeatureTag : CoordinationProvider] = [:] +// +// func add(sensor: Sensor) { +// if let provider = sensor.coordinationProvider() { +// providers.append(provider) +// } +// } +// +// func remove(sensor: Sensor) { +// +// } +// +// func start() { +// featureProviders.removeAll() +// for provider in providers { +// for feature in provider.connectionsProvided() { +// featureProviders[feature] = provider +// } +// } +// } +// +// func iteration() { +// if !running { +// logger.debug("Coordinator iteration called when running=false") +// return +// } +// var assignPrereqs: [CoordinationProvider: [PrioritisedPrerequisite]] = [:] +// var connsRequired: [PrioritisedPrerequisite] = [] +// for provider in providers { +// for conn in provider.requiredConnections() { +// connsRequired.append(conn) +// } +// } +// +// for prereq in connsRequired { +// var featureProvider: CoordinationProvider = featureProviders[PrioritisedPrerequisite] +// } +// } +// +// func stop() { +// +// } +//} diff --git a/Herald/Herald/Sensor/Extensions/DataExtensions.swift b/Herald/Herald/Sensor/Extensions/DataExtensions.swift index ad2481a..14156df 100644 --- a/Herald/Herald/Sensor/Extensions/DataExtensions.swift +++ b/Herald/Herald/Sensor/Extensions/DataExtensions.swift @@ -1,8 +1,8 @@ // // DataExtensions.swift // -// Copyright 2021 Herald Project Contributors -// SPDX-License-Identifier: MIT +// Copyright 2021-2023 Herald Project Contributors +// SPDX-License-Identifier: Apache-2.0 // import Foundation diff --git a/Herald/Herald/Sensor/Location/MobilitySensor.swift b/Herald/Herald/Sensor/Location/MobilitySensor.swift index 8e6496c..0a51a54 100644 --- a/Herald/Herald/Sensor/Location/MobilitySensor.swift +++ b/Herald/Herald/Sensor/Location/MobilitySensor.swift @@ -1,7 +1,7 @@ // // MobilitySensor.swift // -// Copyright 2021 Herald Project Contributors +// Copyright 2021-2023 Herald Project Contributors // SPDX-License-Identifier: Apache-2.0 // @@ -57,6 +57,11 @@ class ConcreteMobilitySensor : NSObject, MobilitySensor, CLLocationManagerDelega } } + public func coordinationProvider() -> CoordinationProvider? { + // Class does not have a coordination provider + return nil + } + /// Establish location accuracy required based on distance resolution required private static func locationAccuracy(_ resolution: Distance) -> CLLocationAccuracy { if resolution.value < 10 { diff --git a/Herald/Herald/Sensor/Motion/InertiaSensor.swift b/Herald/Herald/Sensor/Motion/InertiaSensor.swift index c7d01bc..25edfca 100644 --- a/Herald/Herald/Sensor/Motion/InertiaSensor.swift +++ b/Herald/Herald/Sensor/Motion/InertiaSensor.swift @@ -1,8 +1,8 @@ //// // InertiaSensor.swift // -// Copyright 2021 Herald Project Contributors -// SPDX-License-Identifier: MIT +// Copyright 2021-2023 Herald Project Contributors +// SPDX-License-Identifier: Apache-2.0 // import Foundation @@ -51,6 +51,11 @@ class ConcreteInertiaSensor : NSObject, InertiaSensor { logger.debug("stop") motionManager.stopAccelerometerUpdates() } + + public func coordinationProvider() -> CoordinationProvider? { + // Class does not have a coordination provider + return nil + } private func handleAccelerometerUpdates(data: CMAccelerometerData?, error: Error?) { guard error == nil else { diff --git a/Herald/Herald/Sensor/Sensor.swift b/Herald/Herald/Sensor/Sensor.swift index e96bf77..ee2ac52 100644 --- a/Herald/Herald/Sensor/Sensor.swift +++ b/Herald/Herald/Sensor/Sensor.swift @@ -1,7 +1,7 @@ // // Sensor.swift // -// Copyright 2020-2021 Herald Project Contributors +// Copyright 2020-2023 Herald Project Contributors // SPDX-License-Identifier: Apache-2.0 // @@ -17,5 +17,8 @@ public protocol Sensor { /// Stop sensing. func stop() + + /// Retrieve a CoordinationProvider + func coordinationProvider() -> CoordinationProvider? } diff --git a/Herald/Herald/Sensor/SensorArray.swift b/Herald/Herald/Sensor/SensorArray.swift index fc8fa65..61eb298 100644 --- a/Herald/Herald/Sensor/SensorArray.swift +++ b/Herald/Herald/Sensor/SensorArray.swift @@ -1,7 +1,7 @@ // // SensorArray.swift // -// Copyright 2020-2021 Herald Project Contributors +// Copyright 2020-2023 Herald Project Contributors // SPDX-License-Identifier: Apache-2.0 // @@ -26,10 +26,10 @@ public class SensorArray : NSObject, Sensor { // - Please note, the actual location is not used or recorded by HERALD. if let mobilitySensorResolution = BLESensorConfiguration.mobilitySensorEnabled { if BLESensorConfiguration.standardHeraldServiceDetectionEnabled { - sensorArray.append(ConcreteMobilitySensor(resolution: mobilitySensorResolution, rangeForBeacon: UUID(uuidString: BLESensorConfiguration.linuxFoundationServiceUUID.uuidString))) + sensorArray.append(ConcreteMobilitySensor(resolution: mobilitySensorResolution, rangeForBeacon: UUID(uuidString: BLESensorConfiguration.linuxFoundationServiceUUID.uuidString))) } - if BLESensorConfiguration.customServiceDetectionEnabled && nil != BLESensorConfiguration.customServiceUUID { - sensorArray.append(ConcreteMobilitySensor(resolution: mobilitySensorResolution, rangeForBeacon: UUID(uuidString: BLESensorConfiguration.customServiceUUID.uuidString))) + if let csuuid = BLESensorConfiguration.customServiceUUID, BLESensorConfiguration.customServiceDetectionEnabled { + sensorArray.append(ConcreteMobilitySensor(resolution: mobilitySensorResolution, rangeForBeacon: UUID(uuidString: csuuid.uuidString))) } } // BLE sensor for detecting and tracking proximity @@ -55,6 +55,11 @@ public class SensorArray : NSObject, Sensor { } } + public func coordinationProvider() -> CoordinationProvider? { + // Array does not have a coordination provider + return nil + } + private func deviceModel() -> String { var deviceInformation = utsname() uname(&deviceInformation) From 82f9b66f8f2dc9c04e67bb0c71e742999f0dc57c Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 18 Feb 2023 14:54:46 +0000 Subject: [PATCH 5/7] Connections no longer happen on discovery. Advertising fix. Signed-off-by: Adam Fowler --- Herald-for-iOS.xcodeproj/project.pbxproj | 12 ++----- Herald/Herald.xcodeproj/project.pbxproj | 16 +++------ Herald/Herald/Sensor/BLE/BLEReceiver.swift | 34 ++++++++++++++++--- Herald/Herald/Sensor/BLE/BLETransmitter.swift | 25 ++++++++------ 4 files changed, 50 insertions(+), 37 deletions(-) diff --git a/Herald-for-iOS.xcodeproj/project.pbxproj b/Herald-for-iOS.xcodeproj/project.pbxproj index 73a0267..b672f77 100644 --- a/Herald-for-iOS.xcodeproj/project.pbxproj +++ b/Herald-for-iOS.xcodeproj/project.pbxproj @@ -389,11 +389,7 @@ B692CAA824CADA7A00F45AEE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - "$(ARCHS_STANDARD)", - armv7, - armv7s, - ); + ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; @@ -415,11 +411,7 @@ B692CAA924CADA7A00F45AEE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - "$(ARCHS_STANDARD)", - armv7, - armv7s, - ); + ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; diff --git a/Herald/Herald.xcodeproj/project.pbxproj b/Herald/Herald.xcodeproj/project.pbxproj index df2a5ac..6fdca92 100644 --- a/Herald/Herald.xcodeproj/project.pbxproj +++ b/Herald/Herald.xcodeproj/project.pbxproj @@ -720,11 +720,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = ( - "$(ARCHS_STANDARD)", - armv7, - armv7s, - ); + ARCHS = "$(ARCHS_STANDARD)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -773,7 +769,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -789,11 +785,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = ( - "$(ARCHS_STANDARD)", - armv7, - armv7s, - ); + ARCHS = "$(ARCHS_STANDARD)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -836,7 +828,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; diff --git a/Herald/Herald/Sensor/BLE/BLEReceiver.swift b/Herald/Herald/Sensor/BLE/BLEReceiver.swift index 92a0779..33bfef2 100644 --- a/Herald/Herald/Sensor/BLE/BLEReceiver.swift +++ b/Herald/Herald/Sensor/BLE/BLEReceiver.swift @@ -319,6 +319,7 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral // let targetIdentifier = TargetIdentifier(peripheral: peripheral) let device = database.device(peripheral, delegate: self) logger.debug("taskRegisterConnectedPeripherals (device=\(device))") +// self.central.connect(peripheral, options: nil) // if device.peripheral == nil || device.peripheral != peripheral { // logger.debug("taskRegisterConnectedPeripherals (device=\(device))") // _ = database.device(peripheral, delegate: self) @@ -715,7 +716,9 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral } queue.async { device.lastConnectRequestedAt = Date() - self.central.retrievePeripherals(withIdentifiers: [peripheral.identifier]).forEach { + let peripherals = self.central.retrievePeripherals(withIdentifiers: [peripheral.identifier]) + peripherals.forEach { + self.logger.debug("connect, found peripheral (source=\(source),device=\(device),state=\($0.state)") if $0.state != .connected { var performConnection = false // Check to see if Herald has initiated a connection attempt before @@ -784,6 +787,10 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral self.taskInitiateNextAction("connect|" + source, peripheral: $0) } } + if peripherals.count == 0 { + self.logger.debug("WARNING: connect, could not find peripheral. Not populated until connected? (source=\(source),device=\(device))") +// self.central.connect(peripheral) + } } scheduleScan("connect") } @@ -997,8 +1004,10 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral device.payloadData = legacyAdvertOnlyProtocolData.payloadData logger.debug("didDiscover, legacy payload (device=\(device),service=\(legacyAdvertOnlyProtocolData.service.description),payload=\(legacyAdvertOnlyProtocolData.payloadData.hexEncodedString))") } + // Removed since V2.2 as it always connects to 'unknown' devices that may be unknown because they're Android and not advertising the Herald service + // - i.e. we were always trying to connect to unknown devices even if their next connect time was way in the future if (legacyAdvertOnlyProtocolData == nil || legacyAdvertOnlyProtocolData!.connectable), deviceHasPendingTask(device) { - connect("didDiscover", peripheral); +// connect("didDiscover", peripheral); } else { scanResults.append(device) } @@ -1027,7 +1036,8 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral logger.debug("Unregister invalid device (device=\(device))") database.delete(device, peripheral: peripheral) } else { - connect("didFailToConnect", peripheral) + // Removed since V2.2 as connecting now handled by a lifecycle process, not during the central process +// connect("didFailToConnect", peripheral) } } @@ -1090,8 +1100,15 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral logger.debug("didDiscoverServices, found legacy service (device=\(device),service=\(service.uuid.uuidString))") queue.async { peripheral.discoverCharacteristics(nil, for: service) } return + } else { + logger.debug("didDiscoverServices, found unhandled service (device=\(device),hasServiceUUID:\(service.uuid.uuidString))") } } + if services.count == 0 { + logger.debug("didDiscoverServices, WARNING: device is not advertising any services. Ignoring. Advertising broken or a non-Herald device (device=\(device))") + // V2.2 Add to ignore list (TODO only if this keeps happening repeatedly) as it's a non-Herald device, or broken and not advertising + device.onlyConnectAfter = Date.distantFuture + } disconnect("didDiscoverServices|serviceNotFound", peripheral) // The disconnect calls here shall be handled by didDisconnect which determines whether to retry for iOS or stop for Android } @@ -1100,9 +1117,15 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { // Discover characteristics -> Notify delegates -> Disconnect | Wake transmitter -> Scan again let device = database.device(peripheral, delegate: self) - logger.debug("didDiscoverCharacteristicsFor (device=\(device),error=\(String(describing: error)))") + logger.debug("didDiscoverCharacteristicsFor (device=\(device),service=\(service.uuid.uuidString),error=\(String(describing: error)))") guard let characteristics = service.characteristics else { - disconnect("didDiscoverCharacteristicsFor|characteristicEmpty", peripheral) + // Don't disconnect as there may be other services this callback is activated for +// disconnect("didDiscoverCharacteristicsFor|characteristicNil", peripheral) + return + } + if (characteristics.count == 0) { + // Don't disconnect as there may be other services this callback is activated for +// disconnect("didDiscoverCharacteristicsFor|characteristicEmpty", peripheral) return } for characteristic in characteristics { @@ -1185,6 +1208,7 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral if peripheral.state == .connected { discoverServices("didModifyServices", peripheral) } else if peripheral.state != .connecting { + // Note: This is good as if an Android device 'fixes' itself and starts advertising, this causes it to be read connect("didModifyServices", peripheral) } } diff --git a/Herald/Herald/Sensor/BLE/BLETransmitter.swift b/Herald/Herald/Sensor/BLE/BLETransmitter.swift index dc93672..3b2b4f4 100644 --- a/Herald/Herald/Sensor/BLE/BLETransmitter.swift +++ b/Herald/Herald/Sensor/BLE/BLETransmitter.swift @@ -157,25 +157,30 @@ class ConcreteBLETransmitter : NSObject, BLETransmitter, CBPeripheralManagerDele payloadCharacteristic = CBMutableCharacteristic(type: BLESensorConfiguration.payloadCharacteristicUUID, properties: [.read], value: nil, permissions: [.readable]) legacyPayloadCharacteristic = (BLESensorConfiguration.interopOpenTraceEnabled ? CBMutableCharacteristic(type: BLESensorConfiguration.interopOpenTracePayloadCharacteristicUUID, properties: [.read, .write, .writeWithoutResponse], value: nil, permissions: [.readable, .writeable]) : nil) } - signalCharacteristic?.value = nil - payloadCharacteristic?.value = nil - legacyPayloadCharacteristic?.value = nil - // We do characteristics via GATT only now -// if let legacyPayloadCharacteristic = legacyPayloadCharacteristic { -// legacyPayloadCharacteristic.value = nil -// service.characteristics = [signalCharacteristic!, payloadCharacteristic!, legacyPayloadCharacteristic] -// } else { -// service.characteristics = [signalCharacteristic!, payloadCharacteristic!] -// } queue.async { self.peripheral.stopAdvertising() self.peripheral.removeAllServices() + self.signalCharacteristic?.value = nil + self.payloadCharacteristic?.value = nil if let csuuid = BLESensorConfiguration.customServiceUUID, BLESensorConfiguration.customServiceAdvertisingEnabled { let service = CBMutableService(type: csuuid, primary: true) + service.characteristics = [self.signalCharacteristic!, self.payloadCharacteristic!] + if let legacyPayloadCharacteristic = self.legacyPayloadCharacteristic { + legacyPayloadCharacteristic.value = nil + service.characteristics = [self.signalCharacteristic!, self.payloadCharacteristic!, legacyPayloadCharacteristic] + } else { + service.characteristics = [self.signalCharacteristic!, self.payloadCharacteristic!] + } self.peripheral.add(service) self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [csuuid]]) } else if BLESensorConfiguration.standardHeraldServiceAdvertisingEnabled { let service = CBMutableService(type: BLESensorConfiguration.linuxFoundationServiceUUID, primary: true) + if let legacyPayloadCharacteristic = self.legacyPayloadCharacteristic { + legacyPayloadCharacteristic.value = nil + service.characteristics = [self.signalCharacteristic!, self.payloadCharacteristic!, legacyPayloadCharacteristic] + } else { + service.characteristics = [self.signalCharacteristic!, self.payloadCharacteristic!] + } self.peripheral.add(service) self.peripheral.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [BLESensorConfiguration.linuxFoundationServiceUUID]]) } From 7e4221a7db957192e9f7469fb0c03150dd6f59ec Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 18 Feb 2023 20:00:03 +0000 Subject: [PATCH 6/7] Added Android connect back support to iOS Signed-off-by: Adam Fowler --- Herald/Herald/Sensor/BLE/BLEReceiver.swift | 52 +++++++++++++++---- Herald/Herald/Sensor/BLE/BLESensor.swift | 3 +- Herald/Herald/Sensor/BLE/BLETransmitter.swift | 3 +- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/Herald/Herald/Sensor/BLE/BLEReceiver.swift b/Herald/Herald/Sensor/BLE/BLEReceiver.swift index 33bfef2..0c6a016 100644 --- a/Herald/Herald/Sensor/BLE/BLEReceiver.swift +++ b/Herald/Herald/Sensor/BLE/BLEReceiver.swift @@ -315,16 +315,25 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral services.append(BLESensorConfiguration.legacyHeraldServiceUUID) } if !services.isEmpty { - central.retrieveConnectedPeripherals(withServices: services).forEach() { peripheral in + let connected = central.retrieveConnectedPeripherals(withServices: services) + // Evaluate those that are still connected + connected.forEach() { peripheral in // let targetIdentifier = TargetIdentifier(peripheral: peripheral) let device = database.device(peripheral, delegate: self) logger.debug("taskRegisterConnectedPeripherals (device=\(device))") + taskInitiateNextAction("taskRegisterConnectedPeripherals", peripheral: peripheral) + // Immediately connect back, which also causes taskInitiateNextAction to occur // self.central.connect(peripheral, options: nil) // if device.peripheral == nil || device.peripheral != peripheral { // logger.debug("taskRegisterConnectedPeripherals (device=\(device))") // _ = database.device(peripheral, delegate: self) // } } + // Also fetch those we're no longer connected to who have recently connected to us and may have tasks pending + let peris = database.devices().filter {$0.hasPeripheral() && !connected.contains($0.mostRecentPeripheral()!)} + for peri in peris { + taskInitiateNextAction("taskRegisterConnectedPeripherals|peripheral", peripheral: peri.mostRecentPeripheral()!) + } } } @@ -342,6 +351,10 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral if let peripheral = peripherals.last { logger.debug("taskResolveDevicePeripherals (resolved=\(device))") _ = database.device(peripheral, delegate: self) + // Since v2.2: If OS == unknown, connect to it (which in turn resolves their characteristics) + if device.operatingSystem == .unknown { + central.connect(peripheral) + } } } } @@ -584,6 +597,9 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral } connect("taskConnect|asymmetric", peripheral); } + + // Also now register remotely connection initiated peripherals +// taskRegisterConnectedPeripherals() } /// Empty scan results to produce a list of recently discovered devices for connection and processing @@ -670,27 +686,45 @@ class ConcreteBLEReceiver: NSObject, BLEReceiver, BLEDatabaseDelegate, CBCentral /// code maintenance. An alternative implementation will be introduced in the future. private func taskInitiateNextAction(_ source: String, peripheral: CBPeripheral) { let device = database.device(peripheral, delegate: self) + // Note since v2.2 we've added logic to connect first because this method is called when the remote Android device connects to iOS even if iOS hasn't seen the device before + // TODO replace this with device state maintenance based on device.peripheral() state if device.rssi == nil { // 1. RSSI logger.debug("taskInitiateNextAction (goal=rssi,device=\(device))") readRSSI("taskInitiateNextAction|" + source, peripheral) } else if !(device.protocolIsHerald || device.protocolIsOpenTrace) { // 2. Characteristics - logger.debug("taskInitiateNextAction (goal=characteristics,device=\(device))") - discoverServices("taskInitiateNextAction|" + source, peripheral) + if peripheral.state == .disconnected { + connect("taskInitiateNextAction|" + source, peripheral) + } else { + logger.debug("taskInitiateNextAction (goal=characteristics,device=\(device))") + discoverServices("taskInitiateNextAction|" + source, peripheral) + } } else if device.payloadData == nil { // 3. Payload - logger.debug("taskInitiateNextAction (goal=payload,device=\(device))") - readPayload("taskInitiateNextAction|" + source, device) + if peripheral.state == .disconnected { + connect("taskInitiateNextAction|" + source, peripheral) + } else { + logger.debug("taskInitiateNextAction (goal=payload,device=\(device))") + readPayload("taskInitiateNextAction|" + source, device) + } } else if device.timeIntervalSinceLastPayloadDataUpdate > BLESensorConfiguration.payloadDataUpdateTimeInterval { // 4. Payload update - logger.debug("taskInitiateNextAction (goal=payloadUpdate,device=\(device),elapsed=\(device.timeIntervalSinceLastPayloadDataUpdate))") - readPayload("taskInitiateNextAction|" + source, device) + if peripheral.state == .disconnected { + connect("taskInitiateNextAction|" + source, peripheral) + } else { + logger.debug("taskInitiateNextAction (goal=payloadUpdate,device=\(device),elapsed=\(device.timeIntervalSinceLastPayloadDataUpdate))") + readPayload("taskInitiateNextAction|" + source, device) + } } else if BLESensorConfiguration.interopOpenTraceEnabled, device.protocolIsOpenTrace, device.timeIntervalSinceLastPayloadDataUpdate > BLESensorConfiguration.interopOpenTracePayloadDataUpdateTimeInterval { // 5. Payload update for OpenTrace - logger.debug("taskInitiateNextAction (goal=payloadUpdate|OpenTrace,device=\(device),elapsed=\(device.timeIntervalSinceLastPayloadDataUpdate))") - readPayload("taskInitiateNextAction|" + source, device) + if peripheral.state == .disconnected { + connect("taskInitiateNextAction|" + source, peripheral) + } else { + logger.debug("taskInitiateNextAction (goal=payloadUpdate|OpenTrace,device=\(device),elapsed=\(device.timeIntervalSinceLastPayloadDataUpdate))") + readPayload("taskInitiateNextAction|" + source, device) + } } else if device.operatingSystem != .ios { // 6. Disconnect Android logger.debug("taskInitiateNextAction (goal=disconnect|\(device.operatingSystem.rawValue),device=\(device))") diff --git a/Herald/Herald/Sensor/BLE/BLESensor.swift b/Herald/Herald/Sensor/BLE/BLESensor.swift index 3de7785..5661ce8 100644 --- a/Herald/Herald/Sensor/BLE/BLESensor.swift +++ b/Herald/Herald/Sensor/BLE/BLESensor.swift @@ -214,7 +214,8 @@ public struct BLESensorConfiguration { /// - Upper bound : Set this value to iOS Bluetooth address rotation period (roughly 15 minutes) to maximise continuity when devices go out of range, then return back in range (connection resume period = 15 mins max). /// - Lower bound : Set this value to Android scan-process period (roughly 2 minutes) to minimise workload, but iOS connection resume will be more reliant on re-discovery (connection resume period = 2 mins or more dependent on external factors). /// - iOS-iOS connections may resume beyond the set interval value if the addresses have not changed, due to other mechanisms in Herald. - public static var peripheralCleanInterval: TimeInterval = TimeInterval.minute * 2 + /// - Default changed to 30 minutes in V2.2 to reflect better Android lifecycle management + public static var peripheralCleanInterval: TimeInterval = TimeInterval.minute * 30 /// Enable inertia sensor /// - Inertia sensor (accelerometer) measures acceleration in meters per second (m/s) along device X, Y and Z axis diff --git a/Herald/Herald/Sensor/BLE/BLETransmitter.swift b/Herald/Herald/Sensor/BLE/BLETransmitter.swift index 3b2b4f4..3017f79 100644 --- a/Herald/Herald/Sensor/BLE/BLETransmitter.swift +++ b/Herald/Herald/Sensor/BLE/BLETransmitter.swift @@ -358,7 +358,7 @@ class ConcreteBLETransmitter : NSObject, BLETransmitter, CBPeripheralManagerDele logger.debug("didReceiveWrite -> didRead=\(payloadData.shortName),fromTarget=\(targetIdentifier)") queue.async { peripheral.respond(to: request, withResult: .success) } targetDevice.operatingSystem = .android - targetDevice.receiveOnly = true +// targetDevice.receiveOnly = true // Not true since v2.2 where all android devices write their payload targetDevice.payloadData = payloadData } else { logger.fault("didReceiveWrite, invalid payload (central=\(targetIdentifier),action=writePayload)") @@ -456,6 +456,7 @@ class ConcreteBLETransmitter : NSObject, BLETransmitter, CBPeripheralManagerDele func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) { // Read -> Notify subscribers let central = database.device(TargetIdentifier(request.central.identifier.uuidString)) + switch request.characteristic.uuid { case BLESensorConfiguration.payloadCharacteristicUUID: logger.debug("Read (central=\(central.description),characteristic=payload,offset=\(request.offset))") From 3d4677cf2c23cecc696e8a3fd32da90b2b265dd6 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sun, 19 Feb 2023 15:56:51 +0000 Subject: [PATCH 7/7] Updated iOS testing platforms Signed-off-by: Adam Fowler --- .github/workflows/unit_tests.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 1e126a9..0e02a0e 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -21,12 +21,7 @@ jobs: strategy: matrix: destination: [ - #'platform=iOS Simulator,OS=12.2,name=iPhone X' - #, - # 'platform=iOS Simulator,OS=15.2,name=iPhone 11 Pro' - 'platform=iOS Simulator,OS=16.0,name=iPhone 11 Pro' - #, - #'platform=iOS Simulator,OS=9.3,name=iPhone 5s' + 'platform=iOS Simulator,OS=16.2,name=iPhone 11 Pro' ] steps: