Skip to main content

Mobile Vendor Printing Troubleshooting

Operational runbook for 053-mobile-vendor-printing and the merchant printer surface from 052-mobile-generic-printing.

Architecture: Printer Vendor Port, Printer Config, Cash Drawer. Platform promises: Mobile printing limits.


Scope​

Primary codepaths:

  • packages/printer-transport/src/vendor-profile.ts
  • apps/mobile/src/printing/transport-registry.ts
  • apps/mobile/src/printing/transports/star.transport.ts
  • apps/mobile/src/printing/transports/android.transport.ts
  • apps/backend/src/printer-config/
  • apps/backend/src/cash-drawer/

1) Symptom triage​

SymptomLikely layer
Star printer stays "limited support"SDK not loaded, or vendorLockedGeneric, or evidence never resolved
Ethernet Star works, Bluetooth Star is genericOUI LAA bit — check normaliseOui; evidence must include a MAC
Epson / Bixolon identified but no paper stateExpected: no vendor adapter in this build; generic path has status.supported = false
Sunmi printer missing or no transport for connection kind "sunmi"No Sunmi adapter registered; sunmi has no generic fallback
Classic Bluetooth / USB missing on iPhonePlatform: generic iOS transports are tcp and ble only
Classic Bluetooth / USB missing on Androidprinter-spp / printer-usb Expo modules did not load
Scan finds nothingPermission, radio off, metered LAN — see empty scans
Test print button does nothing physicalPOST .../test-print only returns bytes; outbox / executor must run
Kitchen tickets still go to Print BridgeNo live claim, or heartbeat older than 60s, or printer connection not ready when claiming
401 / forbidden on PUT .../stations or claimsCaller has Printer but not PrinterStationAssignment
No-sale drawer button missing or 403CashDrawer Create is not on the role
Drawer refused with "no cash drawer attached"Row supports_cash_drawer is false (profile capability ≠ attached)
Receipt printed, drawer stayed shutIndependent outcomes — look at cash_drawer_event, not the print job
DHCP moved the printer, now two rowsSave should upsert on stable_identity; client omitted it

2) Vendor resolution checks​

  1. Handshake vendors — if Star is absent, react-native-star-io10 did not load. The printer should still print generically.
  2. Row vendor vs vendor_evidence:
    • NULL — never resolved; backfill or next probe owns it
    • 'generic' — resolved, unrecognised
    • 'star' + vendor_locked_generic = true — merchant override; do not "fix" by re-running backfill
  3. Do not trust display_name. Backfill ignores it on purpose.
  4. iOS BLE peripheral ids are UUIDs, not MACs. Feeding them as macOui would collide. isMacShaped must pass before OUI matching.

Probe bytes (device-id, one write): GS I 65, 66, 67. 66 (manufacturer) is the load-bearing query, verified on an Epson TM-m30III.


3) Station claim checks​

A claim suppresses Print Bridge for that station. Claiming without a ready connection silences the kitchen.

Expected cadence: heartbeat POST /printer-config/manage/claims/heartbeat every 20s, 60s staleness cutoff. One dropped request must not hand the station back.

GET /printer-config/manage?locationId=&deviceId= returns servedBy in the same payload so the setup screen never flashes the opposite of the truth.

iOS withdraws claims on backgrounding. That is a platform rule, not a missed heartbeat. See limits.


4) Cash drawer checks​

Standalone open must leave a row before the pulse:

  1. POST /cash-drawer/open → authorizationId
  2. Native openCashDrawer()
  3. PATCH /cash-drawer/open/:authorizationId

If step 3 never happens, the row stays failed / not_attempted. That is correct, not a stuck job.

Document-attached kicks do not create cash_drawer_event rows. Looking there for a cash sale will look like "the drawer never opened" when the print job is the record.


5) What this release cannot fix in software​

  • iOS MFi Bluetooth for Epson without a PPID (awaiting_mfi_approval on the handshake). Ethernet and USB still apply.
  • Android agent mode (pull document-print-jobs while the merchant uses Chrome). Not built. See topology.
  • Desktop physical printing from the Tauri host (054 FR-095). Still Print Bridge.