8000 Release v0.10.3 by jjohnstz · Pull Request #31 · combustion-inc/combustion-ios-ble · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Release v0.10.3 #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{
"object": {
"pins": [
{
"package": "NordicDFU",
"repositoryURL": "https://github.com/NordicSemiconductor/IOS-DFU-Library",
"state": {
"branch": null,
"revision": "f73213f2de57c8c53700725ee2cff6cd35ef66fe",
"version": "4.11.1"
}
},
{
"package": "swift-collections",
"repositoryURL": "https://github.com/apple/swift-collections",
Expand All @@ -9,6 +18,15 @@
"revision": "48254824bb4248676bf7ce56014ff57b142b77eb",
"version": "1.0.2"
}
},
{
"package": "ZIPFoundation",
"repositoryURL": "https://github.com/weichsel/ZIPFoundation",
"state": {
"branch": null,
"revision": "ec32d62d412578542c0ffb7a6ce34d3e64b43b94",
"version": "0.9.11"
}
}
]
},
Expand Down
6 changes: 4 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ let package = Package(
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/apple/swift-collections", "1.0.0"..<"2.0.0")
.package(url: "https://github.com/apple/swift-collections", "1.0.0"..<"2.0.0"),
.package(url: "https://github.com/NordicSemiconductor/IOS-DFU-Library", .upToNextMajor(from: "4.11.1"))
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "CombustionBLE",
dependencies: [
.product(name: "Collections", package: "swift-collections", condition: nil)
.product(name: "Collections", package: "swift-collections"),
.product(name: "NordicDFU", package: "IOS-DFU-Library")
],
path: "Sources/CombustionBLE"),
/*
Expand Down
23 changes: 20 additions & 3 deletions Sources/CombustionBLE/BleManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ SOFTWARE.

import Foundation
import CoreBluetooth
import NordicDFU


protocol BleManagerDelegate: AnyObject {
func didConnectTo(identifier: UUID)
func didFailToConnectTo(identifier: UUID)
func didDisconnectFrom(identifier: UUID)
func handleSetIDResponse(identifier: UUID, success: Bool)
func handleSetColorResponse(identifier: UUID, success: Bool)
func updateDeviceWithAdvertising(advertising: AdvertisingData, rssi: NSNumber, identifier: UUID)
func updateDeviceWithAdvertising(advertising: AdvertisingData, isConnectable: Bool, rssi: NSNumber, identifier: UUID)
func updateDeviceWithLogResponse(identifier: UUID, logResponse: LogResponse)
func updateDeviceWithSessionInformation(identifier: UUID, sessionInformation: SessionInformation)
func updateDeviceWithStatus(identifier: UUID, status: DeviceStatus)
Expand Down Expand Up @@ -87,6 +89,18 @@ class BleManager : NSObject {
}
}

func startFirmwareUpdate(device: Device, dfu: DFUFirmware) {
if let connectionPeripheral = getConnectedPeripheral(identifier: device.identifier) {
let initiator = DFUServiceInitiator().with(firmware: dfu)

initiator.delegate = device
initiator.progressDelegate = device


initiator.start(target: connectionPeripheral)
}
}

private func getConnectedPeripheral(identifier: String) -> CBPeripheral? {
let uuid = UUID(uuidString: identifier)
let devicePeripherals = peripherals.filter { $0.identifier == uuid }
Expand Down Expand Up @@ -123,6 +137,7 @@ extension BleManager: CBCentralManagerDelegate{
advertisementData: [String : Any], rssi RSSI: NSNumber) {

let manufatureData: Data = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data ?? Data()
let isConnectable = advertisementData[CBAdvertisementDataIsConnectable] as? Bool ?? false

if let advData = AdvertisingData(fromData: manufatureData) {
// For now, only add probes.
Expand All @@ -131,7 +146,10 @@ extension BleManager: CBCentralManagerDelegate{
// Store peripheral reference for later use
peripherals.insert(peripheral)

delegate?.updateDeviceWithAdvertising(advertising: advData, rssi: RSSI, identifier: peripheral.identifier)
delegate?.updateDeviceWithAdvertising(advertising: advData,
isConnectable: isConnectable,
rssi: RSSI,
identifier: peripheral.identifier)
} else {
// print("Ignoring device with type \(advData.type)")
}
Expand Down Expand Up @@ -288,5 +306,4 @@ extension BleManager: CBPeripheralDelegate {
}
}
}

}
61 changes: 60 additions & 1 deletion Sources/CombustionBLE/Device.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ SOFTWARE.
--*/

import Foundation
import NordicDFU

