Bluetooth 5.4. It extends the periodic advertising protocol from Bluetooth 5.0. Periodic advertising, where a device sends broadcast data with deterministic timing,&nb...">

Periodic Advertising with Responses (PAwR): A practical guide (original) (raw)

Periodic Advertising with Responses (PAWR) is a new feature in Bluetooth 5.4. It extends the periodic advertising protocol from Bluetooth 5.0. Periodic advertising, where a device sends broadcast data with deterministic timing, can now carry bidirectional communication. The receivers can transmit response payloads back to the broadcaster. With PAwR, it's possible now to build an ultra-large one-to-many bidirectional network running on extremely low power. There are many applications where one must manage hundreds or thousands of energy-constrained devices with bidirectional communication, for example, Electronic Shelf Labels (ESL), sensor networks, warehouse management, etc. Let's take a deep dive into this very interesting new technology.

Table of Contents

1. How PAwR works

1.1 Advertising types

Bluetooth 5.4 defined three main types of advertising on the logical transport layer: Advertising Broadcast (ADVB), Periodic Advertising Broadcast (PADVB), and Periodic Advertising with Responses (PAwR). These advertising protocols allow an advertiser to broadcast data to any number of scanners in the surrounding, limited only by the RF range of the advertiser.

Both the Bluetooth LE legacy advertising and Bluetooth LE extended advertising are categorized as ADVB. In these modes, the broadcasting is irregular, and data is sent on only one direction. The scanners, in most cases, need to have sufficient power supply because there is no time synchronization between the scanner and the broadcaster. In addition, there is a 0-10 ms random delay added to the advertising interval to avoid timing collision between advertisers. This requires a large RX window on the scanner and, as a result, draws more current consumption.

Different from ADVB, periodic advertising (PADVB) does regular and precise timing broadcasting. There is a time synchronization between the scanner and the advertiser. The 0-10ms random delay of ADVB is not used in PADVB. Because of this, the scanner only needs to listen for a very short, predictable period of time. It's possible to build a large one-to-many low-power network with periodic advertising, for example, audio broadcasting, direction finding, IoT networks, etc. However, what is missing is that the low-power scanners can only receive data and are not able to send data back to the advertiser.

PAwR was introduced to solve this problem. It allows the advertiser to send precise, regular broadcast data and, at the same time, allows the scanners to send response payload back to the advertiser. In addition, it provides a mechanism for the advertiser to establish Bluetooth (Bluetooth LE) connections with the scanners when higher throughput is needed.

1.2 Timing

Similar to other types of advertising, PAwR operates on an interval called periodic advertising interval. This occurs precisely at the exact interval with no random delay. At each PAwR event, there will be multiple subevents. This is different from PADVB, where there is only one periodic advertising packet per event. Importantly, a scanner, when synced to PAwR, will not listen to all subevents but only select subevent(s) that it's subscribed/synced to. Multiple scanners can be subscribed to the same subevent. This mean a scanner can subscribe to multiple subevents. There can be up to 128 subevents per advertising event.

Zooming in on one of the subevents, at the beginning of the event, there is a transmission packet from the advertiser. It can be either:

All scanners synchronized to this subevent scan this packet and process the payload. After the packet, there is a train of response slots for the scanners to send their responses back to the advertiser. There can be up to 256 response slots. Which scanner to send on which response slot is up to the application/profile to define. To avoid collision, only one scanner should respond in a response slot.

This is the R part of PAwR, the main difference from the normal periodic advertising. This allows the forming of an ultra-large bidirectional one-to-many network with very little power consumption. As you can find, a scanner/observer only need to wake up every periodic advertising interval to scan for the subevent transmission packet. If it has data for the advertiser, it can transmit in one of the response slots and sleep again. One single advertiser can serve a large number of scanners as not all of them need to transmit data back at the same time. The latency is low; it can be as low as the periodic advertising interval, which is in the range of 7.5ms to 81.91875s depending on the configuration of the advertiser.

