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) {
|
func sendGPS(_ data: Data) {
|
||||||
guard gpsStreamEnabled, isConnected,
|
guard gpsStreamEnabled, isConnected,
|
||||||
let p = peripheral, let c = gpsChar else { return }
|
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.
|
/// Write a pre-built IMU packet to the tag. Call at 10 Hz.
|
||||||
func sendIMU(_ data: Data) {
|
func sendIMU(_ data: Data) {
|
||||||
guard imuStreamEnabled, isConnected,
|
guard imuStreamEnabled, isConnected,
|
||||||
let p = peripheral, let c = imuChar else { return }
|
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
|
// 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 {
|
private var streamingSection: some View {
|
||||||
Section("Data Streaming") {
|
Section("Data Streaming") {
|
||||||
Toggle(isOn: $sensor.ble.gpsStreamEnabled) {
|
Toggle(isOn: Binding(get: { ble.gpsStreamEnabled }, set: { ble.gpsStreamEnabled = $0 })) {
|
||||||
Label {
|
Label {
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
Text("GPS → Tag")
|
Text("GPS → Tag")
|
||||||
@ -82,7 +82,7 @@ struct BLEStatusView: View {
|
|||||||
.foregroundStyle(.blue)
|
.foregroundStyle(.blue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Toggle(isOn: $sensor.ble.imuStreamEnabled) {
|
Toggle(isOn: Binding(get: { ble.imuStreamEnabled }, set: { ble.imuStreamEnabled = $0 })) {
|
||||||
Label {
|
Label {
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
Text("IMU → Tag")
|
Text("IMU → Tag")
|
||||||
|
|||||||
@ -229,7 +229,7 @@ final class SensorManager: NSObject, ObservableObject {
|
|||||||
locationManager.startUpdatingLocation()
|
locationManager.startUpdatingLocation()
|
||||||
locationManager.startUpdatingHeading()
|
locationManager.startUpdatingHeading()
|
||||||
if !motionManager.isDeviceMotionActive { startIMU() }
|
if !motionManager.isDeviceMotionActive { startIMU() }
|
||||||
if !altimeter.isRelativeAltitudeAvailable() == false { startBarometer() }
|
if CMAltimeter.isRelativeAltitudeAvailable() { startBarometer() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private func stopSensors() {
|
private func stopSensors() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user