Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 43143c902 -> d6bbacbd9


first cut at Host Privacy


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/6e95f444
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/6e95f444
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/6e95f444

Branch: refs/heads/develop
Commit: 6e95f44444865cf1edf7c913ddacf26e5d4ab22d
Parents: 43143c9
Author: Paul Dietrich <paulfdietr...@yahoo.com>
Authored: Fri May 13 10:07:44 2016 -0700
Committer: Paul Dietrich <paulfdietr...@yahoo.com>
Committed: Thu Jun 2 12:51:42 2016 -0700

----------------------------------------------------------------------
 apps/bletiny/src/bletiny.h                  |   9 +-
 apps/bletiny/src/cmd.c                      |  49 +++-
 apps/bletiny/src/main.c                     |  73 +++++-
 net/nimble/host/include/host/ble_gap.h      |  17 +-
 net/nimble/host/include/host/ble_hs.h       |   7 +-
 net/nimble/host/include/host/ble_keycache.h |  75 ++++++
 net/nimble/host/include/host/host_hci.h     |  25 +-
 net/nimble/host/src/ble_gap.c               | 144 +++++++----
 net/nimble/host/src/ble_hci_util.c          |  19 +-
 net/nimble/host/src/ble_hci_util_priv.h     |   3 +-
 net/nimble/host/src/ble_hs.c                |   3 +-
 net/nimble/host/src/ble_hs_cfg.c            |   2 +
 net/nimble/host/src/ble_hs_priv.c           | 154 ++++++++++++
 net/nimble/host/src/ble_hs_priv.h           |  14 +-
 net/nimble/host/src/ble_hs_startup.c        |   4 +-
 net/nimble/host/src/ble_keycache.c          | 205 ++++++++++++++++
 net/nimble/host/src/ble_l2cap_sm.c          |  77 +++---
 net/nimble/host/src/host_hci_cmd.c          | 293 +++++++++++++++++++++--
 net/nimble/host/src/test/ble_gap_test.c     |   4 +-
 net/nimble/host/src/test/ble_hs_test_util.c |  12 +-
 net/nimble/host/src/test/ble_hs_test_util.h |   2 +-
 net/nimble/include/nimble/ble.h             |   6 +-
 net/nimble/include/nimble/hci_common.h      |  23 +-
 net/nimble/src/hci_common.c                 |   3 +-
 24 files changed, 1055 insertions(+), 168 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/apps/bletiny/src/bletiny.h
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/bletiny.h b/apps/bletiny/src/bletiny.h
index d3be8eb..f793550 100644
--- a/apps/bletiny/src/bletiny.h
+++ b/apps/bletiny/src/bletiny.h
@@ -35,6 +35,7 @@ struct ble_l2cap_sig_update_req;
 struct ble_l2cap_sig_update_params;
 union ble_store_value;
 union ble_store_key;
+struct ble_gap_adv_params;
 
 typedef int cmd_fn(int argc, char **argv);
 struct cmd_entry {
@@ -149,8 +150,9 @@ int bletiny_write_long(uint16_t conn_handle, uint16_t 
attr_handle,
                         void *value, uint16_t value_len);
 int bletiny_write_reliable(uint16_t conn_handle, struct ble_gatt_attr *attrs,
                             int num_attrs);
-int bletiny_adv_start(int disc, int conn, uint8_t *peer_addr, int addr_type,
-                       struct hci_adv_params *params);
+int bletiny_adv_start(int disc, int conn, 
+                     uint8_t *peer_addr, uint8_t peer_addr_type,
+                     struct ble_gap_adv_params *params);
 int bletiny_adv_stop(void);
 int bletiny_conn_initiate(int addr_type, uint8_t *peer_addr,
                            struct ble_gap_crt_params *params);
@@ -159,7 +161,7 @@ int bletiny_term_conn(uint16_t conn_handle);
 int bletiny_wl_set(struct ble_gap_white_entry *white_list,
                     int white_list_count);
 int bletiny_scan(uint32_t dur_ms, uint8_t disc_mode, uint8_t scan_type,
-                  uint8_t filter_policy);
+                  uint8_t filter_policy, uint8_t our_addr_mode);
 int bletiny_set_adv_data(struct ble_hs_adv_fields *adv_fields);
 int bletiny_update_conn(uint16_t conn_handle,
                          struct ble_gap_upd_params *params);
