Commit graph

20 commits

Author SHA1 Message Date
58be00cb38 docs: fix misleading comment on post-auth disconnect path
The comment said "treat as non-fatal" but the code calls fail() — which
is correct behavior since we can't write config without a connection.
Updated comment to accurately describe the fail-with-retry-prompt flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 23:03:43 +00:00
54fa973d34 fix: prevent re-entrant disconnect callbacks and handle all disconnect states
- Add isTerminating flag to guard succeed()/fail() against double invocation
  from racing didWriteValueFor + didDisconnectPeripheral callbacks
- Only call cancelPeripheralConnection when peripheral.state == .connected
  (avoids triggering spurious didDisconnectPeripheral on already-disconnected peripheral)
- Handle disconnect during device info read (post-auth) with specific error message
- Include state info in unexpected disconnect errors for easier debugging
- Early-return structure in disconnect handler for clearer control flow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 23:01:30 +00:00
f7a554e282 Merge pull request 'fix: handle expected BLE disconnect after SaveConfig' (#3) from schwifty/fix-saveconfig-disconnect into main 2026-03-21 22:49:05 +00:00
c62dace54d fix: handle SaveConfig write-error path + add disconnect diagnostics
The previous fix only caught the disconnect callback path. But CoreBluetooth
can also fire didWriteValueFor with an error when the beacon reboots mid-ATT
response. This was hitting fail() at the isNonFatalCommand check instead of
being treated as success.

Now handles both paths:
1. didDisconnectPeripheral with state=.writing at last command → succeed()
2. didWriteValueFor error for SaveConfig (last command) → succeed()

Also added detailed state/index logging to disconnect handler for diagnostics.
2026-03-21 22:47:11 +00:00
e387b9ceb1 fix: handle expected BLE disconnect after SaveConfig command
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>
2026-03-21 22:28:47 +00:00
John Pinkyfloyd
9c984b954a Add UUIDFormatting.swift to Xcode project
File was created but not added to the project, causing build failure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-21 15:23:43 -07:00
4618df9191 Merge pull request 'feat: provisioner hardening — multi-password auth & structured errors' (#2) from schwifty/provisioner-hardening into main 2026-03-21 21:44:06 +00:00
9ddb9ebe1b Merge pull request 'refactor: consolidate UUID formatting into shared extension' (#1) from schwifty/consolidate-uuid-formatting into main 2026-03-21 21:43:49 +00:00
06b258ac18 fix: reset passwordIndex in readConfig() to prevent stale auth state
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>
2026-03-21 17:31:01 +00:00
ee366870ea feat: multi-password auth, structured error codes, missing API endpoints
- 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>
2026-03-21 10:31:39 +00:00
237ac38557 refactor: consolidate UUID formatting into shared String extension
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>
2026-03-21 10:02:58 +00:00
John Pinkyfloyd
8b413020ff Fix HardwareId field name to match backend (camelCase)
Backend expects "HardwareId" not "HardwareID" or "hardware_id"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-16 17:37:40 -07:00
John Pinkyfloyd
02592ea249 Read MAC address during provisioning and use as hardware_id
- 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>
2026-03-16 17:35:28 -07:00
John Pinkyfloyd
2ec195243c Migrate API endpoints from CFML to PHP
- Replace all .cfm endpoints with .php (PHP backend migration)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-14 17:17:02 -07:00
John Pinkyfloyd
5283d2d265 Fix DX-Smart provisioning protocol and add debug logging
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>
2026-03-04 20:01:12 -08:00
John Pinkyfloyd
8c2320da44 Add ios-marketing idiom, iPad orientations, launch screen
- 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>
2026-02-10 19:38:11 -08:00
John Pinkyfloyd
c013c8fcd7 Update app icon
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 13:22:48 -08:00
John Mizerek
b5004c1dc7 Add BeaconShardPool for iBeacon shard UUID scanning
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 14:46:18 -08:00
John Pinkyfloyd
962a767863 Rewrite app: simplified architecture, CoreLocation beacon scanning, UI fixes
- 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>
2026-02-04 22:07:39 -08:00
John Pinkyfloyd
4faec5499d Initial commit: Payfrit Beacon iOS native app 2026-02-01 23:39:29 -08:00