second 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/34e4509a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/34e4509a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/34e4509a

Branch: refs/heads/develop
Commit: 34e4509af1f497c6b85cf16f1f43755a998f8e4b
Parents: a8c1718
Author: Paul Dietrich <paulfdietr...@yahoo.com>
Authored: Wed May 18 14:25:17 2016 -0700
Committer: Paul Dietrich <paulfdietr...@yahoo.com>
Committed: Thu Jun 2 14:12:05 2016 -0700

----------------------------------------------------------------------
 apps/bletiny/pkg.yml                        |   2 +-
 apps/bletiny/src/bletiny.h                  |   2 +
 apps/bletiny/src/cmd.c                      | 306 ++++++++++++++++++++---
 apps/bletiny/src/main.c                     |  92 ++-----
 apps/bletiny/src/parse.c                    |  24 +-
 net/nimble/controller/src/ble_ll_hci.c      |   4 +-
 net/nimble/controller/src/ble_ll_rand.c     |   2 +-
 net/nimble/host/include/host/ble_gap.h      |   7 +
 net/nimble/host/include/host/ble_keycache.h |  75 ------
 net/nimble/host/include/host/ble_store.h    |   7 +
 net/nimble/host/src/ble_gap.c               |  61 +++--
 net/nimble/host/src/ble_hs_priv.c           | 161 +++++++++---
 net/nimble/host/src/ble_hs_priv.h           |   5 +-
 net/nimble/host/src/ble_hs_startup.c        |   5 +-
 net/nimble/host/src/ble_keycache.c          | 205 ---------------
 net/nimble/host/src/ble_l2cap_sm.c          |  11 +-
 net/nimble/host/src/ble_store.c             |  72 ++++++
 net/nimble/host/src/host_hci.c              |  30 ++-
 net/nimble/host/src/host_hci_cmd.c          |   4 +-
 net/nimble/host/src/test/ble_hs_test_util.c |  20 +-
 net/nimble/include/nimble/hci_common.h      |   2 +
 21 files changed, 631 insertions(+), 466 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bletiny/pkg.yml b/apps/bletiny/pkg.yml
index 614f76f..90e2286 100644
--- a/apps/bletiny/pkg.yml
+++ b/apps/bletiny/pkg.yml
@@ -33,4 +33,4 @@ pkg.deps:
 pkg.cflags:
     # Reduce the log level from DEBUG to INFO.  This is necessary to fit
     # bletiny on the nRF51dk.
-    - "-DLOG_LEVEL=1"
+    - "-DLOG_LEVEL=0"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/src/bletiny.h
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/bletiny.h b/apps/bletiny/src/bletiny.h
index f793550..0e3cae6 100644
--- a/apps/bletiny/src/bletiny.h
+++ b/apps/bletiny/src/bletiny.h
@@ -96,6 +96,7 @@ extern struct log bletiny_log;
 
 void print_addr(void *addr);
 void print_uuid(void *uuid128);
+void print_bytes(uint8_t *bytes, int len);
 const struct cmd_entry *parse_cmd_find(const struct cmd_entry *cmds,
                                        char *name);
 struct kv_pair *parse_kv_find(struct kv_pair *kvs, char *name);
@@ -111,6 +112,7 @@ uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, 
int *out_status);
 uint32_t parse_arg_uint32(char *name, int *out_status);
 uint64_t parse_arg_uint64(char *name, int *out_status);
 int parse_arg_kv(char *name, struct kv_pair *kvs);
+int parse_arg_kv_default(char *name, struct kv_pair *kvs, int def_val);
 int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len);
 int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len);
 int parse_arg_mac(char *name, uint8_t *dst);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/src/cmd.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/cmd.c b/apps/bletiny/src/cmd.c
index f44c6dd..e0a361b 100644
--- a/apps/bletiny/src/cmd.c
+++ b/apps/bletiny/src/cmd.c
@@ -285,19 +285,20 @@ cmd_adv(int argc, char **argv)
     }
 
     conn = parse_arg_kv("conn", cmd_adv_conn_modes);