@@ -169,7 +171,6 @@ int bletiny_l2cap_update(uint16_t conn_handle,
 int bletiny_sec_start(uint16_t conn_handle);
 int bletiny_sec_restart(uint16_t conn_handle, uint8_t *ltk, uint16_t ediv,
                         uint64_t rand_val, int auth);
-
 #define BLETINY_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
 #define BLETINY_LOG(lvl, ...) \
     LOG_ ## lvl(&bletiny_log, BLETINY_LOG_MODULE, __VA_ARGS__)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/apps/bletiny/src/cmd.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/cmd.c b/apps/bletiny/src/cmd.c
index 535637f..f44c6dd 100644
--- a/apps/bletiny/src/cmd.c
+++ b/apps/bletiny/src/cmd.c
@@ -243,6 +243,8 @@ static struct kv_pair cmd_adv_disc_modes[] = {
 static struct kv_pair cmd_adv_addr_types[] = {
     { "public", BLE_ADDR_TYPE_PUBLIC },
     { "random", BLE_ADDR_TYPE_RANDOM },
+    { "rpa_pub", BLE_ADDR_TYPE_RPA_PUB_DEFAULT },
+    { "rpa_rnd", BLE_ADDR_TYPE_RPA_RND_DEFAULT },
     { NULL }
 };
 
@@ -256,17 +258,17 @@ static struct kv_pair cmd_adv_filt_types[] = {
 static int
 cmd_adv(int argc, char **argv)
 {
-    struct hci_adv_params params = {
+    struct ble_gap_adv_params params = {
         .adv_itvl_min = 0,
         .adv_itvl_max = 0,
         .adv_type = BLE_HCI_ADV_TYPE_ADV_IND,
         .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-        .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
         .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
         .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
     };
-    uint8_t peer_addr[6];
     uint8_t u8;
+    uint8_t peer_addr_type;
+    uint8_t peer_addr[8];
     int addr_type;
     int conn;
     int disc;
@@ -295,7 +297,7 @@ cmd_adv(int argc, char **argv)
     }
 
     if (conn == BLE_GAP_CONN_MODE_DIR) {
-        addr_type = parse_arg_kv("addr_type", cmd_adv_addr_types);
+        addr_type = parse_arg_kv("peer_addr_type", cmd_adv_addr_types);
         if (addr_type == -1) {
             return -1;
         }
@@ -305,10 +307,20 @@ cmd_adv(int argc, char **argv)
             return rc;
         }
     } else {
-        addr_type = 0;
+        addr_type = BLE_ADDR_TYPE_PUBLIC;
         memset(peer_addr, 0, sizeof peer_addr);
     }
 
+    peer_addr_type = addr_type;
+
+    addr_type = parse_arg_kv("own_addr_type", cmd_adv_addr_types);
+    if (addr_type == -1) {
+        return -1;
+    } else {
+        addr_type = BLE_ADDR_TYPE_PUBLIC;
+    }
+    params.own_addr_type = addr_type;
+
     u8 = parse_arg_long_bounds("chan_map", 0, 0xff, &rc);
     if (rc == 0) {
         params.adv_channel_map = u8;
@@ -323,7 +335,7 @@ cmd_adv(int argc, char **argv)
         }
     }
 
-    rc = bletiny_adv_start(disc, conn, peer_addr, addr_type, &params);
+    rc = bletiny_adv_start(disc, conn, peer_addr, peer_addr_type, &params);
     if (rc != 0) {
         console_printf("advertise fail: %d\n", rc);
         return rc;
@@ -363,7 +375,7 @@ cmd_conn(int argc, char **argv)
         return 0;
     }
 
-    addr_type = parse_arg_kv("addr_type", cmd_conn_addr_types);
+    addr_type = parse_arg_kv("peer_addr_type", cmd_conn_addr_types);
     if (addr_type == -1) {
         return -1;
     }
@@ -377,6 +389,11 @@ cmd_conn(int argc, char **argv)
         memset(peer_addr, 0, sizeof peer_addr);
     }
 
+    params.our_addr_type = parse_arg_kv("our_addr_type", cmd_conn_addr_types);
+    if (rc != 0) {
+        return rc;
+    }
+
     params.scan_itvl = parse_arg_uint16_dflt("scan_itvl", 0x0010, &rc);
     if (rc != 0) {
         return rc;
@@ -802,6 +819,14 @@ static struct kv_pair cmd_scan_filt_policies[] = {
     { NULL }
 };
 
+static struct kv_pair cmd_scan_addr_types[] = {
+    { "public",  BLE_ADDR_TYPE_PUBLIC },
+    { "random",  BLE_ADDR_TYPE_RANDOM },
+    { "rpa_pub", BLE_ADDR_TYPE_RPA_PUB_DEFAULT },
+    { "rpa_rnd", BLE_ADDR_TYPE_RPA_RND_DEFAULT },
+    { NULL }
+};
+
 static int
 cmd_scan(int argc, char **argv)
 {
@@ -810,6 +835,7 @@ cmd_scan(int argc, char **argv)
     int type;
     int filt;
     int rc;
+    int addr_mode;
 
     dur = parse_arg_uint16("dur", &rc);
     if (rc != 0) {
@@ -831,7 +857,12 @@ cmd_scan(int argc, char **argv)
         return EINVAL;
     }
 
-    rc = bletiny_scan(dur, disc, type, filt);
+    addr_mode = parse_arg_kv("addr_mode", cmd_scan_addr_types);
+    if (disc == -1) {
+        return EINVAL;
+    }
+
+    rc = bletiny_scan(dur, disc, type, filt, addr_mode);
     if (rc != 0) {
         console_printf("error scanning; rc=%d\n", rc);
         return rc;
@@ -1390,7 +1421,7 @@ cmd_set(int argc, char **argv)
          * needs to be removed.
          */
         memcpy(g_dev_addr, addr, 6);
-        memcpy(ble_hs_our_dev.public_addr, addr, 6);
+        ble_gap_init_identity_addr(g_dev_addr);
     } else if (rc != ENOENT) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index 2bd6b1f..837ddf2 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -42,6 +42,7 @@
 #include "host/ble_gap.h"
 #include "host/ble_gatt.h"
 #include "host/ble_store.h"
+#include "host/ble_keycache.h"
 #include "controller/ble_ll.h"
 
 /* XXX: An app should not include private headers from a library.  The bletiny
@@ -651,6 +652,31 @@ bletiny_dsc_add(uint16_t conn_handle, uint16_t 
chr_def_handle,
     return dsc;
 }
 
+static void
+bletiny_start_auto_advertise(void)
+{
+    struct ble_hs_adv_fields fields;
+    int rc;
+
+    if (BLETINY_AUTO_DEVICE_NAME[0] != '\0') {
+        memset(&fields, 0, sizeof fields);
+
+        fields.name = (uint8_t *)BLETINY_AUTO_DEVICE_NAME;
+        fields.name_len = strlen(BLETINY_AUTO_DEVICE_NAME);
+        fields.name_is_complete = 1;
+        rc = bletiny_set_adv_data(&fields);
+        if (rc != 0) {
+            return;
+        }
+
+        rc = bletiny_adv_start(BLE_GAP_DISC_MODE_GEN, BLE_GAP_CONN_MODE_UND,
+                               0, 0, NULL);
+        if (rc != 0) {
+            return;
+        }
+    }
+}
+
 static int
 bletiny_on_mtu(uint16_t conn_handle, struct ble_gatt_error *error,
                uint16_t mtu, void *arg)
@@ -842,7 +868,37 @@ bletiny_gap_event(int event, struct ble_gap_conn_ctxt 
*ctxt, void *arg)
         print_bytes(ctxt->notify.attr_data, ctxt->notify.attr_len);
         console_printf("\n");
         return 0;
-
+    case BLE_GAP_EVENT_LTK_REQUEST:
+    {
+        struct ble_gap_key_parms  kp;
+        console_printf("looking up ltk with ediv=0x%02x rand=0x%llx\n",
+                       ctxt->ltk_params->ediv, ctxt->ltk_params->rand_num);
+        if ((ble_keycache_find(ctxt->desc->peer_addr_type,
+                                    ctxt->desc->peer_addr, &kp) == 0) &&
+            (kp.ltk_valid) && (kp.ediv_rand_valid)) {
+                console_printf("ltk=");
+                bletiny_print_bytes(kp.ltk, sizeof(kp.ltk));
+                console_printf("\n");
+        } else {
+            console_printf("no matching ltk\n");
+        }
+        return 0;
+    }
+    case BLE_GAP_EVENT_KEY_EXCHANGE:
+        rc = 0;
+        console_printf("key exchange event; status=%d ", status);
+        bletiny_print_key_exchange_parms(ctxt->key_params);
+
+        if(ctxt->key_params->addr_valid)
+        {
+            rc = ble_keycache_add(ctxt->key_params->addr_type,
+                                    ctxt->key_params->addr,
+                                    ctxt->key_params);
+            if (rc != 0) {
+                console_printf("error persisting keys; status=%d\n", rc);
+            }
+        }
+        return rc;
     default:
         return 0;
     }
@@ -1057,12 +1113,13 @@ bletiny_adv_stop(void)
 }
 
 int
-bletiny_adv_start(int disc, int conn, uint8_t *peer_addr, int addr_type,
-                  struct hci_adv_params *params)
+bletiny_adv_start(int disc, int conn,
+                uint8_t *peer_addr, uint8_t peer_addr_type,
+                struct ble_gap_adv_params *params)
 {
     int rc;
 
-    rc = ble_gap_adv_start(disc, conn, peer_addr, addr_type, params,
+    rc = ble_gap_adv_start(disc, conn, peer_addr, peer_addr_type, params,
                            bletiny_gap_event, NULL);
     return rc;
 }
@@ -1107,11 +1164,11 @@ bletiny_wl_set(struct ble_gap_white_entry *white_list, 
int white_list_count)
 
 int
 bletiny_scan(uint32_t dur_ms, uint8_t disc_mode, uint8_t scan_type,
-              uint8_t filter_policy)
+              uint8_t filter_policy, uint8_t addr_mode)
 {
     int rc;
 
-    rc = ble_gap_disc(dur_ms, disc_mode, scan_type, filter_policy,
+    rc = ble_gap_disc(dur_ms, disc_mode, scan_type, filter_policy, addr_mode,
                       bletiny_on_scan, NULL);
     return rc;
 }
@@ -1327,6 +1384,10 @@ main(void)
     rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE);
     assert(rc == 0);
 
+    /* initialize the keycache to store private keys  */
+    rc = ble_keycache_init(4);
+    assert(rc == 0);
+
     rc = cmd_init();
     assert(rc == 0);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/include/host/ble_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gap.h 
b/net/nimble/host/include/host/ble_gap.h
index 57dcbde..7cca333 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -108,6 +108,15 @@ struct ble_gap_sec_state {
     unsigned bonded:1;
 };
 
+struct ble_gap_adv_params {
+    uint8_t adv_type;
+    uint8_t adv_channel_map;
+    uint8_t own_addr_type;
+    uint8_t adv_filter_policy;
+    uint16_t adv_itvl_min;
+    uint16_t adv_itvl_max;
+};
+
 struct ble_gap_conn_desc {
     struct ble_gap_sec_state sec_state;
     uint8_t peer_addr[6];
@@ -119,8 +128,9 @@ struct ble_gap_conn_desc {
 };
 
 struct ble_gap_crt_params {
-    uint16_t scan_itvl;
     uint16_t scan_window;
+    uint16_t scan_itvl;
+    uint8_t our_addr_type;
     uint16_t itvl_min;
     uint16_t itvl_max;
     uint16_t latency;
@@ -241,13 +251,15 @@ int ble_gap_find_conn(uint16_t handle, struct 
ble_gap_conn_desc *out_desc);
 
 int ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
                       uint8_t *peer_addr, uint8_t peer_addr_type,
-                      struct hci_adv_params *adv_params,
+                      const struct ble_gap_adv_params *adv_params,
                       ble_gap_event_fn *cb, void *cb_arg);
+
 int ble_gap_adv_stop(void);
 int ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields);
 int ble_gap_adv_rsp_set_fields(struct ble_hs_adv_fields *rsp_fields);
 int ble_gap_disc(uint32_t duration_ms, uint8_t discovery_mode,
                       uint8_t scan_type, uint8_t filter_policy,
+                      uint8_t addr_mode,
                       ble_gap_disc_fn *cb, void *cb_arg);
 int ble_gap_conn_initiate(int addr_type, uint8_t *addr,
                           struct ble_gap_crt_params *params,
@@ -262,4 +274,5 @@ int ble_gap_security_initiate(uint16_t conn_handle);
 int
 ble_gap_encryption_initiate(uint16_t conn_handle, uint8_t *ltk,
                             uint16_t ediv, uint64_t rand_val, int auth);
+void ble_gap_init_identity_addr(uint8_t *addr);
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h 
b/net/nimble/host/include/host/ble_hs.h
index 82266ce..a23332f 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -110,11 +110,16 @@ struct ble_hs_cfg {
     unsigned sm_keypress:1;
     uint8_t sm_our_key_dist;
     uint8_t sm_their_key_dist;
-
     /** Store settings. */
     ble_store_read_fn *store_read_cb;
     ble_store_write_fn *store_write_cb;
     ble_store_delete_fn *store_delete_cb;
+    /* privacy settings */
+    uint8_t privacy_mode;
+    #define BLE_HS_PRIVACY_MODE_NONE            (0)
+    #define BLE_HS_PRIVACY_MODE_RANDOM_STATIC   (1)
+    #define BLE_HS_PRIVACY_MODE_RESOLV_RAND     (2)
+    uint16_t privacy_resolvable_addr_timeout;
 };
 
 extern const struct ble_hs_cfg ble_hs_cfg_dflt;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/include/host/ble_keycache.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_keycache.h 
b/net/nimble/host/include/host/ble_keycache.h
new file mode 100644
index 0000000..c97aeac
--- /dev/null
+++ b/net/nimble/host/include/host/ble_keycache.h
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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_KEYCACHE_
+#define H_BLE_KEYCACHE_
+
+struct ble_gap_key_parms;
+
+/*
+ * This is a helper library to help the application store and access
+ * keys for devices.  The keys are passed from the stack as a single
+ * blob in ble_gap_key_parms.  When this is written to the cache, it
+ * will overwrite any previous data for that address,  So, if you
+ * want to preserved any information from a previous write for this
+ * address, you had better read the value out first and then
+ * preserve what you want.
+ *
+ * A note on address types.  This cache will store any address type.
+ * Its up to the application to filter the address and determine
+ * whether its worth storing in the keycache or not
+ *
+ * A note on multi-tasking.  This library is written to be access from a single
+ * task.  If you intend to use this from multiple tasks (e.g. a UI task to
+ * delete bonding data and the host task to add bondind data) its up to your
+ * application to provide mutual exclusion
+ */
+
+/**
+ * Adds an entry to the LTK keycache.
+ * Returns an error (negative) if the LTK key cache is full .
+ * Within the key params struct, addr must be valid as this is
+ * the lookup for key cache entries.
+ */
+int
+ble_keycache_add(uint8_t addr_type, uint8_t *key_addr, struct 
ble_gap_key_parms *pltk);
+
+/*
+ * reads values for the given addr from the keycache.  If no entry
+ * is found, a negative value is returned and pout_entry is undefined.
+ */
+int
+ble_keycache_find(uint8_t addr_type, uint8_t *key_addr, struct 
ble_gap_key_parms *pout_entry);
+
+/*
+ * Deletes an entry from the keycache for the give address.
+ * Returns 0 if the entry is successfully deleted.  NOTE: if there is
+ * no entry for the given address the function will return 0.  Returns
+ * negative on error
+ * @Param addr -- a 6 octet mac address of the device
+ */
+ int
+ ble_keycache_delete(uint8_t addr_type, uint8_t *key_addr);
+
+/* Initialize a key-cache.
+ */
+
+int
+ble_keycache_init(int max_entries);
+
+#endif /* H_BLE_KEYCACHE_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/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 cd2463c..f31fa8f 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -48,8 +48,6 @@ void host_hci_cmd_build_le_set_event_mask(uint64_t event_mask,
 void host_hci_cmd_build_le_read_buffer_size(uint8_t *dst, int dst_len);
 int host_hci_cmd_le_read_buffer_size(void);
 void host_hci_cmd_build_le_read_loc_supp_feat(uint8_t *dst, uint8_t dst_len);
-void host_hci_cmd_build_le_set_rand_addr(uint8_t *addr, uint8_t *dst,
-                                         int dst_len);
 void host_hci_cmd_build_le_set_adv_enable(uint8_t enable, uint8_t *dst,
                                           int dst_len);
 int host_hci_cmd_le_set_adv_enable(uint8_t enable);
@@ -98,6 +96,29 @@ uint16_t host_hci_handle_pb_bc_join(uint16_t handle, uint8_t 
pb, uint8_t bc);
 int host_hci_data_rx(struct os_mbuf *om);
 int host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om);
 
+int host_hci_cmd_add_device_to_resolving_list(
+                                    struct hci_add_dev_to_resolving_list *padd,
+                                    uint8_t *dst, int dst_len);
+int host_hci_cmd_remove_device_from_resolving_list(uint8_t addr_type,
+                                            uint8_t *addr, uint8_t *dst,
+                                            int dst_len);
+int host_hci_cmd_read_resolving_list_size(uint8_t *dst, int dst_len);
+int
+host_hci_cmd_clear_resolving_list(uint8_t *dst, int dst_len);
+int host_hci_cmd_read_peer_resolvable_address(uint8_t peer_identity_addr_type,
+                                          uint8_t *peer_identity_addr,
+                                          uint8_t *dst, int dst_len);
+int host_hci_cmd_read_local_resolvable_address(uint8_t 
local_identity_addr_type,
+                                        uint8_t *local_identity_addr,
+                                        uint8_t *dst, int dst_len);
+int host_hci_cmd_set_addr_resolution_enable(uint8_t enable,
+                                          uint8_t *dst, int dst_len);
+int host_hci_cmd_set_resolvable_private_address_timeout(uint16_t timeout,
+                                                            uint8_t *dst,
+                                                            int dst_len);
+
 void host_hci_timer_set(void);
 
+int host_hci_cmd_set_random_addr(uint8_t *addr, uint8_t *dst, int dst_len);
+
 #endif /* H_HOST_HCI_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_gap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c
index 0f7211a..dcaa493 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -25,6 +25,7 @@
 #include "nimble/nimble_opt.h"
 #include "host/host_hci.h"
 #include "ble_hs_priv.h"
+#include "host/ble_keycache.h"
 
 /**
  * GAP - Generic Access Profile.
@@ -85,12 +86,11 @@ static const struct ble_gap_crt_params ble_gap_params_dflt 
= {
     .max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN,
 };
 
-static const struct hci_adv_params ble_gap_adv_params_dflt = {
+static const struct ble_gap_adv_params ble_gap_adv_params_dflt = {
     .adv_itvl_min = 0,
     .adv_itvl_max = 0,
     .adv_type = BLE_HCI_ADV_TYPE_ADV_IND,
     .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-    .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
     .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
     .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
 };
@@ -198,18 +198,18 @@ ble_gap_log_conn(uint8_t addr_type, uint8_t *addr,
 
     BLE_HS_LOG(INFO, " scan_itvl=%d scan_window=%d itvl_min=%d itvl_max=%d "
                      "latency=%d supervision_timeout=%d min_ce_len=%d "
-                     "max_ce_len=%d",
+                     "max_ce_len=%d our_addr_type=%d",
                params->scan_itvl, params->scan_window, params->itvl_min,
                params->itvl_max, params->latency, params->supervision_timeout,
-               params->min_ce_len, params->max_ce_len);
+               params->min_ce_len, params->max_ce_len, params->our_addr_type);
 }
 
 static void
-ble_gap_log_disc(uint8_t scan_type, uint8_t filter_policy)
+ble_gap_log_disc(uint8_t scan_type, uint8_t filter_policy, uint8_t addr_mode)
 {
-    BLE_HS_LOG(INFO, "disc_mode=%d filter_policy=%d scan_type=%d",
+    BLE_HS_LOG(INFO, "disc_mode=%d filter_policy=%d scan_type=%d addr_node %d",
                ble_gap_master.disc.disc_mode,
-               filter_policy, scan_type);
+               filter_policy, scan_type, addr_mode);
 }
 
 static void
@@ -242,11 +242,16 @@ ble_gap_log_wl(struct ble_gap_white_entry *white_list,
 }
 
 static void
-ble_gap_log_adv(struct hci_adv_params *adv_params)
+ble_gap_log_adv(const struct ble_gap_adv_params *adv_params,
+                uint8_t *peer_addr, uint8_t peer_addr_type)
 {
     BLE_HS_LOG(INFO, "disc_mode=%d addr_type=%d addr=",
-               ble_gap_slave.disc_mode, adv_params->peer_addr_type);
-    BLE_HS_LOG_ADDR(INFO, adv_params->peer_addr);
+               ble_gap_slave.disc_mode, peer_addr_type);
+    if(peer_addr) {
+        BLE_HS_LOG_ADDR(INFO, peer_addr);
+    } else {
+        BLE_HS_LOG(INFO, "none");
+    }
     BLE_HS_LOG(INFO, " adv_type=%d adv_channel_map=%d own_addr_type=%d "
                      "adv_filter_policy=%d adv_itvl_min=%d adv_itvl_max=%d "
                      "adv_data_len=%d",
@@ -1268,22 +1273,47 @@ ble_gap_adv_data_tx(void)
 }
 
 static int
-ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
+ble_gap_adv_params_tx(const struct ble_gap_adv_params *adv_params, 
+                      uint8_t *peer_addr, uint8_t peer_addr_type)
 {
+    struct hci_adv_params hci_adv_params;
     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_PARAM_LEN];
     int rc;
+    uint8_t peer[6];
+
+    if(peer_addr) {
+        memcpy(peer, peer_addr, 6);
+    } else {
+        memset(peer, 0, 6);
+    }
+    
+    hci_adv_params.adv_channel_map = adv_params->adv_channel_map;
+    hci_adv_params.own_addr_type = adv_params->own_addr_type;
+    hci_adv_params.adv_filter_policy = adv_params->adv_filter_policy;
+    hci_adv_params.adv_itvl_min = adv_params->adv_itvl_min;
+    hci_adv_params.adv_itvl_max = adv_params->adv_itvl_max;
+
+    if (ble_gap_slave.conn_mode == BLE_GAP_CONN_MODE_DIR) {
+        hci_adv_params.peer_addr_type = peer_addr_type;
+        memcpy(hci_adv_params.peer_addr,peer,
+            sizeof(hci_adv_params.peer_addr));
+    }
+
+    BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; ");
+    ble_gap_log_adv(adv_params, peer, peer_addr_type);
+    BLE_HS_LOG(INFO, "\n");
 
     switch (ble_gap_slave.conn_mode) {
     case BLE_GAP_CONN_MODE_NON:
-        adv_params->adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
+        hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
         break;
 
     case BLE_GAP_CONN_MODE_DIR:
-        adv_params->adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
+        hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
         break;
 
     case BLE_GAP_CONN_MODE_UND:
-        adv_params->adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
+        hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
         break;
 
     default:
@@ -1291,7 +1321,7 @@ ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
         break;
     }
 
-    rc = host_hci_cmd_build_le_set_adv_params(adv_params, buf, sizeof buf);
+    rc = host_hci_cmd_build_le_set_adv_params(&hci_adv_params, buf, sizeof 
buf);
     if (rc != 0) {
         return rc;
     }
@@ -1322,32 +1352,20 @@ ble_gap_adv_params_tx(struct hci_adv_params *adv_params)
  *                                      (directed-connectable; 3.C.9.3.3).
  *                                  o BLE_GAP_CONN_MODE_UND
  *                                      (undirected-connectable; 3.C.9.3.4).
- * @param peer_addr             The address of the peer who is allowed to
- *                                  connect; only meaningful for directed
- *                                  connectable mode.  For other modes, specify
- *                                  NULL.
- * @param peer_addr_type        The type of address specified for the
- *                                  "peer_addr" parameter; only meaningful for
- *                                  directed connectable mode.  For other
- *                                  modes, specify 0.  For directed connectable
- *                                  mode, this should be one of the following
- *                                  constants:
- *                                      o BLE_ADDR_TYPE_PUBLIC
- *                                      o BLE_ADDR_TYPE_RANDOM
  *
  * @return                      0 on success; nonzero on failure.
  */
 int
 ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
                   uint8_t *peer_addr, uint8_t peer_addr_type,
-                  struct hci_adv_params *adv_params,
+                  const struct ble_gap_adv_params *adv_params,
                   ble_gap_event_fn *cb, void *cb_arg)
 {
 #if !NIMBLE_OPT(ADVERTISE)
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct hci_adv_params adv_params_copy;
+    struct ble_gap_adv_params gap_adv_params;
     int rc;
 
     ble_hs_lock();
@@ -1381,7 +1399,9 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t 
connectable_mode,
 
     case BLE_GAP_CONN_MODE_DIR:
         if (peer_addr_type != BLE_ADDR_TYPE_PUBLIC &&
-            peer_addr_type != BLE_ADDR_TYPE_RANDOM) {
+            peer_addr_type != BLE_ADDR_TYPE_RANDOM &&
+            peer_addr_type != BLE_ADDR_TYPE_RPA_PUB_DEFAULT &&
+            peer_addr_type != BLE_ADDR_TYPE_RPA_RND_DEFAULT) {
 
             rc = BLE_HS_EINVAL;
             goto done;
@@ -1393,32 +1413,36 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t 
connectable_mode,
         goto done;
     }
 
-    if (adv_params != NULL) {
-        adv_params_copy = *adv_params;
+    if(adv_params == NULL) {
+        gap_adv_params = ble_gap_adv_params_dflt;
     } else {
-        adv_params_copy = ble_gap_adv_params_dflt;
+        gap_adv_params = *adv_params;
     }
 
+    if(gap_adv_params.own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) {
+        rc = BLE_HS_EINVAL;
+        goto done;
+    }
+    
     BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; ");
-    ble_gap_log_adv(&adv_params_copy);
+    ble_gap_log_adv(&gap_adv_params, peer_addr, peer_addr_type);
     BLE_HS_LOG(INFO, "\n");
 
-    if (connectable_mode == BLE_GAP_CONN_MODE_DIR) {
-        adv_params_copy.peer_addr_type = peer_addr_type;
-        memcpy(adv_params_copy.peer_addr, peer_addr,
-               sizeof adv_params_copy.peer_addr);
-    }
-
     ble_gap_slave.cb = cb;
     ble_gap_slave.cb_arg = cb_arg;
     ble_gap_slave.conn_mode = connectable_mode;
     ble_gap_slave.disc_mode = discoverable_mode;
 
     ble_gap_adv_itvls(discoverable_mode, connectable_mode,
-                      &adv_params_copy.adv_itvl_min,
-                      &adv_params_copy.adv_itvl_max);
+                      &gap_adv_params.adv_itvl_min,
+                      &gap_adv_params.adv_itvl_max);
 
-    rc = ble_gap_adv_params_tx(&adv_params_copy);
+    /* set a new private address for random advertisements */
+    if(gap_adv_params.own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
+        ble_hs_priv_set_nrpa();
+    }
+
+    rc = ble_gap_adv_params_tx(&gap_adv_params, peer_addr, peer_addr_type);
     if (rc != 0) {
         goto done;
     }
@@ -1554,7 +1578,8 @@ ble_gap_disc_tx_enable(void)
 }
 
 static int
-ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy)
+ble_gap_disc_tx_params(uint8_t scan_type, uint8_t filter_policy,
+                        uint8_t addr_mode)
 {
     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
     int rc;
@@ -1563,7 +1588,7 @@ ble_gap_disc_tx_params(uint8_t scan_type, uint8_t 
filter_policy)
         scan_type,
         BLE_GAP_SCAN_FAST_INTERVAL_MIN,
         BLE_GAP_SCAN_FAST_WINDOW,
-        BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+        addr_mode,
         filter_policy,
         buf, sizeof buf);
     BLE_HS_DBG_ASSERT_EVAL(rc == 0);
@@ -1584,7 +1609,7 @@ ble_gap_disc_tx_params(uint8_t scan_type, uint8_t 
filter_policy)
  */
 int
 ble_gap_disc(uint32_t duration_ms, uint8_t discovery_mode,
-             uint8_t scan_type, uint8_t filter_policy,
+             uint8_t scan_type, uint8_t filter_policy, uint8_t addr_mode,
              ble_gap_disc_fn *cb, void *cb_arg)
 {
 #if !NIMBLE_OPT(ROLE_OBSERVER)
@@ -1616,6 +1641,14 @@ ble_gap_disc(uint32_t duration_ms, uint8_t 
discovery_mode,
         goto done;
     }
 
+    if((addr_mode != BLE_HCI_ADV_OWN_ADDR_PUBLIC) &&
+       (addr_mode != BLE_HCI_ADV_OWN_ADDR_RANDOM) &&
+       (addr_mode != BLE_HCI_ADV_OWN_ADDR_PRIV_PUB) &&
+       (addr_mode != BLE_HCI_ADV_OWN_ADDR_PRIV_RAND)) {
+          rc = BLE_HS_EINVAL;
+          goto done;
+      }
+
     if (filter_policy > BLE_HCI_SCAN_FILT_MAX) {
         rc = BLE_HS_EINVAL;
         goto done;
@@ -1630,10 +1663,15 @@ ble_gap_disc(uint32_t duration_ms, uint8_t 
discovery_mode,
     ble_gap_master.disc.cb_arg = cb_arg;
 
     BLE_HS_LOG(INFO, "GAP procedure initiated: discovery; ");
-    ble_gap_log_disc(scan_type, filter_policy);
+    ble_gap_log_disc(scan_type, filter_policy, addr_mode);
     BLE_HS_LOG(INFO, "\n");
 
-    rc = ble_gap_disc_tx_params(scan_type, filter_policy);
+        /* set a new random address for this mode */
+    if(addr_mode == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
+        ble_hs_priv_set_nrpa();
+    }
+
+    rc = ble_gap_disc_tx_params(scan_type, filter_policy, addr_mode);
     if (rc != 0) {
         goto done;
     }
@@ -1682,7 +1720,9 @@ ble_gap_conn_create_tx(int addr_type, uint8_t *addr,
         hcc.peer_addr_type = addr_type;
         memcpy(hcc.peer_addr, addr, sizeof hcc.peer_addr);
     }
-    hcc.own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
+    /* TODO error check our_addr_type */
+    hcc.own_addr_type = params->our_addr_type;
+
     hcc.conn_itvl_min = params->itvl_min;
     hcc.conn_itvl_max = params->itvl_max;
     hcc.conn_latency = params->latency;
@@ -1744,6 +1784,7 @@ ble_gap_conn_initiate(int addr_type, uint8_t *addr,
         rc = BLE_HS_EINVAL;
         goto done;
     }
+    
 
     if (params == NULL) {
         params = (void *)&ble_gap_params_dflt;
@@ -2183,6 +2224,11 @@ ble_gap_notify_event(uint16_t conn_handle, uint16_t 
attr_handle,
     ble_gap_call_event_cb(BLE_GAP_EVENT_NOTIFY, &ctxt, snap.cb, snap.cb_arg);
 }
 
+void ble_gap_init_identity_addr(uint8_t *addr)
+{
+    ble_hs_priv_init_identity(addr);
+}
+
 /*****************************************************************************
  * $init                                                                     *
  *****************************************************************************/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_hci_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.c 
b/net/nimble/host/src/ble_hci_util.c
index 2a661e9..b32826f 100644
--- a/net/nimble/host/src/ble_hci_util.c
+++ b/net/nimble/host/src/ble_hci_util.c
@@ -6,7 +6,7 @@
  * to you 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,
@@ -105,3 +105,20 @@ ble_hci_util_read_rssi(uint16_t conn_handle, int8_t 
*out_rssi)
 
     return 0;
 }
+
+int
+ble_hs_util_set_random_addr(uint8_t *addr)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RAND_ADDR_LEN];
+    int rc;
+
+    /* set the address in the controller */
+
+    rc = host_hci_cmd_set_random_addr(addr, buf, sizeof(buf));
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = ble_hci_cmd_tx_empty_ack(buf);
+    return rc;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_hci_util_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util_priv.h 
b/net/nimble/host/src/ble_hci_util_priv.h
index f73dd47..898296a 100644
--- a/net/nimble/host/src/ble_hci_util_priv.h
+++ b/net/nimble/host/src/ble_hci_util_priv.h
@@ -6,7 +6,7 @@
  * to you 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,
@@ -23,5 +23,6 @@
 int ble_hci_util_read_adv_tx_pwr(int8_t *out_pwr);
 int ble_hci_util_rand(void *dst, int len);
 int ble_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi);
+int ble_hs_util_set_random_addr(uint8_t *addr);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c
index bc83153..9e53ff0 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -6,7 +6,7 @@
  * to you 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,
@@ -37,7 +37,6 @@
 #endif
 
 static struct log_handler ble_hs_log_console_handler;
-struct ble_hs_dev ble_hs_our_dev;
 struct log ble_hs_log;
 
 #define HCI_CMD_BUF_SIZE    (260)       /* XXX: temporary, Fix later */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_hs_cfg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_cfg.c b/net/nimble/host/src/ble_hs_cfg.c
index 3cad0b6..f08b4aa 100644
--- a/net/nimble/host/src/ble_hs_cfg.c
+++ b/net/nimble/host/src/ble_hs_cfg.c
@@ -59,6 +59,8 @@ const struct ble_hs_cfg ble_hs_cfg_dflt = {
     .sm_keypress = 0,
     .sm_our_key_dist = 0,
     .sm_their_key_dist = 0,
+    /** privacy info */
+    .privacy_resolvable_addr_timeout = 300,
 };
 
 struct ble_hs_cfg ble_hs_cfg;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_hs_priv.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.c 
b/net/nimble/host/src/ble_hs_priv.c
new file mode 100644
index 0000000..574c459
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_priv.c
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <inttypes.h>
+#include <host/ble_keycache.h>
+#include <stdio.h>
+#include <string.h>
+#include "ble_hs_priv.h"
+
+int identity_initalized;
+static uint8_t identity_addr[6];
+static uint8_t identity_addr_type;
+static uint8_t irk[16];
+
+/* use this as a default IRK if there is none stored in the
+ * keycache. */
+const uint8_t default_irk[16] = {
+    0xef, 0x8d, 0xe2, 0x16, 0x4f, 0xec, 0x43, 0x0d,
+    0xbf, 0x5b, 0xdd, 0x34, 0xc0, 0x53, 0x1e, 0xb8,
+};
+
+static int
+ble_hs_generate_static_random_addr(uint8_t *addr) {
+    int rc;
+    rc = ble_hci_util_rand(addr, 6);
+    /* TODO -- set bits properly */
+    addr[5] |= 0xc0;
+    return rc;
+}
+
+int ble_hs_priv_set_nrpa(void) {
+    int rc;
+    uint8_t addr[6];
+    rc = ble_hci_util_rand(addr, 6);
+    assert(rc == 0);
+    addr[5] &= ~(0xc0);
+    return ble_hs_util_set_random_addr(addr);
+}
+
+int
+ble_hs_priv_get_identity_addr_type(uint8_t *addr_type) {
+    if(identity_initalized) {
+        return -1;
+    }
+    *addr_type = identity_addr_type;
+    return 0;
+}
+
+static int
+ble_hs_priv_set_addr_to(uint16_t timeout) {
+    int rc;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN];
+    rc = host_hci_cmd_set_resolvable_private_address_timeout(
+            timeout, buf, sizeof(buf));
+    return rc;
+}
+
+
+void
+ble_hs_priv_init_identity(uint8_t *addr) {
+
+    struct ble_gap_key_parms parms;
+    int rc;
+    uint8_t random_addr[6];
+
+    ble_hs_generate_static_random_addr(random_addr);
+    rc = ble_hs_util_set_random_addr(random_addr);
+    assert(rc == 0);
+
+    if(identity_initalized) {
+        return;
+    }
+
+    /* did we get passed an address at initialization */
+    if(addr) {
+        memcpy(identity_addr, addr, 6);
+        identity_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
+    } else if (0 )
+    {
+        /* if that fails, try to get a static random address from nvram */
+        /* TODO */
+    } else
+    {
+        identity_addr_type = BLE_HCI_ADV_OWN_ADDR_RANDOM;
+        memcpy(identity_addr, random_addr, 6);
+        /* TODO store it */
+    }
+
+    /* now try to get an IRK from internal nvram */
+    if(0) {
+        /* TODO */
+    } else {
+        /* if that fails, use the default IRK */
+        memcpy(irk, default_irk, 16);
+    }
+
+    identity_initalized = 1;
+
+    /* write a zero peer addr and addr type */
+    memset(parms.irk, 0, 16);
+    parms.irk_valid = 1;
+    memset(parms.addr, 0, 6);
+    parms.addr_valid = 1;
+    parms.addr_type = 0;
+    rc = ble_keycache_add(identity_addr_type, identity_addr, &parms);
+    assert(rc == 0);
+
+    /* set up the periodic change of our NRA */
+    rc = ble_hs_priv_set_addr_to(ble_hs_cfg.privacy_resolvable_addr_timeout);
+    assert(rc == 0);
+}
+
+uint8_t *
+bls_hs_priv_get_local_identity_addr(uint8_t *type) {
+
+    if(!identity_initalized) {
+        ble_hs_priv_init_identity(NULL);
+    }
+
+    if (type) {
+        *type = identity_addr_type;
+    }
+    return identity_addr;
+}
+
+void
+bls_hs_priv_copy_local_identity_addr(uint8_t *pdst, uint8_t* addr_type) {
+    uint8_t *addr = bls_hs_priv_get_local_identity_addr(addr_type);
+    memcpy(pdst,addr,6);
+}
+
+uint8_t *
+ble_hs_priv_get_local_irk(void)
+{
+    if(!identity_initalized) {
+        ble_hs_priv_init_identity(NULL);
+    }
+    return irk;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h 
b/net/nimble/host/src/ble_hs_priv.h
index a436028..956a355 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -6,7 +6,7 @@
  * to you 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,
@@ -56,13 +56,6 @@ STATS_SECT_START(ble_hs_stats)
 STATS_SECT_END
 extern STATS_SECT_DECL(ble_hs_stats) ble_hs_stats;
 
-struct ble_hs_dev {
-    uint8_t public_addr[6];
-    uint8_t random_addr[6];
-
-    unsigned has_random_addr:1;
-};
-
 struct ble_hci_ack {
     int bha_status;         /* A BLE_HS_E<...> error; NOT a naked HCI code. */
     uint8_t *bha_params;
@@ -110,7 +103,10 @@ int ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t 
evt_buf_len,
 int ble_hci_cmd_tx_empty_ack(void *cmd);
 void ble_hci_cmd_rx_ack(uint8_t *ack_ev);
 void ble_hci_cmd_init(void);
-
+int ble_hs_priv_set_nrpa(void);
+void ble_hs_priv_init_identity(uint8_t *addr);
+void bls_hs_priv_copy_local_identity_addr(uint8_t *pdst, uint8_t* addr_type);
+uint8_t *ble_hs_priv_get_local_irk(void);
 #if PHONY_HCI_ACKS
 typedef int ble_hci_cmd_phony_ack_fn(uint8_t *ack, int ack_buf_len);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_hs_startup.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_startup.c 
b/net/nimble/host/src/ble_hs_startup.c
index 31af1ea..f26eeba 100644
--- a/net/nimble/host/src/ble_hs_startup.c
+++ b/net/nimble/host/src/ble_hs_startup.c
@@ -6,7 +6,7 @@
  * to you 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,
@@ -164,7 +164,7 @@ ble_hs_startup_go(void)
     }
 
     /* XXX: Read BD_ADDR. */
-    memcpy(ble_hs_our_dev.public_addr, g_dev_addr, sizeof g_dev_addr);
+    ble_hs_priv_init_identity(g_dev_addr);
 
     return rc;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_keycache.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_keycache.c 
b/net/nimble/host/src/ble_keycache.c
new file mode 100644
index 0000000..e474785
--- /dev/null
+++ b/net/nimble/host/src/ble_keycache.c
@@ -0,0 +1,205 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <host/ble_gap.h>
+#include <host/ble_keycache.h>
+#include "ble_hs_priv.h"
+
+#define MAC_ADDR_LEN    6
+#define KEYDATA_SIZE_BYTES (sizeof(struct ble_gap_key_parms))
+
+/* FOR NOW we implement this as a simple RAM cache for testing.
+ * The config module is still being invented and I don't want
+ * to duplicate that work */
+
+struct keycache_entry {
+    uint8_t valid;
+    uint8_t key[MAC_ADDR_LEN + 1];
+    uint8_t data[KEYDATA_SIZE_BYTES];
+};
+
+/* a global key cache */
+static struct keycache_entry *p_keycache;
+static int keycache_entries;
+
+int
+ble_keycache_find(uint8_t addr_type, uint8_t *key_addr, struct 
ble_gap_key_parms *pout_entry)
+{
+    int i;
+    for(i = 0; i < keycache_entries; i++) {
+        if (p_keycache[i].valid) {
+            if ((memcmp(key_addr, p_keycache[i].key, MAC_ADDR_LEN) == 0) &&
+                ( p_keycache[i].key[6] == addr_type)) {
+                if (pout_entry) {
+                    memcpy(pout_entry, p_keycache[i].data, KEYDATA_SIZE_BYTES);
+                }
+                return 0;
+            }
+        }
+    }
+
+    return -1;
+}
+
+static int
+ble_keycache_write_irk_entry(struct ble_gap_key_parms *pkeys)
+{
+    struct hci_add_dev_to_resolving_list add;
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_ADD_TO_RESOLV_LIST_LEN];
+    int rc;
+
+    if(!pkeys->irk_valid) {
+        return -1;
+    }
+
+    /* build the message data */
+    memcpy(add.addr, pkeys->addr, 6);
+    memcpy(add.local_irk, ble_hs_priv_get_local_irk(), 16);
+    memcpy(add.peer_irk, pkeys->irk, 16);
+
+    rc = host_hci_cmd_add_device_to_resolving_list(&add, buf, sizeof(buf));
+
+    if (0 == rc) {
+        rc = ble_hci_cmd_tx(buf, NULL, 0, NULL);
+    }
+
+    return rc;
+}
+
+int
+ble_keycache_add(uint8_t addr_type, uint8_t *key_addr, struct 
ble_gap_key_parms *pkeys)
+{
+    int i;
+    int entry = -1;
+    /* loop through once to find the entry. Pick the first empty one
+     * or overwrite the old one */
+    for(i = 0; i < keycache_entries; i++) {
+        if ((!p_keycache[i].valid) && (entry == -1)) {
+            entry = i;
+        } else if ((memcmp(key_addr, p_keycache[i].key, MAC_ADDR_LEN) == 0) &&
+                        ( p_keycache[i].key[6] == addr_type)) {
+            entry = i;
+        }
+    }
+
+    if(entry >= 0 ) {
+        int rc;
+        memcpy(p_keycache[i].data, pkeys, KEYDATA_SIZE_BYTES);
+        memcpy(p_keycache[i].key, key_addr, MAC_ADDR_LEN);
+        p_keycache[i].key[6] = addr_type;
+        p_keycache[i].valid = 1;
+        /* plumb this down to the HW. If it fails, return error,
+         * and remove from this keycache .*/
+         rc = ble_keycache_write_irk_entry(pkeys);
+
+         if(rc) {
+             p_keycache[i].valid = 0;
+         }
+         return rc;
+    }
+    return -1;
+}
+
+static int
+ble_keycache_remove_irk_entry(uint8_t addr_type, uint8_t *addr)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_RMV_FROM_RESOLV_LIST_LEN];
+    int rc;
+
+    /* build the message data */
+    rc = host_hci_cmd_remove_device_from_resolving_list(addr_type, addr,
+                                                   buf, sizeof(buf));
+
+    if (0 == rc) {
+        rc = ble_hci_cmd_tx(buf, NULL, 0, NULL);
+    }
+
+    return rc;
+}
+
+ int
+ ble_keycache_delete(uint8_t addr_type, uint8_t *key_addr)
+{
+    int i;
+    for(i = 0; i < keycache_entries; i++) {
+        if (p_keycache[i].valid) {
+            if ((memcmp(key_addr, p_keycache[i].key, MAC_ADDR_LEN) == 0) &&
+                    ( p_keycache[i].key[6] == addr_type)) {
+                p_keycache[i].valid = 0;
+                ble_keycache_remove_irk_entry(addr_type, key_addr);
+            }
+        }
+    }
+    return 0;
+}
+
+static int
+ble_keycache_clear_irk_enties(void)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN ];
+    int rc;
+
+    /* build the message data */
+    rc = host_hci_cmd_clear_resolving_list(buf, sizeof(buf));
+
+    if (0 == rc) {
+        rc = ble_hci_cmd_tx(buf, NULL, 0, NULL);
+    }
+
+    return rc;
+}
+
+static int
+ble_keycache_set_status(int enable)
+{
+    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADDR_RESOL_ENA_LEN];
+    int rc;
+    rc = host_hci_cmd_set_addr_resolution_enable(enable, buf, sizeof(buf));
+
+    if (0 == rc) {
+        rc = ble_hci_cmd_tx(buf, NULL, 0, NULL);
+    }
+
+    return rc;
+}
+
+int
+ble_keycache_init(int max_entries)
+{
+    if (p_keycache) {
+        return -1;
+    }
+
+    /* TODO this should really be a flash based implementation */
+    p_keycache = calloc(max_entries, sizeof(struct keycache_entry));
+
+    if (NULL == p_keycache) {
+        return -2;
+    }
+    keycache_entries = max_entries;
+
+    /* clear entries in the hardware */
+    ble_keycache_set_status(0);
+    ble_keycache_clear_irk_enties();
+    ble_keycache_set_status(1);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/ble_l2cap_sm.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sm.c 
b/net/nimble/host/src/ble_l2cap_sm.c
index 1f04247..0e9a4dc 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -372,28 +372,6 @@ ble_l2cap_sm_gen_ltk(struct ble_l2cap_sm_proc *proc, 
uint8_t *ltk)
 }
 
 static int
