The DX-Smart CP28 beacon reboots after receiving SaveConfig (0x60) to
persist config to flash. This drops the BLE connection before the write
callback fires, causing the app to report "Unexpected disconnect" even
though the config was successfully saved.
Now we check if we're on the last command (SaveConfig) when disconnect
occurs — if so, treat it as success instead of failure.
Co-Authored-By: Luna <luna@payfrit.com>
Without this reset, if provision() was called first and incremented
passwordIndex, a subsequent readConfig() call would start at the wrong
password index and potentially skip the correct password entirely.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DX-Smart auth now tries multiple passwords in sequence (555555, dx1234, 000000)
instead of hardcoding a single password. Matches Android behavior for better
compatibility across firmware versions.
- Added ProvisioningError enum with structured error codes (CONNECTION_FAILED,
AUTH_FAILED, SERVICE_NOT_FOUND, WRITE_FAILED, etc.) matching Android's
BeaconConfig error codes. All fail() calls now tagged with codes for better
debugging and error reporting.
- Added ProvisioningResult.failureWithCode case and handling in ScanView.
- Added missing API endpoints that Android has:
- getBusiness() - single business fetch
- getBusinessName() - cached business name lookup
- allocateServicePointMinor() - minor value allocation
- Fixed stray print() in Api.swift to use DebugLog.shared.log() for consistency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Created UUIDFormatting.swift with .normalizedUUID and .uuidWithDashes
String extensions, replacing 4 duplicate formatUuidWithDashes() methods
and 6+ inline .replacingOccurrences(of: "-", with: "").uppercased() calls
across Api.swift, BeaconScanner.swift, ScanView.swift,
ServicePointListView.swift, BeaconBanList.swift, and BeaconProvisioner.swift.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Modified BeaconProvisioner to read device info (0x30) before writing config
- Extract MAC address from beacon and return in ProvisioningResult
- Use MAC address as hardware_id field (snake_case for backend)
- Reorder scan view: Configurable Devices section now appears first
- Add debug logging for beacon registration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix critical packet format bugs matching SDK: frame select/type/trigger/disable
commands now send empty data, RSSI@1m corrected to -59 dBm. Add DebugLog,
read-config mode, service point list, and dev scheme.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fixed App Store icon display with ios-marketing idiom
- Added iPad orientation support for multitasking
- Added UILaunchScreen for iPad requirements
- Removed unused BLE permissions and files from build
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Flatten project structure: remove Models/, Services/, ViewModels/, Views/ subdirs
- Replace APIService actor with simpler Api class, IS_DEV flag controls dev vs prod URL
- Rewrite BeaconScanner to use CoreLocation (CLBeaconRegion ranging) instead of
CoreBluetooth — iOS blocks iBeacon data from CBCentralManager
- Add SVG logo on login page with proper scaling (was showing green square)
- Make login page scrollable, add "enter 6-digit code" OTP instruction
- Fix text input visibility (white on white) with .foregroundColor(.primary)
- Add diagonal orange DEV ribbon banner (lower-left corner), gated on Api.IS_DEV
- Update app icon: logo 10% larger, wifi icon closer
- Add en.lproj/InfoPlist.strings for display name localization
- Fix scan flash: keep isScanning=true until enrichment completes
- Add Podfile with SVGKit, Kingfisher, CocoaLumberjack dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>