Bluetooth Smart and the Nordic's Softdevices - Part 1 GAP Advertising

This blog series was created as an attempt to fill in the gap between how Bluetooth Smart is defined in the spec and how you can use our APIs and event from our softdevice to do what defined in the spec.

It should be a good place to begin with if you know little about Bluetooth Smart and want to start with our stack (softdevice). It would also be useful for one who wants to gain deeper understanding of our stack for application developing and debugging.

In this guide, we will try to provide the link between what we describe here and where in the Bluetooth Core Spec v4.2 it's defined. The format is Section x.x Part x Vol x .

Bluetooth Smart defined 4 GAP roles: Broadcaster, Observer, Central, Peripheral [Section 6.2 Vol 1 Part A] and 5 Link layer states: Standby, Advertising, Scanning, Initiating, Connection [Section 1.1 Vol 6 Part B]. One device may have one or multiple roles, working in one or multiple states at the same time.

In this episode we focus on Advertising state of the Broadcaster and the Peripheral.

You can find other parts of the series here:

Part 2 Connection (Link and GAP layer)

Table of content

   A. Theory about advertising
        I. What is advertising
        II. Broadcast topology
        III. Whitelisting
        III. Advertising types and whitelisting
   B. Setting up and start advertising with our Softdevice
        I. APIs provided by the softdevice
        II. GAP events you may receive when advertising:
        III. Example code

A. Theory about advertising

I. What is advertising

Advertising is the act of broadcasting data. We broadcast data for device discovery and data publishing. There are 2 types of data packets that can be transmitted, Advertising packet and Scan Response packet, each can have up to 31 bytes payload. The advertiser address is included in the broadcast data in addition to the payload.

The advertiser constantly broadcasts advertising packets with an advertising interval. Advertising interval can be changed on the fly. There is a requirement for minimum and maximum advertising interval.

For normal, undirected advertising, the advertising intervals ranges from 20ms to 10.24s (Section 7.8.5 Part E Vol2). We will go into detail on different types of advertising in next section.

The scan response packet is transmitted by the advertiser when it receives a scan request from a scanner. The advertiser have to enter a RX period to wait for the scan request. This RX period can be used to receive Connect Request as well. But we will not discuss about connection in this Blog's part.

The following figure describe how the advertising packet and scan response packet is sent.

image description

In some applications when we don't expect a connection and don't have extra data in scan response packet, we can advertise in non-connectable mode and can skip the RX period to save power. The beacon application is one of the use cases.

Note that all Advertising packet, Scan Request packet, Scan Response packet share the same on-air Access Address = 0x8E89BED6. This common address allows any device to scan and receive advertising/scan response data.

Bluetooth Smart uses 40 RF channels in the ISM band (2.4GHz). These RF channels have center frequencies 2402 + k*2MHz where k ranges from 0 to 39. Note that k is not the same as "Channel Index", or channel number (Section 1.4 Vol 6 Part B).

Three of them is dedicated for advertising which is channel 37 (2402MHz), 38 (2426MHz) and 39 (2480MHz). They were selected to avoid interference with the busy channels used by Wifi. This figure shows the 3 advertising channels, 37 data channels, and the curved shapes are wifi busy channels.

image description

In the implementation of our stack, by default we transmit the advertising packet in all 3 channels on every advertising event, on channel 37, 38, 39 respectively. Next figure shows how we do that, and how the advertising packet on a channel is captured by the scanner, which scan on one of the three channels at a time.

image description

II. Broadcast topology

When advertising, the network topology is Broadcast topology. There could be multiple advertisers and multiple scanner at the same time. It is a connection-less network:

image description

Note that one device can do scanning and advertising simultaneously. And one can be in a connection with a central or peripheral and can do advertising at the same time.

The only packet the active scanner can send to the advertiser is the Scan Request packet, which contain only the scanner address. Passive scanner doesn't do Scan Request.

III. Advertising types and whitelisting

There are 4 defined types of Advertising (Section 2.3.1 Vol 6 Part B):

  • ADV_IND: connectable undirected advertising . This is the normal advertising type where any device can send scan response packet and connect request to the advertiser.

  • ADV_DIRECT_IND: connectable directed advertising . You use this to direct your advertise packet to one specific central to ask for connection. The packet is still a broadcast packet but other scanners will ignore the packet if the peer address is not matched with them. And connect request or scan request from unmatched central will be ignored by the advertiser. Directed advertising usually comes with high duty cycle with interval fix at 3.75ms. For low duty cycle directed advertising, it's configurable and should be <10ms. (Section 4.4.2 Part B Vol 6).

  • ADV_SCAN_IND: scannable undirected advertising . This advertising packet won't accept connect request but accept scan request.

  • ADV_NONCONN_IND: non-connectable undirected advertising . This is non RX mode, which mean the advertiser will not accept any connect request or scan request. Staying in this mode the advertiser doesn't need to switch to receiver mode and can save power. The main application for this is beacon application, where maximize battery life time is most important and the beacon doesn't need to interact with the scanner.

Advertise with Whitelist

The advertiser can use a whitelist to limit the interaction to a number of scanner/central device. The whitelist contains an array of the peer device addresses or IRK numbers (when central use resolvable random address). It will reject packets from scanners/centrals whose addresses are not in the list. Whitelist can be configured to filter scan request packets, connect request packets or both.

B. Setting up and start advertising with our Softdevice##

I. APIs provided by the softdevice:

  • Setting up advertising data and the scan response data:

sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen)

  • Start advertising with the parameters:

sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params)

Here is how the 31 bytes Advertising data and Scan response data should look like(Chapter 11 Part C Vol 3).

