3 (RF 0, 12, 39)
37 logical
5 to 16
2
Keywords:
Overview of This Part
Part 1 covered the five Link Layer states and device addressing. This part goes deeper into how BLE manages its 40 RF channels. The 40 raw RF channels are divided into logical channel types — advertising and data — with a non-obvious mapping between the two. We then look at how the Master dynamically manages interference using channel maps, and how the adaptive frequency hopping algorithm works.
8.4 — Physical Channels
The 40 BLE RF channels are not all used for the same purpose. They are divided into two distinct logical types based on their function:
Advertising Physical Channel
Three RF channels dedicated to three activities:
- Discovering other devices (scanning/advertising)
- Creating a new connection (sending CONNECT_REQ)
- Broadcasting data without a connection (BLE beacons)
Data Physical Channel
The remaining 37 RF channels used for all communication between connected devices. Once a connection is established, all data (GATT reads, writes, notifications) flows over these channels using adaptive frequency hopping.
The three advertising channels are not chosen randomly. Their placement is a deliberate engineering decision driven by two requirements: resilience to local interference, and co-existence with Wi-Fi.
Resilience to local interference: The three advertising channels are placed far apart in the spectrum — channel 0 at 2402 MHz, channel 12 at 2426 MHz, and channel 39 at 2480 MHz. If a device has heavy interference in one part of the 2.4 GHz band (say 2400–2420 MHz from a microwave oven nearby), only channel 0 is affected. Channels 12 and 39 remain usable for advertising. Spreading the three channels across the full band maximises the probability that at least one channel is always clear.
Wi-Fi co-existence: Most smartphones, tablets, and laptops have both Bluetooth and Wi-Fi radios. When they are physically close together (as they always are inside a phone), they can interfere with each other. Wi-Fi devices default to channels 1, 6, and 11. The BLE advertising channels were chosen specifically to not overlap with these three Wi-Fi channel centres:
This careful placement means that even when a busy Wi-Fi network is using channels 1, 6, and 11 at full speed, the BLE advertising traffic is in the gaps where Wi-Fi is not transmitting. BLE and Wi-Fi can coexist in the same device without interfering with advertising and connection setup.
The 40 RF channels are numbered 0–39 by their physical frequency. However, the Link Layer refers to channels by logical index numbers — either a Data Channel Index (0–36) or an Advertising Channel Index (37–39). The mapping is not sequential, which sometimes confuses students.
The key insight: RF channels 0, 12, and 39 become advertising channels 37, 38, and 39 respectively. The remaining 37 RF channels get sequential data channel indices starting from 0. Here is the full mapping:
| RF Channel | Frequency (MHz) | Logical Type | Logical Index |
|---|---|---|---|
| RF 0 | 2402 | Advertising | Adv Ch 37 |
| RF 1 | 2404 | Data | Data Ch 0 |
| RF 2 | 2406 | Data | Data Ch 1 |
| RF 3–11 | 2408–2424 | Data | Data Ch 2–10 |
| RF 12 | 2426 | Advertising | Adv Ch 38 |
| RF 13–38 | 2428–2478 | Data | Data Ch 11–36 |
| RF 39 | 2480 | Advertising | Adv Ch 39 |
The Link Layer only ever uses one physical channel at a time — never advertising and data simultaneously.
/* BlueZ internal channel type definitions (from hci.h) */
/* Advertising channel RF frequencies */
#define BLE_ADV_CH37_FREQ 2402 /* RF channel 0 */
#define BLE_ADV_CH38_FREQ 2426 /* RF channel 12 */
#define BLE_ADV_CH39_FREQ 2480 /* RF channel 39 */
/* The advertising channel bitmask used in advertising params */
/* Bit 0 = use ch37, Bit 1 = use ch38, Bit 2 = use ch39 */
#define LE_ADV_CH_37 0x01
#define LE_ADV_CH_38 0x02
#define LE_ADV_CH_39 0x04
#define LE_ADV_CH_ALL 0x07 /* use all three = 00000111 */
/* In hci_le_set_advertising_parameters: */
/* adv_params.chan_map = LE_ADV_CH_ALL; */
/* means: advertise on channels 37, 38, and 39 */
8.5 — Channel Map
Once a BLE connection is established, data exchanges hop across the 37 data channels. But not all of those channels are necessarily clean — some may have persistent interference from Wi-Fi, another Bluetooth device, or other ISM band equipment nearby.
The Channel Map is a mechanism that allows the Master to tell the Slave which of the 37 data channels are considered usable. The Master’s Link Layer continuously monitors signal quality on all data channels and marks any that appear unreliable as unused. Both Master and Slave use the same channel map so their hopping sequences stay synchronised.
Advantage 1 — Fewer Retransmissions
By avoiding channels with known interference, packets are more likely to get through on the first try. Retransmissions waste time and energy — the radio has to stay on longer and the battery drains faster. Skipping bad channels directly reduces retransmission rate.
Advantage 2 — Reduced Impact on Other Technologies
If a channel is being heavily used by Wi-Fi, marking it as unused means BLE will not hop onto that channel during Wi-Fi activity. This makes BLE a “better neighbour” — it reduces how much it disrupts other devices sharing the band.
The channel map is transmitted from Master to Slave inside LL_CHANNEL_MAP_IND PDUs. The Master can update the channel map during an active connection whenever it detects new interference. There is one hard constraint: the Master must keep a minimum of 2 used channels at all times — you cannot mark all 37 channels as unused.
/* Channel map structure in BlueZ (from hci.h) */
/* The channel map is 5 bytes = 40 bits */
/* Bits 0–36 correspond to data channels 0–36 */
/* Bits 37–39 are reserved (always set to 1) */
typedef struct {
uint8_t map[5]; /* 37-bit bitmap, LSB first */
} __attribute__((packed)) le_channel_map;
/* Example: all channels used (no interference) */
/* map = { 0xFF, 0xFF, 0xFF, 0xFF, 0x1F } */
/* Binary: 11111111 11111111 11111111 11111111 000 11111 */
/* (top 3 bits of last byte are reserved=1, */
/* bottom 5 bits are channels 32-36) */
/* Example: channels 3,4,5 marked bad */
/* Bit 3=0, 4=0, 5=0 → byte 0 = 11000111 = 0xC7 */
/* map = { 0xC7, 0xFF, 0xFF, 0xFF, 0x1F } */
8.6 — Adaptive Frequency Hopping
Once in the Connection state, every exchange of data happens on a different data channel. Both Master and Slave must independently compute the same next channel — they cannot communicate “let’s move to channel 14 next” before moving, because that communication would itself need a channel. Instead, both sides run the same deterministic algorithm and end up on the same channel independently.
The algorithm is elegantly simple. It uses only two inputs: the current channel and a hop increment value that was agreed upon when the connection was established:
After computing the next channel number, there are two possible outcomes depending on the channel map:
- If the computed channel is in the used set — use it directly
- If the computed channel is in the unused set — look it up in the remapping table and use the mapped good channel instead
The critical detail in the last step: the next hop is always calculated from the channel formula output (ch 21 in the example), not from the actual channel used after remapping (ch 3). This ensures both Master and Slave compute the same sequence independently, even though they both remap unused channels to different actual channels using the same remapping table.
The hop increment is set to a random value between 5 and 16 inclusive by the Master when the connection is created. This range is chosen to ensure the hopping sequence has good spread across the 37 channels.
Values less than 5 would cause the sequence to cluster around a small region of the band, defeating the purpose of frequency hopping — you would keep revisiting a few nearby channels instead of spreading across the full 37. Values too close to 37 (the modulus) would also produce poor distribution. The range 5–16 gives good statistical coverage of all channels before the sequence repeats.
Comparison with classic Bluetooth BR/EDR: In BR/EDR, the next hop channel was computed using the Master’s Bluetooth clock and BD_ADDR — a complex function that needed many logic gates to implement. BLE dramatically simplified this to a single addition plus modulo operation. Simpler computation means fewer transistors in the controller chip, lower cost, and slightly less power for each hop calculation.
/* BLE Adaptive Frequency Hopping — algorithm in C */
/* Based on Bluetooth Core Spec 4.0, Section 4.5.8 */
#include <stdint.h>
/*
* next_data_channel - compute next BLE data channel
* @current_channel : currently used data channel (0-36)
* @hop_increment : connection-time random value (5-16)
* @channel_map : 37-bit bitmap, bit N=1 if channel N is used
* @num_used : number of used channels in channel_map
*
* Returns the next channel to use (after remapping if needed).
*/
uint8_t next_data_channel(uint8_t current_channel,
uint8_t hop_increment,
uint8_t *channel_map,
uint8_t num_used)
{
/* Step 1: compute unmapped next channel */
uint8_t unmapped_next = (current_channel + hop_increment) % 37;
/* Step 2: check if that channel is used */
uint8_t byte_idx = unmapped_next / 8;
uint8_t bit_idx = unmapped_next % 8;
int is_used = (channel_map[byte_idx] >> bit_idx) & 0x01;
if (is_used) {
/* Channel is good — use it directly */
return unmapped_next;
}
/* Step 3: channel is unused — remap it */
/* Remapping index = unmapped_next mod num_used_channels */
uint8_t remap_index = unmapped_next % num_used;
/* Walk through used channels to find the remap_index-th one */
uint8_t count = 0;
for (uint8_t ch = 0; ch <= 36; ch++) {
uint8_t bi = ch / 8;
uint8_t bj = ch % 8;
if ((channel_map[bi] >> bj) & 0x01) {
if (count == remap_index) return ch;
count++;
}
}
return 0; /* should never reach here */
}
State Machine
- 5 states: Standby, Adv, Scan, Init, Connected
- Standby is the default rest state
- Initiator → Master role
- Advertiser → Slave role
Device Addressing
- Public: permanent, IEEE OUI
- Static: changes per power cycle
- Non-resolvable: fully anonymous
- Resolvable: bonded peers can identify
Physical Channels
- 3 advertising: RF 0, 12, 39
- 37 data: RF 1–11, 13–38
- Placed to avoid WiFi ch 1, 6, 11
- Non-sequential logical mapping
Freq. Hopping
- Channel map: used/unused bitmap
- Minimum 2 used channels
- Formula: (fn + hop) mod 37
- Hop increment: 5 to 16
Chapters 7 & 8 Complete!
You have a solid understanding of the BLE Physical Layer and Link Layer. The next chapter moves up to L2CAP and then the ATT/GATT protocol stack.
