├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Demo ├── License.md ├── blueSTDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcshareddata │ │ └── xcschemes │ │ └── blueSTDemo.xcscheme └── blueSTDemo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Controllers │ ├── Audio │ │ ├── AudioCircularBuffer.swift │ │ ├── AudioPlotDataSource.swift │ │ └── BlueVoiceViewController.swift │ ├── BaseNodeViewController.swift │ ├── DebugConsole │ │ ├── DebugConsoleViewController.swift │ │ └── DebugConsoleViewController.xib │ ├── DiscoveryViewController.swift │ ├── FeatureLogViewController.swift │ ├── FilePicker.swift │ ├── FirmwareSelect │ │ ├── FirmwareSelectViewController.swift │ │ ├── STM32FirmwareTypeView.swift │ │ └── STM32FirmwareTypeView.xib │ ├── LicenseAgreement │ │ ├── LicenseAgreement.swift │ │ └── LicenseAgreement.xib │ ├── NodeDetailViewController.swift │ └── NodeListViewController.swift │ ├── Info.plist │ ├── SceneDelegate.swift │ └── Views │ ├── FeatureCell.swift │ └── NodeCell.swift ├── LICENSE ├── Package.resolved ├── Package.swift ├── Packages └── STCore │ ├── Package.swift │ ├── README.md │ ├── Sources │ └── STCore │ │ ├── Analytics │ │ └── AnalyticsService.swift │ │ ├── Extensions │ │ ├── Bool+Helper.swift │ │ ├── DateFormatter+Helper.swift │ │ ├── FileManager+Helper.swift │ │ └── JSONDecoder+Helper.swift │ │ ├── Localizer │ │ └── Localizable.swift │ │ ├── Logger │ │ └── Logger.swift │ │ ├── Models │ │ ├── App.swift │ │ ├── Auth.swift │ │ ├── BoxedValue.swift │ │ ├── CodableWrapper.swift │ │ ├── Permission.swift │ │ └── STError.swift │ │ ├── Resolver │ │ ├── Container.swift │ │ └── Resolver.swift │ │ ├── STCore.swift │ │ └── Services │ │ ├── AuthDataStorage.swift │ │ ├── DataKeychainPropertyWrapper.swift │ │ ├── JsonDefaultPropertyWrapper.swift │ │ ├── JsonKeychainPropertyWrapper.swift │ │ ├── LoginService.swift │ │ ├── NetworkService.swift │ │ ├── SessionService.swift │ │ └── UserDefaultPropertyWrapper.swift │ └── Tests │ └── STCoreTests │ └── STCoreTests.swift ├── Readme.md ├── SECURITY.md ├── Sources └── STBlueSDK │ ├── Advertise │ ├── AdvertiseFilter.swift │ ├── AdvertiseInfo.swift │ ├── AdvertiseParser.swift │ ├── BlueAdvertiseInfo.swift │ ├── BlueNRGAdvertiseInfo.swift │ └── BlueNRGOtaAdvertiseParser.swift │ ├── Calatog │ ├── CatalogService.swift │ ├── Models │ │ ├── BleCharacteristic.swift │ │ ├── BleCharacteristicFormat.swift │ │ ├── BleCharacteristicStringValue.swift │ │ ├── Catalog.swift │ │ ├── Checksum.swift │ │ ├── CloudApp.swift │ │ ├── DemoDecorator.swift │ │ ├── Firmware.swift │ │ ├── FotaDetails.swift │ │ ├── IconValue.swift │ │ ├── Maturity.swift │ │ ├── OptionByte.swift │ │ └── StringValue.swift │ └── URLSession+Helper.swift │ ├── Commands │ ├── ECCommand │ │ ├── ECCommand.swift │ │ ├── ECCommandSection.swift │ │ ├── ECCustomCommand.swift │ │ └── ECResponse.swift │ ├── Feature │ │ ├── BaseCommandResponse.swift │ │ ├── BatteryCommandResponse.swift │ │ └── FeatureCommand.swift │ ├── PnpLCommand │ │ └── PnpLCommand.swift │ └── StandardJsonCommand.swift │ ├── Core │ ├── BleService.swift │ ├── BlueCharacteristic.swift │ ├── BlueDelegate.swift │ ├── BlueManager+Catalog.swift │ ├── BlueManager+Command.swift │ ├── BlueManager+DebugConsole.swift │ ├── BlueManager+Discovery.swift │ ├── BlueManager+ECCommand.swift │ ├── BlueManager+Feature.swift │ ├── BlueManager+Firmware.swift │ ├── BlueManager+HSDCommand.swift │ ├── BlueManager+Notifications.swift │ ├── BlueManager+PnpLCommand.swift │ ├── BlueManager.swift │ ├── BlueUUID.swift │ ├── DataTransporter.swift │ ├── DebugConsole+Helper.swift │ ├── DebugConsole.swift │ ├── DebugConsoleCallback.swift │ ├── FavoritesServiceCore.swift │ ├── STBlueSDK.swift │ ├── WiFiSettings.swift │ └── WriteDataManager.swift │ ├── Extensions │ ├── Array+BlueCharacteristic.swift │ ├── Array+FeatureType.swift │ ├── BytesUtils.swift │ ├── CBCharacteristic+Common.swift │ ├── CBCharacteristic+Feature.swift │ ├── CBService+Blue.swift │ ├── CBUUID+Helper.swift │ ├── Data+Helper.swift │ ├── Data+NumberConversion.swift │ ├── DateFormatter+Helper.swift │ ├── Int+Helper.swift │ ├── NSRegularExpression+Helper.swift │ ├── Optional+Helper.swift │ ├── String+Helper.swift │ ├── String+Regex.swift │ ├── UInt32+Helper.swift │ └── URL+Helper.swift │ ├── Features │ ├── AILogging │ │ ├── AILoggingCommand.swift │ │ ├── AILoggingData.swift │ │ ├── AILoggingFeature.swift │ │ └── AILoggingStatus.swift │ ├── Acceleration │ │ ├── AccelerationData.swift │ │ └── AccelerationFeature.swift │ ├── AccelerationEvent │ │ ├── AccelerationEventData.swift │ │ └── AccelerationEventFeature.swift │ ├── Activity │ │ ├── ActivityData.swift │ │ ├── ActivityFeature.swift │ │ └── ActivityType.swift │ ├── Audio │ │ ├── ADPCM │ │ │ ├── ADPCMAudioData.swift │ │ │ ├── ADPCMAudioFeature.swift │ │ │ ├── ADPCMAudioSyncFeature.swift │ │ │ ├── ADPCMCodecManager.swift │ │ │ ├── ADPCMEngine.swift │ │ │ └── AudioSyncData.swift │ │ ├── AudioCodec.swift │ │ ├── AudioDataFeature.swift │ │ ├── AudioFeature.swift │ │ ├── AudioPlayer.swift │ │ ├── AudioRecorder.swift │ │ ├── BeamFormingFeature.swift │ │ ├── BlueVoiceSyncQueue.swift │ │ └── Opus │ │ │ ├── OpusAudioConfFeature.swift │ │ │ ├── OpusAudioData.swift │ │ │ ├── OpusAudioFeature.swift │ │ │ ├── OpusCodecManager.swift │ │ │ ├── OpusConfData.swift │ │ │ ├── OpusConstants.swift │ │ │ └── OpusEngine.swift │ ├── AudioClassification │ │ ├── AudioClassificationData.swift │ │ └── AudioClassificationFeature.swift │ ├── Battery │ │ ├── BatteryData.swift │ │ └── BatteryFeature.swift │ ├── BlueNRGOta │ │ ├── ACK │ │ │ ├── BlueNRGOtaAckData.swift │ │ │ └── BlueNRGOtaAckFeature.swift │ │ ├── BlueNRGOtaDataTransferFeature.swift │ │ ├── MemoryInfo │ │ │ ├── BlueNRGOtaMemoryInfoData.swift │ │ │ └── BlueNRGOtaMemoryInfoFeature.swift │ │ └── Settings │ │ │ ├── BlueNRGOtaSettingsData.swift │ │ │ └── BlueNRGOtaSettingsFeature.swift │ ├── COSensor │ │ ├── COSensorCommand.swift │ │ ├── COSensorCommandResponse.swift │ │ ├── COSensorData.swift │ │ └── COSensorFeature.swift │ ├── CarryPosition │ │ ├── CarryPositionData.swift │ │ ├── CarryPositionFeature.swift │ │ └── CarryPositionType.swift │ ├── ColorAmbientLight │ │ ├── ColorAmbientLightData.swift │ │ └── ColorAmbientLightFeature.swift │ ├── Common │ │ ├── BaseFeature+Remote.swift │ │ ├── BaseFeature.swift │ │ ├── EnvironmentalFeature.swift │ │ ├── Feature.swift │ │ ├── FeatureField.swift │ │ ├── FeatureSample.swift │ │ ├── FeatureType.swift │ │ └── TimestampFeature.swift │ ├── Compass │ │ ├── CompassData.swift │ │ └── CompassFeature.swift │ ├── DirectionOfArrival │ │ ├── DirectionOfArrivalCommand.swift │ │ ├── DirectionOfArrivalData.swift │ │ └── DirectionOfArrivalFeature.swift │ ├── EulerAngle │ │ ├── EulerAngleData.swift │ │ └── EulerAngleFeature.swift │ ├── EventCounter │ │ ├── EventCounterData.swift │ │ └── EventCounterFeature.swift │ ├── Extended │ │ ├── ExtendedConfigurationData.swift │ │ └── ExtendedConfigurationFeature.swift │ ├── FFTAmplitude │ │ ├── FFTAmplitudeData.swift │ │ ├── FFTAmplitudeFeature.swift │ │ └── FFTDataTransporter.swift │ ├── FiniteStateMachine │ │ ├── FiniteStateMachineData.swift │ │ └── FiniteStateMachineFeature.swift │ ├── FitnessActivity │ │ ├── FitnessActivityData.swift │ │ ├── FitnessActivityFeature.swift │ │ └── FitnessActivityType.swift │ ├── FreeFall │ │ ├── FreeFallData.swift │ │ └── FreeFallFeature.swift │ ├── GNSS │ │ ├── GNSSData.swift │ │ └── GNSSFeature.swift │ ├── GeneralPurpose │ │ ├── GeneralPurposeData.swift │ │ └── GeneralPurposeFeature.swift │ ├── GestureNavigation │ │ ├── GestureNavigationData.swift │ │ ├── GestureNavigationFeature.swift │ │ └── GestureNavigationType.swift │ ├── Gyroscope │ │ ├── GyroscopeData.swift │ │ └── GyroscopeFeature.swift │ ├── HeartRate │ │ ├── HeartRateData.swift │ │ └── HeartRateFeature.swift │ ├── HighSpeedDataLog │ │ ├── HSDData.swift │ │ └── HSDFeature.swift │ ├── Humidity │ │ ├── HumidityData.swift │ │ └── HumidityFeature.swift │ ├── JsonNFC │ │ ├── JsonNFCData.swift │ │ ├── JsonNFCFeature.swift │ │ └── JsonNFCModel.swift │ ├── Led │ │ └── ControlLedFeature.swift │ ├── Luminosity │ │ ├── LuminosityData.swift │ │ └── LuminosityFeature.swift │ ├── MachineLearningCore │ │ ├── MachineLearningCoreData.swift │ │ └── MachineLearningCoreFeature.swift │ ├── Magnetometer │ │ ├── MagnetometerData.swift │ │ └── MagnetometerFeature.swift │ ├── MemsGesture │ │ ├── GestureType.swift │ │ ├── MemsGestureData.swift │ │ └── MemsGestureFeature.swift │ ├── MemsNorm │ │ ├── MemsNormData.swift │ │ └── MemsNormFeature.swift │ ├── MicLevel │ │ ├── MicLevelFeature.swift │ │ └── MicLevelsData.swift │ ├── MotionAlgorithm │ │ ├── Algorithm.swift │ │ ├── DeskTypeDetection.swift │ │ ├── MotionAlgorithmData.swift │ │ ├── MotionAlgorithmFeature.swift │ │ ├── PoseEstimation.swift │ │ └── VerticalContext.swift │ ├── MotionIntensity │ │ ├── MotionIntensityData.swift │ │ └── MotionIntensityFeature.swift │ ├── MotorTimeParameters │ │ ├── MotorTimeParametersData.swift │ │ └── MotorTimeParametersFeature.swift │ ├── NEAIAnomalyDetection │ │ ├── NEAIAnomalyDetectionCommand.swift │ │ ├── NEAIAnomalyDetectionData.swift │ │ ├── NEAIAnomalyDetectionFeature.swift │ │ └── NEAIAnomalyDetectionModel.swift │ ├── NEAIClassification │ │ ├── NEAIClassificationCommand.swift │ │ ├── NEAIClassificationData.swift │ │ ├── NEAIClassificationFeature.swift │ │ └── NEAIClassificationModel.swift │ ├── Pedometer │ │ ├── PedometerData.swift │ │ └── PedometerFeature.swift │ ├── PnPLike │ │ ├── Array+PnPLikeElement.swift │ │ ├── Configuration │ │ │ ├── PnPLType.swift │ │ │ ├── PnPLikeConfiguration.swift │ │ │ └── PnPLikeConfigurationParameter.swift │ │ ├── ContentType.swift │ │ ├── DTMI │ │ │ ├── Array+PnpLContent.swift │ │ │ ├── PnpLCommandContent.swift │ │ │ ├── PnpLCommandPayload.swift │ │ │ ├── PnpLCommandPayloadContent.swift │ │ │ ├── PnpLComponentContent.swift │ │ │ ├── PnpLContent.swift │ │ │ ├── PnpLEnumerativeContent.swift │ │ │ ├── PnpLInterfaceContent.swift │ │ │ ├── PnpLObjectContent.swift │ │ │ ├── PnpLPrimitiveContent.swift │ │ │ ├── PnpLPropertyContent.swift │ │ │ └── PnpLUnknownContent.swift │ │ ├── JSONValue.swift │ │ ├── PnPLData.swift │ │ ├── PnPLFeature.swift │ │ ├── PnPLResponse.swift │ │ ├── PnPLikeDtmiCommand.swift │ │ └── SchemaContent.swift │ ├── Predictive │ │ ├── AccelerationStatus │ │ │ ├── PredictiveAccelerationStatusData.swift │ │ │ └── PredictiveAccelerationStatusFeature.swift │ │ ├── FrequencyDomain │ │ │ ├── PredictiveFrequencyDomainStatusData.swift │ │ │ └── PredictiveFrequencyDomainStatusFeature.swift │ │ ├── PredictiveStatus.swift │ │ └── SpeedStatus │ │ │ ├── PredictiveSpeedStatusData.swift │ │ │ └── PredictiveSpeedStatusFeature.swift │ ├── Pressure │ │ ├── PressureData.swift │ │ └── PressureFeature.swift │ ├── Proximity │ │ ├── ProximityData.swift │ │ └── ProximityFeature.swift │ ├── ProximityGesture │ │ ├── ProximityGestureData.swift │ │ ├── ProximityGestureFeature.swift │ │ └── ProximityGestureType.swift │ ├── RawPnPL │ │ ├── RawPnPLData.swift │ │ └── RawPnPLFeature.swift │ ├── Remote │ │ ├── RemoteData.swift │ │ ├── RemoteHumidityFeature.swift │ │ ├── RemotePressureFeature.swift │ │ ├── RemoteSwitchFeature.swift │ │ └── RemoteTemperatureFeature.swift │ ├── SDLogging │ │ ├── SDLoggingCommand.swift │ │ ├── SDLoggingData.swift │ │ └── SDLoggingFeature.swift │ ├── STM32OTA │ │ ├── Data+STM32WBControl.swift │ │ ├── Data+STM32WBUpload.swift │ │ ├── STM32WBOtaControlFeature.swift │ │ ├── STM32WBOtaUploadFeature.swift │ │ ├── STM32WBOtaWillRebootFeature.swift │ │ └── STM32WBRebootOtaModeFeature.swift │ ├── STM32Switch │ │ ├── STM32SwitchStatusData.swift │ │ └── STM32SwitchStatusFeature.swift │ ├── STREDL │ │ ├── STREDLData.swift │ │ └── STREDLFeature.swift │ ├── SensorFusion │ │ ├── AutoConfigurationCommand.swift │ │ ├── AutoConfigurationCommandResponse.swift │ │ ├── CommandFeature.swift │ │ ├── QuaternionConfiguration.swift │ │ ├── SensorFusionCompactData.swift │ │ ├── SensorFusionCompactFeature.swift │ │ ├── SensorFusionData.swift │ │ └── SensorFusionFeature.swift │ ├── Switch │ │ ├── SwitchData.swift │ │ ├── SwitchFeature.swift │ │ └── SwitchType.swift │ ├── Temperature │ │ ├── TemperatureData.swift │ │ └── TemperatureFeature.swift │ ├── ToFMultiObject │ │ ├── ToFCommand.swift │ │ ├── ToFMultiObjectData.swift │ │ └── ToFMultiObjectFeature.swift │ └── UnkownFeature.swift │ ├── Firmware │ ├── BaseFirmwareService.swift │ ├── BlueNRG │ │ ├── BlueNRGFirmwareService.swift │ │ ├── Delegates │ │ │ ├── AckUpgradeFirmwareDelegate.swift │ │ │ ├── CheckMemoryAddressDelegate.swift │ │ │ └── CheckUpgradeSettingsDelegate.swift │ │ ├── FirmwareUpgradeParam.swift │ │ ├── FirmwareUpgradeSettings.swift │ │ └── VersionInfoDelegate.swift │ ├── DebugConsole │ │ ├── Data+Firmware.swift │ │ ├── DebugConsoleFirmwareService.swift │ │ └── FirmwareLoaders │ │ │ ├── BaseFirmwareLoader.swift │ │ │ ├── DebugConsoleFirmwareLoader.swift │ │ │ └── DebugConsoleWithResumeFirmwareLoader.swift │ ├── FirmwareServiceFactory.swift │ ├── FirmwareVersion.swift │ ├── STM32 │ │ ├── MemoryLayout.swift │ │ └── STM32WBFirmwareService.swift │ └── URLSession+Firmware.swift │ ├── HSD │ ├── FWErrorInfo.swift │ ├── HSDCmd+GET.swift │ ├── HSDCmd+SET.swift │ ├── HSDCmd.swift │ ├── HSDConfigData.swift │ ├── HSDDevice.swift │ ├── HSDDeviceInfo.swift │ ├── HSDDeviceParser.swift │ ├── HSDDeviceStatus.swift │ ├── HSDOptionModel.swift │ ├── HSDResponse.swift │ ├── HSDSamplesPerTs.swift │ ├── HSDSensor.swift │ ├── HSDSensorStatus.swift │ ├── HSDSubSensor.swift │ ├── HSDTag.swift │ └── HSDTagConfig.swift │ ├── License.md │ ├── Node │ ├── Array+Node.swift │ ├── Array+NodeService.swift │ ├── Node.swift │ ├── NodeService+Command.swift │ ├── NodeService+ECCommand.swift │ ├── NodeService+Notifications.swift │ ├── NodeService+ReadWrite.swift │ ├── NodeService.swift │ ├── NodeState.swift │ └── NodeType.swift │ └── Utils │ ├── BlueSTM32CRC.swift │ ├── FeatureFileLogger.swift │ ├── FeatureLogger.swift │ ├── LoadingView.swift │ ├── UnwrapTimeStamp.swift │ ├── WeakCallback.swift │ └── WeakObject.swift └── Tests └── STBlueSDKTests └── STBlueSDKTests.swift /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/blueSTDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/blueSTDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/blueSTDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "core-plot", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/core-plot/core-plot.git", 7 | "state" : { 8 | "branch" : "release-2.4", 9 | "revision" : "6b70be5294b5aa5961270189b4fded4e32b1b34f" 10 | } 11 | }, 12 | { 13 | "identity" : "jgprogresshud", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/JonasGessner/JGProgressHUD", 16 | "state" : { 17 | "revision" : "78d7cd35f1d90ff74fd82e486f2cbe4b24be8cf9", 18 | "version" : "2.2.0" 19 | } 20 | }, 21 | { 22 | "identity" : "keychainaccess", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/kishikawakatsumi/KeychainAccess.git", 25 | "state" : { 26 | "revision" : "84e546727d66f1adc5439debad16270d0fdd04e7", 27 | "version" : "4.2.2" 28 | } 29 | }, 30 | { 31 | "identity" : "opus-swift", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/ybrid/opus-swift.git", 34 | "state" : { 35 | "revision" : "92e76803ce7efc8e8903433cfd5f7f68938534ba", 36 | "version" : "0.8.0" 37 | } 38 | } 39 | ], 40 | "version" : 2 41 | } 42 | -------------------------------------------------------------------------------- /Demo/blueSTDemo/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Demo/blueSTDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/blueSTDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Demo/blueSTDemo/Views/FeatureCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeatureCell.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import UIKit 13 | 14 | class FeatureCell: UITableViewCell { 15 | 16 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 17 | super.init(style: style, reuseIdentifier: reuseIdentifier) 18 | } 19 | 20 | required init?(coder: NSCoder) { 21 | fatalError("init(coder:) has not been implemented") 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Demo/blueSTDemo/Views/NodeCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NodeCell.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import UIKit 13 | 14 | class NodeCell: UITableViewCell { 15 | 16 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 17 | super.init(style: .subtitle, reuseIdentifier: reuseIdentifier) 18 | } 19 | 20 | required init?(coder: NSCoder) { 21 | fatalError("init(coder:) has not been implemented") 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, 2015 STMicroelectronics 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of STMicroelectronics nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "keychainaccess", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/kishikawakatsumi/KeychainAccess.git", 7 | "state" : { 8 | "revision" : "84e546727d66f1adc5439debad16270d0fdd04e7", 9 | "version" : "4.2.2" 10 | } 11 | }, 12 | { 13 | "identity" : "opus-swift", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/ybrid/opus-swift.git", 16 | "state" : { 17 | "revision" : "92e76803ce7efc8e8903433cfd5f7f68938534ba", 18 | "version" : "0.8.0" 19 | } 20 | } 21 | ], 22 | "version" : 2 23 | } 24 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.6 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "STBlueSDK", 8 | platforms: [ 9 | .iOS(.v13), 10 | .macOS(.v11) 11 | ], 12 | products: [ 13 | // Products define the executables and libraries a package produces, and make them visible to other packages. 14 | .library( 15 | name: "STBlueSDK", 16 | targets: ["STBlueSDK"]), 17 | ], 18 | dependencies: [ 19 | // Dependencies declare other packages that this package depends on. 20 | // // .package(url: /* package url */, from: "1.0.0") 21 | .package(path: "./Packages/STCore"), 22 | .package(url: "https://github.com/ybrid/opus-swift.git", from: "0.8.0") 23 | ], 24 | targets: [ 25 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 26 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 27 | .target( 28 | name: "STBlueSDK", 29 | dependencies: [ 30 | .product(name: "YbridOpus", package: "opus-swift"), 31 | .product(name: "STCore", package: "STCore") 32 | ]), 33 | .testTarget( 34 | name: "STBlueSDKTests", 35 | dependencies: ["STBlueSDK"]), 36 | ] 37 | ) 38 | -------------------------------------------------------------------------------- /Packages/STCore/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.6 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "STCore", 8 | platforms: [ 9 | .iOS(.v13), 10 | .macOS(.v11) 11 | ], 12 | products: [ 13 | // Products define the executables and libraries a package produces, and make them visible to other packages. 14 | .library( 15 | name: "STCore", 16 | targets: ["STCore"]), 17 | ], 18 | dependencies: [ 19 | // Dependencies declare other packages that this package depends on. 20 | // .package(url: /* package url */, from: "1.0.0"), 21 | .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: Version(4, 2, 2)), 22 | ], 23 | targets: [ 24 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 25 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 26 | .target( 27 | name: "STCore", 28 | dependencies: [ 29 | .product(name: "KeychainAccess", package: "KeychainAccess"), 30 | ]), 31 | .testTarget( 32 | name: "STCoreTests", 33 | dependencies: ["STCore"]), 34 | ] 35 | ) 36 | -------------------------------------------------------------------------------- /Packages/STCore/README.md: -------------------------------------------------------------------------------- 1 | # STCore 2 | 3 | A description of this package. 4 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Analytics/AnalyticsService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnalyticsService.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol AnalyticsService { 15 | 16 | func startDemo(withName name: String) 17 | 18 | func stopDemo(withName name: String) 19 | 20 | func etnaBasicAnalytics() 21 | 22 | func etnaUserProfileAnalytics() 23 | 24 | func etnaNodeBaseAnalytics(nodeName: String, nodeType: String) 25 | 26 | func etnaNodeFwVersionAnalytics(fwVersion: String) 27 | 28 | func etnaNodeFullFwNameAnalytics(fullFwName: String) 29 | } 30 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Extensions/Bool+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Bool+Helper.swift 3 | // 4 | // Copyright (c) 2023 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | 13 | import Foundation 14 | 15 | public extension Bool { 16 | var string: String { 17 | self == true ? "true" : "false" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Models/Auth.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Auth.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct Auth { 15 | public let idToken: String? 16 | public let accessToken: String? 17 | public let refreshToken: String? 18 | 19 | public init(idToken: String?, accessToken: String?, refreshToken: String?) { 20 | self.idToken = idToken 21 | self.accessToken = accessToken 22 | self.refreshToken = refreshToken 23 | } 24 | } 25 | 26 | extension Auth: Codable { 27 | enum CodingKeys: String, CodingKey { 28 | case idToken 29 | case accessToken 30 | case refreshToken 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Models/STError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STError.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum STError: Error { 15 | case unknown 16 | case urlNotValid 17 | case dataNotValid 18 | case server(error: Error) 19 | case generic(text: String) 20 | case raw(data: Data) 21 | case notAuthorized 22 | 23 | public var localizedDescription: String { 24 | switch self { 25 | case .unknown: 26 | return "unknown" 27 | case .urlNotValid: 28 | return "urlNotValid" 29 | case .dataNotValid: 30 | return "dataNotValid" 31 | case .server(let error): 32 | return error.localizedDescription 33 | case .generic(let text): 34 | return text 35 | case .raw(let data): 36 | return "raw data: \(data)" 37 | case .notAuthorized: 38 | return "notAuthorized" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Resolver/Container.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Container.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol Container: AnyObject { 15 | typealias Factory = (Container) -> T? 16 | 17 | func register(key: String, instance: T) 18 | func register(key: String, factory: @escaping Factory) 19 | 20 | func register(type: T.Type, instance: T) 21 | func register(type: T.Type, factory: @escaping Factory) 22 | 23 | func resolve() -> T? 24 | func resolve(key: String) -> T? 25 | } 26 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/STCore.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct STCore { 4 | public static let appVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "1.0" 5 | public static let appShortVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0" 6 | } 7 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Services/AuthDataStorage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthDataStorage.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol AuthDataStorage { 15 | var authData: Data? { get set } 16 | } 17 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Services/JsonDefaultPropertyWrapper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JsonDefaultPropertyWrapper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | @propertyWrapper 15 | public struct JsonUserDefault { 16 | let key: String 17 | let defaultValue: Value? 18 | var container: UserDefaults = .standard 19 | 20 | public var wrappedValue: Value? { 21 | get { 22 | let decoder = JSONDecoder() 23 | guard let data = container.data(forKey: key), 24 | let decodedValue = try? decoder.decode(Value.self, from: data) else { return defaultValue } 25 | return decodedValue 26 | } 27 | set { 28 | 29 | guard let value = newValue else { 30 | container.removeObject(forKey: key) 31 | return 32 | } 33 | 34 | let encoder = JSONEncoder() 35 | container.set(try? encoder.encode(value), forKey: key) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Services/LoginService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoginService.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import UIKit 13 | 14 | public typealias LogoutCallback = (Bool) -> Void 15 | public typealias AuthCompletion = (Error?) -> Void 16 | 17 | public protocol LoginService { 18 | var isAuthenticated: Bool { get } 19 | var authData: Data? { get set } 20 | 21 | func resetAuthentication(from controller: UIViewController, completion: LogoutCallback?) 22 | func authenticate(from controller: UIViewController, completion: @escaping AuthCompletion) 23 | func resumeExternalUserAgentFlow(with url: URL) -> Bool 24 | } 25 | -------------------------------------------------------------------------------- /Packages/STCore/Sources/STCore/Services/UserDefaultPropertyWrapper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserDefaultPropertyWrapper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | @propertyWrapper 15 | public struct UserDefault { 16 | let key: String 17 | let defaultValue: Value 18 | var container: UserDefaults = .standard 19 | 20 | public var wrappedValue: Value { 21 | get { 22 | return container.object(forKey: key) as? Value ?? defaultValue 23 | } 24 | set { 25 | container.set(newValue, forKey: key) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Packages/STCore/Tests/STCoreTests/STCoreTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import STCore 3 | 4 | final class STCoreTests: XCTestCase { 5 | func testExample() throws { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Advertise/AdvertiseFilter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AdvertiseFilter.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol AdvertiseFilter { 15 | 16 | /** 17 | * @param data: advertise data from centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) 18 | * @return nill if the advertise doesn't contain all the needed info, otherwise a info object that is used to build the node 19 | */ 20 | func filter(_ data:[String:Any]) -> AdvertiseInfo? 21 | } 22 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Advertise/AdvertiseInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BleAdvertiseInfo.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | public protocol AdvertiseInfo { 13 | var name: String? { get } 14 | var address: String? { get } 15 | var featureMap: UInt32 { get set } 16 | var deviceId: UInt8 { get } 17 | var protocolVersion: UInt8 { get } 18 | var boardType: NodeType { get } 19 | var isSleeping: Bool { get } 20 | var hasGeneralPurpose: Bool { get } 21 | var txPower: UInt8 { get } 22 | var bleFirmwareId: Int { get } 23 | var offsetForFirstOptByte: Int { get } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Advertise/BlueNRGAdvertiseInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueNRGAdvertiseInfo.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import CoreBluetooth 14 | 15 | class BlueNRGAdvertiseInfo: BlueAdvertiseInfo { 16 | 17 | var services: [CBUUID] = [] 18 | 19 | convenience init(name: String?, 20 | address: String?, 21 | featureMap: UInt32, 22 | deviceId: UInt8, 23 | protocolVersion: UInt8, 24 | boardType: NodeType, 25 | isSleeping: Bool, 26 | hasGeneralPurpose: Bool, 27 | txPower: UInt8, 28 | services: [CBUUID]) { 29 | 30 | self.init(name: name, 31 | address: address, 32 | featureMap: featureMap, 33 | deviceId: deviceId, 34 | protocolVersion: protocolVersion, 35 | boardType: boardType, 36 | isSleeping: isSleeping, 37 | hasGeneralPurpose: hasGeneralPurpose, 38 | txPower: txPower) 39 | 40 | self.services = services 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/BleCharacteristic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BleCharacteristic.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct BleCharacteristic { 15 | public let name: String 16 | public let uuid: String 17 | public let uuidType: Int? 18 | public let dtmiName: String? 19 | public let description: String? 20 | public let formatNotify: [BleCharacteristicFormat]? 21 | public let formatWrite: [BleCharacteristicFormat]? 22 | } 23 | 24 | extension BleCharacteristic: Codable { 25 | enum CodingKeys: String, CodingKey { 26 | case name 27 | case uuid 28 | case uuidType = "uuid_type" 29 | case dtmiName = "dtmi_name" 30 | case description 31 | case formatNotify = "format_notify" 32 | case formatWrite = "format_write" 33 | } 34 | } 35 | 36 | extension BleCharacteristic: Hashable { 37 | public var hashValue: String { return self.uuid } 38 | 39 | public static func == (lhs: BleCharacteristic, rhs: BleCharacteristic) -> Bool { 40 | return false 41 | } 42 | 43 | public func hash(into hasher: inout Hasher) { 44 | hasher.combine(uuid) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/BleCharacteristicFormat.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BleCharacteristicFormat.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct BleCharacteristicFormat { 15 | public let length: Int? 16 | public let name: String 17 | public let optional: Bool? 18 | public let unit: String? 19 | public let min: Float? 20 | public let max: Float? 21 | public let offset: Float? 22 | public let scaleFactor: Float? 23 | public let type: String? 24 | public let stringValues: [BleCharacteristicStringValue]? 25 | } 26 | 27 | extension BleCharacteristicFormat: Codable { 28 | enum CodingKeys: String, CodingKey { 29 | case length 30 | case name 31 | case optional 32 | case unit 33 | case min 34 | case max 35 | case offset 36 | case scaleFactor = "scalefactor" 37 | case type 38 | case stringValues = "string_values" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/BleCharacteristicStringValue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BleCharacteristicStringValue.swift 3 | // 4 | // Copyright (c) 2024 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct BleCharacteristicStringValue { 15 | public let displayName: String 16 | public let value: Int 17 | } 18 | 19 | extension BleCharacteristicStringValue: Codable { 20 | enum CodingKeys: String, CodingKey { 21 | case displayName = "display_name" 22 | case value 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/Checksum.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Checksum.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct Checksum: Codable { 15 | public let checksum: String 16 | public let date: String 17 | public let version: String 18 | 19 | enum CodingKeys: String, CodingKey { 20 | case checksum = "checksum" 21 | case date = "date" 22 | case version = "version" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/CloudApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CloudApp.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct CloudApp { 15 | public let description: String? 16 | public let dtmi: String? 17 | public let name: String? 18 | public let shareableLink: String? 19 | public let url: String? 20 | } 21 | 22 | extension CloudApp: Codable { 23 | enum CodingKeys: String, CodingKey { 24 | case description 25 | case dtmi 26 | case name 27 | case shareableLink = "shareable_link" 28 | case url 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/DemoDecorator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoDecorator.swift 3 | // 4 | // Copyright (c) 2024 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct DemoDecorator { 15 | public let add: [String] 16 | public let remove: [String] 17 | public let rename: [DemoRename] 18 | } 19 | 20 | extension DemoDecorator: Codable { 21 | enum CodingKeys: String, CodingKey { 22 | case add 23 | case remove 24 | case rename 25 | } 26 | } 27 | 28 | public struct DemoRename { 29 | public let old: String 30 | public let new: String 31 | } 32 | 33 | extension DemoRename: Codable { 34 | enum CodingKeys: String, CodingKey { 35 | case old 36 | case new 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/FotaDetails.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FotaDetails.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct FotaDetails { 15 | public let partialFota: Int? 16 | public let type: FotaType? 17 | public let fotaMaxChunkLength: Int? 18 | public let fotaChunkDivisorConstraint: Int? 19 | public let url: String? 20 | public let bootLoaderType: BootLoaderType? 21 | } 22 | 23 | extension FotaDetails: Codable { 24 | enum CodingKeys: String, CodingKey { 25 | case partialFota = "partial_fota" 26 | case type 27 | case fotaMaxChunkLength = "fota_max_chunk_length" 28 | case fotaChunkDivisorConstraint = "fota_chunk_divisor_constraint" 29 | case url = "fw_url" 30 | case bootLoaderType = "bootloader_type" 31 | } 32 | } 33 | 34 | public enum FotaType: String, Codable { 35 | case no 36 | case yes 37 | case fast 38 | case wbMode = "wb_mode" 39 | case wbReady = "wb_ready" 40 | } 41 | 42 | public enum BootLoaderType: String, Codable { 43 | case none 44 | case custom 45 | case wb 46 | case sbsfu 47 | } 48 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/IconValue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IconValue.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct IconValue { 15 | public let type: String? 16 | public let displayName: String? 17 | public let comment: String? 18 | public let value: Int? 19 | public let code: Int? 20 | } 21 | 22 | extension IconValue: Codable { 23 | enum CodingKeys: String, CodingKey { 24 | case type 25 | case displayName = "display_name" 26 | case comment 27 | case value 28 | case code = "icon_code" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/Maturity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Maturity.swift 3 | // 4 | // Copyright (c) 2024 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum Maturity: String, Codable, CustomStringConvertible { 15 | case draft 16 | case beta 17 | case release 18 | case demo 19 | case custom 20 | case special 21 | 22 | public var description: String { 23 | switch self { 24 | case .draft: 25 | return "DRAFT FW" 26 | case .beta: 27 | return "BETA FW" 28 | case .release: 29 | return "RELEASE FW" 30 | case .demo: 31 | return "DEMO FW" 32 | case .custom: 33 | return "CUSTOM FW" 34 | case .special: 35 | return "SPECIAL FW" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/OptionByte.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OptionByte.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct OptionByte { 15 | public let format: String? 16 | public let name: String? 17 | public let negativeOffset: Int? 18 | public let scaleFactor: Int? 19 | public let type: String? 20 | public let escapeMessage: String? 21 | public let escapeValue: Int? 22 | public let stringValues: [StringValue]? 23 | public let iconValues: [IconValue]? 24 | } 25 | 26 | extension OptionByte: Codable { 27 | enum CodingKeys: String, CodingKey { 28 | case format 29 | case name 30 | case negativeOffset = "negative_offset" 31 | case scaleFactor = "scale_factor" 32 | case type 33 | case escapeMessage = "escape_message" 34 | case escapeValue = "escape_value" 35 | case stringValues = "string_values" 36 | case iconValues = "icon_values" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Calatog/Models/StringValue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringValue.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct StringValue { 15 | public let type: String? 16 | public let displayName: String? 17 | public let comment: String? 18 | public let value: Int? 19 | } 20 | 21 | extension StringValue: Codable { 22 | enum CodingKeys: String, CodingKey { 23 | case type 24 | case displayName = "display_name" 25 | case comment 26 | case value 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Commands/Feature/BatteryCommandResponse.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatteryCommandResponse.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class BatteryCommandResponse: BaseCommandResponse { 15 | var capacity: Float? { 16 | get { 17 | if commandType == BatteryCommand.getBatteryCapacity.rawValue { 18 | return Float(data.extractUInt16(fromOffset: 0)) 19 | } 20 | 21 | return nil 22 | } 23 | } 24 | 25 | var current: Float? { 26 | get { 27 | if commandType == BatteryCommand.getMaxAssorbedCurrent.rawValue { 28 | return Float(data.extractInt16(fromOffset: 0)) 29 | } 30 | 31 | return nil 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Commands/StandardJsonCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StandardJsonCommand.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct StandardJsonCommand: JsonCommand { 15 | let value: T? 16 | 17 | public init(value: T?) { 18 | self.value = value 19 | } 20 | 21 | public var jsonData: Data? { 22 | try? JSONEncoder().encode(value) 23 | } 24 | public var json: String? { 25 | if let data = jsonData, 26 | let json = String(data: data, encoding: .utf8) { 27 | return json 28 | } 29 | return nil 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/BlueCharacteristic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueCharacteristic.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import CoreBluetooth 14 | 15 | public class BlueCharacteristic { 16 | let characteristic: CBCharacteristic 17 | let maxMtu: Int 18 | let features: [Feature] 19 | 20 | init(characteristic: CBCharacteristic, features: [Feature], maxMtu: Int) { 21 | self.characteristic = characteristic 22 | self.features = features 23 | self.maxMtu = maxMtu 24 | } 25 | } 26 | 27 | public extension BlueCharacteristic { 28 | func parse(_ data: Data, timestamp: UInt64, completion: @escaping (Feature, AnyFeatureSample?) -> Void) { 29 | var offset = 2 30 | 31 | for feature in features { 32 | let newOffset = feature.update(with: timestamp, 33 | data: data, 34 | offset: offset, 35 | mtu: maxMtu) 36 | 37 | offset += newOffset 38 | 39 | guard feature.hasData else { 40 | return 41 | } 42 | 43 | completion(feature, feature.lastSample) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/BlueDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueDelegate.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol BlueDelegate: AnyObject { 15 | /** 16 | * Function called when a new node is discovered 17 | * 18 | * @param manager manager that discovered the node (the manger is a singleton, 19 | * so this parameter is only for have a consistent method sign with the others delegate) 20 | * @param node new node discovered 21 | */ 22 | 23 | func manager(_ manager: BlueManager, discoveringStatus isDiscovering: Bool) 24 | 25 | func manager(_ manager: BlueManager, didDiscover node: Node) 26 | 27 | func manager(_ manager: BlueManager, didRemoveDiscovered nodes: [Node]) 28 | 29 | func manager(_ manager: BlueManager, didChangeStateFor node: Node) 30 | 31 | func manager(_ manager: BlueManager, didUpdateValueFor node: Node, feature: Feature, sample: AnyFeatureSample?) 32 | 33 | func manager(_ manager: BlueManager, didReceiveCommandResponseFor node: Node, feature: Feature, response: FeatureCommandResponse) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/BlueManager+Command.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueManager+Command.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension BlueManager { 15 | 16 | @discardableResult 17 | func sendCommand(_ command: FeatureCommand, to node: Node, feature: Feature) -> Bool { 18 | 19 | guard let nodeService = nodeServices.nodeService(with: node) else { return false } 20 | 21 | return nodeService.sendCommand(command, feature: feature) 22 | } 23 | 24 | @discardableResult 25 | func sendJsonCommand(_ command: JsonCommand, 26 | to node: Node, 27 | feature: Feature) -> Bool { 28 | if let nodeService = nodeServices.nodeService(with: node) { 29 | return nodeService.sendCommand(command, feature: feature) 30 | } 31 | 32 | return false 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/BlueManager+DebugConsole.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueManage+DebugConsole.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension BlueManager { 15 | 16 | @discardableResult 17 | func sendMessage(_ message: String, to node: Node, completion: DebugConsoleCallback) -> Bool { 18 | guard let nodeService = nodeServices.nodeService(with: node), 19 | let debugConsole = nodeService.debugConsole, 20 | let data = DebugConsole.stringToData(message) else { return false } 21 | 22 | debugConsole.addDelegate(completion) 23 | debugConsole.write(data: data) 24 | 25 | return true 26 | } 27 | 28 | @discardableResult 29 | func sendData(_ data: Data, to node: Node, completion: DebugConsoleCallback) -> Bool { 30 | guard let nodeService = nodeServices.nodeService(with: node), 31 | let debugConsole = nodeService.debugConsole else {return false} 32 | 33 | debugConsole.addDelegate(completion) 34 | debugConsole.write(data: data) 35 | 36 | return true 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/BlueManager+Feature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueManager+Feature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension BlueManager { 15 | func read(feature: Feature, for node: Node, delegate: BlueDelegate) { 16 | if let nodeService = nodeServices.nodeService(with: node) { 17 | 18 | addDelegate(delegate) 19 | 20 | if !nodeService.readFeature(feature) { 21 | delegate.manager(self, didUpdateValueFor: node, feature: feature, sample: feature.lastSample) 22 | } 23 | } 24 | } 25 | 26 | func write(value: Data, for feature: Feature, to node: Node, delegate: BlueDelegate) { 27 | if let nodeService = nodeServices.nodeService(with: node) { 28 | nodeService.write(value: value, for: feature) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/BlueManager+PnpLCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueManager+PnpLCommand.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | import Foundation 15 | 16 | public extension BlueManager { 17 | 18 | @discardableResult 19 | func sendPnpLCommand(_ command: PnpLCommand, to node: Node, progress: ((Int, Int) -> Void)? = nil, completion: (() -> Void)? = nil) -> Bool { 20 | guard let nodeService = nodeServices.nodeService(with: node), 21 | let blueChar = node.characteristics.characteristic(with: PnPLFeature.self) else { return false } 22 | 23 | return nodeService.sendCommand(command, blueChar: blueChar, progress: progress, completion: completion) 24 | } 25 | 26 | @discardableResult 27 | func sendPnpLCommand(_ command: PnpLCommand, to node: Node, feature: Feature) -> Bool { 28 | if let nodeService = nodeServices.nodeService(with: node) { 29 | return nodeService.sendCommand(command, feature: feature) 30 | } 31 | 32 | return false 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/DebugConsole+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DebugConsole+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | extension DebugConsole { 15 | internal static let dataChunkSize = 20 16 | 17 | /** 18 | * write the string into the stdin char, if the message is longer than 20byte, 19 | * it is splitted in multiple write that are done without waiting an answer. 20 | */ 21 | func writeWithoutQueue(_ message: String){ 22 | if let data = DebugConsole.stringToData(message) { 23 | var endOffset = min(DebugConsole.dataChunkSize, data.count) 24 | var startOffset = 0 25 | 26 | while (startOffset < endOffset) { 27 | writeFast(data: data[startOffset.. Data? { 35 | return text.data(using: .isoLatin1)?.nullTerminated 36 | } 37 | 38 | static func dataToString(_ data: Data) -> String? { 39 | return String(bytes: data, encoding: .isoLatin1) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/STBlueSDK.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STBlueSDK.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import STCore 14 | 15 | struct STBlueSDK { 16 | static func log(text: String, category: String? = nil) { 17 | Logger.log(level: .debug, category: category ?? "", text: text) 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Core/WiFiSettings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WiFiSettings.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct WiFiSettings: Codable { 15 | public enum WiFiSecurity: String, CaseIterable, Codable { 16 | case OPEN = "OPEN" 17 | case WEP = "WEP" 18 | case WPA = "WPA" 19 | case WPA2 = "WPA2" 20 | case WPAWPA2 = "WPA/WPA2" 21 | } 22 | 23 | public let enable: Bool? 24 | public let ssid: String? 25 | public let password: String? 26 | public let securityType: WiFiSettings.WiFiSecurity? 27 | 28 | public init(enable: Bool?, ssid: String?, password: String?, securityType: WiFiSettings.WiFiSecurity?) { 29 | self.enable = enable 30 | self.ssid = ssid 31 | self.password = password 32 | self.securityType = securityType 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/Array+FeatureType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+FeatureType.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import CoreBluetooth 14 | 15 | public extension Array where Element == FeatureType { 16 | func featureType(with uuid: CBUUID) -> FeatureType? { 17 | for type in self { 18 | if type.uuid == uuid { 19 | return type 20 | } 21 | } 22 | 23 | return nil 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/CBService+Blue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CBService+Blue.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import CoreBluetooth 14 | 15 | public extension CBService { 16 | 17 | var isDebugService: Bool { 18 | get { 19 | return self.uuid == BlueUUID.Service.Debug.uuid 20 | } 21 | } 22 | 23 | var isConfigService: Bool { 24 | get { 25 | return self.uuid == BlueUUID.Service.Config.uuid 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/CBUUID+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CBUUID+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import CoreBluetooth 14 | 15 | public typealias FeatureMask = UInt32 16 | 17 | public extension CBUUID { 18 | /** 19 | * extract the feature mask from an uuid value, tell to the user witch feature 20 | * are exported by this characteristics 21 | * 22 | * @return characteristics feature mask 23 | */ 24 | var featureMask: FeatureMask { 25 | get { 26 | return data.extractUInt32(fromOffset: 0, endian: .big) 27 | } 28 | } 29 | 30 | static func uuid(_ identifier: UInt32, suffix: String) -> CBUUID { 31 | let uuidString = String(format: "%08X%@", identifier, suffix) 32 | return CBUUID(string: uuidString) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/Data+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension Data { 15 | func subdata(in range: ClosedRange) -> Data { 16 | return subdata(in: range.lowerBound ..< range.upperBound + 1) 17 | } 18 | 19 | func swapData() -> Data { 20 | 21 | var mdata = self 22 | let count = count / MemoryLayout.size 23 | mdata.withUnsafeMutableBytes { i16ptr in 24 | for i in 0.. [Data] { 32 | return stride(from: 0, to: count, by: size).map { (startIndex) -> Data in 33 | let endIndex = (startIndex.advanced(by: size) > count) ? count : startIndex + size 34 | return subdata(in: startIndex.. Int { 16 | let ( _, renainder ) = self.quotientAndRemainder(dividingBy: multiple) 17 | return renainder == 0 ? self : self + multiple - renainder 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/NSRegularExpression+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSRegularExpression+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | extension NSRegularExpression { 15 | convenience init(_ pattern: String) { 16 | do { 17 | try self.init(pattern: pattern) 18 | } catch { 19 | preconditionFailure("Illegal regular expression: \(pattern).") 20 | } 21 | } 22 | 23 | func matches(_ string: String) -> Bool { 24 | let range = NSRange(location: 0, length: string.utf16.count) 25 | return firstMatch(in: string, options: [], range: range) != nil 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/Optional+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Optional+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension Optional { 15 | func or(_ other: Optional) -> Optional { 16 | switch self { 17 | case .none: return other 18 | case .some: return self 19 | } 20 | } 21 | 22 | func resolve(with error: @autoclosure () -> Error) throws -> Wrapped { 23 | switch self { 24 | case .none: throw error() 25 | case .some(let wrapped): return wrapped 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/String+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | extension String { 15 | 16 | subscript(_ range: NSRange) -> String { 17 | let start = self.index(self.startIndex, offsetBy: range.lowerBound) 18 | let end = self.index(self.startIndex, offsetBy: range.upperBound) 19 | let subString = self[start.. Bool { 16 | guard let regex = try? NSRegularExpression(pattern: rhs) else { return false } 17 | let range = NSRange(location: 0, length: lhs.utf16.count) 18 | return regex.firstMatch(in: lhs, options: [], range: range) != nil 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/UInt32+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Int32+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal extension UInt32 { 15 | 16 | func features(for node: Node) -> [Feature] { 17 | var features: [Feature] = [Feature]() 18 | var mask: UInt32 = 1 << 31 19 | 20 | for _ in 1..<32 { 21 | if self & mask != 0, 22 | var feature = FeatureType.feature(from: mask, 23 | types: FeatureType.nodeFeatureTypes(node.type)) { 24 | 25 | feature.isEnabled = false 26 | 27 | features.append(feature) 28 | } 29 | 30 | mask = mask >> 1 31 | } 32 | 33 | return features 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Extensions/URL+Helper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // URL+Helper.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal extension URL { 15 | func readFileContent() -> Data? { 16 | let fileHandler = try? FileHandle(forReadingFrom: self) 17 | let data = fileHandler?.readDataToEndOfFile() 18 | fileHandler?.closeFile() 19 | return data 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/AILogging/AILoggingData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AILoggingData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct AILoggingData { 15 | 16 | public let status: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let status = AILoggingStatus(rawValue: data.extractUInt8(fromOffset: offset)) 21 | 22 | self.status = FeatureField(name: "Status", 23 | uom: nil, 24 | min: nil, 25 | max: nil, 26 | value: status) 27 | } 28 | 29 | } 30 | 31 | extension AILoggingData: CustomStringConvertible { 32 | public var description: String { 33 | 34 | let status = status.value ?? .unknown 35 | 36 | return String(format: "Status: %@", status.description) 37 | } 38 | } 39 | 40 | extension AILoggingData: Loggable { 41 | public var logHeader: String { 42 | "\(status.logHeader)" 43 | } 44 | 45 | public var logValue: String { 46 | "\(status.logValue)" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/AILogging/AILoggingFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AILoggingFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class AILoggingFeature: BaseFeature { 15 | 16 | let packetLength = 12 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = AILoggingData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/AILogging/AILoggingStatus.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AILoggingStatus.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum AILoggingStatus: UInt8 { 15 | case stoped = 0x00 16 | case started = 0x01 17 | case missingSD = 0x02 18 | case ioError = 0x03 19 | case update = 0x04 20 | case unknown = 0xFF 21 | } 22 | 23 | extension AILoggingStatus: CustomStringConvertible { 24 | public var description: String { 25 | switch self { 26 | case .stoped: 27 | return "Stopped" 28 | case .started: 29 | return "Started" 30 | case .missingSD: 31 | return "Missing SD" 32 | case .ioError: 33 | return "IO Error" 34 | case .update: 35 | return "Update" 36 | case .unknown: 37 | return "Unknown" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Acceleration/AccelerationFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AccelerationFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class AccelerationFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if data.count - offset < 6 { 19 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | } 21 | 22 | let parsedData = AccelerationData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), 6) 25 | } 26 | 27 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 28 | response 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Activity/ActivityFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ActivityFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class ActivityFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> BaseFeature.FeatureExtractDataResult where T : Loggable { 17 | let packageSize = data.count - offset 18 | 19 | switch packageSize { 20 | case Int.min..<1: 21 | return (FeatureSample(with: timestamp, data: nil, rawData: data), 0) 22 | case 1 : 23 | let activityData = ActivityData(withActivityData: data, offset: offset) 24 | return (FeatureSample(with: timestamp, data: activityData as? T, rawData: data), 1) 25 | default: // else 26 | let activityData = ActivityData(withActivityAndAlgorithmData: data, offset: offset) 27 | return (FeatureSample(with: timestamp, data: activityData as? T, rawData: data), 2) 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Audio/ADPCM/ADPCMAudioSyncFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ADPCMAudioSyncFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class ADPCMAudioSyncFeature: AudioFeature { 15 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 16 | 17 | if data.count - offset < 6 { 18 | return (FeatureSample(with: nil, rawData: data), 0) 19 | } 20 | 21 | let parsedData = AudioSyncData(with: data, offset: offset) 22 | 23 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), 6) 24 | } 25 | 26 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 27 | response 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Audio/AudioCodec.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioCodec.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol AudioCodecSettings { 15 | var codecName: String { get } 16 | /// codec frequency in hz 17 | var samplingFequency: Int { get } 18 | /// number of audio channel into the streaming 19 | var channels: Int { get } 20 | /// byte used to rappresent an audio sample 21 | var bytesPerSample: Int { get } 22 | /// decoded bytes obtined after each ble ble notification 23 | var samplePerBlock: Int { get } 24 | } 25 | 26 | public protocol AudioCodecManager: AudioCodecSettings { 27 | var isAudioEnabled: Bool { get } 28 | func reinit() 29 | func updateParameters(from sample: AnyFeatureSample) 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Audio/AudioDataFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioDataFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol AudioDataFeature: Feature { 15 | var audio: Data? { get } 16 | var rawData: Data? { get } 17 | var codecManager: AudioCodecManager { get } 18 | } 19 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Audio/AudioFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class AudioFeature: TimestampFeature { 15 | } 16 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Audio/BlueVoiceSyncQueue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueVoiceSyncQueue.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | /// it create a queue of size nil element, when the queue is empty it will return the last pop element 15 | public class BlueVoiceSyncQueue { 16 | private var data: [Data?] = [Data?]() 17 | private var prevData: Data? 18 | 19 | private let conditionLock = NSCondition() 20 | 21 | public func push(newData: Data) { 22 | conditionLock.lock() 23 | data.append(newData) 24 | conditionLock.unlock() 25 | } 26 | 27 | public func pop() -> Data? { 28 | var returnValue = prevData 29 | conditionLock.lock() 30 | 31 | if data.count != 0 { 32 | returnValue = data.removeFirst() 33 | prevData = returnValue 34 | } 35 | 36 | conditionLock.unlock() 37 | return returnValue 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Audio/Opus/OpusConstants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OpusConstants.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct OpusConstants { 15 | static let defaultFrameSize: Float = 20 16 | static let defaultSamplingFreq = 16000 17 | static let defaultNumberOfChannel = 1 18 | } 19 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/AudioClassification/AudioClassificationFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioClassificationFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class AudioClassificationFeature: BaseFeature { 15 | 16 | let packetLength = 1 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = AudioClassificationData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), data.count - offset) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/BlueNRGOta/ACK/BlueNRGOtaAckFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueNRGOtaAckFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class BlueNRGOtaAckFeature: TimestampFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if data.count - offset < 3 { 19 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | } 21 | 22 | let parsedData = BlueNRGOtaAckData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), 3) 25 | } 26 | 27 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 28 | response 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/BlueNRGOta/BlueNRGOtaDataTransferFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueNRGOtaDataTransferFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class BlueNRGOtaDataTransferFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 18 | } 19 | 20 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 21 | response 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/BlueNRGOta/MemoryInfo/BlueNRGOtaMemoryInfoFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueNRGOtaMemoryInfoFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class BlueNRGOtaMemoryInfoFeature: TimestampFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | if data.count - offset < 8 { 18 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 19 | } 20 | 21 | let parsedData = BlueNRGOtaMemoryInfoData(with: data, offset: offset) 22 | 23 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), data.count - offset) 24 | } 25 | 26 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 27 | response 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/BlueNRGOta/Settings/BlueNRGOtaSettingsFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlueNRGOtaSettingsFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class BlueNRGOtaSettingsFeature: TimestampFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if data.count - offset < 9 { 19 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | } 21 | 22 | let parsedData = BlueNRGOtaSettingsData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), data.count - offset) 25 | 26 | } 27 | 28 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 29 | response 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/COSensor/COSensorCommandResponse.swift: -------------------------------------------------------------------------------- 1 | // 2 | // COSensorCommandResponse.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class COSensorCommandResponse: BaseCommandResponse { 15 | var sensitivity: Float? { 16 | get { 17 | if commandType == COSensorCommand.getSesintivity.value { 18 | return data.extractFloat(fromOffset: 0) 19 | } 20 | 21 | return nil 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/CarryPosition/CarryPositionFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CarryPositionFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class CarryPositionFeature: BaseFeature { 15 | 16 | let packetLength = 1 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = CarryPositionData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 30 | response 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/ColorAmbientLight/ColorAmbientLightFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorAmbientLightFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class ColorAmbientLightFeature: BaseFeature { 15 | 16 | let packetLength = 8 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = ColorAmbientLightData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Common/BaseFeature+Remote.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseFeature+Remote.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension BaseFeature { 15 | 16 | typealias RemoteFeatureExtractData = (remoteId: UInt16, offset: Int, timestamp: UInt64) 17 | 18 | func remoteExtractData(with timestamp: UInt64, data: Data, offset: Int, nodeUnwrapper: inout [UInt16: UnwrapTimeStamp]) -> RemoteFeatureExtractData? { 19 | 20 | if data.count - offset < 3 { //2 bytes for the ts + 1 for some data 21 | return nil 22 | } 23 | 24 | //remove multiple of 2^16 since the node can unwrap the timestamp 25 | let remoteId = UInt16(timestamp % (1 << 16)) 26 | 27 | let extractedTimestamp = data.extractUInt16(fromOffset: offset) 28 | 29 | if nodeUnwrapper[remoteId] == nil { 30 | nodeUnwrapper[remoteId] = UnwrapTimeStamp() 31 | } 32 | 33 | guard let unwrapTimestamp = nodeUnwrapper[remoteId] else { 34 | return nil 35 | } 36 | 37 | let timestamp = unwrapTimestamp.unwrap(ts: extractedTimestamp) 38 | 39 | return (remoteId, offset + 2, timestamp) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Common/EnvironmentalFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnvironmentalFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol EnvironmentalFeature: Feature { 15 | 16 | var image: String { get } 17 | var missingImage: String { get } 18 | var isSecondaryUomEnabled: Bool { get } 19 | 20 | func valueString(with secondaryUom: Bool, offset: Double) -> String 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Common/Feature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Feature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol Loggable { 15 | var logHeader: String { get } 16 | var logValue: String { get } 17 | } 18 | 19 | public protocol Feature: Loggable { 20 | 21 | var name: String { get } 22 | var simpleDescription: String { get } 23 | var isEnabled: Bool { get set } 24 | var isNotificationsEnabled: Bool { get set } 25 | var type: FeatureType { get } 26 | var notificationDate: Date? { get } 27 | var hasData: Bool { get } 28 | var lastSample: AnyFeatureSample? { get } 29 | 30 | func update(with timestamp: UInt64, data: Data, offset: Int, mtu: Int) -> Int 31 | 32 | func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse 33 | 34 | func description(with sample: AnyFeatureSample?) -> String 35 | } 36 | 37 | public protocol Initializable { 38 | init(name: String, type: FeatureType) 39 | } 40 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Common/FeatureField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeatureField.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct FeatureField { 15 | 16 | public let name: String 17 | public let uom: String? 18 | public let min: ValueType? 19 | public let max: ValueType? 20 | public let value: ValueType? 21 | 22 | } 23 | 24 | extension FeatureField: Loggable { 25 | 26 | public var logHeader: String { 27 | guard let uom = uom else { 28 | return (name) 29 | } 30 | 31 | return "\(name) (\(uom))" 32 | } 33 | 34 | public var logValue: String { 35 | guard let value = value else { return "n/a" } 36 | return "\(value)" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Common/TimestampFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimestampFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class TimestampFeature: BaseFeature { 15 | 16 | public override func update(with timestamp: UInt64, data: Data, offset: Int, mtu: Int) -> Int { 17 | let time = UInt64(Date.timeIntervalSinceReferenceDate * 1000) 18 | 19 | return super.update(with: time, data: data, offset: offset - 2, mtu: mtu) 20 | } 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Compass/CompassFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CompassFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class CompassFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if data.count - offset < 2 { 19 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | } 21 | 22 | let parsedData = CompassData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), 2) 25 | } 26 | 27 | public override func parse(commandResponse response: FeatureCommandResponse) -> 28 | FeatureCommandResponse { 29 | return AutoConfigurationCommandResponse(timestamp: response.timestamp, 30 | featureMask: response.featureMask, 31 | commandType: response.commandType, 32 | rawData: response.data) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/DirectionOfArrival/DirectionOfArrivalFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DirectionOfArrivalFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class DirectionOfArrivalFeature: BaseFeature { 15 | 16 | let packetLength = 2 17 | 18 | public var commands: [FeatureCommandType] = [ 19 | DirectionOfArrivalCommand.changeSensitivity(sentivity: .lowSensitivity), 20 | DirectionOfArrivalCommand.changeSensitivity(sentivity: .highSensitivity) 21 | ] 22 | 23 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 24 | 25 | if data.count - offset < packetLength { 26 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 27 | } 28 | 29 | let parsedData = DirectionOfArrivalData(with: data, offset: offset) 30 | 31 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/EulerAngle/EulerAngleFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EulerAngleFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class EulerAngleFeature: BaseFeature { 15 | 16 | let packetLength = 12 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = EulerAngleData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/EventCounter/EventCounterData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventCounterData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct EventCounterData { 15 | 16 | public let counter: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let counter = data.extractUInt32(fromOffset: offset) 21 | 22 | self.counter = FeatureField(name: "Counter", 23 | uom: nil, 24 | min: 0, 25 | max: UInt32.max, 26 | value: counter) 27 | } 28 | 29 | } 30 | 31 | extension EventCounterData: CustomStringConvertible { 32 | public var description: String { 33 | 34 | let counter = counter.value ?? 0 35 | 36 | return String(format: "Counter: %zd", counter) 37 | } 38 | } 39 | 40 | extension EventCounterData: Loggable { 41 | public var logHeader: String { 42 | "\(counter.logHeader)" 43 | } 44 | 45 | public var logValue: String { 46 | "\(counter.logValue)" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/EventCounter/EventCounterFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventCounterFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class EventCounterFeature: BaseFeature { 15 | 16 | let packetLength = 4 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = EventCounterData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Extended/ExtendedConfigurationData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExtendedConfigurationData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct ExtendedConfigurationData { 15 | 16 | public let response: FeatureField 17 | 18 | init(response: ECResponse) { 19 | 20 | self.response = FeatureField(name: "ExtConfig", 21 | uom: nil, 22 | min: nil, 23 | max: nil, 24 | value: response) 25 | } 26 | } 27 | 28 | extension ExtendedConfigurationData: CustomStringConvertible { 29 | public var description: String { 30 | 31 | if let response = response.value, 32 | let responseData = try? JSONEncoder().encode(response) { 33 | return String(data: responseData, encoding: .utf8) ?? "n/a" 34 | } 35 | 36 | return "n/a" 37 | } 38 | } 39 | 40 | extension ExtendedConfigurationData: Loggable { 41 | public var logHeader: String { 42 | "TBI" 43 | } 44 | 45 | public var logValue: String { 46 | "TBI" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/FFTAmplitude/FFTAmplitudeFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FFTAmplitudeFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class FFTAmplitudeFeature: TimestampFeature { 15 | 16 | let dataTransporter = FFTDataTransporter() 17 | let packetLength = 12 18 | 19 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 20 | 21 | // if data.count - offset < packetLength { 22 | // return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 23 | // } 24 | 25 | let parsedData = dataTransporter.decapsulate(data: data, offset: offset) 26 | 27 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), data.count) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/FFTAmplitude/FFTDataTransporter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FFTDataTransporter.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class FFTDataTransporter { 15 | var sampleData: FFTAmplitudeData? 16 | 17 | public func decapsulate(data: Data, offset: Int) -> FFTAmplitudeData? { 18 | 19 | var sampleData: FFTAmplitudeData? = nil 20 | 21 | if self.sampleData == nil { 22 | self.sampleData = FFTAmplitudeData(with: data, offset: offset) 23 | sampleData = self.sampleData 24 | } else { 25 | self.sampleData?.append(data) 26 | sampleData = self.sampleData 27 | if sampleData?.isCompleted ?? false { 28 | reset() 29 | } 30 | } 31 | 32 | return sampleData 33 | } 34 | 35 | public func reset() { 36 | sampleData = nil 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/FiniteStateMachine/FiniteStateMachineFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FiniteStateMachineFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class FiniteStateMachineFeature: BaseFeature { 15 | 16 | let packetLength = 16 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = FiniteStateMachineData(with: data, offset: offset, numberOfRegiters: packetLength) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/FitnessActivity/FitnessActivityFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FitnessActivityFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class FitnessActivityFeature: BaseFeature { 15 | 16 | let packetLength = 3 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = FitnessActivityData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/FitnessActivity/FitnessActivityType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FitnessActivityType.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum FitnessActivityType: UInt8, FeatureCommandType, CaseIterable { 15 | case noActivity = 0x00 16 | case bicepCurl = 0x01 17 | case squat = 0x02 18 | case pushUp = 0x03 19 | 20 | public var payload: Data? { 21 | return nil 22 | } 23 | 24 | public var useMask: Bool { 25 | false 26 | } 27 | 28 | public func data(with nodeId: UInt8) -> Data { 29 | Data([rawValue]) 30 | } 31 | } 32 | 33 | extension FitnessActivityType: CustomStringConvertible { 34 | public var description: String { 35 | switch self { 36 | case .noActivity: 37 | return "No activity" 38 | case .bicepCurl: 39 | return "Bicep curl" 40 | case .squat: 41 | return "Squat" 42 | case .pushUp: 43 | return "Push up" 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/FreeFall/FreeFallData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FreeFallData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct FreeFallData { 15 | 16 | public let freeFall: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let counter = data.extractUInt8(fromOffset: offset) 21 | 22 | self.freeFall = FeatureField(name: "FreeFall", 23 | uom: nil, 24 | min: 0, 25 | max: 1, 26 | value: counter) 27 | } 28 | 29 | } 30 | 31 | extension FreeFallData: CustomStringConvertible { 32 | public var description: String { 33 | 34 | let freeFall = freeFall.value ?? 0 35 | 36 | return String(format: "FreeFall: %zd", freeFall) 37 | } 38 | } 39 | 40 | extension FreeFallData: Loggable { 41 | public var logHeader: String { 42 | "\(freeFall.logHeader)" 43 | } 44 | 45 | public var logValue: String { 46 | "\(freeFall.logValue)" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/FreeFall/FreeFallFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FreeFallFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class FreeFallFeature: BaseFeature { 15 | 16 | let packetLength = 1 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = FreeFallData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/GNSS/GNSSFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GNSSFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class GNSSFeature: BaseFeature { 15 | 16 | let packetLength = 14 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = GNSSData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/GeneralPurpose/GeneralPurposeData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeneralPurposeData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct GeneralPurposeData { 15 | 16 | public let rawData: FeatureField 17 | 18 | init(data: Data) { 19 | 20 | self.rawData = FeatureField(name: "General purpose", 21 | uom: "RawData", 22 | min: nil, 23 | max: nil, 24 | value: data) 25 | } 26 | } 27 | 28 | extension GeneralPurposeData: CustomStringConvertible { 29 | public var description: String { 30 | let data = rawData.value ?? Data() 31 | return String(format: "RawData: \(data.hex)") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/GeneralPurpose/GeneralPurposeFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GeneralPurposeFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class GeneralPurposeFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), data.count) 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/GestureNavigation/GestureNavigationFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GestureNavigationFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class GestureNavigationFeature: BaseFeature { 15 | 16 | let packetLength = 2 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = GestureNavigationData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Gyroscope/GyroscopeFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GyroscopeFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class GyroscopeFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if data.count - offset < 6 { 19 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | } 21 | 22 | let parsedData = GyroscopeData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), 6) 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/HeartRate/HeartRateFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeartRateFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class HeartRateFeature: BaseFeature { 15 | 16 | let packetLength = 2 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = HeartRateData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Humidity/HumidityData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HumidityData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct HumidityData { 15 | 16 | public let humidity: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let humidity = Float(data.extractUInt16(fromOffset: offset)) / 10.0 21 | 22 | self.humidity = FeatureField(name: "Humidity", 23 | uom: "%", 24 | min: 0, 25 | max: 100, 26 | value: humidity) 27 | } 28 | } 29 | 30 | extension HumidityData: Loggable { 31 | public var logHeader: String { 32 | "TBI" 33 | } 34 | 35 | public var logValue: String { 36 | "TBI" 37 | } 38 | } 39 | 40 | extension HumidityData: CustomStringConvertible { 41 | public var description: String { 42 | 43 | let humidity = humidity.value ?? .nan 44 | 45 | return String(format: "Humidity: %.2f", humidity) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Humidity/HumidityFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HumidityFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class HumidityFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if (data.count - offset < 2) { 19 | return (FeatureSample(with: timestamp, data: nil, rawData: data), 0) 20 | } 21 | let humidityData = HumidityData(with: data, offset: offset) 22 | 23 | return (FeatureSample(with: timestamp, data: humidityData as? T, rawData: data), 2) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/JsonNFC/JsonNFCData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JsonNFCData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct JsonNFCData { 15 | 16 | public let response: FeatureField 17 | 18 | init(response: JsonReadModes) { 19 | 20 | self.response = FeatureField(name: "JsonNFC", 21 | uom: nil, 22 | min: nil, 23 | max: nil, 24 | value: response) 25 | } 26 | } 27 | 28 | extension JsonNFCData: CustomStringConvertible { 29 | public var description: String { 30 | 31 | if let response = response.value, 32 | let responseData = try? JSONEncoder().encode(response) { 33 | return String(data: responseData, encoding: .utf8) ?? "n/a" 34 | } 35 | 36 | return "n/a" 37 | } 38 | } 39 | 40 | extension JsonNFCData: Loggable { 41 | public var logHeader: String { 42 | "TBI" 43 | } 44 | 45 | public var logValue: String { 46 | "TBI" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/JsonNFC/JsonNFCFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JsonNFCFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class JsonNFCFeature: BaseFeature { 15 | 16 | private let dataTransporter = DataTransporter() 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | if var commandFrame = dataTransporter.decapsulate(data: data) { 20 | do { 21 | commandFrame.removeLast() 22 | let response = try JSONDecoder().decode(JsonReadModes.self, from: commandFrame) 23 | dataTransporter.clear() 24 | return (FeatureSample(with: timestamp, data: JsonNFCData(response: response) as? T, rawData: data), 0) 25 | } catch { 26 | STBlueSDK.log(text: "Extract Data parse error: \(error)") 27 | return (FeatureSample(with: timestamp, data: nil, rawData: data), 0) 28 | } 29 | } else { 30 | return (FeatureSample(with: timestamp, data: nil, rawData: data), 0) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Luminosity/LuminosityData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LuminosityData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct LuminosityData { 15 | 16 | public let luminosity: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let luminosity = data.extractUInt16(fromOffset: offset) 21 | 22 | self.luminosity = FeatureField(name: "Luminosity", 23 | uom: "Lux", 24 | min: 0, 25 | max: 1000, 26 | value: luminosity) 27 | } 28 | 29 | } 30 | 31 | extension LuminosityData: CustomStringConvertible { 32 | public var description: String { 33 | 34 | let luminosity = luminosity.value ?? 0 35 | 36 | return String(format: "Luminosity: %zd", luminosity) 37 | } 38 | } 39 | 40 | extension LuminosityData: Loggable { 41 | public var logHeader: String { 42 | "\(luminosity.logHeader)" 43 | } 44 | 45 | public var logValue: String { 46 | "\(luminosity.logValue)" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Luminosity/LuminosityFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LuminosityFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class LuminosityFeature: BaseFeature { 15 | 16 | let packetLength = 2 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = LuminosityData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MachineLearningCore/MachineLearningCoreFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MachineLearningCoreFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MachineLearningCoreFeature: BaseFeature { 15 | 16 | let packetLength = 8 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MachineLearningCoreData(with: data, offset: offset, numberOfRegiters: packetLength) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Magnetometer/MagnetometerFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MagnetometerFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MagnetometerFeature: BaseFeature { 15 | 16 | let packetLength = 6 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MagnetometerData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MemsGesture/GestureType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GestureType.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum GestureType: UInt8 { 15 | case unknown = 0x00 16 | /** 17 | * the pick up gesture 18 | */ 19 | case pickUp = 0x01 20 | /** 21 | * the wake up gesture 22 | */ 23 | case glance = 0x02 24 | /** 25 | * the glance gesture 26 | */ 27 | case wakeUp = 0x03 28 | /** 29 | * the error status 30 | */ 31 | case error = 0xFF 32 | } 33 | 34 | extension GestureType: CustomStringConvertible { 35 | public var description: String { 36 | switch self { 37 | case .unknown: 38 | return "Unknown" 39 | case .pickUp: 40 | return "PickUp" 41 | case .glance: 42 | return "Grance" 43 | case .wakeUp: 44 | return "WakeUp" 45 | case .error: 46 | return "Error" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MemsGesture/MemsGestureData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MemsGestureData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct MemsGestureData { 15 | 16 | public let gesture: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let gesture = GestureType(rawValue: data.extractUInt8(fromOffset: offset)) 21 | 22 | self.gesture = FeatureField(name: "MemsGesture", 23 | uom: nil, 24 | min: nil, 25 | max: nil, 26 | value: gesture) 27 | } 28 | 29 | } 30 | 31 | extension MemsGestureData: CustomStringConvertible { 32 | public var description: String { 33 | 34 | let gesture = gesture.value ?? .unknown 35 | 36 | return String(format: "Gesture: %@", gesture.description) 37 | } 38 | } 39 | 40 | extension MemsGestureData: Loggable { 41 | public var logHeader: String { 42 | "\(gesture.logHeader)" 43 | } 44 | 45 | public var logValue: String { 46 | "\(gesture.logValue)" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MemsGesture/MemsGestureFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MemsGestureFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MemsGestureFeature: BaseFeature { 15 | 16 | let packetLength = 1 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MemsGestureData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MemsNorm/MemsNormData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MemsNormData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct MemsNormData { 15 | 16 | public let norm: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let norm = Float(data.extractUInt16(fromOffset: offset)) 21 | 22 | self.norm = FeatureField(name: "MemsNorm", 23 | uom: nil, 24 | min: 0, 25 | max: 2000, 26 | value: norm) 27 | } 28 | 29 | } 30 | 31 | extension MemsNormData: CustomStringConvertible { 32 | public var description: String { 33 | 34 | let norm = norm.value ?? 0 35 | 36 | return String(format: "MemsNorm: %zd", norm) 37 | } 38 | } 39 | 40 | extension MemsNormData: Loggable { 41 | public var logHeader: String { 42 | "\(norm.logHeader)" 43 | } 44 | 45 | public var logValue: String { 46 | "\(norm.logValue)" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MemsNorm/MemsNormFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MemsNormFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MemsNormFeature: BaseFeature { 15 | 16 | let packetLength = 2 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MemsNormData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MicLevel/MicLevelFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MicLevelFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MicLevelFeature: BaseFeature { 15 | 16 | let packetLength = 0 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset <= packetLength { 21 | return (FeatureSample(with: nil, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MicLevelsData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), data.count - offset) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotionAlgorithm/Algorithm.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Algorithm.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum Algorithm: UInt8, FeatureCommandType, CaseIterable { 15 | case none = 0x00 16 | case poseEstimation = 0x01 17 | case deskTypeDetection = 0x02 18 | case verticalContext = 0x03 19 | 20 | public var payload: Data? { 21 | return nil 22 | } 23 | 24 | public var useMask: Bool { 25 | false 26 | } 27 | 28 | public func data(with nodeId: UInt8) -> Data { 29 | Data([rawValue]) 30 | } 31 | } 32 | 33 | extension Algorithm: CustomStringConvertible { 34 | public var description: String { 35 | switch self { 36 | case .none: 37 | return "None" 38 | case .poseEstimation: 39 | return "Pose Estimation" 40 | case .deskTypeDetection: 41 | return "Desk Type Detection" 42 | case .verticalContext: 43 | return "Vertical Context" 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotionAlgorithm/DeskTypeDetection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeskTypeDetection.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum DeskTypeDetection: UInt8 { 15 | case unknown = 0x00 16 | case sittingDesk = 0x01 17 | case standingDesk = 0x02 18 | } 19 | 20 | extension DeskTypeDetection: CustomStringConvertible { 21 | public var description: String { 22 | switch self { 23 | case .unknown: 24 | return "Unknown" 25 | case .sittingDesk: 26 | return "Sitting Desk" 27 | case .standingDesk: 28 | return "Standing Desk" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotionAlgorithm/MotionAlgorithmFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MotionAlgorithmFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MotionAlgorithmFeature: BaseFeature { 15 | 16 | let packetLength = 2 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MotionAlgorithmData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotionAlgorithm/PoseEstimation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PoseEstimation.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum PoseEstimation : UInt8 { 15 | case unknown = 0x00 16 | case sitting = 0x01 17 | case standing = 0x02 18 | case layingDown = 0x03 19 | } 20 | 21 | extension PoseEstimation: CustomStringConvertible { 22 | public var description: String { 23 | switch self { 24 | case .unknown: 25 | return "Unknown" 26 | case .sitting: 27 | return "Sitting" 28 | case .standing: 29 | return "Standing" 30 | case .layingDown: 31 | return "Laying Down" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotionAlgorithm/VerticalContext.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VerticalContext.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum VerticalContext: UInt8 { 15 | case unknown = 0x00 16 | case floor = 0x01 17 | case upDown = 0x02 18 | case stairs = 0x03 19 | case elevator = 0x04 20 | case escalator = 0x05 21 | } 22 | 23 | extension VerticalContext: CustomStringConvertible { 24 | public var description: String { 25 | switch self { 26 | case .unknown: 27 | return "Unknown" 28 | case .floor: 29 | return "Floor" 30 | case .upDown: 31 | return "Up Down" 32 | case .stairs: 33 | return "Stairs" 34 | case .elevator: 35 | return "Elevetor" 36 | case .escalator: 37 | return "Escalator" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotionIntensity/MotionIntensityData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MotionIntensityData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct MotionIntensityData { 15 | 16 | public let motionIntensity: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let motionIntensity = data.extractUInt8(fromOffset: offset) 21 | 22 | self.motionIntensity = FeatureField(name: "Intensity", 23 | uom: nil, 24 | min: 0, 25 | max: 10, 26 | value: motionIntensity) 27 | } 28 | 29 | } 30 | 31 | extension MotionIntensityData: CustomStringConvertible { 32 | public var description: String { 33 | 34 | let motionIntensity = motionIntensity.value ?? 0 35 | 36 | return String(format: "Intensity: %zd", motionIntensity) 37 | } 38 | } 39 | 40 | extension MotionIntensityData: Loggable { 41 | public var logHeader: String { 42 | "\(motionIntensity.logHeader)" 43 | } 44 | 45 | public var logValue: String { 46 | "\(motionIntensity.logValue)" 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotionIntensity/MotionIntensityFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MotionIntensityFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MotionIntensityFeature: BaseFeature { 15 | 16 | let packetLength = 1 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MotionIntensityData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/MotorTimeParameters/MotorTimeParametersFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MotorTimeParametersFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class MotorTimeParametersFeature: BaseFeature { 15 | 16 | let packetLength = 18 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = MotorTimeParametersData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/NEAIAnomalyDetection/NEAIAnomalyDetectionCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NEAIAnomalyDetectionCommand.swift 3 | // 4 | // Copyright (c) 2023 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum NEAIAnomalyDetectionCommand: UInt8, FeatureCommandType, CustomStringConvertible { 15 | 16 | case stop = 0x00 17 | case learning = 0x01 18 | case detection = 0x02 19 | case resetKnowledge = 0xFF 20 | 21 | public var description: String { 22 | switch self { 23 | case .stop: 24 | return "Stop" 25 | case .learning: 26 | return "Learning" 27 | case .detection: 28 | return "Detection" 29 | case .resetKnowledge: 30 | return "Reset Knowledge" 31 | } 32 | } 33 | 34 | public var payload: Data? { 35 | return nil 36 | } 37 | 38 | public var useMask: Bool { 39 | false 40 | } 41 | 42 | public func data(with nodeId: UInt8) -> Data { 43 | Data([rawValue]) 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/NEAIAnomalyDetection/NEAIAnomalyDetectionFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NEAIAnomalyDetectionFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class NEAIAnomalyDetectionFeature: BaseFeature { 15 | 16 | let packetLength = 9 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset > packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = NEAIAnomalyDetectionData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/NEAIClassification/NEAIClassificationCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NEAIClassificationCommand.swift 3 | // 4 | // Copyright (c) 2023 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum NEAIClassificationCommand: UInt8, FeatureCommandType, CustomStringConvertible { 15 | 16 | case stop = 0x00 17 | case start = 0x01 18 | 19 | public var description: String { 20 | switch self { 21 | case .stop: 22 | return "Stop" 23 | case .start: 24 | return "Start" 25 | } 26 | } 27 | 28 | public var payload: Data? { 29 | return nil 30 | } 31 | 32 | public var useMask: Bool { 33 | false 34 | } 35 | 36 | public func data(with nodeId: UInt8) -> Data { 37 | Data([rawValue]) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/NEAIClassification/NEAIClassificationFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NEAIClassificationFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class NEAIClassificationFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if data.count - offset < 4 { 19 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | } 21 | 22 | let parsedData = NEAIClassificationData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), 32) 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Pedometer/PedometerFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PedometerFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class PedometerFeature: BaseFeature { 15 | 16 | let packetLength = 6 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = PedometerData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/Array+PnPLikeElement.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+PnPLikeElement.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension Array where Element == PnPLikeElement { 15 | func element(with schema: String?) -> PnPLikeElement? { 16 | for element in self { 17 | if element.id == schema { 18 | return element 19 | } 20 | } 21 | 22 | return nil 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/Configuration/PnPLikeConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnPLikeConfiguration.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnPLikeConfiguration { 15 | public let name: String 16 | public let specificSensorOrGeneralType: PnPLType 17 | public let displayName: String? 18 | public var parameters: [PnPLikeConfigurationParameter]? 19 | public var visibile: Bool 20 | } 21 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/Configuration/PnPLikeConfigurationParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnPLikeConfigurationParameter.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnPLikeConfigurationParameter { 15 | public let name: String? 16 | public let displayName: String? 17 | public let type: ParameterType? 18 | public var detail: ParameterDetail? 19 | public let unit: String? 20 | public let writable: Bool? 21 | } 22 | 23 | public struct ParameterDetail { 24 | public let requestName: String? 25 | public let primitiveType: String? 26 | public var currentValue: JSONValue? 27 | public let enumValues: [Int: String]? 28 | public var paramObj: [ObjectNameValue]? 29 | } 30 | 31 | public enum ParameterType { 32 | case propertyStandard 33 | case propertyEnumeration 34 | case propertyObject 35 | case commandEmpty 36 | case commandStandard 37 | case commandEnumeration 38 | case commandObject 39 | } 40 | 41 | public struct ObjectNameValue { 42 | public let primitiveType: String? 43 | public let name: String? 44 | public let displayName: String? 45 | public var currentValue: JSONValue? 46 | } 47 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/DTMI/Array+PnpLContent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+PnpLContent.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension Array where Element == PnpLContent { 15 | func element(with schema: String?) -> PnpLContent? { 16 | 17 | for content in self { 18 | switch content { 19 | case .primitiveProperty(let value): 20 | if value.id == schema { 21 | return content 22 | } 23 | case .property(let value): 24 | if value.id == schema { 25 | return content 26 | } 27 | // case primitiveProperty(PnpLPrimitiveContent) 28 | // case enumerative(PnpLEnumerativeContent) 29 | // case object(PnpLObjectContent) 30 | // case command(PnpLCommandContent) 31 | // case commandPayload(PnpLCommandPayloadContent) 32 | // case unknown(PnpLUnknownContent) 33 | default: 34 | continue 35 | } 36 | } 37 | 38 | return nil 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/DTMI/PnpLCommandContent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnpLCommandContent.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnpLCommandContent: Codable { 15 | public let id: String 16 | public var type: String = "command" 17 | public let commandType: String 18 | public let displayName: DisplayName? 19 | public let name: String 20 | public let request: PnpLCommandPayloadContent? 21 | public let response: PnpLCommandPayloadContent? 22 | 23 | public enum CodingKeys: String, CodingKey { 24 | case id = "@id" 25 | case type = "@type" 26 | case commandType 27 | case displayName 28 | case name 29 | case request 30 | case response 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/DTMI/PnpLCommandPayloadContent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnpLCommandPayloadContent.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnpLCommandPayloadContent: Codable { 15 | public let id: String? 16 | public var type: String = "commandpayload" 17 | public let displayName: DisplayName? 18 | public let name: String 19 | public let schema: PnpLCommandPayload 20 | 21 | public enum CodingKeys: String, CodingKey { 22 | case id = "@id" 23 | case type = "@type" 24 | case displayName 25 | case name 26 | case schema 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/DTMI/PnpLComponentContent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnpLComponentContent.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnpLComponentContent: Codable { 15 | public let id: String 16 | public var type: String = "component" 17 | public let displayName: DisplayName? 18 | public var name: String 19 | public let schema: String 20 | 21 | public enum CodingKeys: String, CodingKey { 22 | case id = "@id" 23 | case type = "@type" 24 | case displayName 25 | case name 26 | case schema 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/DTMI/PnpLInterfaceContent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnpLPrimitiveContent.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnpLInterfaceContent: Codable { 15 | public let id: String 16 | public var type: String = "interface" 17 | public let name: String? 18 | public let context: [String] 19 | public let displayName: DisplayName? 20 | public var contents: [PnpLContent] 21 | 22 | public enum CodingKeys: String, CodingKey { 23 | case id = "@id" 24 | case type = "@type" 25 | case name 26 | case context = "@context" 27 | case contents 28 | case displayName 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/DTMI/PnpLObjectContent.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnpLObjectContent.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnpLObjectContent: Codable { 15 | public let id: String? 16 | public var type: String = "object" 17 | public let name: String? 18 | public let displayName: DisplayName? 19 | public var fields: [PnpLPrimitiveContent] 20 | public let writable: Bool? 21 | 22 | public enum CodingKeys: String, CodingKey { 23 | case id = "@id" 24 | case type = "@type" 25 | case name 26 | case displayName 27 | case fields 28 | case writable 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/PnPLike/PnPLResponse.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PnPLResponse.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PnPLResponse: Codable { 15 | public let schemaVersion: String 16 | public let devices: [PnPLDataModelDevice] 17 | 18 | public enum CodingKeys: String, CodingKey { 19 | case schemaVersion = "schema_version" 20 | case devices 21 | } 22 | } 23 | 24 | // MARK: - PnPLDataModelDevice 25 | public struct PnPLDataModelDevice: Codable { 26 | public let components: JSONValue 27 | 28 | public enum CodingKeys: String, CodingKey { 29 | case components 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Predictive/AccelerationStatus/PredictiveAccelerationStatusFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PredictiveAccelerationStatusFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class PredictiveAccelerationStatusFeature: BaseFeature { 15 | 16 | let packetLength = 12 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: nil, rawData: data), 0) 22 | } 23 | 24 | let parsedData = PredictiveAccelerationStatusData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Predictive/FrequencyDomain/PredictiveFrequencyDomainStatusFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PredictiveFrequencyDomainStatusFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class PredictiveFrequencyDomainStatusFeature: BaseFeature { 15 | 16 | let packetLength = 12 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: nil, rawData: data), 0) 22 | } 23 | 24 | let parsedData = PredictiveFrequencyDomainStatusData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Predictive/SpeedStatus/PredictiveSpeedStatusFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PredictiveSpeedStatusFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class PredictiveSpeedStatusFeature: BaseFeature { 15 | 16 | let packetLength = 12 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: nil, rawData: data), 0) 22 | } 23 | 24 | let parsedData = PredictiveSpeedStatusData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Pressure/PressureData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PressureData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct PressureData { 15 | 16 | public let pressure: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let pressure = Float(data.extractInt32(fromOffset: offset)) / 100.0 21 | 22 | self.pressure = FeatureField(name: "Pressure", 23 | uom: "mBar", 24 | min: 900, 25 | max: 1100, 26 | value: pressure) 27 | } 28 | } 29 | 30 | extension PressureData: CustomStringConvertible { 31 | public var description: String { 32 | 33 | let pressure = pressure.value ?? .nan 34 | 35 | return String(format: "Pressure: %.2f", pressure) 36 | } 37 | } 38 | 39 | extension PressureData: Loggable { 40 | public var logHeader: String { 41 | "\(pressure.logHeader)" 42 | } 43 | 44 | public var logValue: String { 45 | "\(pressure.logValue)" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Pressure/PressureFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PressureFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class PressureFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if (data.count - offset < 4) { 19 | return (FeatureSample(with: timestamp, data: nil, rawData: data), 0) 20 | } 21 | 22 | let pressureData = PressureData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: pressureData as? T, rawData: data), 4) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Proximity/ProximityFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProximityFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class ProximityFeature: BaseFeature { 15 | 16 | let packetLength = 2 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = ProximityData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/ProximityGesture/ProximityGestureData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProximityGestureData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct ProximityGestureData { 15 | 16 | public let gesture: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let gesture = ProximityGestureType(rawValue: data.extractUInt8(fromOffset: offset)) 21 | 22 | self.gesture = FeatureField(name: "Gesture", 23 | uom: nil, 24 | min: nil, 25 | max: nil, 26 | value: gesture) 27 | } 28 | } 29 | 30 | extension ProximityGestureData: CustomStringConvertible { 31 | public var description: String { 32 | 33 | let gesture = gesture.value ?? .unknown 34 | 35 | return String(format: "Gesture: %@", gesture.description) 36 | } 37 | } 38 | 39 | extension ProximityGestureData: Loggable { 40 | public var logHeader: String { 41 | "\(gesture.logHeader)" 42 | } 43 | 44 | public var logValue: String { 45 | "\(gesture.logValue)" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/ProximityGesture/ProximityGestureFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProximityGestureFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class ProximityGestureFeature: BaseFeature { 15 | 16 | let packetLength = 1 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = ProximityGestureData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/ProximityGesture/ProximityGestureType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProximityGestureType.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum ProximityGestureType: UInt8 { 15 | case unknown = 0x00 16 | /** 17 | * the tap gesture 18 | */ 19 | case tap = 0x01 20 | /** 21 | * the left gesture 22 | */ 23 | case left = 0x02 24 | /** 25 | * the right gesture 26 | */ 27 | case right = 0x03 28 | /** 29 | * the error status 30 | */ 31 | case error = 0xFF 32 | } 33 | 34 | extension ProximityGestureType: CustomStringConvertible { 35 | public var description: String { 36 | switch self { 37 | case .unknown: 38 | return "Unknown" 39 | case .tap: 40 | return "Tap" 41 | case .left: 42 | return "Left" 43 | case .right: 44 | return "Right" 45 | case .error: 46 | return "Error" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/RawPnPL/RawPnPLData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RawPnPLData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class RawPnPLData { 15 | 16 | public let rawData: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | var rawD: Data = Data() 21 | 22 | for dataNum in 0..<(data.count - offset) { 23 | rawD.append(data[offset + dataNum]) 24 | } 25 | 26 | 27 | self.rawData = FeatureField(name: "RawPnPLData", 28 | uom: nil, 29 | min: nil, 30 | max: nil, 31 | value: rawD) 32 | } 33 | } 34 | 35 | extension RawPnPLData: CustomStringConvertible { 36 | public var description: String { 37 | 38 | let rawData = rawData.value ?? Data() 39 | 40 | return "RawPnPLData: \(rawData)" 41 | } 42 | } 43 | 44 | extension RawPnPLData: Loggable { 45 | public var logHeader: String { 46 | "\(rawData.logHeader)" 47 | } 48 | 49 | public var logValue: String { 50 | "\(rawData.logValue)" 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/RawPnPL/RawPnPLFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RawPnPLFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class RawPnPLFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | // if data.count - offset < 2 { 19 | // return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | // } 21 | 22 | let parsedData = RawPnPLData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), data.count - offset) 25 | } 26 | 27 | public override func parse(commandResponse response: FeatureCommandResponse) -> 28 | FeatureCommandResponse { 29 | return super.parse(commandResponse: response) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Remote/RemoteData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RemoteData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct RemoteData { 15 | let remoteId: UInt16 16 | let data: T 17 | } 18 | 19 | extension RemoteData: CustomStringConvertible { 20 | public var description: String { 21 | return "Remote Id: \(remoteId), \(data.description)" 22 | } 23 | } 24 | 25 | extension RemoteData: Loggable { 26 | public var logHeader: String { 27 | return "Remote Id, \(data.logHeader)" 28 | } 29 | 30 | public var logValue: String { 31 | return "\(remoteId), \(data.logValue)" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/SDLogging/SDLoggingFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SDLoggingFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class SDLoggingFeature: BaseFeature { 15 | 16 | let packetLength = 9 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = SDLoggingData(with: data, offset: offset) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/STM32OTA/Data+STM32WBUpload.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+STM32WBUpload.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal extension Data { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/STM32OTA/STM32WBOtaControlFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STM32WBOtaControlFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class STM32WBOtaControlFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 18 | } 19 | 20 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 21 | response 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/STM32OTA/STM32WBOtaUploadFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STM32WBOtaUploadFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | extension Data: Loggable { 15 | public var logHeader: String { 16 | "RawData" 17 | } 18 | 19 | public var logValue: String { 20 | hex 21 | } 22 | } 23 | 24 | class STM32WBOtaUploadFeature: BaseFeature { 25 | 26 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 27 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 28 | } 29 | 30 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 31 | response 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/STM32OTA/STM32WBOtaWillRebootFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STM32WBOtaWillRebootFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class STM32WBOtaWillRebootFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if (data.count - (offset - 2)) < 1 { 19 | return (FeatureSample(with: timestamp, data: nil, rawData: data), 0) 20 | } 21 | 22 | let isRebooting = data.extractUInt8(fromOffset: (offset - 2)) == 1 23 | 24 | return (FeatureSample(with: isRebooting as? T, rawData: data), 1) 25 | } 26 | 27 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 28 | response 29 | } 30 | 31 | } 32 | 33 | extension Bool: Loggable { 34 | public var logHeader: String { 35 | "TBI" 36 | } 37 | 38 | public var logValue: String { 39 | "TBI" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/STM32OTA/STM32WBRebootOtaModeFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STM32WBRebootOtaModeFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class STM32WBRebootOtaModeFeature: BaseFeature { 15 | 16 | private static let rebootOtaMode = UInt8(0x01) 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 20 | } 21 | 22 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 23 | response 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/STM32Switch/STM32SwitchStatusFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STM32SwitchStatusFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class STM32SwitchStatusFeature: TimestampFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | if data.count - offset < 2 { 18 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 19 | } 20 | 21 | let parsedData = STM32SwitchStatusData(with: data, offset: offset) 22 | 23 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), 2) 24 | } 25 | 26 | public override func parse(commandResponse response: FeatureCommandResponse) -> 27 | FeatureCommandResponse { 28 | return response 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/STREDL/STREDLFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // STREDLFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class STREDLFeature: BaseFeature { 15 | 16 | let packetLength = 8 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | 20 | if data.count - offset < packetLength { 21 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 22 | } 23 | 24 | let parsedData = STREDLData(with: data, offset: offset, numberOfRegiters: packetLength) 25 | 26 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/SensorFusion/AutoConfigurationCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AutoConfigurationCommand.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum AutoConfigurationCommand: UInt8, FeatureCommandType, CustomStringConvertible { 15 | 16 | case start = 0x00 17 | case stop = 0x01 18 | case get = 0xFF 19 | 20 | public var description: String { 21 | switch self { 22 | case .start: 23 | return "Start Configuration" 24 | case .stop: 25 | return "Stop Configuration" 26 | case .get: 27 | return "Get Configuration" 28 | } 29 | } 30 | 31 | public var useMask: Bool { 32 | true 33 | } 34 | 35 | public func data(with nodeId: UInt8) -> Data { 36 | return Data([rawValue]) 37 | } 38 | 39 | public var payload: Data? { 40 | return nil 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/SensorFusion/AutoConfigurationCommandResponse.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AutoConfigurationCommandResponse.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum AutoConfigurationStatus: UInt8 { 15 | case notConfigured = 0 16 | case configured = 100 17 | } 18 | 19 | public class AutoConfigurationCommandResponse: BaseCommandResponse { 20 | public var status: AutoConfigurationStatus { 21 | get { 22 | if commandType == AutoConfigurationCommand.get.rawValue { 23 | return AutoConfigurationStatus(rawValue: data.extractUInt8(fromOffset: 0)) ?? .notConfigured 24 | } 25 | 26 | return .notConfigured 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/SensorFusion/CommandFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CommandFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol CommandFeature { 15 | var commands: [FeatureCommandType] { get } 16 | } 17 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/SensorFusion/QuaternionConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QuaternionConfiguration.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | struct QuaternionConfiguration { 15 | static let delay: UInt32 = 30 16 | static let scaleFactor: Float = 10000.0 17 | static let decimal: Float = 100 18 | static let min: Float = -1 19 | static let max: Float = 1 20 | } 21 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/SensorFusion/SensorFusionCompactData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SensorFusionCompactData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct SensorFusionCompactData { 15 | public let samples: [SensorFusionData] 16 | } 17 | 18 | extension SensorFusionCompactData: CustomStringConvertible { 19 | public var description: String { 20 | return samples.map { $0.description }.joined(separator: "\n\n") 21 | } 22 | } 23 | 24 | extension SensorFusionCompactData: Loggable { 25 | public var logHeader: String { 26 | "TBI" 27 | } 28 | 29 | public var logValue: String { 30 | "TBI" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Switch/SwitchData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwitchData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct SwitchData { 15 | 16 | public let status: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let status = data.extractUInt8(fromOffset: offset) 21 | 22 | self.status = FeatureField(name: "Status", 23 | uom: nil, 24 | min: 0, 25 | max: UInt8.max, 26 | value: status) 27 | } 28 | } 29 | 30 | extension SwitchData: CustomStringConvertible { 31 | public var description: String { 32 | 33 | let status = status.value ?? 0 34 | 35 | return String(format: "Status: \(status)") 36 | } 37 | } 38 | 39 | extension SwitchData: Loggable { 40 | public var logHeader: String { 41 | "\(status.logHeader)" 42 | } 43 | 44 | public var logValue: String { 45 | "\(status.logValue)" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Switch/SwitchFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwitchFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class SwitchFeature: BaseFeature { 15 | 16 | let packetLength = 1 17 | 18 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 19 | if data.count - offset < packetLength { 20 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 21 | } 22 | 23 | let parsedData = SwitchData(with: data, offset: offset) 24 | 25 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), packetLength) 26 | } 27 | 28 | public override func parse(commandResponse response: FeatureCommandResponse) -> 29 | FeatureCommandResponse { 30 | return response 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Switch/SwitchType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwitchType.swift 3 | // 4 | // Copyright (c) 2023 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum SwitchType: UInt8, FeatureCommandType, CaseIterable { 15 | 16 | case switchOff = 0x00 17 | case switchOn = 0x01 18 | 19 | public var payload: Data? { 20 | return nil 21 | } 22 | 23 | public var useMask: Bool { 24 | true 25 | } 26 | 27 | public func data(with nodeId: UInt8) -> Data { 28 | Data([rawValue]) 29 | } 30 | } 31 | 32 | extension SwitchType: CustomStringConvertible { 33 | public var description: String { 34 | switch self { 35 | case .switchOff: 36 | return "Switch OFF" 37 | case .switchOn: 38 | return "Switch ON" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Temperature/TemperatureData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TemperatureData.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct TemperatureData { 15 | 16 | public let temperature: FeatureField 17 | 18 | init(with data: Data, offset: Int) { 19 | 20 | let temperature = Float(data.extractUInt16(fromOffset: offset)) / 10.0 21 | 22 | self.temperature = FeatureField(name: "Temperature", 23 | uom: "\u{2103}", 24 | min: 0, 25 | max: 100, 26 | value: temperature) 27 | } 28 | } 29 | 30 | extension TemperatureData: CustomStringConvertible { 31 | public var description: String { 32 | 33 | let temperature = temperature.value ?? .nan 34 | 35 | return String(format: "Temperature: %.2f", temperature) 36 | } 37 | } 38 | 39 | extension TemperatureData: Loggable { 40 | public var logHeader: String { 41 | "\(temperature.logHeader)" 42 | } 43 | 44 | public var logValue: String { 45 | "\(temperature.logValue)" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/Temperature/TemperatureFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TemperatureFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class TemperatureFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | 18 | if (data.count - offset < 2) { 19 | return (FeatureSample(with: timestamp, data: nil, rawData: data), 0) 20 | } 21 | 22 | let temperatureData = TemperatureData(with: data, offset: offset) 23 | 24 | return (FeatureSample(with: timestamp, data: temperatureData as? T, rawData: data), 2) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/ToFMultiObject/ToFCommand.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToFCommand.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public enum ToFCommand: UInt8, FeatureCommandType { 15 | 16 | case enablePresenceDetection = 0x01 17 | case disablePresenceDetection = 0x00 18 | 19 | public var payload: Data? { 20 | nil 21 | } 22 | 23 | public var useMask: Bool { 24 | false 25 | } 26 | 27 | public func data(with nodeId: UInt8) -> Data { 28 | Data([rawValue]) 29 | } 30 | } 31 | 32 | extension ToFCommand: CustomStringConvertible { 33 | public var description: String { 34 | switch self { 35 | case .enablePresenceDetection: 36 | return "Enable presence detection" 37 | case .disablePresenceDetection: 38 | return "Disable presence detection" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/ToFMultiObject/ToFMultiObjectFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToFMultiObjectFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class ToFMultiObjectFeature: BaseFeature, CommandFeature { 15 | 16 | 17 | public var commands: [FeatureCommandType] = [ 18 | ToFCommand.enablePresenceDetection, 19 | ToFCommand.disablePresenceDetection 20 | ] 21 | 22 | 23 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 24 | 25 | let parsedData = ToFMultiObjectData(with: data, offset: offset) 26 | 27 | return (FeatureSample(with: timestamp, data: parsedData as? T, rawData: data), data.count) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Features/UnkownFeature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnkownFeature.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class UnkownFeature: BaseFeature { 15 | 16 | override func extractData(with timestamp: UInt64, data: Data, offset: Int) -> FeatureExtractDataResult { 17 | return (FeatureSample(with: timestamp, data: data as? T, rawData: data), 0) 18 | } 19 | 20 | public override func parse(commandResponse response: FeatureCommandResponse) -> FeatureCommandResponse { 21 | response 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Firmware/BaseFirmwareService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseFirmwareService.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal class BaseFirmwareService: FirmwareService { 15 | 16 | var firmwareType: FirmwareType? 17 | var url: URL? 18 | var firmwareData: Data? 19 | var callback: FirmwareUpgradeCallback? 20 | 21 | func currentVersion(_ completion: @escaping FirmwareVersionCompletion) { 22 | 23 | } 24 | 25 | func upgradeFirmware(with url: URL, type: FirmwareType, callback: FirmwareUpgradeCallback) { 26 | 27 | do { 28 | let fileHandler = try FileHandle(forReadingFrom: url) 29 | let data = fileHandler.readDataToEndOfFile() 30 | fileHandler.closeFile() 31 | startLoading(with: url, type: type, firmwareData: data, callback: callback) 32 | } catch { 33 | callback.completion(url, .invalidFwFile) 34 | } 35 | } 36 | 37 | func startLoading(with url: URL, type: FirmwareType, firmwareData: Data, callback: FirmwareUpgradeCallback) { 38 | self.url = url 39 | self.firmwareType = type 40 | self.firmwareData = firmwareData 41 | self.callback = callback 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Firmware/BlueNRG/FirmwareUpgradeParam.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirmwareUpgradeParam.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal struct FirmwareUpgradeParam { 15 | 16 | private static let safePackageLength = UInt(16) 17 | 18 | let file: URL 19 | let baseAddress: UInt32? 20 | let packageSize: UInt 21 | 22 | static func buildSafeParamFrom(param: FirmwareUpgradeParam) -> FirmwareUpgradeParam { 23 | return FirmwareUpgradeParam(file: param.file, 24 | baseAddress: param.baseAddress, 25 | packageSize: FirmwareUpgradeParam.safePackageLength) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Firmware/BlueNRG/FirmwareUpgradeSettings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirmwareUpgradeSettings.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal struct FirmwareUpgradeSettings { 15 | 16 | internal static let defaultAckInterval: UInt8 = 8 17 | 18 | let file: URL 19 | let data: Data 20 | let ackInterval: UInt8 21 | let uploadSize: UInt32 22 | let baseAddress: UInt32 23 | let packageSize: UInt 24 | 25 | var parameterData: Data { 26 | var message = Data() 27 | 28 | withUnsafeBytes(of: ackInterval) { message.append(contentsOf: $0) } 29 | withUnsafeBytes(of: uploadSize.littleEndian) { message.append(contentsOf: $0) } 30 | withUnsafeBytes(of: baseAddress.littleEndian) { message.append(contentsOf: $0) } 31 | 32 | // message.append(ackInterval) 33 | // var imageSizeLe = uploadSize.littleEndian 34 | // message.append(UnsafeBufferPointer(start: &imageSizeLe, count: 1)) 35 | // var baseAddressLe = baseAddress.littleEndian 36 | // message.append(UnsafeBufferPointer(start: &baseAddressLe, count: 1)) 37 | 38 | return message 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Firmware/DebugConsole/Data+Firmware.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+Firmware.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal extension Data { 15 | func buildLoadCommand() -> Data? { 16 | 17 | var command = Data() 18 | guard let commandData = "upgradeFw".data(using: .isoLatin1) else { return nil } 19 | command.append(commandData) 20 | 21 | let crc = BlueSTM32CRC.getCrc(self) 22 | 23 | Swift.withUnsafeBytes(of: UInt32(count)) { command.append(contentsOf: $0) } 24 | Swift.withUnsafeBytes(of: crc) { command.append(contentsOf: $0) } 25 | 26 | return command 27 | } 28 | } 29 | 30 | internal extension Array where Element == Data { 31 | 32 | var dataSize: Int { 33 | map { $0.count } 34 | .reduce(0, +) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Firmware/DebugConsole/FirmwareLoaders/DebugConsoleFirmwareLoader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DebugConsoleFirmwareLoader.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal class DebugConsoleFirmwareLoader: BaseFirmwareLoader { 15 | 16 | private var lastCall: Date = Date() 17 | 18 | override func sendFwPackage(console: DebugConsole) -> Bool { 19 | 20 | let packageSize = min(firmwareData.count - byteSent, chunkSize) 21 | guard packageSize != 0 else { 22 | return false; // nothing to send 23 | } 24 | 25 | let dataToSend = firmwareData[byteSent.. HSDSensor? { 20 | sensor.first(where: { $0.id == id }) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/HSD/HSDDeviceStatus.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HSDDeviceStatus.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public struct HSDDeviceStatus: Codable { 15 | public let type: String? 16 | public let isLogging: Bool? 17 | public let isSDInserted: Bool? 18 | public let cpuUsage: Double? 19 | public let batteryVoltage: Double? 20 | public let batteryLevel: Double? 21 | public let ssid: String? 22 | public let password: String? 23 | public let ip: String? 24 | public let sensorId: Int? 25 | public let sensorStatus: HSDSensor.SensorStatusDescriptor? 26 | } 27 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/HSD/HSDOptionModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HSDOptionModel.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class HSDOptionModel { 15 | public enum Mode { 16 | case odr 17 | case fs 18 | } 19 | 20 | public let mode: Mode 21 | public let name: String 22 | public let unit: String? 23 | public let values: [Double] 24 | public let selected: Double 25 | 26 | init(mode: Mode, name: String, unit: String?, values: [Double], selected: Double) { 27 | self.mode = mode 28 | self.name = name 29 | self.unit = unit 30 | self.values = values 31 | self.selected = selected 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/HSD/HSDResponse.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HSDResponse.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | class HSDResponse: Codable { 15 | let JSONVersion: String 16 | let device: HSDDevice 17 | } 18 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/HSD/HSDSamplesPerTs.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HSDSamplesPerTs.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class HSDSamplesPerTs: Codable { 15 | public let min: Int 16 | public let max: Int 17 | public let dataType: String 18 | } 19 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/HSD/HSDSubSensor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HSDSubSensor.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import UIKit 14 | 15 | public class HSDSubSensor: Codable { 16 | public enum SensorType: String, Codable { 17 | case Accelerometer = "ACC" 18 | case Magnetometer = "MAG" 19 | case Gyroscope = "GYRO" 20 | case Temperature = "TEMP" 21 | case Humidity = "HUM" 22 | case Pressure = "PRESS" 23 | case Microphone = "MIC" 24 | case MLC = "MLC" 25 | case Unknown = "" 26 | } 27 | 28 | public let id: Int 29 | public let sensorType: String 30 | public let dimensions: Int 31 | public let dimensionsLabel: [String] 32 | public let unit: String? 33 | public let dataType: String? 34 | public let FS: [Double]? 35 | public let ODR: [Double]? 36 | public let samplesPerTs: HSDSamplesPerTs 37 | 38 | public var type: SensorType { 39 | SensorType(rawValue: sensorType) ?? .Unknown 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/HSD/HSDTag.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HSDTag.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class HSDTag: Codable, Hashable { 15 | public enum TagType: Int, Codable { 16 | case software 17 | case hardware 18 | 19 | public var title: String { 20 | switch self { 21 | case .software: 22 | return "hsd.tag.software.title" 23 | case .hardware: 24 | return "hsd.tag.hardware.title" 25 | } 26 | } 27 | } 28 | 29 | public static func == (lhs: HSDTag, rhs: HSDTag) -> Bool { 30 | return lhs.id == rhs.id && lhs.type == rhs.type 31 | } 32 | 33 | public func hash(into hasher: inout Hasher) { 34 | hasher.combine(id) 35 | hasher.combine(type?.rawValue ?? 0) 36 | } 37 | 38 | public let id: Int 39 | public var label: String 40 | public let pinDesc: String? 41 | public let enabled: Bool? 42 | 43 | public var type: TagType? = .software 44 | } 45 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/HSD/HSDTagConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HSDTagConfig.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public class HSDTagConfigContainer: Codable { 15 | public let tagConfig: HSDTagConfig 16 | } 17 | 18 | public class HSDTagConfig: Codable { 19 | public let maxTagsPerAcq: Int 20 | public let swTags: [HSDTag] 21 | public let hwTags: [HSDTag] 22 | 23 | public func updateTypes() { 24 | swTags.forEach { $0.type = .software } 25 | hwTags.forEach { $0.type = .hardware } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Node/Array+NodeService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array+NodeService.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public extension Array where Element: NodeService { 15 | func nodeService(with node: Node) -> NodeService? { 16 | return first { $0.node.address == node.address } 17 | } 18 | 19 | mutating func remove(with node: Node) { 20 | removeAll(where: { $0 === node }) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Node/NodeService+ReadWrite.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NodeService+ReadWrite.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | internal extension NodeService { 15 | 16 | @discardableResult 17 | func readFeature(_ feature: Feature) -> Bool { 18 | guard let blueChar = node.characteristics.characteristic(with: feature), 19 | blueChar.characteristic.isCharacteristicCanBeRead else { 20 | return false 21 | } 22 | 23 | node.peripheral.readValue(for: blueChar.characteristic) 24 | 25 | return true 26 | } 27 | 28 | @discardableResult 29 | func write(value data: Data, for feature: Feature) -> Bool { 30 | guard let blueChar = node.characteristics.characteristic(with: feature), 31 | blueChar.characteristic.isCharacteristicCanBeWrite else { 32 | return false 33 | } 34 | 35 | bleService.write(data: data, characteristic: blueChar.characteristic) 36 | 37 | return true 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Node/NodeState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NodeState.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | //connecting 15 | //connected 16 | //disconnecting 17 | //disconneted 18 | //ready connesso + scansione servizi 19 | 20 | 21 | public enum NodeState: Int { 22 | case disconnected = 0 23 | case connecting = 1 24 | case connected = 2 25 | case disconnecting = 3 26 | } 27 | 28 | public extension NodeState { 29 | 30 | /** 31 | * convert the enum value to a string 32 | * 33 | * @param state enum with the current board status 34 | * 35 | * @return a string representation of the enum value 36 | */ 37 | 38 | var stringValue: String { 39 | switch self { 40 | case .disconnected: 41 | return NSLocalizedString("Disconnected", comment: "") 42 | case .connecting: 43 | return NSLocalizedString("Connecting", comment: "") 44 | case .connected: 45 | return NSLocalizedString("Connected", comment: "") 46 | case .disconnecting: 47 | return NSLocalizedString("Disconnecting", comment: "") 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Utils/FeatureLogger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FeatureLogger.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol FeatureLogger { 15 | 16 | var loggedFile: [URL] { get } 17 | 18 | var isEnabled: Bool { get } 19 | 20 | func start() 21 | 22 | func stop() 23 | 24 | func clear() 25 | 26 | func log(feature: Feature, node: Node) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Utils/WeakCallback.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeakCallback.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | import CoreBluetooth 14 | 15 | public typealias WriteCallback = (Error?) -> () 16 | 17 | public class WeakCallback : Equatable { 18 | let id = UUID() 19 | 20 | weak var refItem: AnyObject? 21 | let callback: T 22 | 23 | public init(refItem: AnyObject, callback: T) { 24 | self.refItem = refItem 25 | self.callback = callback 26 | } 27 | 28 | public static func == (lhs: WeakCallback, rhs: WeakCallback) -> Bool { 29 | return lhs.id == rhs.id 30 | } 31 | } 32 | 33 | public class WeakWriteCallBack : WeakCallback { 34 | var characteristicUUID: CBUUID 35 | 36 | public init(refItem: AnyObject, characteristicUUID: CBUUID, callback: @escaping WriteCallback) { 37 | self.characteristicUUID = characteristicUUID 38 | 39 | super.init(refItem: refItem, callback: callback) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sources/STBlueSDK/Utils/WeakObject.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeakObject.swift 3 | // 4 | // Copyright (c) 2022 STMicroelectronics. 5 | // All rights reserved. 6 | // 7 | // This software is licensed under terms that can be found in the LICENSE file in 8 | // the root directory of this software component. 9 | // If no LICENSE file comes with this software, it is provided AS-IS. 10 | // 11 | 12 | import Foundation 13 | 14 | public protocol Object { 15 | var id: UUID { get } 16 | var refItem: AnyObject? { get } 17 | } 18 | 19 | public class StrongObject: Equatable, Object { 20 | public var id = UUID() 21 | 22 | public var refItem: AnyObject? 23 | 24 | public init(refItem: AnyObject) { 25 | self.refItem = refItem 26 | } 27 | 28 | public static func == (lhs: StrongObject, rhs: StrongObject) -> Bool { 29 | return lhs.id == rhs.id 30 | } 31 | } 32 | 33 | public class WeakObject: Equatable, Object { 34 | public var id = UUID() 35 | 36 | public weak var refItem: AnyObject? 37 | 38 | public init(refItem: AnyObject) { 39 | self.refItem = refItem 40 | } 41 | 42 | public static func == (lhs: WeakObject, rhs: WeakObject) -> Bool { 43 | return lhs.id == rhs.id 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Tests/STBlueSDKTests/STBlueSDKTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import STBlueSDK 3 | 4 | final class STBlueSDKTests: XCTestCase { 5 | func testExample() { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | } 10 | } 11 | --------------------------------------------------------------------------------