-ble_l2cap_sm_gen_irk(struct ble_l2cap_sm_proc *proc, uint8_t *irk)
-{
-    int rc;
-
-#ifdef BLE_HS_DEBUG
-    if (ble_l2cap_sm_dbg_next_irk_set) {
-        ble_l2cap_sm_dbg_next_irk_set = 0;
-        memcpy(irk, ble_l2cap_sm_dbg_next_irk,
-               sizeof ble_l2cap_sm_dbg_next_irk);
-        return 0;
-    }
-#endif
-
-    rc = ble_hci_util_rand(irk, 16);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-static int
 ble_l2cap_sm_gen_csrk(struct ble_l2cap_sm_proc *proc, uint8_t *csrk)
 {
     int rc;
@@ -994,15 +972,13 @@ ble_l2cap_sm_confirm_prepare_args(struct 
ble_l2cap_sm_proc *proc,
     conn = ble_hs_conn_find(proc->conn_handle);
     if (conn != NULL) {
         if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) {
-            *iat = BLE_ADDR_TYPE_PUBLIC; /* XXX: Support random addresses. */
-            memcpy(ia, ble_hs_our_dev.public_addr, 6);
-
+            *iat = BLE_ADDR_TYPE_PUBLIC;
+            bls_hs_priv_copy_local_identity_addr(ra, rat);
             *rat = conn->bhc_addr_type;
             memcpy(ra, conn->bhc_addr, 6);
         } else {
-            *rat = BLE_ADDR_TYPE_PUBLIC; /* XXX: Support random addresses. */
-            memcpy(ra, ble_hs_our_dev.public_addr, 6);
-
+            *rat = BLE_ADDR_TYPE_PUBLIC;
+            bls_hs_priv_copy_local_identity_addr(ia, iat);
             *iat = conn->bhc_addr_type;
             memcpy(ia, conn->bhc_addr, 6);
         }
@@ -1336,11 +1312,11 @@ static int
 ble_l2cap_sm_key_exchange_go(struct ble_l2cap_sm_proc *proc,
                              uint8_t *sm_status)
 {
-    struct ble_l2cap_sm_iden_addr_info addr_info;
     struct ble_l2cap_sm_signing_info sign_info;
     struct ble_l2cap_sm_master_iden master_iden;
     struct ble_l2cap_sm_iden_info iden_info;
     struct ble_l2cap_sm_enc_info enc_info;
+    struct ble_l2cap_sm_iden_addr_info iden_addr_info;
     uint8_t our_key_dist;
     int rc;
 
@@ -1385,32 +1361,33 @@ ble_l2cap_sm_key_exchange_go(struct ble_l2cap_sm_proc 
*proc,
     }
 
     if (our_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_ID) {
-        /* Send identity information. */
-        rc = ble_l2cap_sm_gen_irk(proc, iden_info.irk_le);
-        if (rc != 0) {
-            return rc;
-        }
+        /* send IRK and BD ADDR */
+        uint8_t *irk = ble_hs_priv_get_local_irk();
+
+        memcpy(iden_info.irk_le, irk, 16);
+
         rc = ble_l2cap_sm_iden_info_tx(proc->conn_handle, &iden_info);
         if (rc != 0) {
-            return rc;
+            *sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+          return rc;
         }
-        proc->our_keys.irk_valid = 1;
-        memcpy(proc->our_keys.irk, iden_info.irk_le, 16);
 
-        /* Send identity address information. */
-        if (ble_hs_our_dev.has_random_addr) {
-            addr_info.addr_type = BLE_ADDR_TYPE_RANDOM;
-            memcpy(addr_info.bd_addr_le, ble_hs_our_dev.random_addr, 6);
-        } else {
-            addr_info.addr_type = BLE_ADDR_TYPE_PUBLIC;
-            memcpy(addr_info.bd_addr_le, ble_hs_our_dev.public_addr, 6);
-        }
-        rc = ble_l2cap_sm_iden_addr_tx(proc->conn_handle, &addr_info);
+        bls_hs_priv_copy_local_identity_addr(iden_addr_info.bd_addr_le,
+                                            &iden_addr_info.addr_type);
+        rc = ble_l2cap_sm_iden_addr_tx(proc->conn_handle, &iden_addr_info);
         if (rc != 0) {
-            return rc;
+            *sm_status = BLE_L2CAP_SM_ERR_UNSPECIFIED;
+          return rc;
         }
-        proc->our_keys.addr_type = addr_info.addr_type;
-        memcpy(proc->our_keys.addr, addr_info.bd_addr_le, 6);
+
+        /* copy data to pass to application */
+        proc->our_keys.is_ours = 1;
+        proc->our_keys.irk_valid = 1;
+        proc->our_keys.addr_valid = 1;
+        memcpy(proc->our_keys.irk, irk,16);
+        proc->our_keys.addr_type = iden_addr_info.addr_type;
+        memcpy(proc->our_keys.addr, iden_addr_info.bd_addr_le, 6);
+        memcpy(proc->our_keys.ltk, enc_info.ltk_le, 16);
     }
 
     if (our_key_dist & BLE_L2CAP_SM_PAIR_KEY_DIST_SIGN) {
@@ -1427,10 +1404,10 @@ ble_l2cap_sm_key_exchange_go(struct ble_l2cap_sm_proc 
*proc,
         memcpy(proc->our_keys.csrk, sign_info.sig_key_le, 16);
     }
 
+    /* XXX: Send remainining key information. */
     return 0;
 }
 
-
 static int
 ble_l2cap_sm_rx_key_exchange(uint16_t conn_handle, uint8_t op,
                                struct os_mbuf **om)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/host_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci_cmd.c 
b/net/nimble/host/src/host_hci_cmd.c
index e78e2dd..837e6f4 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -422,22 +422,6 @@ host_hci_cmd_build_le_read_loc_supp_feat(uint8_t *dst, 
uint8_t dst_len)
                        0, dst);
 }
 
-/**
- * OGF=LE, OCF=0x0005
- */
-void
-host_hci_cmd_build_le_set_rand_addr(uint8_t *addr, uint8_t *dst, int dst_len)
-{
-    BLE_HS_DBG_ASSERT(dst_len >=
-        BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_SET_RAND_ADDR_LEN);
-
-    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RAND_ADDR,
-                       BLE_HCI_LE_SET_RAND_ADDR_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    memcpy(dst, addr, 6);
-}
-
 static void
 host_hci_cmd_body_le_set_adv_enable(uint8_t enable, uint8_t *dst)
 {
@@ -986,3 +970,280 @@ host_hci_cmd_build_read_rssi(uint16_t handle, uint8_t 
*dst, int dst_len)
 
     host_hci_cmd_body_read_rssi(handle, dst);
 }
+
+static int
+host_hci_cmd_body_add_device_to_resolving_list(uint8_t addr_type,
+                                               uint8_t *addr,
+                                               uint8_t *peer_irk,
+                                               uint8_t *local_irk,
+                                               uint8_t *dst)
+{
+    if (addr_type > BLE_ADDR_TYPE_RANDOM) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    dst[0] = addr_type;
+    memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);
+    memcpy(dst + 1 + 6, peer_irk , 16);
+    memcpy(dst + 1 + 6 + 16, peer_irk , 16);
+    /* 16 + 16 + 6 + 1 == 39 */
+    return 0;
+}
+
+int
+host_hci_cmd_add_device_to_resolving_list(
+                                struct hci_add_dev_to_resolving_list *padd,
+                                uint8_t *dst,
+                                int dst_len)
+{
+    int rc;
+
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_ADD_TO_RESOLV_LIST_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ADD_RESOLV_LIST,
+                       BLE_HCI_ADD_TO_RESOLV_LIST_LEN, dst);
+
+    rc = host_hci_cmd_body_add_device_to_resolving_list(padd->addr_type,
+                                                padd->addr,
+                                                padd->peer_irk,
+                                                padd->local_irk,
+                                                dst + BLE_HCI_CMD_HDR_LEN);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+static int
+host_hci_cmd_body_remove_device_from_resolving_list(uint8_t addr_type,
+                                                   uint8_t *addr,
+                                                   uint8_t *dst)
+{
+    if (addr_type > BLE_ADDR_TYPE_RANDOM) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    dst[0] = addr_type;
+    memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);
+    return 0;
+}
+
+
+int
+host_hci_cmd_remove_device_from_resolving_list(uint8_t addr_type,
+                                              uint8_t *addr,
+                                              uint8_t *dst,
+                                              int dst_len)
+{
+    int rc;
+
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_RMV_FROM_RESOLV_LIST_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RMV_RESOLV_LIST,
+                       BLE_HCI_RMV_FROM_RESOLV_LIST_LEN, dst);
+
+    rc = host_hci_cmd_body_remove_device_from_resolving_list(addr_type, addr,
+                                                dst + BLE_HCI_CMD_HDR_LEN);
+    if (rc != 0) {
+        return rc;
+    }
+    return 0;
+}
+
+int
+host_hci_cmd_clear_resolving_list(uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CMD_HDR_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CLR_RESOLV_LIST,
+                       0, dst);
+
+    return 0;
+}
+
+int
+host_hci_cmd_read_resolving_list_size(uint8_t *dst, int dst_len)
+{
+    BLE_HS_DBG_ASSERT(dst_len >= BLE_HCI_CMD_HDR_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_RESOLV_LIST_SIZE,
+                       0, dst);
+
+    return 0;
+}
+
+static int
+host_hci_cmd_body_read_peer_resolvable_address (uint8_t 
peer_identity_addr_type,
+                                                uint8_t *peer_identity_addr,
+                                                uint8_t *dst)
+{
+    if (peer_identity_addr_type > BLE_ADDR_TYPE_RANDOM) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    dst[0] = peer_identity_addr_type;
+    memcpy(dst + 1, peer_identity_addr, BLE_DEV_ADDR_LEN);
+    return 0;
+}
+
+int
+host_hci_cmd_read_peer_resolvable_address(uint8_t peer_identity_addr_type,
+                                          uint8_t *peer_identity_addr,
+                                          uint8_t *dst,
+                                          int dst_len)
+{
+    int rc;
+
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_RD_PEER_RESOLV_ADDR_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_PEER_RESOLV_ADDR,
+                       BLE_HCI_RD_PEER_RESOLV_ADDR_LEN, dst);
+
+    rc = 
host_hci_cmd_body_read_peer_resolvable_address(peer_identity_addr_type,
+                                                peer_identity_addr,
+                                                dst + BLE_HCI_CMD_HDR_LEN);
+    if (rc != 0) {
+        return rc;
+    }
+    return 0;
+}
+
+static int
+host_hci_cmd_body_read_local_resolvable_address(uint8_t 
local_identity_addr_type,
+                                                uint8_t *local_identity_addr,
+                                                uint8_t *dst)
+{
+    if (local_identity_addr_type > BLE_ADDR_TYPE_RANDOM) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    dst[0] = local_identity_addr_type;
+    memcpy(dst + 1, local_identity_addr, BLE_DEV_ADDR_LEN);
+    return 0;
+}
+
+int
+host_hci_cmd_read_local_resolvable_address(uint8_t local_identity_addr_type,
+                                          uint8_t *local_identity_addr,
+                                          uint8_t *dst,
+                                          int dst_len)
+{
+    int rc;
+
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_RD_LOC_RESOLV_ADDR_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_LOCAL_RESOLV_ADDR,
+                       BLE_HCI_RD_LOC_RESOLV_ADDR_LEN, dst);
+
+    rc = host_hci_cmd_body_read_local_resolvable_address
+                                               (local_identity_addr_type,
+                                                local_identity_addr,
+                                                dst + BLE_HCI_CMD_HDR_LEN);
+    if (rc != 0) {
+        return rc;
+    }
+    return 0;
+}
+
+static int
+host_hci_cmd_body_set_addr_resolution_enable(uint8_t enable,
+                                            uint8_t *dst)
+{
+    if (enable > 1) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    dst[0] = enable;
+    return 0;
+}
+
+int
+host_hci_cmd_set_addr_resolution_enable(uint8_t enable,
+                                          uint8_t *dst,
+                                          int dst_len)
+{
+    int rc;
+
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADDR_RESOL_ENA_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADDR_RES_EN,
+                       BLE_HCI_SET_ADDR_RESOL_ENA_LEN, dst);
+
+    rc = host_hci_cmd_body_set_addr_resolution_enable(enable,
+                                                    dst + BLE_HCI_CMD_HDR_LEN);
+    if (rc != 0) {
+        return rc;
+    }
+    return 0;
+}
+
+static int
+host_hci_cmd_body_set_resolvable_private_address_timeout(uint16_t timeout,
+                                                        uint8_t *dst)
+{
+    if ((timeout == 0) || (timeout > 0xA1B8)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    htole16(dst, timeout);
+    return 0;
+}
+
+int
+host_hci_cmd_set_resolvable_private_address_timeout(uint16_t timeout,
+                                                      uint8_t *dst,
+                                                      int dst_len)
+{
+    int rc;
+
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RESOLV_PRIV_ADDR,
+                       BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN, dst);
+
+    rc = host_hci_cmd_body_set_resolvable_private_address_timeout(timeout,
+                                                    dst + BLE_HCI_CMD_HDR_LEN);
+    if (rc != 0) {
+        return rc;
+    }
+    return 0;
+}
+
+static int
+host_hci_cmd_body_set_random_addr(struct hci_rand_addr *paddr,
+                                uint8_t *dst)
+{
+    memcpy(dst, paddr->addr, BLE_DEV_ADDR_LEN);
+    return 0;
+}
+
+int
+host_hci_cmd_set_random_addr(uint8_t *addr,
+                              uint8_t *dst,
+                              int dst_len)
+{
+    struct hci_rand_addr r_addr;
+    int rc;
+
+    memcpy(r_addr.addr, addr, sizeof(r_addr.addr));
+
+    BLE_HS_DBG_ASSERT(
+        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RAND_ADDR_LEN);
+
+    host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RAND_ADDR,
+                       BLE_HCI_SET_RAND_ADDR_LEN, dst);
+
+    rc = host_hci_cmd_body_set_random_addr(&r_addr,
+                                                dst + BLE_HCI_CMD_HDR_LEN);
+    if (rc != 0) {
+        return rc;
+    }
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/test/ble_gap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gap_test.c 
b/net/nimble/host/src/test/ble_gap_test.c
index cf9c4a3..620c067 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -561,7 +561,7 @@ TEST_CASE(ble_gap_test_case_conn_disc_bad_args)
 
     /*** Invalid discovery mode. */
     rc = ble_gap_disc(0, BLE_GAP_DISC_MODE_NON, BLE_HCI_SCAN_TYPE_ACTIVE,
-                      BLE_HCI_SCAN_FILT_NO_WL, ble_gap_test_util_disc_cb,
+                      BLE_HCI_SCAN_FILT_NO_WL, BLE_ADDR_TYPE_PUBLIC, 
ble_gap_test_util_disc_cb,
                       NULL);
     TEST_ASSERT(rc == BLE_HS_EINVAL);
 
