Two roles for one link
A Bluetooth Low Energy connection is not symmetrical. Before it exists, one device has to make itself known and the other has to go looking. The Bluetooth Core Specification names these roles in its Generic Access Profile:
- A Peripheral accepts the establishment of a connection. Before that, it advertises so that others can find it.
- A Central starts the connection. Before that, it scans for advertisements from the peripherals it wants.
The same profile defines two more LE roles for devices that never connect: a Broadcaster sends advertising events, and an Observer receives them. A beacon is a broadcaster; an app that only listens to beacons is an observer.
Apple’s Core Bluetooth guide describes the central and peripheral as the two major players in all Bluetooth LE communication. The peripheral typically has data that other devices need. The central typically uses that data to do something, such as showing a heart rate from a chest strap.
What happens when they meet
The usual sequence, in Android’s description of a phone and an activity tracker:
- The tracker, the peripheral, advertises and waits for a connection request.
- The phone, the central, scans, finds the tracker’s advertisement and connects.
- Once connected, the two exchange GATT metadata, and the phone asks for data.
Android’s overview then states the rule that matters for app design: two devices that only support the peripheral role cannot talk to each other, and neither can two devices that only support the central role. Somebody has to advertise, and somebody has to scan.
Central and peripheral are not client and server
A second pair of roles applies after the connection is made. In GATT, the server holds services and characteristics, and the client sends requests to read, write or subscribe to them.
The two pairs often line up, because a peripheral is usually the device with data to serve. They do not have to. Android’s overview points out that a phone acting as the central could run the GATT server instead. The GATT chapter of the Core Specification goes further: client and server roles are taken when a device starts a procedure and released when it ends, and a device can be client and server at the same time.
The practical rule: central and peripheral decide who connects to whom. Client and server decide who asks and who answers.
How phones play each role
Phones commonly act as centrals for accessories such as fitness trackers, and Android’s BLE overview describes its built-in platform support in terms of the central role. Both major mobile platforms also let apps act as peripherals:
- iOS.
CBCentralManagerscans for, discovers and connects to peripherals.CBPeripheralManagerpublishes services in the device’s GATT database and advertises them. Apple’s guide says Mac and iOS devices have been able to act as peripherals since macOS 10.9 and iOS 6. On watchOS, tvOS and visionOS, an app cannot advertise services withCBPeripheralManager. - Android.
BluetoothLeScannerandBluetoothGattcover the central side.BluetoothLeAdvertiserandBluetoothGattServercover the peripheral side. The advertiser is not guaranteed:getBluetoothLeAdvertiser()returns null if Bluetooth is off or the device does not support LE advertising.
Background limits apply to the peripheral role too. Apple’s CBPeripheralManager reference says that without the bluetooth-peripheral background mode, an app’s services are disabled while it is in the background or suspended.
Why phone-to-phone apps need both roles
Some BLE libraries for mobile apps implement only the central role, because they were built to talk to accessories. Two phones running such a library can both scan, but neither advertises, so they never find each other. Whether react-native-ble-plx can connect two phones walks through one documented case.
A phone-to-phone app has to make at least one phone a peripheral. If either user may start the exchange, each phone runs both roles: it advertises a shared service so others can find it, and it scans for that service to find others. The Core Specification allows a device to operate in several roles at once if its controller supports it. The app then needs a rule for which side opens the connection, so two phones that discover each other at the same moment do not connect twice.
The Offline Protocol mesh SDK works this way on phones: its React Native installation guide asks for both the bluetooth-central and bluetooth-peripheral background modes on iOS, and for the scan, advertise and connect permissions on Android, because each phone scans and advertises.