image description

It's up to the application to prepare the advertising data and set it in the softdevice using sd_ble_gap_adv_data_set().


  • The data in the input parameter is an array of uint8_t. You need to encode data to match with this.
  • You should set the length of the advertising data (dlen) to match with the significant part length so that the non-significant part (zero padding) will not be transferred over the air.
  • 31 bytes includes also the overhead so the actual payload for application is 27 bytes when using manufacturing data type.
  • Flags can only be excluded if non-connectable advertising is used.

After you have set-up the advertising packet you can tell the softdevice to start advertising by calling sd_ble_gap_adv_start(). For this call, you need to configure:

  • Advertising interval (the period between each advertising)

  • Advertising timeout: how long you want to advertise. You will receive BLE_GAP_EVT_TIMEOUT event after this timeout.

  • Advertising types (connectable, non-connectable, directed, etc),

  • The peer address if you do directed advertising,

  • The whitelist list if you have.

  • Filter policy: Choose how to use the whitelist, filter scan request, connect request or both.

  • Channel(s) you want to advertise, you can choose one of or two of or all 3 channels to advertise.

II. GAP events you may receive when advertising:

  • BLE_GAP_EVT_TIMEOUT: Occurs when the advertising timeout is passed. The application can decide to continue advertising in different mode or to enter sleep mode. The application should check the src parameter to check if the timeout event is from advertising timeout or not. See BLE_GAP_TIMEOUT_SOURCES list.

  • BLE_GAP_EVT_SCAN_REQ_REPORT: The application receives this event when there is a scan request received by the advertiser. The event comes with address of the peer device and RSSI value. Note: you only get this event if you enable it using the option API sd_ble_opt_set().

  • BLE_GAP_EVT_CONNECTED: You receive this when there is a central device send connect request and the connection is established.

III. Example code

The following code (for S110v8.0/S130v1.0) will setup the advertising packet with device name, flag, Battery service UUID, and advertise with interval = 40ms (0.625 ms unit) and advertising timeout = 180 seconds. It advertises with whitelist applied for connect request. And the only peer address in the whitelist is 0xE05FDAECA271. _

uint32_t             err_code;
ble_gap_adv_params_t adv_params;
ble_gap_whitelist_t  whitelist;
ble_gap_addr_t   * p_whitelist_addr[1];
ble_gap_addr_t		whitelist_addr={BLE_GAP_ADDR_TYPE_RANDOM_STATIC,{0x71,0xA2,0xEC,0xDA,0x5F,0xE0}} ;
uint8_t addr[6] = {0x71,0xA2,0xEC,0xDA,0x5F,0xE0};  
uint8_t adv_data[15] = {0x07,0x09,0x4E,0x6F,0x72,0x64,0x69,0x63,0x02,0x01,0x04,0x03,0x03,0x0F,0x18};
uint8_t adv_data_length = 15;

//Setting up the advertising data with scan response data = Null
err_code = sd_ble_gap_adv_data_set(adv_data, adv_data_length, NULL, NULL);	

//Configure the advertising parameter and whitelist
memset(&adv_params, 0, sizeof(adv_params));
adv_params.type        = BLE_GAP_ADV_TYPE_ADV_IND;
adv_params.p_peer_addr = NULL;
adv_params.interval    = 64;
adv_params.timeout     = 180;
p_whitelist_addr[0] = &whitelist_addr;
whitelist.addr_count = 1;
whitelist.pp_addrs   =  p_whitelist_addr;
whitelist.pp_irks = NULL;
whitelist.irk_count =0;
adv_params.fp          = BLE_GAP_ADV_FP_FILTER_CONNREQ;
adv_params.p_whitelist = &whitelist;
err_code = sd_ble_gap_adv_start(&adv_params);

Here is what the scanner sees when receiving the advertising packet:

image description

Breaking down the raw advertising data: {0x07,0x09,0x4E,0x6F,0x72,0x64,0x69,0x63,0x02,0x01,0x04,0x03,0x03,0x0F,0x18}

0x07 = length 7 octets    
0x09 = AD type Complete Local Name    
0x4E,0x6F,0x72,0x64,0x69,0x63 = "Nordic" in ASCII

0x02 = length 2 octects    
0x01 = AD type flags     

0x03 =length 3 octects    
0x03 = AD type Complete List of 16-bit Service Class UUIDs    
0x0F,0x18 = Battery Service 

List of AD types can be found here.

To make the code short and simple, the check of the return code (err_code) of the API call is not added here. When you implement your code, make sure the return code of each API is checked and it should return NRF_SUCCESS (0x00).

The examples in our SDK used an Advertising module (ble_advertising.c) with abstraction layers and predefined modes. Documentation can be found here.

In addition we provide the advertising data encoding module (ble_advdata.c) that you can use to generate the advertising/scan response packet.


1. Why am I seeing the advertising period is not the same between each packet ?
Bluetooth spec defined a random delay (0-10ms) on each advertising period to perturb interval and avoid interference (Section part B Vol 6).

2. If I want to advertise my custom data how should I put it in the advertising packet ? You should use Manufacturer Specific Data ADtype (0xFF) as defined here. Note that with that type, the 2 first bytes are for Company ID.


You can find other parts of the series here:

Part 2 Connection (Link and GAP layer)


Bluetooth Core Spec v4.2

Getting Started with Bluetooth Low Energy

Useful links:

BLE Advertising, a beginner's tutorial: A tutorial on how to set up advertising packet using our ble_advdata.c in the nRF51 SDK.

Parents Comment Children
No Data