You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2015/11/04 02:39:06 UTC

[2/2] incubator-mynewt-larva git commit: Add whitelisting. Not yet working for advertising filter policy but basically working for scanner filter policy

Add whitelisting. Not yet working for advertising filter policy but basically working for scanner filter policy


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/3838ff01
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/3838ff01
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/3838ff01

Branch: refs/heads/master
Commit: 3838ff01ff129ba6193c9225a4c4fb1b9d079408
Parents: fb01df4
Author: Willam San Filippo <wi...@micosa.io>
Authored: Tue Nov 3 17:35:24 2015 -0800
Committer: Willam San Filippo <wi...@micosa.io>
Committed: Tue Nov 3 17:37:17 2015 -0800

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll.h      |   3 -
 .../controller/include/controller/ble_ll_adv.h  |   3 +
 .../controller/include/controller/ble_ll_scan.h |   8 +-
 .../controller/include/controller/ble_phy.h     |   1 -
 net/nimble/controller/src/ble_ll.c              |  18 +-
 net/nimble/controller/src/ble_ll_adv.c          |  26 +-
 net/nimble/controller/src/ble_ll_hci.c          |  30 ++-
 net/nimble/controller/src/ble_ll_scan.c         | 253 ++++++++++++-------
 net/nimble/controller/src/ble_phy.c             |   2 +
 net/nimble/host/include/host/host_hci.h         |   5 +
 net/nimble/host/src/host_hci.c                  |  83 ++++++
 net/nimble/include/nimble/ble.h                 |  11 +-
 net/nimble/include/nimble/hci_common.h          |  13 +-
 project/bletest/src/main.c                      |  63 +++--
 14 files changed, 382 insertions(+), 137 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/include/controller/ble_ll.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
index 6d8504c..a32a51d 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -408,9 +408,6 @@ int ble_ll_is_valid_random_addr(uint8_t *addr);
 /* Calculate the amount of time a pdu of 'len' bytes will take to transmit */
 uint16_t ble_ll_pdu_tx_time_get(uint16_t len);
 
-/* Boolean returning true if device is on whitelist */
-int ble_ll_is_on_whitelist(uint8_t *addr, int addr_type);
-
 /* Is this address a resolvable private address? */
 int ble_ll_is_resolvable_priv_addr(uint8_t *addr);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/include/controller/ble_ll_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_adv.h b/net/nimble/controller/include/controller/ble_ll_adv.h
index 15f8d25..4001dd4 100644
--- a/net/nimble/controller/include/controller/ble_ll_adv.h
+++ b/net/nimble/controller/include/controller/ble_ll_adv.h
@@ -150,4 +150,7 @@ void ble_ll_adv_init(void);
 /* Called when a scan request has been received. */
 int ble_ll_adv_rx_scan_req(uint8_t *rxbuf);
 
+/* Boolean function denoting whether or not the whitelist can be changed */
+int ble_ll_adv_can_chg_whitelist(void);
+
 #endif /* H_LL_ADV_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/include/controller/ble_ll_scan.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_scan.h b/net/nimble/controller/include/controller/ble_ll_scan.h
index 42f1be7..6fe3728 100644
--- a/net/nimble/controller/include/controller/ble_ll_scan.h
+++ b/net/nimble/controller/include/controller/ble_ll_scan.h
@@ -77,9 +77,13 @@ void ble_ll_scan_init(void);
 int ble_ll_scan_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
 
 /* Called when Link Layer has finished receiving a PDU while scanning */
-int ble_ll_scan_rx_pdu_end(uint8_t *rxbuf);
+int ble_ll_scan_rx_pdu_end(struct os_mbuf *rxpdu);
 
 /* Process a scan response PDU */
-void ble_ll_scan_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, int8_t rssi);
+void ble_ll_scan_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, int8_t rssi,
+                             uint8_t flags);
+
+/* Boolean function denoting whether or not the whitelist can be changed */
+int  ble_ll_scan_can_chg_whitelist(void);
 
 #endif /* H_LL_SCAN_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/include/controller/ble_phy.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_phy.h b/net/nimble/controller/include/controller/ble_phy.h
index f527c44..cfd03b7 100644
--- a/net/nimble/controller/include/controller/ble_phy.h
+++ b/net/nimble/controller/include/controller/ble_phy.h
@@ -105,5 +105,4 @@ void ble_phy_disable(void);
 /* Gets the current state of the PHY */
 int ble_phy_state_get(void);
 
-
 #endif /* H_BLE_PHY_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index 35da12e..d53a0bb 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -172,14 +172,6 @@ ble_ll_count_rx_pkts(uint8_t pdu_type)
     }
 }
 
-
-int
-ble_ll_is_on_whitelist(uint8_t *addr, int addr_type)
-{
-    /* XXX: implement this */
-    return 1;
-}
-
 int
 ble_ll_is_resolvable_priv_addr(uint8_t *addr)
 {
@@ -352,7 +344,8 @@ ble_ll_rx_pkt_in_proc(void)
             break;
         case BLE_LL_STATE_SCANNING:
             if (ble_hdr->crcok) {
-                ble_ll_scan_rx_pdu_proc(pdu_type, rxbuf, ble_hdr->rssi);
+                ble_ll_scan_rx_pdu_proc(pdu_type, rxbuf, ble_hdr->rssi,
+                                        ble_hdr->flags);
             }
 
             /* We need to re-enable the PHY if we are in idle state */
@@ -530,12 +523,7 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t crcok)
         break;
     case BLE_LL_STATE_SCANNING:
         if (crcok) {
-            /* 
-             * NOTE: If this returns a positive number there was an error but
-             * there is no need to disable the PHY on return as that was
-             * done already.
-             */
-            rc = ble_ll_scan_rx_pdu_end(rxbuf);
+            rc = ble_ll_scan_rx_pdu_end(rxpdu);
         }
         break;
     default:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/src/ble_ll_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c