The limitation here is the throughput. If a scanner needs to transfer or receive a large amount of data, it may be limited by the advertising interval. As mentioned above, the interval can be up to 81.91875s, and changing the advertising interval to a shorter one requires updating all the scanners to sync to the new interval. In most cases, this is non-practical.

A solution for this is to establish a Bluetooth LE connection between the scanner and the advertiser. PAwR supports connection establishment without doing the traditional ADVB. To initiate the connection, the advertiser sends a **AUX_CONNECT_REQ** packet in the subevent transmission packet instead of the **AUX_SYNC_SUBEVENT_IND** packet. Inside AUX_CONNECT_REQ is the address of the scanner and the connection parameters that the scanner should use to enter the Bluetooth LE connection. The scanner to be connected is expected to respond with a **AUX_CONNECT_RSP**. This response should be sent right after the **AUX_CONNECT_REQ** packet without waiting for one of the response slots. A Bluetooth LE connection will be established right after that. The advertiser will become the central, and the scanner will become the peripheral. They can communicate with higher throughput via this separated Bluetooth LE connection.

1.3 Synchronization

To be able to follow the periodic advertising and subscribe to the subevent, the scanner needs to have sync and PAwR information from the advertiser. The procedure of getting sync information is similar to normal periodic advertising PADVB. The scanner either gets the info by scanning for the extended advertising packets **ADV_EXT_IND**:

Or by establishing a connection and performing the Periodic Advertising Sync Transfer (PAST) procedure.

There are pros and cons of both methods. Scanning extended advertising packet ADV_EXT_IND doesn't require a connection, but it requires the scanner to be able to conduct a continuous scanning to catch the advertising packet.
In contrast, having a connection and receiving timing information with PAST would work with a scanner that has a limited power supply, as it only requires the scanner to do normal Bluetooth LE advertising. However, it makes the advertiser's radio scheduling more demanding as the advertiser would need to do both periodic advertising and scanning to establish Bluetooth LE connection. An advertiser can decide not to do **ADV_EXT_IND** and only do periodic advertising** AUX_SYNC_SUBEVENT_IND.** This is to reduce the workload on the advertiser. In that case, PAST is the only option for synchronizing the scanner.

Compared to PADVB, besides SyncInfo (periodic advertising interval, sync Packet Window Offset), there is some extra information exchanged specifically for PAwR:

You may find that the information about which subevent(s) or which response slot(s) the scanner should subscribe to is not defined in these procedures. It's up to the application/upper layers to decide how the scanner should get the information about subevent(s) and response slot(s) it should use. For example, configure response slots when doing PAST, or hardcode it with the scanner so that it automatically chooses the slot based on its own address.

2. PAwR Advantages and Limitations

2.1 Advantages

2.2 Limitations

3. Implementation in nRF Connect SDK.

This section focuses on how to implement the PAwR application in nRF Connect SDK. There are two pairs of samples in nRF Connect SDK added in v2.4.0 that demonstrate PAwR. We will take a deeper dive into the code to understand how PAwR is implemented in these samples.

3.1 Advertising

Let's have a closer look at how periodic advertising is set up in the periodic_adv_rsp sample:

Configurations:

#define NUM_RSP_SLOTS 5 #define NUM_SUBEVENTS 5

static const struct bt_le_per_adv_param per_adv_params = { .interval_min = 0xFF, .interval_max = 0xFF, .options = 0, .num_subevents = NUM_SUBEVENTS, .subevent_interval = 0x30, .response_slot_delay = 0x5, .response_slot_spacing = 0x50, .num_response_slots = NUM_RSP_SLOTS, }; struct bt_le_ext_adv *pawr_adv; static const struct bt_le_ext_adv_cb adv_cb = { .pawr_data_request = request_cb, .pawr_response = response_cb, };

You will need to pay extra attention when configuring the subevent and response slot timing parameter.

