BLE LINK LAYER – channel map adaptive frequency hopping

 

Chapter 8 — BLE Link Layer
Part 2: Physical Channels, RF Mapping, WiFi Avoidance, Channel Maps & Adaptive Frequency Hopping
Adv Channels
3 (RF 0, 12, 39)
Data Channels
37 logical
Hop Range
5 to 16
Min Used Ch
2

Keywords:

BLE advertising channel RF mapping BLE data physical channel BLE WiFi channel interference BLE channel map bitmap BLE adaptive frequency hopping BLE hop increment formula BLE fn+1 mod 37 BLE channel remapping table BlueZ channel map BLE used unused channels

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

Two Logical Channel Types From 40 RF 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)
RF Channels used: 0, 12, and 39

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.

RF Channels used: 1–11 and 13–38 (37 channels total)
Why RF Channels 0, 12, and 39 for Advertising?

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:

BLE Advertising Channels vs WiFi Channels — Avoiding Overlap

2400241224202426243724622480MHz

Wi-Fi Channels (each ~22 MHz wide)
Ch1
Ch6
Ch11

BLE Advertising Channels (2 MHz each — placed in the gaps)
37
38
39
✓ Ch37 (2402 MHz) — below WiFi Ch1 ✓ Ch38 (2426 MHz) — between WiFi Ch1 and Ch6 ✓ Ch39 (2480 MHz) — above WiFi Ch11

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.

RF Channel to Logical Channel Index Mapping

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 → Logical Channel Index 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

Marking Channels as Used or Unused to Avoid Interference

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.

Channel Map — Used vs Unused Channels Bitmap
37 data channels (0–36) represented as a 37-bit bitmap sent from Master to Slave

Bit position = Data Channel index. 1 = used (good), 0 = unused (has interference)

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
█ Used channel (good signal) █ Unused channel (interference detected)
In this example, data channels 3, 4, 5, 12, 21, 22 are marked unused. All hopping skips these channels.

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

The Hopping Algorithm — Simple, Deterministic, and Adaptive

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:

fn+1 = (fn + hopIncrement) mod 37
Where hopIncrement is a random value between 5 and 16, chosen by the Master at connection setup

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
Adaptive Frequency Hopping — Step-by-Step Example
Setup: hopIncrement = 7 (chosen randomly by Master)
Unused channels: {5, 12, 19, 26} — these will be remapped

Start: ch 0
+7 mod 37 =
ch 7
✓ ch 7 is used → transmit on ch 7

Now: ch 7
+7 mod 37 =
ch 14
✓ ch 14 is used → transmit on ch 14

Now: ch 14
+7 mod 37 =
ch 21
✗ ch 21 is UNUSED → look up remapping table

Remap:
ch 21 → ch 3 (next available good channel from remap table)
→ Actually transmit on ch 3 (the remapped good channel)

⚠️ Important: next hop formula uses ch 21 (the computed value), NOT the remapped ch 3
Next: (21 + 7) mod 37 = ch 28 → check if used…

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.

Why hopIncrement Is Between 5 and 16

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.

Hop Sequence Distribution — hopIncrement = 7 Over 10 Steps
Starting channel 0, hopIncrement=7, mod 37: 0→7→14→21→28→35→5→12→19→26→33→3→10…

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Green cells = channels visited in first ~12 hops. Distribution is spread widely, not clustered.

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 */
}

Chapter 8 Summary — Link Layer Concepts Mastered

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.

Leave a Reply

Your email address will not be published. Required fields are marked *