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:05 UTC

[1/2] incubator-mynewt-larva git commit: Add whitelisting

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master fb01df470 -> 5fcced151


Add whitelisting


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/5fcced15
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/5fcced15
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/5fcced15

Branch: refs/heads/master
Commit: 5fcced15100a2782015642bd4bf3485d795f028c
Parents: 3838ff0
Author: Willam San Filippo <wi...@micosa.io>
Authored: Tue Nov 3 17:36:15 2015 -0800
Committer: Willam San Filippo <wi...@micosa.io>
Committed: Tue Nov 3 17:37:17 2015 -0800

----------------------------------------------------------------------
 .../controller/include/controller/ble_hw.h      |  43 ++++
 .../include/controller/ble_ll_whitelist.h       |  43 ++++
 net/nimble/controller/src/ble_hw.c              | 159 ++++++++++++
 net/nimble/controller/src/ble_ll_whitelist.c    | 253 +++++++++++++++++++
 4 files changed, 498 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5fcced15/net/nimble/controller/include/controller/ble_hw.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_hw.h b/net/nimble/controller/include/controller/ble_hw.h
new file mode 100644
index 0000000..a141823
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_hw.h
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_HW_
+#define H_BLE_HW_
+
+#define BLE_USES_HW_WHITELIST   (1)
+
+/* Returns the number of hw whitelist elements */
+uint8_t ble_hw_whitelist_size(void);
+
+/* Clear the whitelist */
+void ble_hw_whitelist_clear(void);
+
+/* Remove a device from the hw whitelist */
+void ble_hw_whitelist_rmv(uint8_t *addr, uint8_t addr_type);
+
+/* Add a device to the hw whitelist */
+int ble_hw_whitelist_add(uint8_t *addr, uint8_t addr_type);
+
+/* Enable hw whitelisting */
+void ble_hw_whitelist_enable(void);
+
+/* Enable hw whitelisting */
+void ble_hw_whitelist_disable(void);
+
+/* Boolean function returning true if address matches a whitelist entry */
+int ble_hw_whitelist_match(void);
+
+#endif /* H_BLE_HW_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5fcced15/net/nimble/controller/include/controller/ble_ll_whitelist.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_whitelist.h b/net/nimble/controller/include/controller/ble_ll_whitelist.h
new file mode 100644
index 0000000..590b132
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_ll_whitelist.h
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_LL_WHITELIST_
+#define H_BLE_LL_WHITELIST_
+
+#define BLE_LL_CFG_WHITELIST_SIZE   (8)
+
+/* Clear the whitelist */
+int ble_ll_whitelist_clear(void);
+
+/* Read the size of the whitelist */
+int ble_ll_whitelist_read_size(uint8_t *rspbuf);
+
+/* Add a device to the whitelist */
+int ble_ll_whitelist_add(uint8_t *addr, uint8_t addr_type);
+
+/* Remove a device fromthe whitelist */
+int ble_ll_whitelist_rmv(uint8_t *addr, uint8_t addr_type);
+
+/* Enable whitelisting */
+void ble_ll_whitelist_enable(void);
+
+/* Disable whitelisting */
+void ble_ll_whitelist_disable(void);
+
+/* Boolean function returning true if address matches a whitelist entry */
+int ble_ll_whitelist_match(uint8_t *addr, uint8_t addr_type);
+
+#endif /* H_BLE_LL_WHITELIST_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5fcced15/net/nimble/controller/src/ble_hw.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_hw.c b/net/nimble/controller/src/ble_hw.c
new file mode 100644
index 0000000..1d93d8e
--- /dev/null
+++ b/net/nimble/controller/src/ble_hw.c
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2015 Stack Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <assert.h>
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "mcu/nrf52.h"
+#include "mcu/nrf52_bitfields.h"
+
+#define BLE_HW_WHITE_LIST_SIZE      (8)
+
+/* We use this to keep track of which entries are set to valid addresses */
+static uint8_t g_ble_hw_whitelist_mask;
+
+/**
+ * Clear the whitelist
+ * 
+ * @return int 
+ */
+void
+ble_hw_whitelist_clear(void)
+{
+    NRF_RADIO->DACNF = 0;
+    g_ble_hw_whitelist_mask = 0;
+}
+
+/**
+ * Add a device to the hw whitelist 
+ * 
+ * @param addr 
+ * @param addr_type 
+ * 
+ * @return int 0: success, BLE error code otherwise
+ */
+int
+ble_hw_whitelist_add(uint8_t *addr, uint8_t addr_type)
+{
+    int i;
+    uint32_t mask;
+
+    /* Find first ununsed device address match element */
+    mask = 0x01;
+    for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) {
+        if ((mask & g_ble_hw_whitelist_mask) == 0) {
+            NRF_RADIO->DAB[i] = le32toh(addr);
+            NRF_RADIO->DAP[i] = le16toh(addr + 4);
+            if (addr_type == BLE_ADDR_TYPE_RANDOM) {
+                NRF_RADIO->DACNF |= (mask << 8);
+            }
+            g_ble_hw_whitelist_mask |= mask;
+            return BLE_ERR_SUCCESS;
+        }
+        mask <<= 1;
+    }
+
+    return BLE_ERR_MEM_CAPACITY;
+}
+
+/**
+ * Remove a device from the hw whitelist 
+ * 
+ * @param addr 
+ * @param addr_type 
+ * 
+ */
+void
+ble_hw_whitelist_rmv(uint8_t *addr, uint8_t addr_type)
+{
+    int i;
+    uint8_t cfg_addr;
+    uint16_t dap;
+    uint16_t txadd;
+    uint32_t dab;
+    uint32_t mask;
+
+    /* Find first ununsed device address match element */
+    dab = le32toh(addr);
+    dap = le16toh(addr + 4);
+    txadd = NRF_RADIO->DACNF >> 8;
+    mask = 0x01;
+    for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) {
+        if (mask & g_ble_hw_whitelist_mask) {
+            if ((dab == NRF_RADIO->DAB[i]) && (dap == NRF_RADIO->DAP[i])) {
+                cfg_addr = txadd & mask;
+                if (addr_type == BLE_ADDR_TYPE_RANDOM) {
+                    if (cfg_addr != 0) {
+                        break;
+                    }
+                } else {
+                    if (cfg_addr == 0) {
+                        break;
+                    }
+                }
+            }
+        }
+        mask <<= 1;
+    }
+
+    if (i < BLE_HW_WHITE_LIST_SIZE) {
+        g_ble_hw_whitelist_mask &= ~mask;
+        NRF_RADIO->DACNF &= ~mask;
+    }
+}
+
+/**
+ * Returns the size of the whitelist in HW 
+ * 
+ * @return int Number of devices allowed in whitelist
+ */
+uint8_t
+ble_hw_whitelist_size(void)
+{
+    return BLE_HW_WHITE_LIST_SIZE;
+}
+
+/**
+ * Enable the whitelisted devices 
+ */
+void
+ble_hw_whitelist_enable(void)
+{
+    /* Enable the configured device addresses */
+    NRF_RADIO->DACNF |= g_ble_hw_whitelist_mask;
+}
+
+/**
+ * Disables the whitelisted devices 
+ */
+void
+ble_hw_whitelist_disable(void)
+{
+    /* Disable all whitelist devices */
+    NRF_RADIO->DACNF &= 0x0000ff00;
+}
+
+/**
+ * Boolean function which returns true ('1') if there is a match on the 
+ * whitelist. 
+ * 
+ * @return int 
+ */
+int
+ble_hw_whitelist_match(void)
+{
+    return (int)NRF_RADIO->EVENTS_DEVMATCH;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/5fcced15/net/nimble/controller/src/ble_ll_whitelist.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_whitelist.c b/net/nimble/controller/src/ble_ll_whitelist.c
new file mode 100644
index 0000000..6eea1c4
--- /dev/null
+++ b/net/nimble/controller/src/ble_ll_whitelist.c
@@ -0,0 +1,253 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "nimble/ble.h"
+#include "controller/ble_ll_whitelist.h"
+#include "controller/ble_ll_hci.h"
+#include "controller/ble_ll_adv.h"
+#include "controller/ble_ll_scan.h"
+#include "controller/ble_hw.h"
+
+#ifndef BLE_USES_HW_WHITELIST
+struct ble_ll_whitelist_entry
+{
+    uint8_t wl_valid;
+    uint8_t wl_addr_type;
+    uint8_t wl_dev_addr[BLE_DEV_ADDR_LEN];
+};
+
+struct ble_ll_whitelist_entry g_ble_ll_whitelist[BLE_LL_CFG_WHITELIST_SIZE];
+#endif
+
+static int
+ble_ll_whitelist_chg_allowed(void)
+{
+    int rc;
+
+    /* XXX: add initiating to this */
+    /* 
+     * This command is not allowed if:
+     *  -> advertising uses the whitelist and we are currently advertising.
+     *  -> scanning uses the whitelist and is enabled.
+     *  -> initiating uses whitelist and a LE create connection command is in
+     *     progress
+     */
+    rc = 1;
+    if (!ble_ll_adv_can_chg_whitelist() || !ble_ll_scan_can_chg_whitelist()) {
+        rc = 0;
+    }
+    return rc;
+}
+
+/**
+ * Clear the whitelist.
+ * 
+ * @return int 0: success, BLE error code otherwise 
+ */
+int
+ble_ll_whitelist_clear(void)
+{
+
+    /* Check proper state */
+    if (!ble_ll_whitelist_chg_allowed()) {
+        return BLE_ERR_CMD_DISALLOWED;
+    }
+
+#ifdef BLE_USES_HW_WHITELIST
+    ble_hw_whitelist_clear();
+#else
+    int i;
+    struct ble_ll_whitelist_entry *wl;
+
+    /* Set the number of entries to 0 */
+    wl = &g_ble_ll_whitelist[0];
+    for (i = 0; i < BLE_LL_CFG_WHITELIST_SIZE; ++i) {
+        wl->wl_valid = 0;
+        ++wl;
+    }
+#endif
+
+    return BLE_ERR_SUCCESS;
+}
+
+/**
+ * Read the size of the whitelist. This is the total number of whitelist 
+ * entries allowed by the controller. 
+ * 
+ * @param rspbuf Pointer to response buffer
+ * 
+ * @return int 0: success.
+ */
+int
+ble_ll_whitelist_read_size(uint8_t *rspbuf)
+{
+#ifdef BLE_USES_HW_WHITELIST
+    rspbuf[0] = ble_hw_whitelist_size();
+#else
+    rspbuf[0] = BLE_LL_CFG_WHITELIST_SIZE;
+#endif
+    return BLE_ERR_SUCCESS;
+}
+
+#ifndef BLE_USES_HW_WHITELIST
+/**
+ * Used to determine if the device is on the whitelist. 
+ * 
+ * @param addr 
+ * @param addr_type Public address (0) or random address (1)
+ * 
+ * @return int 0: device is not on whitelist; otherwise the return value 
+ * is the 'position' of the device in the whitelist (the index of the element 
+ * plus 1). 
+ */
+static int
+ble_ll_is_on_whitelist(uint8_t *addr, uint8_t addr_type)
+{
+    int i;
+    struct ble_ll_whitelist_entry *wl;
+
+    wl = &g_ble_ll_whitelist[0];
+    for (i = 0; i < BLE_LL_CFG_WHITELIST_SIZE; ++i) {
+        if ((wl->wl_valid) && (wl->wl_addr_type == addr_type) &&
+            (!memcmp(&wl->wl_dev_addr[0], addr, BLE_DEV_ADDR_LEN))) {
+            return i + 1;
+        }
+        ++wl;
+    }
+
+    return 0;
+}
+#endif
+
+/**
+ * Is there a match between the device and a device on the whitelist 
+ * 
+ * @param addr 
+ * @param addr_type Public address (0) or random address (1)
+ * 
+ * @return int 
+ */
+int
+ble_ll_whitelist_match(uint8_t *addr, uint8_t addr_type)
+{
+    int rc;
+#ifdef BLE_USES_HW_WHITELIST
+    rc = ble_hw_whitelist_match();
+#else
+    rc = ble_ll_is_on_whitelist(addr, addr_type);
+#endif
+    return rc;
+}
+
+/**
+ * Add a device to the whitelist 
+ * 
+ * @return int 
+ */
+int
+ble_ll_whitelist_add(uint8_t *addr, uint8_t addr_type)
+{
+    int rc;
+
+    /* Must be in proper state */
+    if (!ble_ll_whitelist_chg_allowed()) {
+        return BLE_ERR_CMD_DISALLOWED;
+    }
+
+    /* Check if we have any open entries */
+#ifdef BLE_USES_HW_WHITELIST
+    rc = ble_hw_whitelist_add(addr, addr_type);
+#else
+    int i;
+    struct ble_ll_whitelist_entry *wl;
+
+    rc = BLE_ERR_SUCCESS;
+    if (!ble_ll_is_on_whitelist(addr, addr_type)) {
+        wl = &g_ble_ll_whitelist[0];
+        for (i = 0; i < BLE_LL_CFG_WHITELIST_SIZE; ++i) {
+            if (wl->wl_valid == 0) {
+                memcpy(&wl->wl_dev_addr[0], addr, BLE_DEV_ADDR_LEN);
+                wl->wl_addr_type = addr_type;
+                wl->wl_valid = 1;
+                break;
+            }
+            ++wl;
+        }
+
+        if (i == BLE_LL_CFG_WHITELIST_SIZE) {
+            rc = BLE_ERR_MEM_CAPACITY;
+        }
+    }
+#endif
+
+    return rc;
+}
+
+/**
+ * Remove a device from the whitelist 
+ * 
+ * @param cmdbuf 
+ * 
+ * @return int 0: success, BLE error code otherwise
+ */
+int
+ble_ll_whitelist_rmv(uint8_t *addr, uint8_t addr_type)
+{
+    /* Must be in proper state */
+    if (!ble_ll_whitelist_chg_allowed()) {
+        return BLE_ERR_CMD_DISALLOWED;
+    }
+
+#ifdef BLE_USES_HW_WHITELIST
+    ble_hw_whitelist_rmv(addr, addr_type);
+#else
+    int position;
+
+    position = ble_ll_is_on_whitelist(addr, addr_type);
+    if (position) {
+        g_ble_ll_whitelist[position - 1].wl_valid = 0;
+    }
+#endif
+
+    return BLE_ERR_SUCCESS;
+}
+
+/* Enable whitelisting */
+void
+ble_ll_whitelist_enable(void)
+{
+#ifdef BLE_USES_HW_WHITELIST
+    ble_hw_whitelist_enable();
+#else
+    /* XXX: Is there anything to do here? */
+#endif
+}
+
+/* Disable whitelisting */
+void
+ble_ll_whitelist_disable(void)
+{
+#ifdef BLE_USES_HW_WHITELIST
+    ble_hw_whitelist_disable();
+#else
+    /* XXX: Is there anything to do here? */
+#endif
+}
+
+


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

Posted by we...@apache.org.
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);
     }