@@ -569,7 +569,7 @@ TEST_CASE(ble_gap_test_case_conn_disc_bad_args)
     rc = ble_hs_test_util_conn_initiate(BLE_GAP_ADDR_TYPE_WL, NULL, NULL,
                                         ble_gap_test_util_connect_cb, NULL, 0);
     rc = ble_gap_disc(0, BLE_GAP_DISC_MODE_GEN, BLE_HCI_SCAN_TYPE_ACTIVE,
-                      BLE_HCI_SCAN_FILT_NO_WL, ble_gap_test_util_disc_cb,
+                      BLE_HCI_SCAN_FILT_NO_WL, BLE_ADDR_TYPE_PUBLIC, 
ble_gap_test_util_disc_cb,
                       NULL);
     TEST_ASSERT(rc == BLE_HS_EALREADY);
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/test/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.c 
b/net/nimble/host/src/test/ble_hs_test_util.c
index fb3bf3b..3aa6fcf 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -415,7 +415,8 @@ ble_hs_test_util_disc(uint32_t duration_ms, uint8_t 
discovery_mode,
         { 0 }
     }));
 
-    rc = ble_gap_disc(duration_ms, discovery_mode, scan_type, filter_policy,
+    rc = ble_gap_disc(duration_ms, discovery_mode, scan_type, filter_policy, 
+                      BLE_ADDR_TYPE_PUBLIC,
                       cb, cb_arg);
     return rc;
 }
