You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/11/12 01:17:41 UTC

incubator-mynewt-larva git commit: Concurrent roles; change ack mechanism.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 6f952b463 -> a1dbea4a4


Concurrent roles; change ack mechanism.


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

Branch: refs/heads/master
Commit: a1dbea4a4e4d6830869c1e3f09f17943e6b09ce4
Parents: 6f952b4
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Nov 11 16:17:04 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Nov 11 16:17:04 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/src/ble_gap_conn.c          | 150 ++++++++++++++++++++-
 net/nimble/host/src/ble_gap_conn.h          |  18 +++
 net/nimble/host/src/ble_hs.c                |   6 +
 net/nimble/host/src/ble_hs_ack.c            |  90 +++----------
 net/nimble/host/src/ble_hs_ack.h            |  10 +-
 net/nimble/host/src/ble_hs_conn.c           | 161 ++++-------------------
 net/nimble/host/src/ble_hs_conn.h           |   7 +-
 net/nimble/host/src/host_hci.c              |  52 +++++---
 net/nimble/host/src/host_hci_cmd.c          |   2 +-
 net/nimble/host/src/test/ble_hs_conn_test.c | 103 +++++++++++----
 net/nimble/host/src/test/ble_hs_test_util.c |  11 +-
 net/nimble/include/nimble/hci_common.h      |   2 +
 12 files changed, 349 insertions(+), 263 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/net/nimble/host/src/ble_gap_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_conn.c b/net/nimble/host/src/ble_gap_conn.c
index 3587982..9daae09 100644
--- a/net/nimble/host/src/ble_gap_conn.c
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -19,12 +19,20 @@
 #include <errno.h>
 #include "os/os.h"
 #include "host/host_hci.h"
+#include "ble_hs_ack.h"
 #include "ble_hs_conn.h"
 #include "ble_gap_conn.h"
 
+int ble_gap_conn_state_master;
+int ble_gap_conn_state_slave;
+
+static uint8_t ble_gap_conn_addr_master[BLE_DEV_ADDR_LEN];
+static uint8_t ble_gap_conn_addr_slave[BLE_DEV_ADDR_LEN];
+
 /**
  * Initiates a connection using the GAP Direct Connection Establishment
  * Procedure.
+ * XXX: Add timeout parameter.
  *
  * @return 0 on success; nonzero on failure.
  */
@@ -34,8 +42,8 @@ ble_gap_conn_initiate_direct(int addr_type, uint8_t *addr)
     struct hci_create_conn hcc;
     int rc;
 