Otherwise you will receive error 12 BT_HCI_ERR_INVALID_PARAM.

Setup and start advertising:

/* Create a non-connectable non-scannable advertising set / bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, &adv_cb, &pawr_adv); / Set periodic advertising parameters / bt_le_per_adv_set_param(pawr_adv, &per_adv_params); / Enable Periodic Advertising / bt_le_per_adv_start(pawr_adv); / Start Periodic Advertising */ bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT);

After bt_le_ext_adv_start(), the advertiser will do both extended advertising and PAwR. This includes the packets showed at figure 4: ADV_EXT_IND, AUX_ADV_IND, and AUX_SYNC_SUBEVENT_IND.

As mentioned in the last section. An advertiser can choose not to do extended advertising (ADV_EXT_IND & AUX_ADV_IND) and only do periodic advertising. This will help reduce the extra advertising activities on the advertiser so it can serve more connections/responses. To stop extended advertising you call bt_le_ext_adv_stop() after the periodic advertising started. This will not stop the periodic advertising. To stop periodic advertising you need to call bt_le_per_adv_stop().
Note: Most sniffers rely on the extended advertising's Syncinfo to follow the periodic advertising train. If you turn off extended advertising, the sniffer won't be able to find the periodic advertising packets.

There are 2 callbacks for the periodic advertiser:

These are the main differences to normal advertising or periodic advertising. You can now control the payload for the exact advertising packet (subevent packet). And you can get response data from a scanner which you can't have with the scan request when you do other types of advertising.

3.2 Synchronization

For synchronizing, either extended advertising or PAST is needed. If you want to do PAST, you would need to scans for normal advertising to establish Bluetooth LE connection then do PAST. You would need to call bt_le_per_adv_set_info_transfer() after the connection is established. This will send the syncinfo and the PAwR info to the scanner.

In the periodic_adv_rsp sample, you can find a write command to send some proprietary data (sync_config) about subevent number and response slot number for the scanner. This is up to the application to decide how this should be done.

The following code is from periorid_adv_rsp. The advertiser stop scanning after the maximum number of synced device reached.

while (num_synced < MAX_SYNCS) {
    err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
    if (err) {
        printk("Scanning failed to start (err %d)\n", err);
        return 0;
    }

    printk("Scanning successfully started\n");

    k_sem_take(&sem_connected, K_FOREVER);

    err = bt_le_per_adv_set_info_transfer(pawr_adv, default_conn, 0);
    if (err) {
        printk("Failed to send PAST (err %d)\n", err);

        goto disconnect;
    }

    printk("PAST sent\n");

    discover_params.uuid = &pawr_char_uuid.uuid;
    discover_params.func = discover_func;
    discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
    discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
    discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
    err = bt_gatt_discover(default_conn, &discover_params);
    if (err) {
        printk("Discovery failed (err %d)\n", err);

        goto disconnect;
    }

    printk("Discovery started\n");

    err = k_sem_take(&sem_discovered, K_SECONDS(10));
    if (err) {
        printk("Timed out during GATT discovery\n");

        goto disconnect;
    }

    sync_config.subevent = num_synced % NUM_SUBEVENTS;
    sync_config.response_slot = num_synced / NUM_RSP_SLOTS;
    num_synced++;

    write_params.func = write_func;
    write_params.handle = pawr_attr_handle;
    write_params.offset = 0;
    write_params.data = &sync_config;
    write_params.length = sizeof(sync_config);

    err = bt_gatt_write(default_conn, &write_params);
    if (err) {
        printk("Write failed (err %d)\n", err);
        num_synced--;

        goto disconnect;
    }

    printk("Write started\n");

    err = k_sem_take(&sem_written, K_SECONDS(10));
    if (err) {
        printk("Timed out during GATT write\n");
        num_synced--;

        goto disconnect;
    }

    printk("PAwR config written to sync %d, disconnecting\n", num_synced - 1);

disconnect: err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); if (err) { return 0; }

    k_sem_take(&sem_disconnected, K_FOREVER);
}