-    if (conn == -1) {
+    if (conn <  0) {
         console_printf("invalid 'conn' parameter\n");
         return -1;
     }
 
     disc = parse_arg_kv("disc", cmd_adv_disc_modes);
-    if (disc == -1) {
+    if (conn <  0) {
         console_printf("missing 'disc' parameter\n");
         return -1;
     }
 
     if (conn == BLE_GAP_CONN_MODE_DIR) {
-        addr_type = parse_arg_kv("peer_addr_type", cmd_adv_addr_types);
+        addr_type = parse_arg_kv_default
+                ("peer_addr_type", cmd_adv_addr_types, BLE_ADDR_TYPE_PUBLIC);
         if (addr_type == -1) {
             return -1;
         }
@@ -313,13 +314,13 @@ cmd_adv(int argc, char **argv)
 
     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;
+    rc = parse_arg_kv_default
+                ("own_addr_type", cmd_adv_addr_types, BLE_ADDR_TYPE_PUBLIC);
+    if (rc == -1) {
+        return rc;
     }
-    params.own_addr_type = addr_type;
+
+    params.own_addr_type = rc;
 
     u8 = parse_arg_long_bounds("chan_map", 0, 0xff, &rc);
     if (rc == 0) {
@@ -348,7 +349,7 @@ cmd_adv(int argc, char **argv)
  * $connect                                                                  *
  *****************************************************************************/
 
-static struct kv_pair cmd_conn_addr_types[] = {
+static struct kv_pair cmd_conn_peer_addr_types[] = {
     { "public",         BLE_HCI_CONN_PEER_ADDR_PUBLIC },
     { "random",         BLE_HCI_CONN_PEER_ADDR_RANDOM },
     { "public_ident",   BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT },
@@ -357,6 +358,14 @@ static struct kv_pair cmd_conn_addr_types[] = {
     { NULL }
 };
 
+static struct kv_pair cmd_conn_own_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_conn(int argc, char **argv)
 {
@@ -375,7 +384,7 @@ cmd_conn(int argc, char **argv)
         return 0;
     }
 
-    addr_type = parse_arg_kv("peer_addr_type", cmd_conn_addr_types);
+    addr_type = parse_arg_kv("peer_addr_type", cmd_conn_peer_addr_types);
     if (addr_type == -1) {
         return -1;
     }
@@ -389,10 +398,12 @@ 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) {
+    rc = parse_arg_kv_default("own_addr_type",
+                        cmd_conn_own_addr_types, BLE_ADDR_TYPE_PUBLIC);
+    if (rc < 0) {
         return rc;
     }
+    params.our_addr_type = rc;
 
     params.scan_itvl = parse_arg_uint16_dflt("scan_itvl", 0x0010, &rc);
     if (rc != 0) {
@@ -843,22 +854,23 @@ cmd_scan(int argc, char **argv)
     }
 
     disc = parse_arg_kv("disc", cmd_scan_disc_modes);
-    if (disc == -1) {
+    if (disc < 0) {
         return EINVAL;
     }
 
     type = parse_arg_kv("type", cmd_scan_types);
-    if (type == -1) {
+    if (type < 0) {
         return EINVAL;
     }
 
     filt = parse_arg_kv("filt", cmd_scan_filt_policies);
-    if (disc == -1) {
+    if (filt < 0) {
         return EINVAL;
     }
 
-    addr_mode = parse_arg_kv("addr_mode", cmd_scan_addr_types);
-    if (disc == -1) {
+    addr_mode = parse_arg_kv_default("addr_mode", 
+                                    cmd_scan_addr_types, BLE_ADDR_TYPE_PUBLIC);
+    if (addr_mode == -1) {
         return EINVAL;
     }
 
@@ -1012,25 +1024,9 @@ cmd_sec_restart(int argc, char **argv)
     return 0;
 }
 
-static int
-cmd_sec_ltk(int argc, char **argv)
-{
-    /* TODO */
-    return -1;
-}
-
-static int
-cmd_sec_request(int argc, char **argv)
-{
-    /* TODO */
-    return -1;
-}
-
 static struct cmd_entry cmd_sec_entries[] = {
     { "start", cmd_sec_start },
     { "restart", cmd_sec_restart },
-    { "ltk", cmd_sec_ltk },
-    { "request", cmd_sec_request }
 };
 
 static int
@@ -1399,6 +1395,7 @@ cmd_set(int argc, char **argv)
 {
     uint16_t mtu;
     uint8_t addr[6];
+    uint8_t irk[16];
     int good;
     int rc;
 
@@ -1436,6 +1433,14 @@ cmd_set(int argc, char **argv)
         return rc;
     }
 
+    rc = parse_arg_byte_stream_exact_length("irk", irk, 16);
+    if (rc == 0) {
+        good = 1;
+        ble_hs_priv_update_irk(irk);
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
     if (!good) {
         console_printf("Error: no valid settings specified\n");
         return -1;
@@ -1676,6 +1681,238 @@ cmd_write(int argc, char **argv)
     return 0;
 }
 
+/*****************************************************************************
+ * store                                                                     *
+ *****************************************************************************/
+#define BLETINY_CMD_KEYSTORE_ENTRY_TYPE_MST_SEC 0
+#define BLETINY_CMD_KEYSTORE_ENTRY_TYPE_SLV_SEC 1
+#define BLETINY_CMD_KEYSTORE_ENTRY_TYPE_CCCD_SEC 2
+
+static struct kv_pair cmd_keystore_entry_type[] = {
+    { "msec",         BLE_STORE_OBJ_TYPE_MST_SEC },
+    { "ssec",         BLE_STORE_OBJ_TYPE_SLV_SEC },
+    { "cccd",         BLE_STORE_OBJ_TYPE_CCCD },
+    { NULL }
+};
+
+static struct kv_pair cmd_keystore_addr_type[] = {
+    { "public",         BLE_ADDR_TYPE_PUBLIC },
+    { "random",         BLE_ADDR_TYPE_RANDOM },
+    { NULL }
+};
+
+static int
+cmd_keystore_parse_keydata(int argc, char **argv, union ble_store_key *out,
+                           int *obj_type)
+{
+    int type;
+    int rc;
+
+    memset(out, 0, sizeof(*out));
+    type = parse_arg_kv("type", cmd_keystore_entry_type);
+    *obj_type = type;
+
+    switch (type) {
+        case BLE_STORE_OBJ_TYPE_MST_SEC:
+        case BLE_STORE_OBJ_TYPE_SLV_SEC:
+            /* try to parse by address and type */
+                out->sec.peer_addr_type =
+                        parse_arg_kv("addr_type", cmd_keystore_addr_type);
+                rc = parse_arg_mac("addr", out->sec.peer_addr);
+
+                if (rc || out->sec.peer_addr_type < 0) {
+
+                    out->sec.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE;
+
+                    out->sec.ediv = parse_arg_uint16("ediv", &rc);
+                    if (rc != 0) {
+                        return rc;
+                    }
+
+                    out->sec.rand_num = parse_arg_uint64("rand", &rc);
+                    if (rc != 0) {
+                        return rc;
+                    }
+                }
+
+                break;
+        default:
+            return -1;
+    }
+    return 0;
+}
+
+static int
+cmd_keystore_parse_valuedata(int argc, char **argv,
+                             int obj_type,
+                             union ble_store_key *key,
+                             union ble_store_value *out)
+{
+    int rc;
+    int valcnt = 0;
+    memset(out, 0, sizeof(*out));
+
+    switch (obj_type) {
+        case BLE_STORE_OBJ_TYPE_MST_SEC:
+        case BLE_STORE_OBJ_TYPE_SLV_SEC:
+            rc = parse_arg_byte_stream_exact_length("ltk", out->sec.ltk, 16);
+            if (rc == 0) {
+                out->sec.ltk_present = 1;
+                valcnt++;
+            } else if (rc != ENOENT) {
+                return rc;
+            }
+            rc = parse_arg_byte_stream_exact_length("irk", out->sec.irk, 16);
+            if (rc == 0) {
+                out->sec.irk_present = 1;
+                valcnt++;
+            } else if (rc != ENOENT) {
+                return rc;
+            }
+            rc = parse_arg_byte_stream_exact_length("csrk", out->sec.csrk, 16);
+            if (rc == 0) {
+                out->sec.csrk_present = 1;
+                valcnt++;
+            } else if (rc != ENOENT) {
+                return rc;
+            }
+            out->sec.peer_addr_type = key->sec.peer_addr_type;
+            memcpy(out->sec.peer_addr, key->sec.peer_addr, 6);
+            out->sec.ediv = key->sec.ediv;
+            out->sec.rand_num = key->sec.rand_num;
+            break;
+    }
+
+    if (valcnt) {
+        return 0;
+    }
+    return -1;
+}
+
+static int
+cmd_keystore_add(int argc, char **argv)
+{
+    union ble_store_key key;
+    union ble_store_value value;
+    int obj_type;
+    int rc;
+
+    rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type);
+
+    if (rc) {
+        return rc;
+    }
+
+    rc = cmd_keystore_parse_valuedata(argc, argv, obj_type, &key, &value);
+
+    if (rc) {
+        return rc;
+    }
+
+    switch(obj_type) {
+        case BLE_STORE_OBJ_TYPE_MST_SEC:
+            rc = ble_store_write_mst_sec(&value.sec);
+            break;
+        case BLE_STORE_OBJ_TYPE_SLV_SEC:
+            rc = ble_store_write_slv_sec(&value.sec);
+            break;
+        case BLE_STORE_OBJ_TYPE_CCCD:
+            rc = ble_store_write_cccd(&value.cccd);
+            break;
+        default:
+            rc = ble_store_write(obj_type, &value);
+    }
+    return rc;
+}
+
+static int
+cmd_keystore_del(int argc, char **argv)
+{
+    union ble_store_key key;
+    int obj_type;
+    int rc;
+
+    rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type);
+
+    if (rc) {
+        return rc;
+    }
+    rc = ble_store_delete(obj_type, &key);
+    return rc;
+}
+
+static int
+cmd_keystore_iterator(int obj_type,
+                      union ble_store_value *val,
+                      void *cookie) {
+
+    switch (obj_type) {
+        case BLE_STORE_OBJ_TYPE_MST_SEC:
+        case BLE_STORE_OBJ_TYPE_SLV_SEC:
+            console_printf("Key: ");
+            if (val->sec.peer_addr_type == BLE_STORE_ADDR_TYPE_NONE) {
+                console_printf("ediv=%u ", val->sec.ediv);
+                console_printf("ediv=%llu ", val->sec.rand_num);
+            } else {
+                console_printf("addr_type=%u ", val->sec.peer_addr_type);
+                print_addr(val->sec.peer_addr);
+            }
+            console_printf("\n");
+
+            if (val->sec.ltk_present) {
+                console_printf("    LTK: ");
+                print_bytes(val->sec.ltk, 16);
+                console_printf("\n");
+            }
+            if (val->sec.irk_present) {
+                console_printf("    IRK: ");
+                print_bytes(val->sec.irk, 16);
+                console_printf("\n");
+            }
+            if (val->sec.csrk_present) {
+                console_printf("    CSRK: ");
+                print_bytes(val->sec.csrk, 16);
+                console_printf("\n");
+            }
+            break;
+    }
+    return 0;
+}
+
+static int
+cmd_keystore_show(int argc, char **argv)
+{
+    int type;
+
+    type = parse_arg_kv("type", cmd_keystore_entry_type);
+
+    if (type < 0) {
+        return type;
+    }
+
+    ble_store_iterate(type, &cmd_keystore_iterator, NULL);
+    return 0;
+}
+
+static struct cmd_entry cmd_keystore_entries[] = {
+    { "add", cmd_keystore_add },
+    { "del", cmd_keystore_del },
+    { "show", cmd_keystore_show },
+    { NULL, NULL }
+};
+
+static int
+cmd_keystore(int argc, char **argv)
+{
+    int rc;
+
+    rc = cmd_exec(cmd_keystore_entries, argc, argv);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
 
 /*****************************************************************************
  * $passkey                                                                  *
@@ -1750,6 +1987,7 @@ static struct cmd_entry cmd_b_entries[] = {
     { "show",       cmd_show },
     { "sec",        cmd_sec },
     { "set",        cmd_set },
+    { "store",      cmd_keystore },
     { "term",       cmd_term },
     { "update",     cmd_update },
     { "wl",         cmd_wl },

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index 837ddf2..47394b3 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -42,7 +42,6 @@
 #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
@@ -146,11 +145,19 @@ bletiny_print_error(char *msg, uint16_t conn_handle,
 }
 
 static void
+bletiny_print_mac(uint8_t *mac) {
+    int i;
+    for (i = 5; i >= 0; i--) {
+        console_printf("%s0x%02x", i != 5 ? ":" : "", mac[i]);
+    }
+}
+
+static void
 bletiny_print_conn_desc(struct ble_gap_conn_desc *desc)
 {
     console_printf("handle=%d peer_addr_type=%d peer_addr=",
                    desc->conn_handle, desc->peer_addr_type);
-    print_bytes(desc->peer_addr, 6);
+    bletiny_print_mac(desc->peer_addr);
     console_printf(" conn_itvl=%d conn_latency=%d supervision_timeout=%d "
                    "pair_alg=%d enc_enabled=%d authenticated=%d",
                    desc->conn_itvl, desc->conn_latency,
@@ -161,6 +168,15 @@ bletiny_print_conn_desc(struct ble_gap_conn_desc *desc)
 }
 
 static void
+bletiny_print_enh_conn_info(struct ble_gap_enhanced_conn *penh)
+{
+    console_printf(" local_rpa ");
+    bletiny_print_mac(penh->local_rpa);
+    console_printf(" peer_rpa ");
+    bletiny_print_mac(penh->peer_rpa);
+}
+
+static void
 bletiny_print_adv_fields(struct ble_hs_adv_fields *fields)
 {
     uint32_t u32;
@@ -257,7 +273,7 @@ bletiny_print_adv_fields(struct ble_hs_adv_fields *fields)
 
     if (fields->le_addr != NULL) {
         console_printf("    le_addr=");
-        print_bytes(fields->le_addr, BLE_HS_ADV_LE_ADDR_LEN);
+        bletiny_print_mac(fields->le_addr);
         console_printf("\n");
     }
 
@@ -652,31 +668,6 @@ 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)
@@ -812,6 +803,10 @@ bletiny_gap_event(int event, struct ble_gap_conn_ctxt 
*ctxt, void *arg)
                        ctxt->connect.status == 0 ? "established" : "failed",
                        ctxt->connect.status);
         bletiny_print_conn_desc(ctxt->desc);
+
+        if (ctxt->connect.status  == 0) {
+            bletiny_print_enh_conn_info(ctxt->connect.enhanced_conn);
+        }
         console_printf("\n");
 
         if (ctxt->connect.status == 0) {
@@ -868,37 +863,6 @@ 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;
     }
@@ -918,7 +882,7 @@ bletiny_on_scan(int event, int status, struct 
ble_gap_disc_desc *desc,
     case BLE_GAP_EVENT_DISC_SUCCESS:
         console_printf("received advertisement; event_type=%d addr_type=%d "
                        "addr=", desc->event_type, desc->addr_type);
-        print_bytes(desc->addr, 6);
+        bletiny_print_mac(desc->addr);
         console_printf(" length_data=%d rssi=%d data=", desc->length_data,
                        desc->rssi);
         print_bytes(desc->data, desc->length_data);
@@ -1130,8 +1094,8 @@ bletiny_conn_initiate(int addr_type, uint8_t *peer_addr,
 {
     int rc;
 
-    rc = ble_gap_conn_initiate(addr_type, peer_addr, NULL, bletiny_gap_event,
-                               params);
+    rc = ble_gap_conn_initiate(addr_type, peer_addr, params, bletiny_gap_event,
+                               NULL);
     return rc;
 }
 
@@ -1384,10 +1348,6 @@ 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/34e4509a/apps/bletiny/src/parse.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/parse.c b/apps/bletiny/src/parse.c
index 457cb7c..a739d3d 100644
--- a/apps/bletiny/src/parse.c
+++ b/apps/bletiny/src/parse.c
@@ -214,17 +214,37 @@ parse_arg_kv(char *name, struct kv_pair *kvs)
 
     sval = parse_arg_find(name);
     if (sval == NULL) {
-        return ENOENT;
+        return -1;
     }
 
     kv = parse_kv_find(kvs, sval);
     if (kv == NULL) {
-        return EINVAL;
+        return -2;
     }
 
     return kv->val;
 }
 
+int
+parse_arg_kv_default(char *name, struct kv_pair *kvs, int def_val)
+{
+    struct kv_pair *kv;
+    char *sval;
+
+    sval = parse_arg_find(name);
+    if (sval == NULL) {
+        return def_val;
+    }
+
+    kv = parse_kv_find(kvs, sval);
+    if (kv == NULL) {
+        return -1;
+    }
+
+    return kv->val;
+}
+
+
 static int
 parse_arg_byte_stream_delim(char *sval, char *delims, int max_len,
                             uint8_t *dst, int *out_len)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 3cbec48..ec26019 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -642,10 +642,10 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, 
uint8_t *rsplen)
 #endif
 #if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
     case BLE_HCI_OCF_LE_ADD_RESOLV_LIST :
-        ble_ll_resolv_list_add(cmdbuf);
+        rc = ble_ll_resolv_list_add(cmdbuf);
         break;
     case BLE_HCI_OCF_LE_RMV_RESOLV_LIST:
-        ble_ll_resolv_list_rmv(cmdbuf);
+        rc = ble_ll_resolv_list_rmv(cmdbuf);
         break;
     case BLE_HCI_OCF_LE_CLR_RESOLV_LIST:
         rc = ble_ll_resolv_list_clr();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/controller/src/ble_ll_rand.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_rand.c 
b/net/nimble/controller/src/ble_ll_rand.c
index 4da599f..c5201f9 100644
--- a/net/nimble/controller/src/ble_ll_rand.c
+++ b/net/nimble/controller/src/ble_ll_rand.c
@@ -31,7 +31,7 @@ struct ble_ll_rnum_data
 {
     uint8_t *rnd_in;
     uint8_t *rnd_out;
-    uint8_t rnd_size;
+    volatile uint8_t rnd_size;
 };
 
 struct ble_ll_rnum_data g_ble_ll_rnum_data;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 7cca333..65b1a11 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -171,12 +171,18 @@ struct ble_gap_passkey_action {
     uint8_t action;
 };
 
+struct ble_gap_enhanced_conn {
+    uint8_t peer_rpa[6];
+    uint8_t local_rpa[6];
+};
+
 struct ble_gap_conn_ctxt {
     struct ble_gap_conn_desc *desc;
 
     union {
         struct {
             int status;
+            struct ble_gap_enhanced_conn *enhanced_conn;
         } connect;
 
         struct {
@@ -274,5 +280,6 @@ 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);
+int ble_gap_provide_ltk(uint16_t conn_handle, uint8_t *ltk);
 void ble_gap_init_identity_addr(uint8_t *addr);
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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
deleted file mode 100644
index c97aeac..0000000
--- a/net/nimble/host/include/host/ble_keycache.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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/34e4509a/net/nimble/host/include/host/ble_store.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_store.h 
b/net/nimble/host/include/host/ble_store.h
index 7a75703..72b177e 100644
--- a/net/nimble/host/include/host/ble_store.h
+++ b/net/nimble/host/include/host/ble_store.h
@@ -136,4 +136,11 @@ void ble_store_key_from_value_sec(struct ble_store_key_sec 
*out_key,
 void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key,
                                    struct ble_store_value_cccd *value);
 
+typedef int ble_store_iterator_fn(int obj_type,
+                                  union ble_store_value *val,
+                                  void *cookie);
+
+void ble_store_iterate(int obj_type,
+                       ble_store_iterator_fn *callback,
+                       void *cookie);
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 dcaa493..4ec25d4 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -25,7 +25,6 @@
 #include "nimble/nimble_opt.h"
 #include "host/host_hci.h"
 #include "ble_hs_priv.h"
-#include "host/ble_keycache.h"
 
 /**
  * GAP - Generic Access Profile.
@@ -824,6 +823,7 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
     struct ble_gap_conn_ctxt ctxt;
     struct ble_gap_snapshot snap;
     struct ble_hs_conn *conn;
+    struct ble_gap_enhanced_conn enhanced_conn;
     int rc;
 
     STATS_INC(ble_gap_stats, rx_conn_complete);
@@ -916,6 +916,9 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt)
 
     memset(&ctxt, 0, sizeof ctxt);
     ctxt.desc = &snap.desc;
+    memcpy(enhanced_conn.local_rpa, evt->local_rpa,6);
+    memcpy(enhanced_conn.peer_rpa, evt->peer_rpa,6);
+    ctxt.connect.enhanced_conn = &enhanced_conn;
     ctxt.connect.status = 0;
     ble_gap_call_event_cb(BLE_GAP_EVENT_CONNECT, &ctxt, snap.cb, snap.cb_arg);
 
@@ -1273,7 +1276,7 @@ ble_gap_adv_data_tx(void)
 }
 
 static int
-ble_gap_adv_params_tx(const struct ble_gap_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;
@@ -1286,16 +1289,19 @@ ble_gap_adv_params_tx(const struct ble_gap_adv_params 
*adv_params,
     } 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;
+    hci_adv_params.peer_addr_type = peer_addr_type;
+    hci_adv_params.adv_type = adv_params->adv_type;
 
-    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,
+    if ((ble_gap_slave.conn_mode == BLE_GAP_CONN_MODE_DIR) ||
+        (adv_params->own_addr_type == BLE_ADDR_TYPE_RPA_PUB_DEFAULT) ||
+        (adv_params->own_addr_type == BLE_ADDR_TYPE_RPA_RND_DEFAULT)) {
+            memcpy(hci_adv_params.peer_addr,peer,
             sizeof(hci_adv_params.peer_addr));
     }
 
@@ -1303,24 +1309,6 @@ ble_gap_adv_params_tx(const struct ble_gap_adv_params 
*adv_params,
     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:
-        hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
-        break;
-
-    case BLE_GAP_CONN_MODE_DIR:
-        hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
-        break;
-
-    case BLE_GAP_CONN_MODE_UND:
-        hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
-        break;
-
-    default:
-        BLE_HS_DBG_ASSERT(0);
-        break;
-    }
-
     rc = host_hci_cmd_build_le_set_adv_params(&hci_adv_params, buf, sizeof 
buf);
     if (rc != 0) {
         return rc;
@@ -1423,7 +1411,7 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t 
connectable_mode,
         rc = BLE_HS_EINVAL;
         goto done;
     }
-    
+
     BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; ");
     ble_gap_log_adv(&gap_adv_params, peer_addr, peer_addr_type);
     BLE_HS_LOG(INFO, "\n");
@@ -1442,6 +1430,24 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t 
connectable_mode,
         ble_hs_priv_set_nrpa();
     }
 
+    switch (connectable_mode) {
+    case BLE_GAP_CONN_MODE_NON:
+        gap_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
+        break;
+
+    case BLE_GAP_CONN_MODE_DIR:
+        gap_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
+        break;
+
+    case BLE_GAP_CONN_MODE_UND:
+        gap_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
+        break;
+
+    default:
+        BLE_HS_DBG_ASSERT(0);
+        break;
+    }
+
     rc = ble_gap_adv_params_tx(&gap_adv_params, peer_addr, peer_addr_type);
     if (rc != 0) {
         goto done;
@@ -1779,12 +1785,13 @@ ble_gap_conn_initiate(int addr_type, uint8_t *addr,
 
     if (addr_type != BLE_HCI_CONN_PEER_ADDR_PUBLIC &&
         addr_type != BLE_HCI_CONN_PEER_ADDR_RANDOM &&
+        addr_type != BLE_HCI_CONN_PEER_ADDR_PUB_ID &&
+        addr_type != BLE_HCI_CONN_PEER_ADDR_RAND_ID &&
         addr_type != BLE_GAP_ADDR_TYPE_WL) {
 
         rc = BLE_HS_EINVAL;
         goto done;
     }
-    
 
     if (params == NULL) {
         params = (void *)&ble_gap_params_dflt;
@@ -2226,7 +2233,7 @@ ble_gap_notify_event(uint16_t conn_handle, uint16_t 
attr_handle,
 
 void ble_gap_init_identity_addr(uint8_t *addr)
 {
-    ble_hs_priv_init_identity(addr);
+    ble_hs_priv_update_identity(addr);
 }
 
 /*****************************************************************************

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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
index 574c459..75d210b 100644
--- a/net/nimble/host/src/ble_hs_priv.c
+++ b/net/nimble/host/src/ble_hs_priv.c
@@ -17,7 +17,6 @@
  * under the License.
  */
 #include <inttypes.h>
-#include <host/ble_keycache.h>
 #include <stdio.h>
 #include <string.h>
 #include "ble_hs_priv.h"
@@ -25,10 +24,11 @@
 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. */
+uint8_t g_irk[16];
+
+
+/* use this as a default IRK if there is none stored in the ble_store */
 const uint8_t default_irk[16] = {
     0xef, 0x8d, 0xe2, 0x16, 0x4f, 0xec, 0x43, 0x0d,
     0xbf, 0x5b, 0xdd, 0x34, 0xc0, 0x53, 0x1e, 0xb8,
@@ -70,66 +70,159 @@ ble_hs_priv_set_addr_to(uint16_t timeout) {
     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_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;
+}
+
+
+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;
+}
+
+
+int
+ble_keycache_write_irk_entry(uint8_t *addr, uint8_t addr_type, uint8_t *irk)
+{
+    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;
+
+    /* build the message data */
+    add.addr_type = addr_type;
+    memcpy(add.addr, addr, 6);
+    memcpy(add.local_irk, ble_hs_priv_get_local_irk(), 16);
+    memcpy(add.peer_irk, 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;
+}
+
 
 void
-ble_hs_priv_init_identity(uint8_t *addr) {
+ble_hs_priv_update_identity(uint8_t *addr) {
 
-    struct ble_gap_key_parms parms;
     int rc;
     uint8_t random_addr[6];
+    int first_init = (identity_initalized == 0);
 
-    ble_hs_generate_static_random_addr(random_addr);
-    rc = ble_hs_util_set_random_addr(random_addr);
-    assert(rc == 0);
-
-    if(identity_initalized) {
-        return;
+    /* only do this stuff once */
+    if(first_init) {
+        /* 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);
     }
 
-    /* did we get passed an address at initialization */
+    /* did we get passed an address */
     if(addr) {
         memcpy(identity_addr, addr, 6);
         identity_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
-    } else if (0 )
+    } else if (0)
     {
         /* if that fails, try to get a static random address from nvram */
         /* TODO */
     } else
     {
+        /* generate a new static random address and store to memory */
+        ble_hs_generate_static_random_addr(random_addr);
+        rc = ble_hs_util_set_random_addr(random_addr);
+        assert(rc == 0);
+
         identity_addr_type = BLE_HCI_ADV_OWN_ADDR_RANDOM;
         memcpy(identity_addr, random_addr, 6);
         /* TODO store it */
     }
 
+    identity_initalized = 1;
+}
+
+void
+ble_hs_priv_update_irk(uint8_t *irk)
+{
+    uint8_t tmp_addr[6];
+    int irk_changed;
+    uint8_t new_irk[16];
+
+    memset(new_irk, 0, sizeof(new_irk));
+
     /* now try to get an IRK from internal nvram */
-    if(0) {
-        /* TODO */
+    if (irk) {
+        memcpy(new_irk, irk, 16);
+    } else if(0) {
+        /* TODO call to application internal nvram */
     } else {
         /* if that fails, use the default IRK */
-        memcpy(irk, default_irk, 16);
+        memcpy(new_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);
+    irk_changed = memcmp(g_irk, new_irk, 16);
+
+    /* if we are changing our IRK, we need to clear this. Also, for
+     * first time, clear this  */
+    if (irk_changed) {
+        memcpy(g_irk, new_irk, 16);
+
+        /* we need to clear this cache since all the other entries used
+         * our IRK */
+        ble_keycache_set_status(0);
+        ble_keycache_clear_irk_enties();
+        ble_keycache_set_status(1);
+        /* push our identity to the controller as a keycache entry.with a zero
+         * MAC address. The controller uses this entry to generate a RPA when
+         * we do advertising with own addr type = rpa */
+        memset(tmp_addr, 0, 6);
+        ble_keycache_write_irk_entry(tmp_addr, 0 ,g_irk);
+    }
 }
 
 uint8_t *
 bls_hs_priv_get_local_identity_addr(uint8_t *type) {
 
     if(!identity_initalized) {
-        ble_hs_priv_init_identity(NULL);
+        ble_hs_priv_update_identity(NULL);
     }
 
     if (type) {
@@ -148,7 +241,7 @@ uint8_t *
 ble_hs_priv_get_local_irk(void)
 {
     if(!identity_initalized) {
-        ble_hs_priv_init_identity(NULL);
+        ble_hs_priv_update_identity(NULL);
     }
-    return irk;
+    return g_irk;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 956a355..fd9247a 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -104,9 +104,12 @@ 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 ble_hs_priv_update_identity(uint8_t *addr);
+void ble_hs_priv_update_irk(uint8_t *irk);
 void bls_hs_priv_copy_local_identity_addr(uint8_t *pdst, uint8_t* addr_type);
 uint8_t *ble_hs_priv_get_local_irk(void);
+int ble_keycache_remove_irk_entry(uint8_t addr_type, uint8_t *addr);
+int ble_keycache_write_irk_entry(uint8_t *addr, uint8_t addrtype, uint8_t 
*irk);
 #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/34e4509a/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 f26eeba..d0f96a2 100644
--- a/net/nimble/host/src/ble_hs_startup.c
+++ b/net/nimble/host/src/ble_hs_startup.c
@@ -84,7 +84,7 @@ ble_hs_startup_le_set_evmask_tx(void)
     int rc;
 
     /* [ Default event set ]. */
-    host_hci_cmd_build_le_set_event_mask(0x000000000000001f, buf, sizeof buf);
+    host_hci_cmd_build_le_set_event_mask(0x000000000000021f, buf, sizeof buf);
     rc = ble_hci_cmd_tx_empty_ack(buf);
     if (rc != 0) {
         return rc;
@@ -164,7 +164,8 @@ ble_hs_startup_go(void)
     }
 
     /* XXX: Read BD_ADDR. */
-    ble_hs_priv_init_identity(g_dev_addr);
+    ble_hs_priv_update_identity(g_dev_addr);
+    ble_hs_priv_update_irk(NULL);
 
     return rc;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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
deleted file mode 100644
index e474785..0000000
--- a/net/nimble/host/src/ble_keycache.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * 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/34e4509a/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 0e9a4dc..fb89877 100644
--- a/net/nimble/host/src/ble_l2cap_sm.c
+++ b/net/nimble/host/src/ble_l2cap_sm.c
@@ -972,13 +972,11 @@ 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;
-            bls_hs_priv_copy_local_identity_addr(ra, rat);
+            bls_hs_priv_copy_local_identity_addr(ia, iat);
             *rat = conn->bhc_addr_type;
             memcpy(ra, conn->bhc_addr, 6);
         } else {
-            *rat = BLE_ADDR_TYPE_PUBLIC;
-            bls_hs_priv_copy_local_identity_addr(ia, iat);
+            bls_hs_priv_copy_local_identity_addr(ra, rat);
             *iat = conn->bhc_addr_type;
             memcpy(ia, conn->bhc_addr, 6);
         }
@@ -1381,7 +1379,6 @@ ble_l2cap_sm_key_exchange_go(struct ble_l2cap_sm_proc 
*proc,
         }
 
         /* 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);
@@ -1795,7 +1792,7 @@ ble_l2cap_sm_lt_key_req_ltk_handle(struct 
hci_le_lt_key_req *evt)
     int store_rc;
     int rc;
 
-    /* Tell applicaiton to look up LTK by ediv/rand pair. */
+    /* Tell application to look up LTK by ediv/rand pair. */
     /* XXX: Also filter by peer address? */
     memset(&key_sec, 0, sizeof key_sec);
     key_sec.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE;
@@ -2004,7 +2001,7 @@ ble_l2cap_sm_rx_sec_req(uint16_t conn_handle, uint8_t op, 
struct os_mbuf **om)
     ble_hs_unlock();
 
     if (rc == 0) {
-        /* Query database for an LTK corresonding to the sender.  We are the
+        /* Query database for an LTK corresponding to the sender.  We are the
          * master, so retrieve a master key.
          */
         rc = ble_store_read_mst_sec(&key_sec, &value_sec);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_store.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_store.c b/net/nimble/host/src/ble_store.c
index a49d6b1..f03f671 100644
--- a/net/nimble/host/src/ble_store.c
+++ b/net/nimble/host/src/ble_store.c
@@ -101,6 +101,11 @@ ble_store_read_mst_sec(struct ble_store_key_sec *key_sec,
     store_key = (void *)key_sec;
     store_value = (void *)value_sec;
     rc = ble_store_read(BLE_STORE_OBJ_TYPE_MST_SEC, store_key, store_value);
+
+    if (rc) {
+        return rc;
+    }
+
     return rc;
 }
 
@@ -112,6 +117,35 @@ ble_store_write_mst_sec(struct ble_store_value_sec 
*value_sec)
 
     store_value = (void *)value_sec;
     rc = ble_store_write(BLE_STORE_OBJ_TYPE_MST_SEC, store_value);
+
+    if ((value_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) &&
+       (value_sec->irk_present)) {
+        /* Write the peer IRK to the controller keycache
+         * There is not much to do here if it fails */
+        rc = ble_keycache_write_irk_entry(value_sec->peer_addr,
+                                          value_sec->peer_addr_type,
+                                          value_sec->irk);
+    }
+
+    return rc;
+}
+
+int
+ble_store_delete_mst_sec(struct ble_store_key_sec *key_sec)
+{
+    union ble_store_key *store_key;
+    int rc;
+
+    store_key = (void *)key_sec;
+    rc = ble_store_delete(BLE_STORE_OBJ_TYPE_MST_SEC, store_key);
+
+    if(key_sec->peer_addr_type == BLE_STORE_ADDR_TYPE_NONE) {
+        /* don't error check this since we don't know without looking up
+         * the value whether it had a valid IRK */
+        ble_keycache_remove_irk_entry(key_sec->peer_addr_type,
+                                    key_sec->peer_addr);
+    }
+
     return rc;
 }
 
@@ -173,3 +207,41 @@ ble_store_key_from_value_sec(struct ble_store_key_sec 
*out_key,
     out_key->ediv_rand_present = 1;
     out_key->idx = 0;
 }
+
+void ble_store_iterate(int obj_type,
+                       ble_store_iterator_fn *callback,
+                       void *cookie)
+{
+    union ble_store_key key;
+    union ble_store_value value;
+    int idx = 0;
+    uint8_t *pidx;
+
+    /* a magic value to retrieve anything */
+    memset(&key, 0, sizeof(key));
+    switch(obj_type) {
+        case BLE_STORE_OBJ_TYPE_MST_SEC:
+        case BLE_STORE_OBJ_TYPE_SLV_SEC:
+            key.sec.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE;
+            pidx = &key.sec.idx;
+            break;
+        case BLE_STORE_OBJ_TYPE_CCCD:
+            key.cccd.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE;
+            pidx = &key.cccd.idx;
+        default:
+            return;
+    }
+
+    while (1) {
+        int rc;
+        *pidx = idx;
+        rc = ble_store_read(obj_type, &key, &value);
+        if (rc != 0) {
+            /* read error or no more entries */
+            break;
+        } else if (callback) {
+            callback(obj_type, &value, cookie);
+        }
+        idx++;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 a030c89..2bbdd8f 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -87,6 +87,7 @@ static const struct host_hci_le_event_dispatch_entry
     { BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE, host_hci_rx_le_conn_upd_complete },
     { BLE_HCI_LE_SUBEV_LT_KEY_REQ, host_hci_rx_le_lt_key_req },
     { BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ, host_hci_rx_le_conn_parm_req },
+    { BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE, host_hci_rx_le_conn_complete },
 };
 
 #define HOST_HCI_LE_EVENT_DISPATCH_SZ \
@@ -132,7 +133,7 @@ host_hci_le_dispatch_entry_find(uint8_t event_code)
     const struct host_hci_le_event_dispatch_entry *entry;
     int i;
 
-    for (i = 0; i < HOST_HCI_EVENT_DISPATCH_SZ; i++) {
+    for (i = 0; i < HOST_HCI_LE_EVENT_DISPATCH_SZ; i++) {
         entry = host_hci_le_event_dispatch + i;
         if (entry->hmd_subevent == event_code) {
             return entry;
@@ -240,22 +241,41 @@ static int
 host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
 {
     struct hci_le_conn_complete evt;
+    int extended_offset = 0;
     int rc;
 
     if (len < BLE_HCI_LE_CONN_COMPLETE_LEN) {
         return BLE_HS_EMSGSIZE;
     }
 
+    /* this code processes two different events that are really similar */
+    if ((subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) &&
+        ( len < BLE_HCI_LE_ENH_CONN_COMPLETE_LEN)) {
+        return BLE_HS_EMSGSIZE;
+    }
+
     evt.subevent_code = data[0];
     evt.status = data[1];
     evt.connection_handle = le16toh(data + 2);
     evt.role = data[4];
     evt.peer_addr_type = data[5];
     memcpy(evt.peer_addr, data + 6, BLE_DEV_ADDR_LEN);
-    evt.conn_itvl = le16toh(data + 12);
-    evt.conn_latency = le16toh(data + 14);
-    evt.supervision_timeout = le16toh(data + 16);
-    evt.master_clk_acc = data[18];
+
+    /* enhanced connection event has the same information with these
+     * extra fields stuffed into the middle */
+    if (subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) {
+        memcpy(evt.local_rpa, data + 12, BLE_DEV_ADDR_LEN);
+        memcpy(evt.peer_rpa, data + 18, BLE_DEV_ADDR_LEN);
+        extended_offset = 12;
+    } else {
+        memset(evt.local_rpa, 0, BLE_DEV_ADDR_LEN);
+        memset(evt.peer_rpa, 0, BLE_DEV_ADDR_LEN);
+    }
+
+    evt.conn_itvl = le16toh(data + 12 + extended_offset);
+    evt.conn_latency = le16toh(data + 14 + extended_offset);
+    evt.supervision_timeout = le16toh(data + 16 + extended_offset);
+    evt.master_clk_acc = data[18 + extended_offset];
 
     if (evt.status == 0) {
         if (evt.role != BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER &&

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 9763974..16b6d0a 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -985,7 +985,7 @@ host_hci_cmd_body_add_device_to_resolving_list(uint8_t 
addr_type,
     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);
+    memcpy(dst + 1 + 6 + 16, local_irk , 16);
     /* 16 + 16 + 6 + 1 == 39 */
     return 0;
 }
@@ -1203,7 +1203,7 @@ 
host_hci_cmd_set_resolvable_private_address_timeout(uint16_t timeout,
     int rc;
 
     BLE_HS_DBG_ASSERT(
-        dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RESPRIV_ADDR_TO_LEN);
+        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_RPA_TMO,
                        BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN, dst);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 3aa6fcf..0de8842 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -425,6 +425,7 @@ 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 ble_gap_adv_params *adv_params,
                            ble_gap_event_fn *cb, void *cb_arg,
                            int fail_idx, uint8_t fail_status)
 {
@@ -673,7 +674,22 @@ ble_hs_test_util_set_startup_acks(void)
             .evt_params = { 0 },
             .evt_params_len = 8,
         },
-
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                           BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
+        },
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                           BLE_HCI_OCF_LE_CLR_RESOLV_LIST),
+        },
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                           BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
+        },
+        {
+            .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                           BLE_HCI_OCF_LE_ADD_RESOLV_LIST),
+        },
         { 0 }
     }));
 }
@@ -757,7 +773,7 @@ ble_hs_test_util_tx_all(void)
 void
 ble_hs_test_util_set_public_addr(uint8_t *addr)
 {
-    ble_hs_priv_init_identity(addr);
+    ble_hs_priv_update_identity(addr);
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/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 67fe6e8..be72f5b 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -653,6 +653,8 @@ struct hci_le_conn_complete
     uint16_t conn_latency;
     uint16_t supervision_timeout;
     uint8_t master_clk_acc;
+    uint8_t local_rpa[BLE_DEV_ADDR_LEN];
+    uint8_t peer_rpa[BLE_DEV_ADDR_LEN];
 };
 
 /* Connection update complete LE meta subevent */

Reply via email to