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);
}