fix: resolve all Swift compiler errors and BLE write type mismatch
- BLEManager: fall back to withResponse write when characteristic lacks PROPERTY_WRITE_NR (0x4); NimBLE defaults to PROPERTY_WRITE (0x8) only, causing iOS to silently drop every withoutResponse write at 5/10 Hz - BLEManager: scan withServices:nil so NimBLE scan-response UUIDs are found; filter by UWB_TAG name prefix in didDiscover - BLEPackets: remove custom clamping extensions (Int16/Int32/UInt16/UInt8) that shadowed Swift.max() with Int16.max inside the extension scope; stdlib BinaryInteger.init(clamping:) covers all cases - BLEStatusView: use explicit Binding(get:set:) for gpsStreamEnabled / imuStreamEnabled — SwiftUI cannot synthesize $binding through a let computed property backed by a class reference - SensorManager: fix isRelativeAltitudeAvailable() — it is a class method, not an instance method; also fixed inverted double-negative logic Note for HAL: add NimBLE PROPERTY_WRITE_NR to GPS (abcdef3) and IMU (abcdef4) characteristics for no-ACK streaming at 5/10 Hz. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7b911d3591
commit
7f9f159016
@ -68,14 +68,21 @@ final class BLEManager: NSObject, ObservableObject {
|
||||
func sendGPS(_ data: Data) {
|
||||
guard gpsStreamEnabled, isConnected,
|
||||
let p = peripheral, let c = gpsChar else { return }
|
||||
p.writeValue(data, for: c, type: .withoutResponse)
|
||||
// Use writeWithoutResponse if the characteristic supports it (lower latency,
|
||||
// no ACK overhead). Fall back to write-with-response if the firmware only
|
||||
// advertises PROPERTY_WRITE (0x08) — e.g. NimBLE default without WRITE_NR.
|
||||
let writeType: CBCharacteristicWriteType =
|
||||
c.properties.contains(.writeWithoutResponse) ? .withoutResponse : .withResponse
|
||||
p.writeValue(data, for: c, type: writeType)
|
||||
}
|
||||
|
||||
/// Write a pre-built IMU packet to the tag. Call at 10 Hz.
|
||||
func sendIMU(_ data: Data) {
|
||||
guard imuStreamEnabled, isConnected,
|
||||
let p = peripheral, let c = imuChar else { return }
|
||||
p.writeValue(data, for: c, type: .withoutResponse)
|
||||
let writeType: CBCharacteristicWriteType =
|
||||
c.properties.contains(.writeWithoutResponse) ? .withoutResponse : .withResponse
|
||||
p.writeValue(data, for: c, type: writeType)
|
||||
}
|
||||
|
||||
// MARK: - Internal helpers
|
||||
|
||||
@ -164,25 +164,3 @@ private extension Data {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Safe integer clamping
|
||||
|
||||
private extension Int16 {
|
||||
init(clamping value: Int64) {
|
||||
self = Int16(max(Int64(Int16.min), min(Int64(Int16.max), value)))
|
||||
}
|
||||
}
|
||||
private extension Int32 {
|
||||
init(clamping value: Int64) {
|
||||
self = Int32(max(Int64(Int32.min), min(Int64(Int32.max), value)))
|
||||
}
|
||||
}
|
||||
private extension UInt16 {
|
||||
init(clamping value: Int64) {
|
||||
self = UInt16(max(Int64(0), min(Int64(UInt16.max), value)))
|
||||
}
|
||||
}
|
||||
private extension UInt8 {
|
||||
init(clamping value: Int64) {
|
||||
self = UInt8(max(Int64(0), min(Int64(UInt8.max), value)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ struct BLEStatusView: View {
|
||||
|
||||
private var streamingSection: some View {
|
||||
Section("Data Streaming") {
|
||||
Toggle(isOn: $sensor.ble.gpsStreamEnabled) {
|
||||
Toggle(isOn: Binding(get: { ble.gpsStreamEnabled }, set: { ble.gpsStreamEnabled = $0 })) {
|
||||
Label {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("GPS → Tag")
|
||||
@ -82,7 +82,7 @@ struct BLEStatusView: View {
|
||||
.foregroundStyle(.blue)
|
||||
}
|
||||
}
|
||||
Toggle(isOn: $sensor.ble.imuStreamEnabled) {
|
||||
Toggle(isOn: Binding(get: { ble.imuStreamEnabled }, set: { ble.imuStreamEnabled = $0 })) {
|
||||
Label {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("IMU → Tag")
|
||||
|
||||
@ -229,7 +229,7 @@ final class SensorManager: NSObject, ObservableObject {
|
||||
locationManager.startUpdatingLocation()
|
||||
locationManager.startUpdatingHeading()
|
||||
if !motionManager.isDeviceMotionActive { startIMU() }
|
||||
if !altimeter.isRelativeAltitudeAvailable() == false { startBarometer() }
|
||||
if CMAltimeter.isRelativeAltitudeAvailable() { startBarometer() }
|
||||
}
|
||||
|
||||
private func stopSensors() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user