@@ -424,7 +425,6 @@ int
 ble_hs_test_util_adv_start(uint8_t discoverable_mode,
                            uint8_t connectable_mode,
                            uint8_t *peer_addr, uint8_t peer_addr_type,
-                           struct hci_adv_params *adv_params,
                            ble_gap_event_fn *cb, void *cb_arg,
                            int fail_idx, uint8_t fail_status)
 {
@@ -471,8 +471,10 @@ ble_hs_test_util_adv_start(uint8_t discoverable_mode,
     memset(acks + i, 0, sizeof acks[i]);
 
     ble_hs_test_util_set_ack_seq(acks);
-    rc = ble_gap_adv_start(discoverable_mode, connectable_mode, peer_addr,
-                           peer_addr_type, adv_params, cb, cb_arg);
+    
+    rc = ble_gap_adv_start(discoverable_mode, connectable_mode, 
+                        peer_addr, peer_addr_type,
+                        adv_params, cb, cb_arg);
 
     return rc;
 }
@@ -755,7 +757,7 @@ ble_hs_test_util_tx_all(void)
 void
 ble_hs_test_util_set_public_addr(uint8_t *addr)
 {
-    memcpy(ble_hs_our_dev.public_addr, addr, 6);
+    ble_hs_priv_init_identity(addr);
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/host/src/test/ble_hs_test_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.h 
b/net/nimble/host/src/test/ble_hs_test_util.h
index 60b4819..d53a7ea 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.h
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -70,7 +70,7 @@ int ble_hs_test_util_disc(uint32_t duration_ms, uint8_t 
discovery_mode,
 int ble_hs_test_util_adv_start(uint8_t discoverable_mode,
                                uint8_t connectable_mode,
                                uint8_t *peer_addr, uint8_t peer_addr_type,
-                               struct hci_adv_params *adv_params,
+                               struct ble_gap_adv_params *adv_params,
                                ble_gap_event_fn *cb, void *cb_arg,
                                int fail_idx, uint8_t fail_status);
 int ble_hs_test_util_adv_stop(uint8_t hci_status);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index c58a095..27ad284 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -220,7 +220,9 @@ enum ble_error_codes
 };
 
 /* Address types */
-#define BLE_ADDR_TYPE_PUBLIC    (0)
-#define BLE_ADDR_TYPE_RANDOM    (1)
+#define BLE_ADDR_TYPE_PUBLIC            (0)
+#define BLE_ADDR_TYPE_RANDOM            (1)
+#define BLE_ADDR_TYPE_RPA_PUB_DEFAULT   (2)
+#define BLE_ADDR_TYPE_RPA_RND_DEFAULT   (3)
 
 #endif /* H_BLE_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/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 2459d8a..1007477 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -148,8 +148,8 @@
 /* --- LE read local supported features (OCF 0x0003) --- */
 #define BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN     (8)
 
-/* --- LE set random address (OCF 0x0005) --- */
-#define BLE_HCI_LE_SET_RAND_ADDR_LEN           (6)
+/* --- LE set random address (OCF 0x0005) */
+#define BLE_HCI_SET_RAND_ADDR_LEN           (6)
 
 /* --- LE set advertising parameters (OCF 0x0006) */
 #define BLE_HCI_SET_ADV_PARAM_LEN           (15)
@@ -355,6 +355,12 @@
 /* --- LE read peer resolvable address (OCF 0x002C) */
 #define BLE_HCI_RD_LOC_RESOLV_ADDR_LEN      (7)
 
+/* --- LE set address resolution enable (OCF 0x002D) */
+#define BLE_HCI_SET_ADDR_RESOL_ENA_LEN      (1)
+
+/* --- LE set resolvable private address timeout (OCF 0x002E) */
+#define BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN (2)
+
 /* --- LE read maximum data length (OCF 0x002F) */
 #define BLE_HCI_RD_MAX_DATALEN_RSPLEN       (8)
 
@@ -543,6 +549,12 @@ struct hci_loc_ver_info
    uint8_t lmp_pal_subversion;
 };
 
+/* set random address command (ocf = 0x0005) */
+struct hci_rand_addr
+{
+    uint8_t addr[6];
+};
+
 /* set advertising parameters command (ocf = 0x0006) */
 struct hci_adv_params
 {
@@ -706,6 +718,13 @@ struct hci_data_hdr
 #define BLE_HCI_PB_FIRST_FLUSH              2
 #define BLE_HCI_PB_FULL                     3
 
+struct hci_add_dev_to_resolving_list {
+    uint8_t addr_type;
+    uint8_t addr[6];
+    uint8_t local_irk[16];
+    uint8_t peer_irk[16];
+};
+
 /* External data structures */
 extern const uint8_t g_ble_hci_le_cmd_len[BLE_HCI_NUM_LE_CMDS];
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6e95f444/net/nimble/src/hci_common.c
----------------------------------------------------------------------
diff --git a/net/nimble/src/hci_common.c b/net/nimble/src/hci_common.c
index 93998b3..70c34f4 100644
--- a/net/nimble/src/hci_common.c
+++ b/net/nimble/src/hci_common.c
@@ -32,7 +32,7 @@ const uint8_t g_ble_hci_le_cmd_len[BLE_HCI_NUM_LE_CMDS] =
     BLE_HCI_RD_BUF_SIZE_LEN,            /* 0x0002: read buffer size */
     0,                                  /* 0x0003: read local supp features */
     0,                                  /* 0x0004: not defined */
-    BLE_DEV_ADDR_LEN,                   /* 0x0005: set random address */
+    BLE_HCI_SET_RAND_ADDR_LEN,          /* 0x0005: set random address */
     BLE_HCI_SET_ADV_PARAM_LEN,          /* 0x0006: set advertising parameters 
*/
     0,                                  /* 0x0007: read adv chan tx power */
     BLE_HCI_SET_ADV_DATA_LEN,           /* 0x0008: set advertising data */
@@ -76,4 +76,3 @@ const uint8_t g_ble_hci_le_cmd_len[BLE_HCI_NUM_LE_CMDS] =
     sizeof(uint16_t),                   /* 0x002E: Set resolv priv addr tmo */
     0,                                  /* 0x002F: Read max data length */
 };
-

Reply via email to