index 071f645..959f4ce 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -56,7 +56,8 @@
  *    we need to send a CONNECTION COMPLETE event. Do this.
  * 9) How does the advertising channel tx power get set? I dont implement
  * that currently.
- * 10) Add whitelist! Do this to the code.
+ * 10) Add whitelist! Do this to the code. Need to enable/disable whitelisting
+ * appropriately. Also need to set appropriate bits at the PHY (DEVMATCH).
  */
 
 /* 
@@ -881,6 +882,29 @@ ble_ll_adv_tx_done_proc(void *arg)
 }
 
 /**
+ * Checks if the controller can change the whitelist. If advertising is enabled 
+ * and is using the whitelist the controller is not allowed to change the 
+ * whitelist. 
+ * 
+ * @return int 0: not allowed to change whitelist; 1: change allowed.
+ */
+int
+ble_ll_adv_can_chg_whitelist(void)
+{
+    int rc;
+    struct ble_ll_adv_sm *advsm;
+
+    advsm = &g_ble_ll_adv_sm;
+    if (advsm->enabled && (advsm->adv_filter_policy != BLE_HCI_ADV_FILT_NONE)) {
+        rc = 0;
+    } else {
+        rc = 1;
+    }
+
+    return rc;
+}
+
+/**
  * Initialize the advertising functionality of a BLE device. This should 
  * be called once on initialization
  */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/src/ble_ll_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c
index 59a314a..8e6107c 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -24,6 +24,7 @@
 #include "controller/ble_ll_scan.h"
 #include "controller/ble_ll.h"
 #include "controller/ble_ll_hci.h"
+#include "controller/ble_ll_whitelist.h"
 
 /* LE event mask */
 uint8_t g_ble_ll_hci_le_event_mask[BLE_HCI_SET_LE_EVENT_MASK_LEN];
@@ -132,9 +133,9 @@ ble_ll_hci_is_le_event_enabled(int bitpos)
  *  -> Length of parameters (1 byte; does include command header bytes).
  * 
  * @param cmdbuf Pointer to command buffer. Points to start of command header.
- * @param len 
- * @param ocf 
- * 
+ * @param ocf    Opcode command field.
+ * @param *rsplen Pointer to length of response
+ *  
  * @return int 
  */
 static int
@@ -219,6 +220,29 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
             rc = ble_ll_scan_set_scan_params(cmdbuf);
         }
         break;
+    case BLE_HCI_OCF_LE_CLEAR_WHITE_LIST:
+        /* No params with this command  */
+        if (len == 0) {
+            rc = ble_ll_whitelist_clear();
+        }
+        break;
+    case BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE:
+        /* No params with this command  */
+        if (len == 0) {
+            rc = ble_ll_whitelist_read_size(rspbuf);
+            *rsplen = 1;
+        }
+        break;
+    case BLE_HCI_OCF_LE_ADD_WHITE_LIST:
+        if (len == BLE_HCI_CHG_WHITE_LIST_LEN) {
+            rc = ble_ll_whitelist_add(cmdbuf + 1, cmdbuf[0]);
+        }
+        break;
+    case BLE_HCI_OCF_LE_RMV_WHITE_LIST:
+        if (len == BLE_HCI_CHG_WHITE_LIST_LEN) {
+            rc = ble_ll_whitelist_rmv(cmdbuf + 1, cmdbuf[0]);
+        }
+        break;
     default:
         /* XXX: deal with unsupported command */
         break;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index 8da717a..ca578f6 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -26,12 +26,12 @@
 #include "controller/ble_ll_adv.h"
 #include "controller/ble_ll_scan.h"
 #include "controller/ble_ll_hci.h"
+#include "controller/ble_ll_whitelist.h"
 #include "hal/hal_cputime.h"
 #include "hal/hal_gpio.h"
 
  /* 
  * XXX:
- * 1) Implement white list.
  * 2) Need to look at packets for us and those not for us. Probably some of
  * this code needs to go into the link layer (in ll.c).
  * 3) Interleave sending scan requests to different advertisers? I guess I need 
@@ -51,9 +51,7 @@
  * code might be made simpler.
  */
 