The advertiser goes straight to disconnect after sending the transfer information. It doesn't know if the scanner has synced to the PAwR train or not. It can be improved by putting a delay before disconnecting or better have a response from the scanner before disconnect. You can find the delay added in the provided code at the end of this guide.

On the scanner's side, if you have a look at **perioridc_sync_conn** sample you can find how it register PAwR and scans for extended advertising packet that contain sync and PAwr information.

bt_le_scan_cb_register(&scan_callbacks);
bt_le_per_adv_sync_cb_register(&sync_callbacks);

err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
if (err) {
    printk("failed (err %d)\n", err);

    return 0;
}

Note that after you have captured the extended advertising packet you would need to create sync object so that the scanner can start following the periodic advertising packet. To create sync object you call bt_le_per_adv_sync_create(). This will allow you to receive the bt_le_per_adv_sync_cb.synced callback when the scanner synced to periodic advertising (not PAwR) :

static void sync_cb(struct bt_le_per_adv_sync *sync, struct bt_le_per_adv_sync_synced_info *info) { struct bt_le_per_adv_sync_subevent_params params; uint8_t subevents[1]; char le_addr[BT_ADDR_LE_STR_LEN]; int err;

bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
printk("Synced to %s with %d subevents\n", le_addr, info->num_subevents);

params.properties = 0;
params.num_subevents = 1;
params.subevents = subevents;
subevents[0] = 0;
err = bt_le_per_adv_sync_subevent(sync, &params);
if (err) {
    printk("Failed to set subevents to sync to (err %d)\n", err);
}

k_sem_give(&sem_per_sync);

}

As you may find in the code, after syncing, if you want to receive the PAwR subevent packet, you need to call **bt_le_per_adv_sync_subevent**() to subscribe to a subevent(s). In this sample the subevent to subscribe to is hardcoded to subevent 0 and the response slot in this subevent is also hardcoded to 0 (see recv_cb function).
The sample sends the device's address to the advertiser and wait for a connection (connection v2 via AUX_CONNECT_REQ) from the advertiser. This is specific to this application. Call bt_le_per_adv_set_response_data() with the subevent and the response slot you want to send data with.

static void recv_cb(struct bt_le_per_adv_sync *sync, const struct bt_le_per_adv_sync_recv_info *info, struct net_buf_simple *buf) { int err; struct bt_le_oob oob; char addr_str[BT_ADDR_LE_STR_LEN];

if (default_conn) {
    /* Only respond with address if not already connected */
    return;
}

if (buf && buf->len) {
    /* Respond with own address for the advertiser to connect to */
    net_buf_simple_reset(&rsp_buf);

    rsp_params.request_event = info->periodic_event_counter;
    rsp_params.request_subevent = info->subevent;
    rsp_params.response_subevent = info->subevent;
    rsp_params.response_slot = 0;

    err = bt_le_oob_get_local(BT_ID_DEFAULT, &oob);
    if (err) {
        printk("Failed to get OOB data (err %d)\n", err);

        return;
    }

    bt_addr_le_to_str(&oob.addr, addr_str, sizeof(addr_str));
    printk("Responding with own addr: %s\n", addr_str);

    net_buf_simple_add_u8(&rsp_buf, sizeof(bt_addr_le_t));
    net_buf_simple_add_u8(&rsp_buf, BT_DATA_LE_BT_DEVICE_ADDRESS);
    net_buf_simple_add_mem(&rsp_buf, &oob.addr.a, sizeof(oob.addr.a));
    net_buf_simple_add_u8(&rsp_buf, oob.addr.type);

    err = bt_le_per_adv_set_response_data(sync, &rsp_params, &rsp_buf);
    if (err) {
        printk("Failed to send response (err %d)\n", err);
    }
} else if (buf) {
    printk("Received empty indication: subevent %d\n", info->subevent);
} else {
    printk("Failed to receive indication: subevent %d\n", info->subevent);
}

}