-    /* Make sure no connection attempt is already in progress. */
-    if (ble_hs_conn_pending()) {
+    /* Make sure no master connection attempt is already in progress. */
+    if (ble_gap_conn_state_master != BLE_GAP_CONN_STATE_NULL) {
         return EALREADY;
     }
 
@@ -50,12 +58,146 @@ ble_gap_conn_initiate_direct(int addr_type, uint8_t *addr)
     hcc.conn_latency = 0;
     hcc.supervision_timeout = 0x0100; // XXX
     hcc.min_ce_len = 0x0010; // XXX
-    hcc.min_ce_len = 0x0300; // XXX
+    hcc.max_ce_len = 0x0300; // XXX
+
+    rc = host_hci_cmd_le_create_connection(&hcc);
+    if (rc != 0) {
+        return rc;
+    }
+
+    ble_gap_conn_state_master = BLE_GAP_CONN_STATE_MASTER_DIRECT_UNACKED;
+    memcpy(ble_gap_conn_addr_master, addr, BLE_DEV_ADDR_LEN);
+
+    return 0;
+}
+
+/* XXX: Add timeout parameter. */
+int
+ble_gap_conn_advertise_direct(int addr_type, uint8_t *addr)
+{
+    struct hci_adv_params hap;
+    int rc;
+
+    /* Make sure no slave connection attempt is already in progress. */
+    if (ble_gap_conn_state_slave != BLE_GAP_CONN_STATE_NULL) {
+        return EALREADY;
+    }
+
+    hap.adv_itvl_min = BLE_HCI_ADV_ITVL_DEF;
+    hap.adv_itvl_max = BLE_HCI_ADV_ITVL_DEF;
+    hap.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
+    hap.own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
+    hap.peer_addr_type = addr_type;
+    memcpy(hap.peer_addr, addr, sizeof hap.peer_addr);
+    hap.adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF;
+    hap.adv_filter_policy = BLE_HCI_ADV_FILT_DEF;
 
-    rc = ble_hs_conn_initiate(&hcc);
+    rc = host_hci_cmd_le_set_adv_params(&hap);
     if (rc != 0) {
         return rc;
     }
 
+    ble_gap_conn_state_slave = BLE_GAP_CONN_STATE_SLAVE_DIRECT_UNACKED;
+    memcpy(ble_gap_conn_addr_slave, addr, BLE_DEV_ADDR_LEN);
+
+    return 0;
+}
+
+int
+ble_gap_conn_rx_ack_create_conn(struct ble_hs_ack *ack)
+{
+    if (ble_gap_conn_state_master != BLE_GAP_CONN_STATE_MASTER_DIRECT_UNACKED) {
+        return ENOENT;
+    }
+
+    if (ack->bha_status == BLE_ERR_SUCCESS) {
+        ble_gap_conn_state_master = BLE_GAP_CONN_STATE_MASTER_DIRECT_ACKED;
+    } else {
+        ble_gap_conn_state_master = BLE_GAP_CONN_STATE_NULL;
+    }
+
+    return 0;
+}
+
+static int
+ble_gap_conn_accept_conn(uint8_t *addr)
+{
+    switch (ble_gap_conn_state_master) {
+    case BLE_GAP_CONN_STATE_MASTER_DIRECT_ACKED:
+        if (memcmp(ble_gap_conn_addr_master, addr, BLE_DEV_ADDR_LEN) == 0) {
+            ble_gap_conn_state_master = BLE_GAP_CONN_STATE_NULL;
+            return 0;
+        }
+        break;
+    }
+
+    switch (ble_gap_conn_state_slave) {
+    case BLE_GAP_CONN_STATE_SLAVE_DIRECT_ACKED:
+        if (memcmp(ble_gap_conn_addr_slave, addr, BLE_DEV_ADDR_LEN) == 0) {
+            ble_gap_conn_state_slave = BLE_GAP_CONN_STATE_NULL;
+            return 0;
+        }
+        break;
+    }
+
+    return ENOENT;
+}
+
+
+int
+ble_gap_conn_rx_conn_complete(struct hci_le_conn_complete *evt)
+{
+    struct ble_hs_conn *conn;
+    int rc;
+
+    rc = ble_gap_conn_accept_conn(evt->peer_addr);
+    if (rc != 0) {
+        return ENOENT;
+    }
+
+    if (evt->status != BLE_ERR_SUCCESS) {
+        return 0;
+    }
+
+    /* XXX: Ensure device address is expected. */
+    /* XXX: Ensure event fields are acceptable. */
+
+    conn = ble_hs_conn_alloc();
+    if (conn == NULL) {
+        return ENOMEM;
+    }
+
+    conn->bhc_handle = evt->connection_handle;
+    memcpy(conn->bhc_addr, evt->peer_addr, sizeof conn->bhc_addr);
+
+    ble_hs_conn_insert(conn);
+
+    /* XXX: Notify someone. */
+
+    return 0;
+}
+
+int
+ble_gap_conn_rx_ack_set_adv_params(struct ble_hs_ack *ack)
+{
+    if (ble_gap_conn_state_slave != BLE_GAP_CONN_STATE_SLAVE_DIRECT_UNACKED) {
+        return ENOENT;
+    }
+
+    if (ack->bha_status == BLE_ERR_SUCCESS) {
+        ble_gap_conn_state_slave = BLE_GAP_CONN_STATE_SLAVE_DIRECT_ACKED;
+    } else {
+        ble_gap_conn_state_slave = BLE_GAP_CONN_STATE_NULL;
+    }
+
+    return 0;
+}
+
+int
+ble_gap_conn_init(void)
+{
+    ble_gap_conn_state_master = BLE_GAP_CONN_STATE_NULL;
+    ble_gap_conn_state_slave = BLE_GAP_CONN_STATE_NULL;
+
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/net/nimble/host/src/ble_gap_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_conn.h b/net/nimble/host/src/ble_gap_conn.h
index f2d9d90..b24bffd 100644
--- a/net/nimble/host/src/ble_gap_conn.h
+++ b/net/nimble/host/src/ble_gap_conn.h
@@ -17,6 +17,24 @@
 #ifndef H_BLE_GAP_CONN_
 #define H_BLE_GAP_CONN_
 
+struct ble_hs_ack;
+
+#define BLE_GAP_CONN_STATE_NULL                     0
+
+#define BLE_GAP_CONN_STATE_MASTER_DIRECT_UNACKED    1
+#define BLE_GAP_CONN_STATE_MASTER_DIRECT_ACKED      2
+
+#define BLE_GAP_CONN_STATE_SLAVE_DIRECT_UNACKED     1
+#define BLE_GAP_CONN_STATE_SLAVE_DIRECT_ACKED       2
+
 int ble_gap_conn_initiate_direct(int addr_type, uint8_t *addr);
+int ble_gap_conn_advertise_direct(int addr_type, uint8_t *addr);
+int ble_gap_conn_rx_ack_create_conn(struct ble_hs_ack *ack);
+int ble_gap_conn_rx_conn_complete(struct hci_le_conn_complete *evt);
+int ble_gap_conn_rx_ack_set_adv_params(struct ble_hs_ack *ack);
+int ble_gap_conn_init(void);
+
+extern int ble_gap_conn_state_master;
+extern int ble_gap_conn_state_slave;
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/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 e6f4b81..626be94 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -20,6 +20,7 @@
 #include "host/ble_hs.h"
 #include "ble_hs_att.h"
 #include "ble_hs_conn.h"
+#include "ble_gap_conn.h"
 
 #define HCI_CMD_BUFS        (8)
 #define HCI_CMD_BUF_SIZE    (260)       /* XXX: temporary, Fix later */
@@ -101,5 +102,10 @@ ble_hs_init(void)
         return rc;
     }
 