/// Struct containing info about a thermometer device.
public class Device : ObservableObject {
Expand Down Expand Up @@ -54,6 +55,9 @@ public class Device : ObservableObject {
/// Current connection state of device
@Published public internal(set) var connectionState: ConnectionState = .disconnected

/// Connectable flag set in advertising packet
@Published public internal(set) var isConnectable = false

/// Signal strength to device
@Published public internal(set) var rssi: Int

Expand All @@ -63,6 +67,26 @@ public class Device : ObservableObject {
/// Tracks whether the data has gone stale (no new data in some time)
@Published public internal(set) var stale = false

/// DFU state
@Published public private(set) var dfuState: DFUState?

public struct DFUErrorMessage {
public let error: DFUError
public let message: String
}

/// DFU error message
@Published public private(set) var dfuError: DFUErrorMessage?

public struct DFUUploadProgress {
public let part: Int
public let totalParts: Int
public let progress: Int
}

/// DFU Upload progress
@Published public private(set) var dfuUploadProgress: DFUUploadProgress?

/// Time at which device was last updated
internal var lastUpdateTime = Date()

Expand All @@ -82,6 +106,22 @@ public class Device : ObservableObject {

func updateDeviceStale() {
stale = Date().timeIntervalSince(lastUpdateTime) > Constants.STALE_TIMEOUT


// If device data is stale, assume its not longer connectable
if(stale) {
isConnectable = false
}
}

public func isDFURunning() -> Bool {
guard let dfuState = dfuState else { return false }

if(dfuState == .completed) {
return false
}

return true
}
}

Expand All @@ -95,7 +135,6 @@ extension Device {
/// Attempt to connect to the device.
public func connect() {
// Mark that we should maintain a connection to this device.
// TODO - this doesn't seem to be propagating back to the UI??
maintainingConnection = true

if(connectionState != .connected) {
Expand Down Expand Up @@ -123,3 +162,23 @@ extension Device: Hashable {
hasher.combine(identifier)
}
}

extension Device: DFUServiceDelegate {
public func dfuStateDidChange(to state: DFUState) {
dfuState = state
}

public func dfuError(_ error: DFUError, didOccurWithMessage message: String) {
dfuError = DFUErrorMessage(error: error, message: message)
}
}

extension Device: DFUProgressDelegate {
public func dfuProgressDidChange(for part: Int,
outOf totalParts: Int,
to progress: Int,
currentSpeedBytesPerSecond: Double,
avgSpeedBytesPerSecond: Double) {
dfuUploadProgress = DFUUploadProgress(part: part, totalParts: totalParts, progress: progress)
}
}
21 changes: 16 additions & 5 deletions Sources/CombustionBLE/DeviceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ SOFTWARE.

import Foundation
import SwiftUI

import NordicDFU

/// Singleton that provides list of detected Devices
/// (either via Bluetooth or from a list in the Cloud)
Expand Down Expand Up @@ -162,11 +162,22 @@ public class DeviceManager : ObservableObject {
/// - parameter ProbeColor: New Probe color
public func setProbeColor(_ device: Device, color: ProbeColor, completionHandler: @escaping (Bool) -> Void) {
setColorCompetionHandlers[device.identifier] = MessageHandler(timeSent: Date(), handler: completionHandler)

let request = SetColorRequest(color: color)
BleManager.shared.sendRequest(identifier: device.identifier, request: request)
}

public func runSoftwareUpgrade(_ device: Device, otaFile: URL) -> Bool {
do {
let dfu = try DFUFirmware(urlToZipFile: otaFile)
BleManager.shared.startFirmwareUpdate(device: device, dfu: dfu)
return true
}
catch {
return false
}
}

private func checkForMessageTimeout(messageHandlers: inout [String: MessageHandler]) {
let currentTime = Date()

Expand Down Expand Up @@ -225,14 +236,14 @@ extension DeviceManager : BleManagerDelegate {
}
}

func updateDeviceWithAdvertising(advertising: AdvertisingData, rssi: NSNumber, identifier: UUID) {
func updateDeviceWithAdvertising(advertising: AdvertisingData, isConnectable: Bool, rssi: NSNumber, identifier: UUID) {
if devices[identifier.uuidString] != nil {
if let probe = devices[identifier.uuidString] as? Probe {
probe.updateWithAdvertising(advertising, RSSI: rssi)
probe.updateWithAdvertising(advertising, isConnectable: isConnectable, RSSI: rssi)
}
}
else {
let device = Probe(advertising, RSSI: rssi, identifier: identifier)
let device = Probe(advertising, isConnectable: isConnectable, RSSI: rssi, identifier: identifier)
addDevice(device: device)
}
}
Expand Down
40 changes: 24 additions & 16 deletions Sources/CombustionBLE/Probe.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ public class Probe : Device {
/// Time at which probe instant read was last updated
internal var lastInstantRead: Date?

public init(_ advertising: AdvertisingData, RSSI: NSNumber, identifier: UUID) {
public init(_ advertising: AdvertisingData, isConnectable: Bool, RSSI: NSNumber, identifier: UUID) {
serialNumber = advertising.serialNumber
id = advertising.id
color = advertising.color

super.init(identifier: identifier, RSSI: RSSI)

updateWithAdvertising(advertising, RSSI: RSSI)
updateWithAdvertising(advertising, isConnectable: isConnectable, RSSI: RSSI)
}

override func updateConnectionState(_ state: ConnectionState) {
Expand Down Expand Up @@ -108,21 +108,29 @@ extension Probe {
}


func updateWithAdvertising(_ advertising: AdvertisingData, RSSI: NSNumber) {
if(advertising.mode == .Normal) {
currentTemperatures = advertising.temperatures
}
else if(advertising.mode == .InstantRead ){
updateInstantRead(advertising.temperatures.values[0])
}
func updateWithAdvertising(_ advertising: AdvertisingData, isConnectable: Bool, RSSI: NSNumber) {
// Always update probe RSSI and isConnectable flag
self.rssi = RSSI.intValue
self.isConnectable = isConnectable

rssi = RSSI.intValue

id = advertising.id
color = advertising.color
batteryStatus = advertising.batteryStatus

lastUpdateTime = Date()
// Only update rest of data if not connected to probe. Otherwise, rely on status
// notifications to update data
if(connectionState != .connected)
{
if(advertising.mode == .Normal) {
currentTemperatures = advertising.temperatures
}
else if(advertising.mode == .InstantRead ){
updateInstantRead(advertising.temperatures.values[0])
}


id = advertising.id
color = advertising.color
batteryStatus = advertising.batteryStatus

lastUpdateTime = Date()
}
}

/// Updates the Device based on newly-received DeviceStatus message. Requests missing records.
Expand Down
4 changes: 2 additions & 2 deletions Sources/CombustionBLE/SimulatedProbe.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SimulatedProbe: Probe {
init() {
let advertising = AdvertisingData(fakeSerial: UInt32.random(in: 0 ..< UINT32_MAX),
fakeTemperatures: ProbeTemperatures.withRandomData())
super.init(advertising, RSSI: SimulatedProbe.randomeRSSI(), identifier: UUID())
super.init(advertising, isConnectable: true, RSSI: SimulatedProbe.randomeRSSI(), identifier: UUID())

firmareVersion = "v1.2.3"
hardwareRevision = "v0.31-A1"
Expand Down Expand Up @@ -64,7 +64,7 @@ class SimulatedProbe: Probe {
private func updateFakeAdvertising() {
let advertising = AdvertisingData(fakeSerial: UInt32.random(in: 0 ..< UINT32_MAX),
fakeTemperatures: ProbeTemperatures.withRandomData())
updateWithAdvertising(advertising, RSSI: SimulatedProbe.randomeRSSI())
updateWithAdvertising(advertising, isConnectable: true, RSSI: SimulatedProbe.randomeRSSI())
}

private func updateFakeStatus() {
Expand Down
18 changes: 5 additions & 13 deletions Sources/CombustionBLE/UART/LogRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,15 @@ SOFTWARE.
import Foundation

class LogRequest: Request {
static let PAYLOAD_LENGTH: UInt8 = 8

init(minSequence: UInt32, maxSequence: UInt32) {
super.init(payloadLength: LogRequest.PAYLOAD_LENGTH, type: .Log)
var payload = Data()

var min = minSequence
let minData = Data(bytes: &min, count: MemoryLayout.size(ofValue: min))
self.data[Request.HEADER_SIZE + 0] = minData[0]
self.data[Request.HEADER_SIZE + 1] = minData[1]
self.data[Request.HEADER_SIZE + 2] = minData[2]
self.data[Request.HEADER_SIZE + 3] = minData[3]
payload.append(Data(bytes: &min, count: MemoryLayout.size(ofValue: min)))

var max = maxSequence
let maxData = Data(bytes: &max, count: MemoryLayout.size(ofValue: max))
self.data[Request.HEADER_SIZE + 4] = maxData[0]
self.data[Request.HEADER_SIZE + 5] = maxData[1]
self.data[Request.HEADER_SIZE + 6] = maxData[2]
self.data[Request.HEADER_SIZE + 7] = maxData[3]
payload.append(Data(bytes: &max, count: MemoryLayout.size(ofValue: max)))

super.init(payload: payload, type: .Log)
}
}
Loading
0