← ProjectsCase study — 2024
Rabbah Vending Platform
An Android system that runs smart vending machines end to end — speaking the MDB protocol over serial, taking NFC payments, and failing safe the moment connectivity can't be trusted.
Overview
Most vending machines are dumb hardware with a coin mech. Rabbah's machines are different: an Android device is the brain, and everything — payment, dispensing, telemetry — flows through software I could design, test, and ship. The same payment platform extends beyond vending to smart lockers and other unattended machines, paid with integrated NFC cards.
This is the project where the two halves of my background meet. Reading a machine's electrical protocol is not that different from reading a physiological signal: both are unforgiving, both punish assumptions, and both reward engineers who respect the specification.
Problem
A vending machine is a hostile environment for software:
- The machine speaks MDB — a decades-old, timing-sensitive protocol designed for embedded controllers, not mobile operating systems.
- Payments happen over NFC in seconds, in the field, with no cashier to retry a failed transaction.
- Connectivity is never guaranteed — and an unattended machine must never take money it can't process.
- Hardware fails in ways software rarely sees: jams, power cuts mid-dispense, sensors that lie.
Solution
I built the Android platform that drives the machine end to end:
- An MDB protocol layer over serial — framing, timing, retries, and the vending session state handled exactly as the specification demands.
- NFC payment flows engineered for the field: fast taps, clear failure states, and no ambiguous "did I pay?" moments.
- Hardware state machines as the backbone: every dispense is an explicit state graph with defined recovery for every failure path — no boolean-flag spaghetti deciding whether a customer gets their product.
- Fail-safe connectivity handling: the device continuously monitors the network and disables the payment device the moment connectivity drops — no customer is ever charged for a transaction the system can't complete — re-enabling automatically when the network returns.
Architecture
The system is layered so the unforgiving parts stay isolated:
- Hardware boundary — serial communication and MDB framing, isolated in its own service and exposed to the app over AIDL.
- Machine domain — the vending state machines: sessions, dispensing, payment, recovery.
- Application layer — the Jetpack Compose UI the customer touches, kept deliberately thin.
Because the protocol layer is isolated behind an interface, it can be exercised against simulated hardware — dispense failures, payment timeouts, and power interruptions are testable scenarios, not production surprises.
Stack
Gallery
Results
The first-year goal was 500 machines in the field. The fleet passed 1,000 machines before the year ended — double the target, ahead of schedule — and the platform crossed its revenue targets in its third month.
- Daily sales grew from 85,000 SAR to more than 900,000 SAR.
- The machines now process more than 2 million transactions a month.
The state-machine core turned "mystery hardware bug" into "named state with a defined recovery" — which is the difference between debugging in a workshop and debugging over the phone.


