IoT and BLE companion apps for connected products
A connected product is judged on the app. The hardware can be finished and correct, and the product still reviews badly because pairing takes three attempts, the connection drops halfway through a sync, or a firmware update stalls at 60%. Those are mobile problems, and they are the ones we solve: the iOS and Android side of a BLE product, built against your device and verified on the wire rather than against a log line.
Start here
Which situation is yours?
BLE work arrives in three shapes. They need different first moves, and the most common mistake is treating the second one as a bug hunt in the app when the evidence has not been gathered yet.
| Where you are | First move | What it involves |
|---|---|---|
| Hardware exists, no mobile app yet | Protocol review, then build | The device works and the GATT surface is either designed or still open. The early decisions — how commands are framed, how state is reported, whether the app can be treated as trusted — are cheap to change now and expensive later. We review the protocol before writing the app against it. |
| An app exists but the BLE layer is unreliable | Readiness review on the wire | Drops, reconnect loops, stalled transfers, works-on-one-phone. These are rarely fixed by reading the app code alone. We reproduce the failure with a packet capture and establish whether the app, the device, or the connection parameters are at fault before changing anything. |
| The app works but OTA is missing or unsafe | OTA architecture review | A field-update path that can brick a device is worse than none. We look at the staging-and-swap design, resumability, and where the firmware is signed and verified, then build the mobile side against a device design that fails safe. |
The terms, defined
- GATT
- The layer that defines how a Bluetooth Low Energy peripheral exposes its data: a tree of services holding characteristics, each identified by a UUID.
- Characteristic
- A single addressable value in a peripheral’s GATT database — a sensor reading, a command register, a status word — that can be read, written or subscribed to.
- MTU
- The largest attribute payload a BLE connection will carry. The default is 23 bytes, leaving 20 usable per write; the specification allows negotiating up to 517.
- CCCD
- The descriptor a client writes to turn notifications on. Until that write succeeds on the peripheral, no notifications arrive — configuring the client side is not enough.
- Bonding
- Storing pairing keys so two devices reconnect encrypted without pairing again. A common source of platform-specific reconnection bugs.
- OTA / DFU
- Delivering new firmware over the wireless link. In BLE products the phone is the transport: it carries the image, the device validates and installs it.
Why BLE apps fail in the field and not in the lab
Because the lab removes every condition that breaks BLE. On a desk the phone is unlocked and in the foreground, the device is a metre away on one firmware revision, and the tester is holding one handset. None of that is true for a customer. Four things go wrong, and they are worth naming before an engagement rather than discovering them in a support queue.
Connection parameters
BLE defaults are conservative by design. The default ATT MTU is 23 bytes, which leaves 20 usable per write; the specification allows negotiating up to 517. Data Length Extension raises the link-layer payload from 27 to 251 bytes, and it is negotiated at a different layer from the MTU — you need both. Connection interval interacts with these in ways that are not intuitive: a longer interval can yield higher throughput when it lets more packets move per connection event. An app that never negotiates is not broken on a desk. It is unusably slow across a room.
Background execution
The OS decides how much of your BLE work survives the app leaving the foreground, and it decides differently on each platform. On Android a long transfer needs a foreground service with a visible notification or Doze and the background limits will end it. On iOS, Core Bluetooth's background rules constrain what a backgrounded app may do, and you cannot assume a multi-minute operation survives. Features that quietly depend on the app staying alive are the ones that fail for real users first.
Lifecycle and recovery
Most "unreliable Bluetooth" reports are not about the happy path at all. They are about what happens after a drop: whether the app reconnects, whether it re-subscribes, and whether a half-finished operation resumes or silently restarts. Subscription is a good example of how easily this is got wrong — configuring the client-side callback does not subscribe anything on its own; until the CCCD write lands on the peripheral and its result is checked, no notifications arrive. Code that treats the local call as success works right up until the first reconnection.
Fragmentation
Android BLE behaviour varies by vendor, by OS version and by chipset, and bonding state persists in the platform outside your app's control — which is why "it only fails on that one phone model" is a real finding rather than a brush-off. Handles are the other fragmentation trap: they identify attributes in the device's current GATT database and can move when firmware changes it, so an app that hard-codes them breaks on a firmware release rather than on a code change.
What happens first
What happens first: the BLE readiness review
Before quoting a build or a rescue, we run a fixed-scope review and hand back written findings with an effort range. It is deliberately not a proposal: it establishes what the protocol is, which failure modes are real, and what it would take to fix them, so the budget conversation starts from evidence. There is no obligation to continue, and if you do run the work with us, the review folds into it.
- 01
Protocol and GATT surface review
Services, characteristics, properties and the command framing on top of them, read against what the app actually needs. Where the protocol assumes the app is trusted, we say so — that assumption is the one that does not survive contact with a packet capture.
- 02
Connection lifecycle audit
Pairing, bonding, reconnection, and what happens after a drop. Most "unreliable Bluetooth" reports resolve into a lifecycle the app handles on one platform and not the other.
- 03
Throughput and connection parameters
MTU negotiation, Data Length Extension, connection interval and write type, measured against what the product is trying to move. This is where transfers that stall in the field are usually decided.
- 04
Background and OS-constraint assessment
What the app is allowed to do when it is not in the foreground on each platform, and which product behaviours depend on something the OS does not guarantee.
- 05
OTA update path review
Where the image is signed and where it is verified, whether a partial transfer can resume, and whether an interrupted update can leave a device unusable.
- 06
Written findings and an effort range
The failure modes we found, in priority order, with the evidence for each and an effort range you can take to a budget conversation. Yours to keep whether or not we build the work.
What we do not do
We build the mobile side and integrate with your device. That is the whole of it, and saying so up front saves a conversation that otherwise happens three weeks in. We are a mobile engineering studio: iOS, Android and cross-platform. Your device, its firmware and the people who build it stay yours.
What that means in practice is that we will review your GATT surface, tell you when a failure is on the device side rather than the app side, and give you the packet evidence for the claim — but we will not go and change the firmware ourselves. When the honest answer is that the fix belongs in the device, we say so, even though it is the answer that keeps work out of our scope.
Outside our scope
- ✕ Device firmware and bootloader development
- ✕ Hardware, PCB and antenna design
- ✕ RF, regulatory and Bluetooth qualification testing
- ✕ Manufacturing, provisioning lines and factory test rigs
We work alongside the teams and suppliers who own these, and the readiness review is usually the document that makes that split explicit.
Track record
Why MaboaSoft for this
Because we debug BLE on the wire rather than from the app's own logs. A phone's HCI snoop log records what actually crossed the link — the connection, the discovery, the MTU exchange, every read, subscription and write — and reading it in Wireshark settles arguments that logging cannot. Our published work on this is on the blog, and it is the same method we bring to an engagement.
It also shapes how we think about BLE security. Everything the app knows is recoverable from a capture taken on a phone the attacker controls, without touching the APK. That is not a reason for alarm; it is a design constraint, and it is why we treat "the protocol is undocumented" as a fact about documentation rather than a security control.
And we build the rest of the product, not only the radio layer. A BLE companion app is still an app: onboarding, sync, account handling, offline state, store release and the maintenance that follows. We have been shipping production iOS and Android apps since 2014, in Flutter, .NET MAUI and native, which is why the Bluetooth work lands inside a product rather than beside one.
Capabilities relevant to this work
FAQ
Frequently asked questions
Why does our BLE app work in the office but fail for customers?
Because the lab removes the conditions that break BLE. On a desk the phone is unlocked, in the foreground, a metre from the device, on one firmware revision and usually one handset model. In the field the app is backgrounded, the connection drops mid-operation, the device is at the edge of range, and the fleet spans several Android vendors and OS versions. The bugs are almost always in the recovery paths — reconnect, resubscribe, resume — which the lab never exercises.
Do you write the device firmware as well as the app?
No. We build the mobile side and integrate against your device. Firmware, bootloader, hardware and RF certification stay with your embedded team or supplier. We will review the GATT surface and the OTA design and tell you plainly when a problem is on the device side rather than the app side.
Can you work from a packet capture instead of the device?
For diagnosis, often yes. An Android HCI snoop log records the traffic between the phone and the peripheral, and reading it in Wireshark shows the actual sequence of connect, discovery, MTU exchange, reads, subscriptions and writes. It tells you what really happened rather than what the app logged. For building and verifying a fix we need the hardware.
Is a hidden protocol or an undocumented UUID enough protection?
No. Anything the app knows, an attacker can recover — the protocol is visible in a snoop log taken on a phone the attacker controls, with no reverse engineering of the APK required. Sensitive commands have to be authenticated by the device itself, not merely hidden from casual inspection.
How long does a BLE readiness review take?
It is fixed-scope and short — days rather than weeks — because it deliberately stops at findings. What varies is the size of the GATT surface and how many platform behaviours are in play, which is why we agree the scope in writing before it starts rather than quoting a build off a description of the symptoms.
Can you take over a BLE app someone else built?
Yes, and it is a common starting point. The review is the handover: it establishes what the protocol is, which failure modes are live, and what the app is actually responsible for, so the takeover starts from evidence instead of from the previous team’s assumptions.
Next step
Start with the evidence, not the estimate
A fixed-scope BLE readiness review tells you what your protocol actually does, which failure modes are real, and what fixing them takes — before anyone commits a budget.