AOSP Framework & Internals
7 min read

WiFi, Bluetooth, GPS, NFC Drivers

A brief overview of how Android handles wireless connectivity radios at the kernel level.

Have you ever wondered what actually happens when you toggle a wireless setting on your phone? A modern smartphone contains multiple independent computers dedicated entirely to radio communication. The Wi-Fi, Bluetooth, GPS, and NFC chips all run their own proprietary firmware. They manage cryptographic handshakes, maintain complex state machines, and transfer massive amounts of data in real time.

If the Linux kernel tried to handle all this protocol logic directly, the codebase would collapse under its own weight. Kernel panics would happen every time a Wi-Fi connection dropped. We need a way to isolate radio logic from the core operating system.

Android solves this by treating the kernel as a dumb transport layer. The kernel simply moves raw bytes over high-speed buses or serial lines. User-space daemons do the actual heavy lifting. This architecture keeps the kernel stable while allowing engineers to update protocol stacks directly through user-space components.

The following diagram shows the division of labor between the user-space daemons, the kernel transport layer, and the physical hardware. This visualization clarifies how Android keeps complex protocol logic entirely out of the kernel. Notice how the kernel sits in the middle acting only as a messenger.

The daemons at the top hold the complex protocol logic. Kernel components in the middle shuttle bytes back and forth to the silicon at the bottom. To see this exact separation in action, we can examine how your phone connects to a wireless network.

Why the Kernel Does Not Know Your Wi-Fi Password

Connecting to a secure network requires complex cryptographic handshakes. If the kernel managed this negotiation directly, a single vulnerability in the protocol could compromise the entire operating system. Updating the stack would also require manufacturers to ship a new kernel image.

Android avoids this risk by moving Wi-Fi management entirely into user-space. The kernel uses a framework called cfg80211 to represent the Wi-Fi chip as a standard network interface. A user-space daemon named wpa_supplicant handles the actual connection logic. During a connection request, the framework asks the daemon to connect, and the daemon performs the cryptographic negotiation directly with the access point.

The sequence below tracks the flow of a Wi-Fi connection request from the Android framework down to the hardware. This visualization highlights how the daemon isolates the cryptographic negotiation from the kernel. Watch how the kernel merely passes commands along.

The framework initiates the request, but the daemon handles the scanning and mathematical handshakes. Your kernel acts strictly as a messenger to the physical radio. You can verify the result of this process from the command line by checking the IP configuration of the active network interface.

adb shell ip addr show wlan0

This command prints the current state of the wireless interface. You will see the assigned IP address if the daemon successfully authenticated.

Common Mistake: Engineers often assume the kernel handles Wi-Fi passwords. If a device fails to connect, the issue usually lives in the wpa_supplicant logs, not the kernel logs.

Wi-Fi connections rely on standard IP networking. Bluetooth handles a vastly different set of requirements.

The Host and Controller Divide in Bluetooth

Bluetooth manages a massive variety of tasks, from streaming high-fidelity audio to pinging low-energy beacons. Baking dozens of complex profiles into the kernel would create an unmaintainable mess. The Bluetooth specification solves this by splitting the work into two strict halves.

The physical chip processing the radio waves is called the Controller. Software sitting in user-space is called the Host. They communicate using a standardized protocol called the Host Controller Interface. Your Linux kernel simply provides a fast serial UART connection to pass raw packets between them.

This strict separation allowed Google to rewrite the entire Android Bluetooth stack recently. Historically, Android used a C++ stack called Fluoride. Recent versions shifted to a memory-safe Rust implementation named Gabeldorsche. Because the kernel only shuttles raw bytes, engineers swapped out the entire user-space brain without touching the underlying kernel drivers.

You can inspect the state of this user-space manager directly from your terminal. The following command dumps the current Bluetooth configuration.

adb shell dumpsys bluetooth_manager

Running this command reveals a list of paired devices, active audio profiles, and connection states.

Common Mistake: Beginners try to read kernel logs when Bluetooth audio stutters. Because the audio encoding happens in user-space, the kernel logs only show successful UART packet transfers. They hide the actual encoding failure.

Debugging Bluetooth requires tracking states across multiple software profiles. Tracking global position relies on a completely different architectural approach.

Reading Text Strings from the GPS Radio

Triangulating coordinates demands massive amounts of real-time math. You might assume that calculating a global position from satellites requires an intensely complicated kernel driver. System CPUs should not waste cycles doing satellite calculations.

The reality is surprisingly simple. Physical GNSS chips handle the intense mathematical triangulation internally. Once the chip calculates your coordinates, it outputs plain text strings. These strings follow a standard format called NMEA.

At the OS level, the kernel driver operates as a basic serial port driver that reads this incoming text stream. The user-space GNSS HAL takes over from there. It parses the NMEA text strings to extract the latitude and longitude. Hardware abstraction layers also download assistance data over the cellular network to help the chip lock onto satellites faster. Finally, the service passes the clean coordinates up to the Android location framework.

This design keeps the kernel driver incredibly thin. We see a similar pattern when handling highly secure operations.

Sending Raw Commands to the NFC Controller

Near Field Communication handles secure transactions and physical tag reading. The kernel should never know about secure elements or payment tokens. We must isolate this sensitive data entirely.

To interact with the hardware, the kernel exposes the bus connection as a basic character device node. The Android NFC service opens this node and takes full control. It sends raw instructions using the NFC Controller Interface format over an I2C or SPI bus.

Strict separation ensures that the kernel remains completely unaware of the transaction details. The Java service manages the secure state machine. It configures the chip to act as a reader or emulate a card.

Android follows a remarkably consistent pattern across all radio technologies. The kernel provides a dumb pipe. User-space provides the intelligence. By pushing complex state machines into user-space daemons, the platform isolates failures and speeds up updates. Physical hardware will continue to evolve, but this division of labor ensures the operating system remains stable.

All these intelligent daemons must be running before the system can connect to anything. Something has to bring them online in the correct order, configure their permissions, and restart them if they crash. That crucial responsibility falls to the very first process that starts when the kernel finishes booting.