3.3 Connection v2

A PAwR advertiser can decide to connect to a synced scanner when it needs to communicate with the scanner at higher throughput or lower latency. To do that the advertiser needs to have the scanner device's address and the subevent that the scanner listens to. To establish the connection you need to call bt_conn_le_create_synced():

bt_addr_le_to_str(&peer, addr_str, sizeof(addr_str));
printk("Connecting to %s in subevent %d\n", addr_str, info->subevent);

synced_param.peer = &peer;
synced_param.subevent = info->subevent;

/* Choose same interval as PAwR advertiser to avoid scheduling conflicts */
conn_param.interval_min = SUBEVENT_INTERVAL;
conn_param.interval_max = SUBEVENT_INTERVAL;

/* Default values */
conn_param.latency = 0;
conn_param.timeout = 400;

err = bt_conn_le_create_synced(adv, &synced_param, &conn_param, &default_conn);
if (err) {
    printk("Failed to initiate connection (err %d)", err);
}

There is no concept of scan timeout when you do connection v2, the result of the bt_conn_le_create_synced() command is returned in the next periodic advertising interval in the callback.

Note: It is suggested to choose the connection interval to be equal or multiple of the subevent interval. This would cause less scheduling config resulting in better throughput.

4. Low power consumption demo

Attached is slightly modified version of the periodic_adv_rsp & periodic_sync_rsp samples. The advertiser will scan and establish Bluetooth LE connection to send PAST information and subevent information. The scanner after synced to the advertiser will send data back on each advertising interval.

The main modification is to turn off UART logging on the scanner and adding more meaningful data in the response. The scanner would send back its internal temperature on each response slot. The advertiser is slightly changed to make it more robust with longer advertising interval. The main point of the code is to demonstrate the low power consumption of the scanner (the sensor) with varied periodic advertising intervals.

You can download the demo source code here (tested on nRF Connect SDK v2.5.0): 8562.PAwR_Demo.zip

When running the demo, on the advertiser side you will see the temperature report from each scanner:

Unchanged from the periodic_adv_rsp, the advertiser only supports one scanner per subevent. However it should be possible to modify the code to support more scanner per subevent or to increase the number of subevent. You will need to decide the logic on how the scanners in the same subevent should send response back; very often the number of response slot per subevent is smaller than the number of scanner.

Following are some power measurements on the scanner with different periodic advertising interval, varied from 100ms to 1s to 10s. This varies the latency of the scanner. The longer the latency the lower the power consumption.

80uA at 100ms intervals, 4 bytes response for each subevent.

15uA at 1s interval 4 bytes response each subevent.

7.3uA at 10s interval, 4 bytes response each subevent.

One can achieve very low power consumption at 15uA at a relatively low latency of 1s. We can do a rough calculation considering a CR2032 battery with 250mAh capacity. If we can utilize 70% of the capacity for Bluetooth LE, it would last 250mAh * 70% / 15uA = 12500 hours = 520 days

5. Summary

PAwR is an exciting new feature of Bluetooth LE. It enhanced the periodic advertising protocol and may open the door for Bluetooth LE technology in new business verticals. Many applications once not possible or too complex to build are now feasible with Bluetooth LE and PAwR. We are excited to see how it will be implemented and ready to help you get this technology out to the market.

If you are interested in ESL, one of the main applications of PAwR, please continue with the following guide:

Getting started with Bluetooth Electronic Shelf Labels (ESL) and Periodic Advertising with Responses (PAwR)

Further reading:

If you are new to nRF Connect SDK or to Bluetooth Low Energy, it's recommended to get started with our Developer Academy courses: nRF Connect fundamentals and Bluetooth LE fundamentals.

If you have further questions or issues with the demo or the content of the guide, please create a DevZone ticket with a link to this guide. We will try to avoid having long discussions or troubleshooting in the guide's comment section.