+    rc = ble_gap_conn_init();
+    if (rc != 0) {
+        return rc;
+    }
+
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/net/nimble/host/src/ble_hs_ack.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_ack.c b/net/nimble/host/src/ble_hs_ack.c
index aa7dbb0..a2860c4 100644
--- a/net/nimble/host/src/ble_hs_ack.c
+++ b/net/nimble/host/src/ble_hs_ack.c
@@ -17,51 +17,34 @@
 #include <stddef.h>
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
+#include "ble_gap_conn.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_ack.h"
 
-typedef int ble_hs_ack_rx_cmd_complete_fn(uint16_t ocf, uint8_t *params,
-                                          int param_len);
+typedef int ble_hs_ack_rx_fn(struct ble_hs_ack *ack);
 
-struct ble_hs_ack_cmd_complete_dispatch_entry {
-    uint8_t hac_ocf;
-    ble_hs_ack_rx_cmd_complete_fn *hac_fn;
+struct ble_hs_ack_dispatch_entry {
+    uint8_t bhe_ocf;
+    ble_hs_ack_rx_fn *bhe_fn;
 };
 
-static const struct ble_hs_ack_cmd_complete_dispatch_entry
-        ble_hs_ack_cmd_complete_dispatch[] = {
-    { 0, NULL }, /* XXX */
+static const struct ble_hs_ack_dispatch_entry ble_hs_ack_dispatch[] = {
+    { BLE_HCI_OCF_LE_CREATE_CONN, ble_gap_conn_rx_ack_create_conn },
+    { BLE_HCI_OCF_LE_SET_ADV_PARAMS, ble_gap_conn_rx_ack_set_adv_params },
 };
 
-#define BLE_HS_ACK_CMD_COMPLETE_DISPATCH_SZ         \
-    (sizeof ble_hs_ack_cmd_complete_dispatch /      \
-     sizeof ble_hs_ack_cmd_complete_dispatch[0])
+#define BLE_HS_ACK_DISPATCH_SZ  \
+    (sizeof ble_hs_ack_dispatch / sizeof ble_hs_ack_dispatch[0])
 
-typedef int ble_hs_ack_rx_cmd_status_fn(uint16_t ocf, uint8_t status);
-
-struct ble_hs_ack_cmd_status_dispatch_entry {
-    uint8_t hat_ocf;
-    ble_hs_ack_rx_cmd_status_fn *hat_fn;
-};
-
-static const struct ble_hs_ack_cmd_status_dispatch_entry
-        ble_hs_ack_cmd_status_dispatch[] = {
-    { BLE_HCI_OCF_LE_CREATE_CONN, ble_hs_conn_rx_cmd_status_create_conn },
-};
-
-#define BLE_HS_ACK_CMD_STATUS_DISPATCH_SZ       \
-    (sizeof ble_hs_ack_cmd_status_dispatch /    \
-     sizeof ble_hs_ack_cmd_status_dispatch[0])
-
-static const struct ble_hs_ack_cmd_complete_dispatch_entry *
-ble_hs_cmd_complete_find_entry(uint16_t ocf)
+static const struct ble_hs_ack_dispatch_entry *
+ble_hs_ack_find_dispatch_entry(uint16_t ocf)
 {
-    const struct ble_hs_ack_cmd_complete_dispatch_entry *entry;
+    const struct ble_hs_ack_dispatch_entry *entry;
     int i;
 
-    for (i = 0; i < 0/*XXX BLE_HS_ACK_CMD_COMPLETE_DISPATCH_SZ*/; i++) {
-        entry = ble_hs_ack_cmd_complete_dispatch + i;
-        if (entry->hac_ocf == ocf) {
+    for (i = 0; i < BLE_HS_ACK_DISPATCH_SZ; i++) {
+        entry = ble_hs_ack_dispatch + i;
+        if (entry->bhe_ocf == ocf) {
             return entry;
         }
     }
@@ -69,48 +52,15 @@ ble_hs_cmd_complete_find_entry(uint16_t ocf)
     return NULL;
 }
 
-static const struct ble_hs_ack_cmd_status_dispatch_entry *
-ble_hs_cmd_status_find_entry(uint16_t ocf)
-{
-    const struct ble_hs_ack_cmd_status_dispatch_entry *entry;
-    int i;
-
-    for (i = 0; i < BLE_HS_ACK_CMD_STATUS_DISPATCH_SZ; i++) {
-        entry = ble_hs_ack_cmd_status_dispatch + i;
-        if (entry->hat_ocf == ocf) {
-            return entry;
-        }
-    }
-
-    return NULL;
-}
-
-int
-ble_hs_ack_rx_cmd_complete(uint16_t ocf, uint8_t *params, int param_len)
-{
-    const struct ble_hs_ack_cmd_complete_dispatch_entry *entry;
-    int rc;
-
-    entry = ble_hs_cmd_complete_find_entry(ocf);
-    if (entry != NULL) {
-        rc = entry->hac_fn(ocf, params, param_len);
-        if (rc != 0) {
-            return rc;
-        }
-    }
-
-    return 0;
-}
-
 int
-ble_hs_ack_rx_cmd_status(uint16_t ocf, uint8_t status)
+ble_hs_ack_rx(struct ble_hs_ack *ack)
 {
-    const struct ble_hs_ack_cmd_status_dispatch_entry *entry;
+    const struct ble_hs_ack_dispatch_entry *entry;
     int rc;
 
-    entry = ble_hs_cmd_status_find_entry(ocf);
+    entry = ble_hs_ack_find_dispatch_entry(ack->bha_ocf);
     if (entry != NULL) {
-        rc = entry->hat_fn(ocf, status);
+        rc = entry->bhe_fn(ack);
         if (rc != 0) {
             return rc;
         }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/net/nimble/host/src/ble_hs_ack.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_ack.h b/net/nimble/host/src/ble_hs_ack.h
index 7129b1d..e06b7c9 100644
--- a/net/nimble/host/src/ble_hs_ack.h
+++ b/net/nimble/host/src/ble_hs_ack.h
@@ -19,7 +19,13 @@
 
 #include <inttypes.h>
 
-int ble_hs_ack_rx_cmd_complete(uint16_t ocf, uint8_t *params, int param_len);
-int ble_hs_ack_rx_cmd_status(uint16_t ocf, uint8_t status);
+struct ble_hs_ack {
+    uint16_t bha_ocf;
+    uint8_t bha_status;
+    uint8_t *bha_params;
+    int bha_params_len;
+};
+
+int ble_hs_ack_rx(struct ble_hs_ack *ack);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
index 254080a..b08bad1 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -29,17 +29,6 @@ static SLIST_HEAD(, ble_hs_conn) ble_hs_conns;
 static struct os_mempool ble_hs_conn_pool;
 static struct os_mutex ble_hs_conn_mutex;
 
-#define BLE_HS_CONN_STATE_NULL      0
-#define BLE_HS_CONN_STATE_UNACKED   1
-#define BLE_HS_CONN_STATE_ACKED     2
-
-static struct {
-    uint8_t bhcp_state;
-
-    uint8_t bhcp_addr[BLE_DEV_ADDR_LEN];
-    unsigned bhcp_use_white:1;
-} ble_hs_conn_cur;
-
 void
 ble_hs_conn_lock(void)
 {
@@ -58,28 +47,7 @@ ble_hs_conn_unlock(void)
     assert(rc == 0 || rc == OS_NOT_STARTED);
 }
 
-static void
-ble_hs_conn_free(struct ble_hs_conn *conn)
-{
-    struct ble_l2cap_chan *chan;
-    int rc;
-
-    if (conn == NULL) {
-        return;
-    }
-
-    SLIST_REMOVE(&ble_hs_conns, conn, ble_hs_conn, bhc_next);
-
-    while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) {
-        SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, blc_next);
-        ble_l2cap_chan_free(chan);
-    }
-
-    rc = os_memblock_put(&ble_hs_conn_pool, conn);
-    assert(rc == 0);
-}
-
-static struct ble_hs_conn *
+struct ble_hs_conn *
 ble_hs_conn_alloc(void)
 {
     struct ble_l2cap_chan *chan;
@@ -107,7 +75,28 @@ err:
     return NULL;
 }
 
-static void
+void
+ble_hs_conn_free(struct ble_hs_conn *conn)
+{
+    struct ble_l2cap_chan *chan;
+    int rc;
+
+    if (conn == NULL) {
+        return;
+    }
+
+    SLIST_REMOVE(&ble_hs_conns, conn, ble_hs_conn, bhc_next);
+
+    while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) {
+        SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, blc_next);
+        ble_l2cap_chan_free(chan);
+    }
+
+    rc = os_memblock_put(&ble_hs_conn_pool, conn);
+    assert(rc == 0);
+}
+
+void
 ble_hs_conn_insert(struct ble_hs_conn *conn)
 {
     ble_hs_conn_lock();
@@ -142,110 +131,6 @@ ble_hs_conn_first(void)
     return SLIST_FIRST(&ble_hs_conns);
 }
 
-int
-ble_hs_conn_pending(void)
-{
-    return ble_hs_conn_cur.bhcp_state != BLE_HS_CONN_STATE_NULL;
-}
-
-int
-ble_hs_conn_initiate(struct hci_create_conn *hcc)
-{
-    int rc;
-
-    ble_hs_conn_lock();
-
-    if (ble_hs_conn_pending()) {
-        rc = EALREADY;
-        goto done;
-    }
-
-    ble_hs_conn_cur.bhcp_state = BLE_HS_CONN_STATE_UNACKED;
-    memcpy(ble_hs_conn_cur.bhcp_addr, hcc->peer_addr,
-           sizeof ble_hs_conn_cur.bhcp_addr);
-    ble_hs_conn_cur.bhcp_use_white = 0;
-
-    rc = host_hci_cmd_le_create_connection(hcc);
-    if (rc != 0) {
-        ble_hs_conn_cur.bhcp_state = BLE_HS_CONN_STATE_NULL;
-        goto done;
-    }
-
-    rc = 0;
-
-done:
-    ble_hs_conn_unlock();
-    return rc;
-}
-
-int
-ble_hs_conn_rx_cmd_status_create_conn(uint16_t ocf, uint8_t status)
-{
-    int rc;
-
-    ble_hs_conn_lock();
-
-    if (ble_hs_conn_cur.bhcp_state != BLE_HS_CONN_STATE_UNACKED) {
-        rc = ENOENT;
-        goto done;
-    }
-
-    if (status == BLE_ERR_SUCCESS) {
-        ble_hs_conn_cur.bhcp_state = BLE_HS_CONN_STATE_ACKED;
-    } else {
-        ble_hs_conn_cur.bhcp_state = BLE_HS_CONN_STATE_NULL;
-    }
-
-    rc = 0;
-
-done:
-    ble_hs_conn_unlock();
-    return rc;
-}
-
-int
-ble_hs_conn_rx_conn_complete(struct hci_le_conn_complete *evt)
-{
-    struct ble_hs_conn *conn;
-    int rc;
-
-    ble_hs_conn_lock();
-
-    if (ble_hs_conn_cur.bhcp_state != BLE_HS_CONN_STATE_ACKED) {
-        rc = ENOENT;
-        goto done;
-    }
-
-    /* Clear pending connection. */
-    ble_hs_conn_cur.bhcp_state = BLE_HS_CONN_STATE_NULL;
-
-    if (evt->status != BLE_ERR_SUCCESS) {
-        rc = 0;
-        goto done;
-    }
-
-    /* XXX: Ensure device address is expected. */
-    /* XXX: Ensure event fields are acceptable. */
-
-    conn = ble_hs_conn_alloc();
-    if (conn == NULL) {
-        rc = ENOMEM;
-        goto done;
-    }
-
-    conn->bhc_handle = evt->connection_handle;
-    memcpy(conn->bhc_addr, evt->peer_addr, sizeof conn->bhc_addr);
-
-    ble_hs_conn_insert(conn);
-
-    /* XXX: Notify someone (GAP?) of new connection. */
-
-    rc = 0;
-
-done:
-    ble_hs_conn_unlock();
-    return rc;
-}
 
 int 
 ble_hs_conn_init(void)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
index b72388f..636a30d 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -36,12 +36,11 @@ struct ble_hs_conn {
 
 void ble_hs_conn_lock(void);
 void ble_hs_conn_unlock(void);
+struct ble_hs_conn *ble_hs_conn_alloc(void);
+void ble_hs_conn_free(struct ble_hs_conn *conn);
+void ble_hs_conn_insert(struct ble_hs_conn *conn);
 struct ble_hs_conn *ble_hs_conn_find(uint16_t con_handle);
 struct ble_hs_conn *ble_hs_conn_first(void);
-int ble_hs_conn_pending(void);
-int ble_hs_conn_initiate(struct hci_create_conn *hcc);
-int ble_hs_conn_rx_cmd_status_create_conn(uint16_t ocf, uint8_t status);
-int ble_hs_conn_rx_conn_complete(struct hci_le_conn_complete *evt);
 int ble_hs_conn_init(void);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/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 8fe9f07..d864426 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -27,6 +27,7 @@
 #include "ble_hs_conn.h"
 #include "ble_l2cap.h"
 #include "ble_hs_ack.h"
+#include "ble_gap_conn.h"
 
 static int host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data,
                                     int len);
@@ -73,7 +74,7 @@ struct host_hci_event_dispatch_entry {
     host_hci_event_fn *hed_fn;
 };
 
-static struct host_hci_event_dispatch_entry host_hci_event_dispatch[] = {
+static const struct host_hci_event_dispatch_entry host_hci_event_dispatch[] = {
     { BLE_HCI_EVCODE_COMMAND_COMPLETE, host_hci_rx_cmd_complete },
     { BLE_HCI_EVCODE_COMMAND_STATUS, host_hci_rx_cmd_status },
     { BLE_HCI_EVCODE_LE_META, host_hci_rx_le_meta },
@@ -89,17 +90,18 @@ struct host_hci_le_event_dispatch_entry {
     host_hci_le_event_fn *hmd_fn;
 };
 
-static struct host_hci_le_event_dispatch_entry host_hci_le_event_dispatch[] = {
+static const struct host_hci_le_event_dispatch_entry
+        host_hci_le_event_dispatch[] = {
     { BLE_HCI_LE_SUBEV_CONN_COMPLETE, host_hci_rx_le_conn_complete },
 };
 
 #define HOST_HCI_LE_EVENT_DISPATCH_SZ \
     (sizeof host_hci_le_event_dispatch / sizeof host_hci_le_event_dispatch[0])
 
-static struct host_hci_event_dispatch_entry *
+static const struct host_hci_event_dispatch_entry *
 host_hci_dispatch_entry_find(uint8_t event_code)
 {
-    struct host_hci_event_dispatch_entry *entry;
+    const struct host_hci_event_dispatch_entry *entry;
     int i;
 
     for (i = 0; i < HOST_HCI_EVENT_DISPATCH_SZ; i++) {
@@ -112,10 +114,10 @@ host_hci_dispatch_entry_find(uint8_t event_code)
     return NULL;
 }
 
-static struct host_hci_le_event_dispatch_entry *
+static const struct host_hci_le_event_dispatch_entry *
 host_hci_le_dispatch_entry_find(uint8_t event_code)
 {
-    struct host_hci_le_event_dispatch_entry *entry;
+    const struct host_hci_le_event_dispatch_entry *entry;
     int i;
 
     for (i = 0; i < HOST_HCI_EVENT_DISPATCH_SZ; i++) {
@@ -131,11 +133,10 @@ host_hci_le_dispatch_entry_find(uint8_t event_code)
 static int
 host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
 {
+    struct ble_hs_ack ack;
     uint16_t opcode;
-    uint16_t ocf;
     uint8_t num_pkts;
     uint8_t *params;
-    int param_len;
     int rc;
 
     if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) {
@@ -162,9 +163,16 @@ host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
         host_hci_outstanding_opcode = 0;
     }
 
-    ocf = BLE_HCI_OCF(opcode);
-    param_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
-    rc = ble_hs_ack_rx_cmd_complete(ocf, params, param_len);
+    ack.bha_ocf = BLE_HCI_OCF(opcode);
+    ack.bha_params = params;
+    ack.bha_params_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
+    if (ack.bha_params_len > 0) {
+        ack.bha_status = params[0];
+    } else {
+        ack.bha_status = 255;
+    }
+
+    rc = ble_hs_ack_rx(&ack);
     if (rc != 0) {
         return rc;
     }
@@ -175,8 +183,8 @@ host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
 static int
 host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len)
 {
+    struct ble_hs_ack ack;
     uint16_t opcode;
-    uint16_t ocf;
     uint8_t num_pkts;
     uint8_t status;
     int rc;
@@ -206,8 +214,12 @@ host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len)
         host_hci_outstanding_opcode = 0;
     }
 
-    ocf = BLE_HCI_OCF(opcode);
-    rc = ble_hs_ack_rx_cmd_status(ocf, status);
+    ack.bha_ocf = BLE_HCI_OCF(opcode);
+    ack.bha_params = NULL;
+    ack.bha_params_len = 0;
+    ack.bha_status = status;
+
+    rc = ble_hs_ack_rx(&ack);
     if (rc != 0) {
         return rc;
     }
@@ -218,7 +230,7 @@ host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len)
 static int
 host_hci_rx_le_meta(uint8_t event_code, uint8_t *data, int len)
 {
-    struct host_hci_le_event_dispatch_entry *entry;
+    const struct host_hci_le_event_dispatch_entry *entry;
     uint8_t subevent;
     int rc;
 
@@ -261,7 +273,7 @@ host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
     evt.supervision_timeout = le16toh(data + 16);
     evt.master_clk_acc = data[18];
 
-    rc = ble_hs_conn_rx_conn_complete(&evt);
+    rc = ble_gap_conn_rx_conn_complete(&evt);
     if (rc != 0) {
         return rc;
     }
@@ -272,9 +284,10 @@ host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
 int
 host_hci_event_rx(uint8_t *data)
 {
-    struct host_hci_event_dispatch_entry *entry;
+    const struct host_hci_event_dispatch_entry *entry;
     uint8_t event_code;
     uint8_t param_len;
+    int event_len;
     int rc;
 
     /* Count events received */
@@ -286,12 +299,15 @@ host_hci_event_rx(uint8_t *data)
     /* Process the event */
     event_code = data[0];
     param_len = data[1];
+
+    event_len = param_len + 2;
+
     entry = host_hci_dispatch_entry_find(event_code);
     if (entry == NULL) {
         ++g_host_hci_stats.unknown_events_rxd;
         rc = ENOTSUP;
     } else {
-        rc = entry->hed_fn(event_code, data, param_len + 2);
+        rc = entry->hed_fn(event_code, data, event_len);
     }
 
     return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/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 1593309..fd564ba 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -90,7 +90,7 @@ host_hci_cmd_le_set_adv_params(struct hci_adv_params *adv)
 
     /* Make sure parameters are valid */
     rc = -1;
-    if ((adv->adv_itvl_min >= adv->adv_itvl_max) ||
+    if ((adv->adv_itvl_min > adv->adv_itvl_max) ||
         (adv->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) ||
         (adv->peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX) ||
         (adv->adv_filter_policy > BLE_HCI_ADV_FILT_MAX) ||

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/net/nimble/host/src/test/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_conn_test.c b/net/nimble/host/src/test/ble_hs_conn_test.c
index 29a90fd..ad6ba38 100644
--- a/net/nimble/host/src/test/ble_hs_conn_test.c
+++ b/net/nimble/host/src/test/ble_hs_conn_test.c
@@ -24,13 +24,15 @@
 #include "ble_l2cap.h"
 #include "ble_hs_att.h"
 #include "ble_hs_conn.h"
+#include "ble_hs_ack.h"
 #include "ble_gap_conn.h"
 #include "ble_hs_test_util.h"
 #include "testutil/testutil.h"
 
-TEST_CASE(ble_hs_conn_test_success)
+TEST_CASE(ble_hs_conn_test_master_direct_success)
 {
     struct hci_le_conn_complete evt;
+    struct ble_hs_ack ack;
     struct ble_hs_conn *conn;
     uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
     int rc;
@@ -39,19 +41,21 @@ TEST_CASE(ble_hs_conn_test_success)
     TEST_ASSERT_FATAL(rc == 0);
 
     /* Ensure no current or pending connections. */
-    TEST_ASSERT(!ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 
     /* Initiate connection. */
     rc = ble_gap_conn_initiate_direct(0, addr);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master != BLE_GAP_CONN_STATE_NULL);
 
     /* Receive command status event. */
-    rc = ble_hs_conn_rx_cmd_status_create_conn(BLE_HCI_OCF_LE_CREATE_CONN,
-                                               BLE_ERR_SUCCESS);
+    memset(&ack, 0, sizeof ack);
+    ack.bha_ocf = BLE_HCI_OCF_LE_CREATE_CONN;
+    ack.bha_status = BLE_ERR_SUCCESS;
+    rc = ble_hs_ack_rx(&ack);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master != BLE_GAP_CONN_STATE_NULL);
 
     /* Receive successful connection complete event. */
     memset(&evt, 0, sizeof evt);
@@ -59,20 +63,21 @@ TEST_CASE(ble_hs_conn_test_success)
     evt.status = BLE_ERR_SUCCESS;
     evt.connection_handle = 2;
     memcpy(evt.peer_addr, addr, 6);
-    rc = ble_hs_conn_rx_conn_complete(&evt);
+    rc = ble_gap_conn_rx_conn_complete(&evt);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(!ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
 
     conn = ble_hs_conn_first();
-    TEST_ASSERT(conn != NULL);
+    TEST_ASSERT_FATAL(conn != NULL);
     TEST_ASSERT(conn->bhc_handle == 2);
     TEST_ASSERT(conn->bhc_att_mtu == BLE_HS_ATT_MTU_DFLT);
     TEST_ASSERT(memcmp(conn->bhc_addr, addr, 6) == 0);
 }
 
-TEST_CASE(ble_hs_conn_test_hci_errors)
+TEST_CASE(ble_hs_conn_test_master_direct_hci_errors)
 {
     struct hci_le_conn_complete evt;
+    struct ble_hs_ack ack;
     uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
     int rc;
 
@@ -80,13 +85,13 @@ TEST_CASE(ble_hs_conn_test_hci_errors)
     TEST_ASSERT_FATAL(rc == 0);
 
     /* Ensure no current or pending connections. */
-    TEST_ASSERT(!ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 
     /* Initiate connection. */
     rc = ble_gap_conn_initiate_direct(0, addr);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master != BLE_GAP_CONN_STATE_NULL);
 
     /* Receive connection complete event without intervening command status. */
     memset(&evt, 0, sizeof evt);
@@ -94,28 +99,82 @@ TEST_CASE(ble_hs_conn_test_hci_errors)
     evt.status = BLE_ERR_SUCCESS;
     evt.connection_handle = 2;
     memcpy(evt.peer_addr, addr, 6);
-    rc = ble_hs_conn_rx_conn_complete(&evt);
+    rc = ble_gap_conn_rx_conn_complete(&evt);
     TEST_ASSERT(rc != 0);
-    TEST_ASSERT(ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master != BLE_GAP_CONN_STATE_NULL);
 
-    /* Receive connection complete event. */
-    rc = ble_hs_conn_rx_cmd_status_create_conn(BLE_HCI_OCF_LE_CREATE_CONN,
-                                               BLE_ERR_SUCCESS);
+    /* Receive success command status event. */
+    memset(&ack, 0, sizeof ack);
+    ack.bha_ocf = BLE_HCI_OCF_LE_CREATE_CONN;
+    ack.bha_status = BLE_ERR_SUCCESS;
+    rc = ble_hs_ack_rx(&ack);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master != BLE_GAP_CONN_STATE_NULL);
 
     /* Receive failure connection complete event. */
     evt.status = BLE_ERR_UNSPECIFIED;
-    rc = ble_hs_conn_rx_conn_complete(&evt);
+    rc = ble_gap_conn_rx_conn_complete(&evt);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(!ble_hs_conn_pending());
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 }
 
+TEST_CASE(ble_hs_conn_test_slave_direct_success)
+{
+    struct hci_le_conn_complete evt;
+    struct ble_hs_conn *conn;
+    struct ble_hs_ack ack;
+    uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
+    int rc;
+
+    rc = ble_hs_init();
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /* Ensure no current or pending connections. */
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
+    TEST_ASSERT(ble_gap_conn_state_slave == BLE_GAP_CONN_STATE_NULL);
+    TEST_ASSERT(ble_hs_conn_first() == NULL);
+
+    /* Initiate advertising. */
+    rc = ble_gap_conn_advertise_direct(0, addr);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
+    TEST_ASSERT(ble_gap_conn_state_slave ==
+                BLE_GAP_CONN_STATE_SLAVE_DIRECT_UNACKED);
+
+    /* Receive command status event. */
+    memset(&ack, 0, sizeof ack);
+    ack.bha_ocf = BLE_HCI_OCF_LE_SET_ADV_PARAMS;
+    ack.bha_status = BLE_ERR_SUCCESS;
+    rc = ble_hs_ack_rx(&ack);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
+    TEST_ASSERT(ble_gap_conn_state_slave ==
+                BLE_GAP_CONN_STATE_SLAVE_DIRECT_ACKED);
+
+    /* Receive successful connection complete event. */
+    memset(&evt, 0, sizeof evt);
+    evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
+    evt.status = BLE_ERR_SUCCESS;
+    evt.connection_handle = 2;
+    memcpy(evt.peer_addr, addr, 6);
+    rc = ble_gap_conn_rx_conn_complete(&evt);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(ble_gap_conn_state_master == BLE_GAP_CONN_STATE_NULL);
+    TEST_ASSERT(ble_gap_conn_state_slave == BLE_GAP_CONN_STATE_NULL);
+
+    conn = ble_hs_conn_first();
+    TEST_ASSERT_FATAL(conn != NULL);
+    TEST_ASSERT(conn->bhc_handle == 2);
+    TEST_ASSERT(conn->bhc_att_mtu == BLE_HS_ATT_MTU_DFLT);
+    TEST_ASSERT(memcmp(conn->bhc_addr, addr, 6) == 0);
+}
+
 TEST_SUITE(conn_suite)
 {
-    ble_hs_conn_test_success();
-    ble_hs_conn_test_hci_errors();
+    ble_hs_conn_test_master_direct_success();
+    ble_hs_conn_test_master_direct_hci_errors();
+    ble_hs_conn_test_slave_direct_success();
 }
 
 int

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/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 26c27df..e294a54 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -18,7 +18,7 @@
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
 #include "testutil/testutil.h"
-#include "ble_hs_conn.h"
+#include "ble_hs_ack.h"
 #include "ble_gap_conn.h"
 #include "ble_hs_test_util.h"
 
@@ -53,13 +53,16 @@ void
 ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr)
 {
     struct hci_le_conn_complete evt;
+    struct ble_hs_ack ack;
     int rc;
 
     rc = ble_gap_conn_initiate_direct(0, addr);
     TEST_ASSERT(rc == 0);
 
-    rc = ble_hs_conn_rx_cmd_status_create_conn(BLE_HCI_OCF_LE_CREATE_CONN,
-                                               BLE_ERR_SUCCESS);
+    memset(&ack, 0, sizeof ack);
+    ack.bha_ocf = BLE_HCI_OCF_LE_CREATE_CONN;
+    ack.bha_status = BLE_ERR_SUCCESS;
+    rc = ble_gap_conn_rx_ack_create_conn(&ack);
     TEST_ASSERT(rc == 0);
 
     memset(&evt, 0, sizeof evt);
@@ -67,5 +70,5 @@ ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr)
     evt.status = BLE_ERR_SUCCESS;
     evt.connection_handle = 2;
     memcpy(evt.peer_addr, addr, 6);
-    rc = ble_hs_conn_rx_conn_complete(&evt);
+    rc = ble_gap_conn_rx_conn_complete(&evt);
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a1dbea4a/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 3f77d52..3a3413e 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -166,6 +166,8 @@
 #define BLE_HCI_ADV_FILT_BOTH               (3)
 #define BLE_HCI_ADV_FILT_MAX                (3)
 
+#define BLE_HCI_ADV_FILT_DEF                (BLE_HCI_ADV_FILT_NONE)
+
 /* Advertising interval */
 #define BLE_HCI_ADV_ITVL                    (625)           /* usecs */
 #define BLE_HCI_ADV_ITVL_MIN                (32)            /* units */