-/* 
- * Scanning state machine 
- */
+/* Scanning state machine */
 struct ble_ll_scan_sm
 {
     uint8_t scan_enabled;
@@ -82,7 +80,7 @@ struct ble_ll_scan_stats
 {
     uint32_t scan_starts;
     uint32_t scan_stops;
-    uint32_t scan_win_late;
+    uint32_t scan_win_misses;
     uint32_t cant_set_sched;
     uint32_t scan_req_txf;
     uint32_t scan_req_txg;
@@ -201,12 +199,12 @@ ble_ll_scan_req_pdu_make(struct ble_ll_scan_sm *scansm, uint8_t *adv_addr,
  * Checks to see if an advertiser is on the duplicate address list. 
  * 
  * @param addr Pointer to address
- * @param addr_type Type of address
+ * @param txadd TxAdd bit. 0: public; random otherwise
  * 
  * @return uint8_t 0: not on list; any other value is 
  */
 static struct ble_ll_scan_advertisers *
-ble_ll_scan_find_dup_adv(uint8_t *addr, uint8_t addr_type)
+ble_ll_scan_find_dup_adv(uint8_t *addr, uint8_t txadd)
 {
     uint8_t num_advs;
     struct ble_ll_scan_advertisers *adv;
@@ -217,7 +215,7 @@ ble_ll_scan_find_dup_adv(uint8_t *addr, uint8_t addr_type)
     while (num_advs) {
         if (!memcmp(&adv->adv_addr, addr, BLE_DEV_ADDR_LEN)) {
             /* Address type must match */
-            if (addr_type) {
+            if (txadd) {
                 if ((adv->sc_adv_flags & BLE_LL_SC_ADV_F_RANDOM_ADDR) == 0) {
                     continue;
                 }
@@ -245,11 +243,11 @@ ble_ll_scan_find_dup_adv(uint8_t *addr, uint8_t addr_type)
  * @return int 0: not a duplicate. 1:duplicate
  */
 int
-ble_ll_scan_is_dup_adv(uint8_t pdu_type, uint8_t addr_type, uint8_t *addr)
+ble_ll_scan_is_dup_adv(uint8_t pdu_type, uint8_t txadd, uint8_t *addr)
 {
     struct ble_ll_scan_advertisers *adv;
 
-    adv = ble_ll_scan_find_dup_adv(addr, addr_type);
+    adv = ble_ll_scan_find_dup_adv(addr, txadd);
     if (adv) {
         /* Check appropriate flag (based on type of PDU) */
         if (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND) {
@@ -272,16 +270,16 @@ ble_ll_scan_is_dup_adv(uint8_t pdu_type, uint8_t addr_type, uint8_t *addr)
  * report to the host. 
  * 
  * @param addr 
- * @param addr_type 
+ * @param Txadd. TxAdd bit (0 public, random otherwise)
  */
 void
-ble_ll_scan_add_dup_adv(uint8_t *addr, uint8_t addr_type)
+ble_ll_scan_add_dup_adv(uint8_t *addr, uint8_t txadd)
 {
     uint8_t num_advs;
     struct ble_ll_scan_advertisers *adv;
 
     /* Check to see if on list. */
-    adv = ble_ll_scan_find_dup_adv(addr, addr_type);
+    adv = ble_ll_scan_find_dup_adv(addr, txadd);
     if (!adv) {
         /* XXX: for now, if we dont have room, just leave */
         num_advs = g_ble_ll_scan_num_dup_advs;
@@ -295,7 +293,7 @@ ble_ll_scan_add_dup_adv(uint8_t *addr, uint8_t addr_type)
         ++g_ble_ll_scan_num_dup_advs;
 
         adv->sc_adv_flags = 0;
-        if (addr_type) {
+        if (txadd) {
             adv->sc_adv_flags |= BLE_LL_SC_ADV_F_RANDOM_ADDR;
         }
     }
@@ -311,12 +309,12 @@ ble_ll_scan_add_dup_adv(uint8_t *addr, uint8_t addr_type)
  * Checks to see if we have received a scan response from this advertiser. 
  * 
  * @param adv_addr Address of advertiser
- * @param addr_type Type of address (0: public; random otherwise)
+ * @param txadd TxAdd bit (0: public; random otherwise)
  * 
  * @return int 0: have not received a scan response; 1 otherwise.
  */
 static int
-ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t addr_type)
+ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t txadd)
 {
     uint8_t num_advs;
     struct ble_ll_scan_advertisers *adv;
@@ -327,7 +325,7 @@ ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t addr_type)
     while (num_advs) {
         if (!memcmp(&adv->adv_addr, addr, BLE_DEV_ADDR_LEN)) {
             /* Address type must match */
-            if (addr_type) {
+            if (txadd) {
                 if (adv->sc_adv_flags & BLE_LL_SC_ADV_F_RANDOM_ADDR) {
                     return 1;
                 }
@@ -345,7 +343,7 @@ ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t addr_type)
 }
 
 static void
-ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t addr_type)
+ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd)
 {
     uint8_t num_advs;
     struct ble_ll_scan_advertisers *adv;
@@ -357,7 +355,7 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t addr_type)
     }
 
     /* Check if address is already on the list */
-    if (ble_ll_scan_have_rxd_scan_rsp(addr, addr_type)) {
+    if (ble_ll_scan_have_rxd_scan_rsp(addr, txadd)) {
         return;
     }
 
@@ -365,7 +363,7 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t addr_type)
     adv = &g_ble_ll_scan_rsp_advs[num_advs];
     memcpy(&adv->adv_addr, addr, BLE_DEV_ADDR_LEN);
     adv->sc_adv_flags = BLE_LL_SC_ADV_F_SCAN_RSP_RXD;
-    if (addr_type) {
+    if (txadd) {
         adv->sc_adv_flags |= BLE_LL_SC_ADV_F_RANDOM_ADDR;
     }
     ++g_ble_ll_scan_num_rsp_advs;
@@ -380,12 +378,12 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t addr_type)
  * will just send for one for now. 
  * 
  * @param pdu_type 
- * @param rxadv 
- * 
- * @return int 
+ * @param txadd 
+ * @param rxbuf 
+ * @param rssi 
  */
-static int
-ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t addr_type, uint8_t *rxbuf,
+static void
+ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t txadd, uint8_t *rxbuf,
                            int8_t rssi)
 {
     int rc;
@@ -428,7 +426,7 @@ ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t addr_type, uint8_t *rxbuf,
             evbuf[4] = evtype;
 
             /* XXX: need to deal with resolvable addresses here! */
-            if (addr_type) {
+            if (txadd) {
                 evbuf[5] = BLE_HCI_ADV_OWN_ADDR_RANDOM;
             } else {
                 evbuf[5] = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
@@ -444,25 +442,26 @@ ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t addr_type, uint8_t *rxbuf,
             if (!rc) {
                 /* If filtering, add it to list of duplicate addresses */
                 if (g_ble_ll_scan_sm.scan_filt_dups) {
-                    ble_ll_scan_add_dup_adv(rxbuf, addr_type);
+                    ble_ll_scan_add_dup_adv(rxbuf, txadd);
                 }
             }
         }
     }
-
-    return rc;
 }
 
 /**
- * ble ll scan chk filter policy 
- * 
+ * Checks the scanner filter policy to determine if we should allow or discard 
+ * the received PDU. 
+ *  
+ * NOTE: connect requests and scan requests are not passed here 
+ *  
  * @param pdu_type 
  * @param rxbuf 
  * 
  * @return int 0: pdu allowed by filter policy. 1: pdu not allowed
  */
 int
-ble_ll_scan_chk_filter_policy(uint8_t pdu_type, uint8_t *rxbuf)
+ble_ll_scan_chk_filter_policy(uint8_t pdu_type, uint8_t *rxbuf, uint8_t flags)
 {
     uint8_t *addr;
     uint8_t addr_type;
@@ -491,10 +490,11 @@ ble_ll_scan_chk_filter_policy(uint8_t pdu_type, uint8_t *rxbuf)
     }
 
     /* If we are using the whitelist, check that first */
-    addr = rxbuf + BLE_LL_PDU_HDR_LEN;
-    if (use_whitelist) {
-        addr_type = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK;
-        if (!ble_ll_is_on_whitelist(addr, addr_type)) {
+    if (use_whitelist && (pdu_type != BLE_ADV_PDU_TYPE_SCAN_RSP)) {
+        /* If there was a devmatch, we will allow the PDU */
+        if (flags & BLE_MBUF_HDR_F_DEVMATCH) {
+            return 0;
+        } else {
             return 1;
         }
     }
@@ -502,6 +502,7 @@ ble_ll_scan_chk_filter_policy(uint8_t pdu_type, uint8_t *rxbuf)
     /* If this is a directed advertisement, check that it is for us */
     if (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND) {
         /* Is this for us? If not, is it resolvable */
+        addr = rxbuf + BLE_LL_PDU_HDR_LEN;
         addr_type = rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK;
         if (!ble_ll_is_our_devaddr(addr + BLE_DEV_ADDR_LEN, addr_type)) {
             if (!chk_inita || !ble_ll_is_resolvable_priv_addr(addr)) {
@@ -547,8 +548,6 @@ ble_ll_scan_start_cb(struct ble_ll_sched_item *sch)
         /* Set link layer state to scanning */
         ble_ll_state_set(BLE_LL_STATE_SCANNING);
 
-        /* XXX: scan forever? */
-
         /* Set end time to end of scan window */
         sch->next_wakeup = sch->end_time;
         sch->sched_cb = ble_ll_scan_win_end_cb;
@@ -576,6 +575,9 @@ ble_ll_scan_sm_stop(struct ble_ll_scan_sm *scansm)
     /* Disable the PHY */
     ble_phy_disable();
 
+    /* Disable whitelisting (just in case) */
+    ble_ll_whitelist_disable();
+
     /* Disable scanning state machine */
     scansm->scan_enabled = 0;
 
@@ -594,17 +596,14 @@ ble_ll_scan_sched_set(struct ble_ll_scan_sm *scansm)
         /* Set sched type */
         sch->sched_type = BLE_LL_SCHED_TYPE_SCAN;
 
-        /* XXX: probably the PHY should provide an API to return this stuff
-           to me as opposed to # define (XCVR_RX_SCHED) */
         /* Set the start time of the event */
         sch->start_time = scansm->scan_win_start_time - 
             cputime_usecs_to_ticks(XCVR_RX_SCHED_DELAY_USECS);
 
-        /* XXX: what about continuous scanning? */
         /* Set the callback, arg, start and end time */
         sch->cb_arg = scansm;
         sch->sched_cb = ble_ll_scan_start_cb;
-        sch->end_time = sch->start_time + 
+        sch->end_time = scansm->scan_win_start_time + 
             cputime_usecs_to_ticks(scansm->scan_window * BLE_HCI_SCAN_ITVL);
 
         /* XXX: for now, we cant get an overlap so assert on error. */
@@ -640,6 +639,13 @@ ble_ll_scan_sm_start(struct ble_ll_scan_sm *scansm)
         }
     }
 
+    /* Enable/disable whitelisting */
+    if (scansm->scan_filt_policy & 1) {
+        ble_ll_whitelist_enable();
+    } else {
+        ble_ll_whitelist_disable();
+    }
+
     /* Count # of times started */
     ++g_ble_ll_scan_stats.scan_starts;
 
@@ -672,6 +678,7 @@ ble_ll_scan_win_end_proc(void *arg)
 {
     int32_t delta_t;
     uint32_t itvl;
+    uint32_t win_ticks;
     struct ble_ll_scan_sm *scansm;
 
     /* Toggle the LED */
@@ -692,27 +699,28 @@ ble_ll_scan_win_end_proc(void *arg)
         ble_ll_scan_req_backoff(scansm, 0);
     }
 
-    /* XXX: deal with scan forever */
+    /* Calculate # of ticks per scan window */
+    win_ticks = cputime_usecs_to_ticks(scansm->scan_window * BLE_HCI_SCAN_ITVL);
 
     /* Set next scan window start time */
     itvl = cputime_usecs_to_ticks(scansm->scan_itvl * BLE_HCI_SCAN_ITVL);
     scansm->scan_win_start_time += itvl;
         
-    /* 
-     * The scheduled time better be in the future! If it is not, we will
-     * count a statistic and close the current advertising event. We will
-     * then setup the next advertising event.
-     */
-    delta_t = (int32_t)(scansm->scan_win_start_time - cputime_get32());
-    if (delta_t < 0) {
+    /* Set next scanning window start. */        
+    delta_t = (int32_t)(cputime_get32() - scansm->scan_win_start_time);
+    if (delta_t >= win_ticks) {
+        /* 
+         * Since it is possible to scan continuously, it is possible
+         * that we will be late here if the scan window is equal to the
+         * scan interval (or very close). So what we will do here is only
+         * increment a stat if we missed a scan window
+         */
         /* Count times we were late */
-        ++g_ble_ll_scan_stats.scan_win_late;
+        ++g_ble_ll_scan_stats.scan_win_misses;
 
         /* Calculate start time of next scan windowe */
-        while (delta_t < 0) {
-            scansm->scan_win_start_time += itvl;
-            delta_t += (int32_t)itvl;
-        }
+        scansm->scan_win_start_time += itvl;
+        delta_t -= (int32_t)itvl;
     }
 
     if (!ble_ll_scan_sched_set(scansm)) {
@@ -778,39 +786,84 @@ ble_ll_scan_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu)
     return rc;
 }
 
+
+/* 
+ * NOTE: If this returns a positive number there was an error but
+ * there is no need to disable the PHY on return as that was
+ * done already.
+ */
+
+/**
+ * Called when a receive PDU has ended. 
+ *  
+ * Context: Interrupt 
+ * 
+ * @param rxpdu 
+ * 
+ * @return int 
+ *       < 0: Disable the phy after reception.
+ *      == 0: Success. Do not disable the PHY.
+ *       > 0: Do not disable PHY as that has already been done.
+ */
 int
-ble_ll_scan_rx_pdu_end(uint8_t *rxbuf)
+ble_ll_scan_rx_pdu_end(struct os_mbuf *rxpdu)
 {
     int rc;
+    int chk_send_req;
+    int chk_whitelist;
     uint8_t pdu_type;
     uint8_t addr_type;
     uint8_t *adv_addr;
+    uint8_t *rxbuf;
+    struct ble_mbuf_hdr *ble_hdr;
     struct ble_ll_scan_sm *scansm;
 
     /* If passively scanning return (with -1) since no scan request is sent */
-    rc = -1;
     scansm = &g_ble_ll_scan_sm;
-    if (scansm->scan_type != BLE_HCI_SCAN_TYPE_ACTIVE) {
-        return -1;
-    }
 
-    /* Get pdu type */
+    /* Get pdu type, pointer to address and address "type"  */
+    rxbuf = rxpdu->om_data;
     pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
+    adv_addr = rxbuf + BLE_LL_PDU_HDR_LEN;
+    if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) {
+        addr_type = BLE_ADDR_TYPE_RANDOM;
+    } else {
+        addr_type = BLE_ADDR_TYPE_PUBLIC;
+    }
 
-    /* We only care about indirect advertisements or scan indirect */
-    if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||
-        (pdu_type == BLE_ADV_PDU_TYPE_ADV_SCAN_IND)) {
-        /* See if we should check the whitelist */
-        adv_addr = rxbuf + BLE_LL_PDU_HDR_LEN;
-        addr_type = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK;
-        if ((scansm->scan_filt_policy == BLE_HCI_SCAN_FILT_USE_WL) ||
-            (scansm->scan_filt_policy == BLE_HCI_SCAN_FILT_USE_WL_INITA)) {
-            /* Check if device is on whitelist. If not, leave */
-            if (!ble_ll_is_on_whitelist(adv_addr, addr_type)) {
-                return -1;
-            }
+    /* Determine if request may be sent and if whitelist needs to be checked */
+    chk_send_req = 0;
+    switch (pdu_type) {
+    case BLE_ADV_PDU_TYPE_ADV_IND:
+    case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
+        if (scansm->scan_type == BLE_HCI_SCAN_TYPE_ACTIVE) {
+            chk_send_req = 1;
         }
+        chk_whitelist = 1;
+        break;
+    case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND:
+    case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
+        chk_whitelist = 1;
+        break;
+    default:
+        chk_whitelist = 0;
+        break;
+    }
+
+    /* Set device match bit if we are whitelisting */
+    if (chk_whitelist && (scansm->scan_filt_policy & 1)) {
+        /* Check if device is on whitelist. If not, leave */
+        if (!ble_ll_whitelist_match(adv_addr, addr_type)) {
+            return -1;
+        } else {
+            ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
+            ble_hdr->flags |= BLE_MBUF_HDR_F_DEVMATCH;
+        }
+    }
 
+    /* Should we send a scan request? */
+    rc = -1;
+    if (chk_send_req) {
         /* 
          * Check to see if we have received a scan response from this
          * advertisor. If so, no need to send scan request.
@@ -850,11 +903,13 @@ ble_ll_scan_rx_pdu_end(uint8_t *rxbuf)
  * @param rxbuf 
  */
 void
-ble_ll_scan_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, int8_t rssi)
+ble_ll_scan_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, int8_t rssi,
+                        uint8_t flags)
 {
     uint8_t *adv_addr;
     uint8_t *adva;
-    uint8_t addr_type;
+    uint8_t txadd;
+    uint8_t rxadd;
     struct ble_ll_scan_sm *scansm;
 
     /* We dont care about scan requests or connect requests */
@@ -864,12 +919,12 @@ ble_ll_scan_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, int8_t rssi)
     }
 
     /* Check the scanner filter policy */
-    if (ble_ll_scan_chk_filter_policy(pdu_type, rxbuf)) {
+    if (ble_ll_scan_chk_filter_policy(pdu_type, rxbuf, flags)) {
         return;
     }
 
     /* Get advertisers address type and a pointer to the address */
-    addr_type = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK;
+    txadd = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK;
     adv_addr = rxbuf + BLE_LL_PDU_HDR_LEN;
 
     /* 
@@ -886,18 +941,18 @@ ble_ll_scan_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, int8_t rssi)
          */
         if (scansm->scan_rsp_pending) {
             /* 
-             * XXX: should I check address type as well? To compare
-             * the received scan response to the address in the scan
-             * request?
-             * 
-             * I could also check the timing of the scan reponse; make sure
-             * that it is relatively close to the end of the scan request.
+             * We could also check the timing of the scan reponse; make sure
+             * that it is relatively close to the end of the scan request but
+             * we wont for now.
              */
             adva = scansm->scan_req_pdu->om_data + BLE_LL_PDU_HDR_LEN +
                    BLE_DEV_ADDR_LEN;
-            if (!memcmp(adv_addr, adva, BLE_DEV_ADDR_LEN)) {
+            rxadd = scansm->scan_req_pdu->om_data[0] & 
+                    BLE_ADV_PDU_HDR_RXADD_MASK;
+            if (((txadd && rxadd) || ((txadd + rxadd) == 0)) &&
+                !memcmp(adv_addr, adva, BLE_DEV_ADDR_LEN)) {
                 /* We have received a scan response. Add to list */
-                ble_ll_scan_add_scan_rsp_adv(adv_addr, addr_type);
+                ble_ll_scan_add_scan_rsp_adv(adv_addr, txadd);
 
                 /* Perform scan request backoff procedure */
                 ble_ll_scan_req_backoff(scansm, 1);
@@ -913,14 +968,13 @@ ble_ll_scan_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, int8_t rssi)
 
     /* Filter duplicates */
     if (scansm->scan_filt_dups) {
-        if (ble_ll_scan_is_dup_adv(pdu_type, addr_type, adv_addr)) {
+        if (ble_ll_scan_is_dup_adv(pdu_type, txadd, adv_addr)) {
             return;
         }
     }
 
-    /* XXX: what do I do with return code here? Anything? */
     /* Send the advertising report */
-    ble_ll_hci_send_adv_report(pdu_type, addr_type, rxbuf, rssi);
+    ble_ll_hci_send_adv_report(pdu_type, txadd, rxbuf, rssi);
 }
 
 int
@@ -1027,6 +1081,29 @@ ble_ll_scan_set_enable(uint8_t *cmd)
 }
 
 /**
+ * Checks if controller can change the whitelist. If scanning is enabled and
+ * using the whitelist the controller is not allowed to change the whitelist.
+ * 
+ * @return int 0: not allowed to change whitelist; 1: change allowed.
+ */
+int
+ble_ll_scan_can_chg_whitelist(void)
+{
+    int rc;
+    struct ble_ll_scan_sm *scansm;
+
+    scansm = &g_ble_ll_scan_sm;
+    if (scansm->scan_enabled && (scansm->scan_filt_policy & 1)) {
+        rc = 0;
+    } else {
+        rc = 1;
+    }
+
+    return rc;
+}
+
+
+/**
  * ble ll scan init 
  *  
  * Initialize a scanner. 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/controller/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_phy.c b/net/nimble/controller/src/ble_phy.c
index 3ed5a27..f0d12e6 100644
--- a/net/nimble/controller/src/ble_phy.c
+++ b/net/nimble/controller/src/ble_phy.c
@@ -158,6 +158,7 @@ ble_phy_isr(void)
                 /* I want to know when 1st byte received (after address) */
                 NRF_RADIO->BCC = 8; /* in bits */
                 NRF_RADIO->EVENTS_ADDRESS = 0;
+                NRF_RADIO->EVENTS_DEVMATCH = 0;
                 NRF_RADIO->EVENTS_BCMATCH = 0;
                 NRF_RADIO->EVENTS_RSSIEND = 0;
                 NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | 
@@ -369,6 +370,7 @@ ble_phy_rx(void)
     NRF_RADIO->EVENTS_DISABLED = 0;
     NRF_RADIO->EVENTS_BCMATCH = 0;
     NRF_RADIO->EVENTS_RSSIEND = 0;
+    NRF_RADIO->EVENTS_DEVMATCH = 0;
 
     /* I want to know when 1st byte received (after address) */
     NRF_RADIO->BCC = 8; /* in bits */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/host/include/host/host_hci.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/host_hci.h b/net/nimble/host/include/host/host_hci.h
index 4860c55..526c57e 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -31,5 +31,10 @@ int host_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups);
 int host_hci_cmd_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl, 
                                     uint16_t scan_window, uint8_t own_addr_type,
                                     uint8_t filter_policy);
+int host_hci_cmd_le_clear_whitelist(void);
+int host_hci_cmd_le_read_whitelist(void);
+int host_hci_cmd_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type);
+int host_hci_cmd_le_rmv_from_whitelist(uint8_t *addr, uint8_t addr_type);
+
 
 #endif /* H_HOST_HCI_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/host/src/host_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c
index 629ea3d..08b18ae 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -80,6 +80,22 @@ host_hci_le_cmd_send(uint16_t ocf, uint8_t len, void *cmddata)
     return rc;
 }
 
+static int
+host_hci_cmd_le_whitelist_chg(uint8_t *addr, uint8_t addr_type, uint8_t ocf)
+{
+    int rc;
+    uint8_t cmd[BLE_HCI_CHG_WHITE_LIST_LEN];
+
+    if (addr_type <= BLE_ADDR_TYPE_RANDOM) {
+        cmd[0] = addr_type;
+        memcpy(cmd + 1, addr, BLE_DEV_ADDR_LEN);
+        rc = host_hci_le_cmd_send(ocf, BLE_HCI_CHG_WHITE_LIST_LEN, cmd);
+    } else {
+        rc = BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+    return rc;
+}
+
 int
 host_hci_cmd_le_set_adv_params(struct hci_adv_params *adv)
 {
@@ -277,6 +293,73 @@ host_hci_cmd_le_set_scan_enable(uint8_t enable, uint8_t filter_dups)
     return rc;
 }
 
+/**
+ * Clear the whitelist.
+ * 
+ * @return int 
+ */
+int
+host_hci_cmd_le_clear_whitelist(void)
+{
+    int rc;
+
+    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_CLEAR_WHITE_LIST, 0, NULL);
+    return rc;
+}
+
+/**
+ * Read the whitelist size. Note that this is not how many elements have 
+ * been added to the whitelist; rather it is the number of whitelist entries 
+ * allowed by the controller. 
+ * 
+ * @return int 
+ */
+int
+host_hci_cmd_le_read_whitelist(void)
+{
+    int rc;
+
+    rc = host_hci_le_cmd_send(BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE, 0, NULL);
+    return rc;
+}
+
+/**
+ * Add a device to the whitelist.
+ * 
+ * @param addr 
+ * @param addr_type 
+ * 
+ * @return int 
+ */
+int
+host_hci_cmd_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type)
+{
+    int rc;
+
+    rc = host_hci_cmd_le_whitelist_chg(addr, addr_type, 
+                                       BLE_HCI_OCF_LE_ADD_WHITE_LIST);
+
+    return rc;
+}
+
+/**
+ * Remove a device from the whitelist.
+ * 
+ * @param addr 
+ * @param addr_type 
+ * 
+ * @return int 
+ */
+int
+host_hci_cmd_le_rmv_from_whitelist(uint8_t *addr, uint8_t addr_type)
+{
+    int rc;
+
+    rc = host_hci_cmd_le_whitelist_chg(addr, addr_type, 
+                                       BLE_HCI_OCF_LE_RMV_WHITE_LIST);
+    return rc;
+}
+
 void
 host_hci_event_proc(struct os_event *ev)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index 03e5c42..6760735 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -35,7 +35,8 @@ extern struct os_mempool g_hci_os_event_pool;
  *      struct ble_mbuf_hdr     (4)
  * 
  * The BLE mbuf header contains the following:
- *  flags: currently unused
+ *  flags: bitfield with the following values
+ *      0x01:   Set if there was a match on the whitelist
  *  channel: The logical BLE channel PHY channel # (0 - 39)
  *  crcok: flag denoting CRC check passed (1) or failed (0).
  *  rssi: RSSI, in dBm.
@@ -48,6 +49,9 @@ struct ble_mbuf_hdr
     int8_t rssi;
 };
 
+/* Flag definitions */
+#define BLE_MBUF_HDR_F_DEVMATCH     (0x01)
+
 #define BLE_MBUF_HDR_PTR(om)    \
     (struct ble_mbuf_hdr *)((uint8_t *)om + sizeof(struct os_mbuf) + \
                             sizeof(struct os_mbuf_pkthdr))
@@ -64,6 +68,7 @@ uint32_t le32toh(uint8_t *buf);
 uint64_t le64toh(uint8_t *buf);
 /* XXX */
 
+/* BLE Error Codes (Core v4.2 Vol 2 part D) */
 enum ble_error_codes
 {
     /* An "error" code of 0 means success */
@@ -136,4 +141,8 @@ enum ble_error_codes
     BLE_ERR_MAX                 = 255
 };
 
+/* Address types */
+#define BLE_ADDR_TYPE_PUBLIC    (0)
+#define BLE_ADDR_TYPE_RANDOM    (1)
+
 #endif /* H_BLE_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index eebca4c..03af0de 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -153,11 +153,11 @@
  *  CONN: process all scan request but only connection requests from white list
  *  BOTH: ignore all scan and connection requests unless in white list.
  */
-#define BLE_HCI_ADV_FILT_NONE               (0x01)
-#define BLE_HCI_ADV_FILT_SCAN               (0x02)
-#define BLE_HCI_ADV_FILT_CONN               (0x03)
-#define BLE_HCI_ADV_FILT_BOTH               (0x04)
-#define BLE_HCI_ADV_FILT_MAX                (0x04)
+#define BLE_HCI_ADV_FILT_NONE               (0)
+#define BLE_HCI_ADV_FILT_SCAN               (1)
+#define BLE_HCI_ADV_FILT_CONN               (2)
+#define BLE_HCI_ADV_FILT_BOTH               (3)
+#define BLE_HCI_ADV_FILT_MAX                (3)
 
 /* Advertising interval */
 #define BLE_HCI_ADV_ITVL                    (625)           /* usecs */
@@ -205,6 +205,9 @@
 #define BLE_HCI_SCAN_FILT_USE_WL_INITA      (3)
 #define BLE_HCI_SCAN_FILT_MAX               (3)
 
+/* Whitelist commands */
+#define BLE_HCI_CHG_WHITE_LIST_LEN          (7)
+
 /* Event Codes */
 #define BLE_HCI_EVCODE_INQUIRY_CMP          (0x01)
 #define BLE_HCI_EVCODE_INQUIRY_RESULT       (0x02)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/3838ff01/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index eb6a758..b5d763e 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -63,17 +63,19 @@ struct os_mempool g_mbuf_mempool;
 os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE];
 
 /* Some application configurations */
-#define BLETEST_ROLE_ADVERTISER     (0)
-#define BLETEST_ROLE_SCANNER        (1)
-#define BLETEST_CFG_FILT_DUP_ADV    (0)
-#define BLETEST_CFG_ADV_ITVL        (500000 / BLE_HCI_ADV_ITVL)
-#define BLETEST_CFG_ADV_TYPE        BLE_HCI_ADV_TYPE_ADV_SCAN_IND
-#define BLETEST_CFG_SCAN_ITVL       (700000 / BLE_HCI_SCAN_ITVL)
-#define BLETEST_CFG_SCAN_WINDOW     (650000 / BLE_HCI_SCAN_ITVL)
-#define BLETEST_CFG_ROLE            (BLETEST_ROLE_SCANNER)
-#define BLETEST_CFG_SCAN_TYPE       (BLE_HCI_SCAN_TYPE_ACTIVE)
+#define BLETEST_ROLE_ADVERTISER         (0)
+#define BLETEST_ROLE_SCANNER            (1)
+#define BLETEST_CFG_FILT_DUP_ADV        (0)
+#define BLETEST_CFG_ADV_ITVL            (500000 / BLE_HCI_ADV_ITVL)
+#define BLETEST_CFG_ADV_TYPE            BLE_HCI_ADV_TYPE_ADV_SCAN_IND
+#define BLETEST_CFG_SCAN_ITVL           (700000 / BLE_HCI_SCAN_ITVL)
+#define BLETEST_CFG_SCAN_WINDOW         (650000 / BLE_HCI_SCAN_ITVL)
+#define BLETEST_CFG_ROLE                (BLETEST_ROLE_SCANNER)
+#define BLETEST_CFG_SCAN_TYPE           (BLE_HCI_SCAN_TYPE_PASSIVE)
+#define BLETEST_CFG_SCAN_FILT_POLICY    (BLE_HCI_SCAN_FILT_USE_WL)
+
 uint32_t g_next_os_time;
-int bletest_state;
+int g_bletest_state;
 
 void
 bletest_inc_adv_pkt_num(void)
@@ -173,20 +175,45 @@ bletest_init_advertising(void)
 
     /* Set scan response data */
     rc = host_hci_cmd_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
+    assert(rc == 0);
 }
 
 void
 bletest_init_scanner(void)
 {
     int rc;
+    uint8_t dev_addr[BLE_DEV_ADDR_LEN];
+    uint8_t filter_policy;
 
     /* Set scanning parameters */
     rc = host_hci_cmd_le_set_scan_params(BLETEST_CFG_SCAN_TYPE,
                                          BLETEST_CFG_SCAN_ITVL,
                                          BLETEST_CFG_SCAN_WINDOW,
                                          BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-                                         BLE_HCI_SCAN_FILT_NO_WL);
+                                         BLETEST_CFG_SCAN_FILT_POLICY);
     assert(rc == 0);
+
+    filter_policy = BLETEST_CFG_SCAN_FILT_POLICY;
+    if (filter_policy & 1) {
+        /* Add some whitelist addresses */
+        dev_addr[0] = 0x91;
+        dev_addr[1] = 0xab;
+        dev_addr[2] = 0x1c;
+        dev_addr[3] = 0x7e;
+        dev_addr[4] = 0x4f;
+        dev_addr[5] = 0xd0;
+        rc = host_hci_cmd_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_PUBLIC);
+        assert(rc == 0);
+
+        dev_addr[0] = 0x94;
+        dev_addr[1] = 0x0e;
+        dev_addr[2] = 0xf4;
+        dev_addr[3] = 0x8f;
+        dev_addr[4] = 0x20;
+        dev_addr[5] = 0xe7;
+        rc = host_hci_cmd_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_RANDOM);
+        assert(rc == 0);
+    }
 }
 
 void 
@@ -215,7 +242,7 @@ host_task_handler(void *arg)
 #endif
 
     /* Init bletest varibles */
-    bletest_state = 0;
+    g_bletest_state = 0;
     g_next_os_time = os_time_get();
 
     /* We are initialized */
@@ -233,14 +260,14 @@ bletest_execute(void)
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
     /* Enable advertising */
     if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-        if (bletest_state) {
+        if (g_bletest_state) {
             rc = host_hci_cmd_le_set_adv_enable(0);
             assert(rc == 0);
-            bletest_state = 0;
+            g_bletest_state = 0;
         } else {
             rc = host_hci_cmd_le_set_adv_enable(1);
             assert(rc == 0);
-            bletest_state = 1;
+            g_bletest_state = 1;
         }
         g_next_os_time += (OS_TICKS_PER_SEC * 60);
     }
@@ -248,14 +275,14 @@ bletest_execute(void)
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
     /* Enable scanning */
     if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-        if (bletest_state) {
+        if (g_bletest_state) {
             rc = host_hci_cmd_le_set_scan_enable(0, BLETEST_CFG_FILT_DUP_ADV);
             assert(rc == 0);
-            bletest_state = 0;
+            g_bletest_state = 0;
         } else {
             rc = host_hci_cmd_le_set_scan_enable(1, BLETEST_CFG_FILT_DUP_ADV);
             assert(rc == 0);
-            bletest_state = 1;
+            g_bletest_state = 1;
         }
         g_next_os_time += (OS_TICKS_PER_SEC * 60);
     }