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/11 02:37:00 UTC

incubator-mynewt-larva git commit: Handle connection events.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 2df2509a8 -> 8895970ad


Handle connection events.

Also, remove obsolete host_test project.


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

Branch: refs/heads/master
Commit: 8895970ad4f878b18db08499ed957a2363e8e1d1
Parents: 2df2509
Author: Christopher Collins <cc...@gmail.com>
Authored: Tue Nov 10 17:27:05 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Tue Nov 10 17:27:05 2015 -0800

----------------------------------------------------------------------
 net/nimble/controller/src/ble_ll_hci.c       |   2 +-
 net/nimble/host/include/host/ble_hs.h        |   7 -
 net/nimble/host/include/host/ble_hs_test.h   |   1 +
 net/nimble/host/src/arch/sim/ble_hs_itf.c    | 298 ----------------------
 net/nimble/host/src/ble_gap_conn.c           |  61 +++++
 net/nimble/host/src/ble_gap_conn.h           |  22 ++
 net/nimble/host/src/ble_hs.c                 |  46 ----
 net/nimble/host/src/ble_hs_ack.c             | 120 +++++++++
 net/nimble/host/src/ble_hs_ack.h             |  25 ++
 net/nimble/host/src/ble_hs_att_cmd.c         |  16 ++
 net/nimble/host/src/ble_hs_conn.c            | 218 +++++++++++-----
 net/nimble/host/src/ble_hs_conn.h            |  12 +-
 net/nimble/host/src/ble_hs_itf.h             |  27 --
 net/nimble/host/src/host_hci.c               | 121 ++++++++-
 net/nimble/host/src/test/ble_host_hci_test.c |  63 ++---
 net/nimble/host/src/test/ble_hs_att_test.c   |   9 +-
 net/nimble/host/src/test/ble_hs_conn_test.c  | 127 +++++++++
 net/nimble/host/src/test/ble_hs_test.c       |   1 +
 net/nimble/host/src/test/ble_hs_test_util.c  |  71 ++++++
 net/nimble/host/src/test/ble_hs_test_util.h  |  30 +++
 net/nimble/host/src/test/ble_l2cap_test.c    |  14 +-
 net/nimble/include/nimble/hci_common.h       |  26 +-
 project/host_test/host_test.yml              |   5 -
 project/host_test/src/main.c                 |  95 -------
 24 files changed, 818 insertions(+), 599 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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 e66c811..3c6a3f8 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -174,7 +174,7 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
      * command data itself. That is fine, as each command reads all the data
      * before crafting a response.
      */ 
-    rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
+    rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN;
 
     /* Move past HCI command header */
     cmdbuf += BLE_HCI_CMD_HDR_LEN;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index e16bccd..1b7a38d 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -19,14 +19,7 @@
 
 #include <inttypes.h>
 
-extern int ble_host_listen_enabled;
-
-/** --- */
-
 void ble_hs_task_handler(void *arg);
-int ble_host_send_data_connectionless(uint16_t con_handle, uint16_t cid,
-                                      uint8_t *data, uint16_t len);
-int ble_hs_poll(void);
 int ble_hs_init(void);
 
 #endif /* _BLE_HOST_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/include/host/ble_hs_test.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs_test.h b/net/nimble/host/include/host/ble_hs_test.h
index 5d2b484..b436601 100644
--- a/net/nimble/host/include/host/ble_hs_test.h
+++ b/net/nimble/host/include/host/ble_hs_test.h
@@ -20,6 +20,7 @@
 int l2cap_test_all(void);
 int ble_hs_att_test_all(void);
 int ble_host_hci_test_all(void);
+int ble_hs_conn_test_all(void);
 
 #endif
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/src/arch/sim/ble_hs_itf.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/arch/sim/ble_hs_itf.c b/net/nimble/host/src/arch/sim/ble_hs_itf.c
deleted file mode 100644
index d115c0e..0000000
--- a/net/nimble/host/src/arch/sim/ble_hs_itf.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <os/os.h>
-
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h> 
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <unistd.h>
-#include "nimble/ble.h"
-#include "nimble/hci_common.h"
-#include "host/ble_hs.h"
-#include "host/host_hci.h"
-#include "ble_hs_conn.h"
-#include "ble_hs_att.h"
-#include "ble_hs_itf.h"
-
-#define BLE_SIM_BASE_PORT       10000
-
-static void
-set_nonblock(int fd)
-{
-    int flags;
-    int rc;
-
-    flags = fcntl(fd, F_GETFL, 0);
-    rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-    assert(rc >= 0);
-}
-
-
-int
-ble_sim_listen(uint16_t con_handle)
-{
-    struct ble_hs_conn *conn;
-    struct sockaddr_in sin;
-    struct hostent *ent;
-    int fd;
-    int rc;
-
-    conn = ble_hs_conn_alloc();
-    if (conn == NULL) {
-        rc = ENOMEM;
-        goto err;
-    }
-
-    /* resolve host addr first, then create a socket and bind() to 
-     * that address.
-     */
-    ent = gethostbyname("localhost");
-    if (ent == NULL) {
-        rc = errno;
-        goto err;
-    }
-
-    memset(&sin, 0, sizeof(sin));
-    memcpy(&sin.sin_addr, ent->h_addr_list[0], ent->h_length);
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(BLE_SIM_BASE_PORT + con_handle);
-
-    fd = socket(AF_INET, SOCK_DGRAM, 0);
-    if (fd < 0) {
-        rc = errno;
-        goto err;
-    }
-
-    set_nonblock(fd);
-
-    rc = bind(fd, (struct sockaddr *)&sin, sizeof sin);
-    if (rc != 0) {
-        close(fd);
-        rc = errno;
-        goto err;
-    }
-
-    memset(conn, 0, sizeof *conn);
-    conn->bhc_handle = con_handle;
-    conn->bhc_fd = fd;
-
-    return 0;
-
-err:
-    ble_hs_conn_free(conn);
-    return rc;
-}
-
-static int
-ble_sim_connect(uint16_t con_handle, struct ble_hs_conn **out_conn)
-{
-    struct ble_hs_conn *conn;
-    struct sockaddr_in sin;
-    struct hostent *ent;
-    int fd;
-    int rc;
-
-    conn = ble_hs_conn_alloc();
-    if (conn == NULL) {
-        rc = ENOMEM;
-        goto err;
-    }
-
-    /* resolve host addr first, then create a socket and bind() to 
-     * that address.
-     */
-    ent = gethostbyname("localhost");
-    if (ent == NULL) {
-        rc = errno;
-        goto err;
-    }
-
-    memset(&sin, 0, sizeof(sin));
-    memcpy(&sin.sin_addr, ent->h_addr_list[0], ent->h_length);
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(BLE_SIM_BASE_PORT + con_handle);
-
-    fd = socket(AF_INET, SOCK_DGRAM, 0);
-    if (fd < 0) {
-        rc = errno;
-        goto err;
-    }
-
-    set_nonblock(fd);
-
-    rc = connect(fd, (struct sockaddr *)&sin, sizeof sin);
-    if (rc != 0 && errno != EINPROGRESS) {
-        rc = errno;
-        goto err;
-    }
-
-    memset(conn, 0, sizeof *conn);
-    conn->bhc_handle = con_handle;
-    conn->bhc_fd = fd;
-
-    *out_conn = conn;
-
-    return 0;
-
-err:
-    ble_hs_conn_free(conn);
-    *out_conn = NULL;
-    return rc;
-}
-
-static int
-ble_sim_ensure_connection(uint16_t con_handle, struct ble_hs_conn **conn)
-{
-    int rc;
-
-    *conn = ble_hs_conn_find(con_handle);
-    if (*conn == NULL) {
-        rc = ble_sim_connect(con_handle, conn);
-        if (rc != 0) {
-            return rc;
-        }
-    }
-
-    return 0;
-}
-
-static int
-ble_sim_send(uint16_t con_handle, const void *data, uint16_t len)
-{
-    struct ble_hs_conn *conn;
-    int rc;
-    int i;
-
-    rc = ble_sim_ensure_connection(con_handle, &conn);
-    if (rc != 0) {
-        return rc;
-    }
-
-    printf("sending %d bytes: ", len);
-    for (i = 0; i < len; i++) {
-        printf("%02x ", ((const uint8_t *)data)[i]);
-    }
-    printf("\n");
-
-    while (len > 0) {
-        rc = send(conn->bhc_fd, data, len, 0);
-        if (rc >= 0) {
-            data += rc;
-            len -= rc;
-        } else {
-            return errno;
-        }
-    }
-
-    return 0;
-}
-
-int
-ble_host_sim_send_data_connectionless(uint16_t con_handle, uint16_t cid,
-                                      uint8_t *data, uint16_t len)
-{
-    static uint8_t buf[1024];
-    int off;
-    int rc;
-
-    off = 0;
-
-    htole16(buf + off, con_handle | (0 << 12) | (0 << 14));
-    off += 2;
-
-    htole16(buf + off, len + 4);
-    off += 2;
-
-    htole16(buf + off, len);
-    off += 2;
-
-    htole16(buf + off, cid);
-    off += 2;
-
-    memcpy(buf + off, data, len);
-    off += len;
-
-    rc = ble_sim_send(con_handle, buf, off);
-    return rc;
-}
-
-int 
-ble_host_sim_poll(void)
-{
-    static uint8_t buf[1024];
-    struct ble_hs_conn *conn;
-    fd_set r_fd_set;
-    fd_set w_fd_set;
-    uint16_t pkt_size;
-    int nevents;
-    int max_fd;
-    int fd;
-    int rc;
-    int i;
-
-    FD_ZERO(&r_fd_set);
-    FD_ZERO(&w_fd_set);
-
-    max_fd = 0;
-    for (conn = ble_hs_conn_first();
-         conn != NULL;
-         conn = SLIST_NEXT(conn, bhc_next)) {
-
-        fd = conn->bhc_fd;
-        FD_SET(fd, &r_fd_set);
-        FD_SET(fd, &w_fd_set);
-        if (fd > max_fd) {
-            max_fd = fd;
-        }
-    }
-
-    do {
-        nevents = select(max_fd + 1, &r_fd_set, &w_fd_set, NULL, NULL);
-    } while (nevents < 0 && errno == EINTR);
-
-    if (nevents > 0) {
-    for (conn = ble_hs_conn_first();
-         conn != NULL;
-         conn = SLIST_NEXT(conn, bhc_next)) {
-
-            if (FD_ISSET(conn->bhc_fd, &r_fd_set)) {
-                while (1) {
-                    rc = recv(conn->bhc_fd, buf, sizeof buf, 0);
-                    if (rc <= 0) {
-                        break;
-                    }
-                    pkt_size = rc;
-
-                    printf("received HCI data packet (%d bytes): ", pkt_size);
-                    for (i = 0; i < pkt_size; i++) {
-                        printf("%02x ", buf[i]);
-                    }
-                    printf("\n");
-
-                    rc = host_hci_data_rx(buf, pkt_size);
-                }
-            }
-        }
-    }
-
-    return 0;
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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
new file mode 100644
index 0000000..3587982
--- /dev/null
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include "os/os.h"
+#include "host/host_hci.h"
+#include "ble_hs_conn.h"
+#include "ble_gap_conn.h"
+
+/**
+ * Initiates a connection using the GAP Direct Connection Establishment
+ * Procedure.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
+int
+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()) {
+        return EALREADY;
+    }
+
+    hcc.scan_itvl = 0x0010;
+    hcc.scan_window = 0x0010;
+    hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL;
+    hcc.peer_addr_type = addr_type;
+    memcpy(hcc.peer_addr, addr, sizeof hcc.peer_addr);
+    hcc.own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
+    hcc.conn_itvl_min = 24;
+    hcc.conn_itvl_max = 40;
+    hcc.conn_latency = 0;
+    hcc.supervision_timeout = 0x0100; // XXX
+    hcc.min_ce_len = 0x0010; // XXX
+    hcc.min_ce_len = 0x0300; // XXX
+
+    rc = ble_hs_conn_initiate(&hcc);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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
new file mode 100644
index 0000000..f2d9d90
--- /dev/null
+++ b/net/nimble/host/src/ble_gap_conn.h
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_GAP_CONN_
+#define H_BLE_GAP_CONN_
+
+int ble_gap_conn_initiate_direct(int addr_type, uint8_t *addr);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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 505b1d7..e6f4b81 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -20,9 +20,6 @@
 #include "host/ble_hs.h"
 #include "ble_hs_att.h"
 #include "ble_hs_conn.h"
-#ifdef ARCH_sim
-#include "ble_hs_itf.h"
-#endif
 
 #define HCI_CMD_BUFS        (8)
 #define HCI_CMD_BUF_SIZE    (260)       /* XXX: temporary, Fix later */
@@ -41,40 +38,6 @@ os_membuf_t g_hci_os_event_buf[OS_MEMPOOL_SIZE(HCI_NUM_OS_EVENTS,
 struct os_eventq g_ble_host_hci_evq;
 #define BLE_HOST_HCI_EVENT_CTLR_EVENT   (OS_EVENT_T_PERUSER)
 
-int ble_host_listen_enabled;
-
-int
-ble_host_send_data_connectionless(uint16_t con_handle, uint16_t cid,
-                                  uint8_t *data, uint16_t len)
-{
-    int rc;
-
-#ifdef ARCH_sim
-    rc = ble_host_sim_send_data_connectionless(con_handle, cid, data, len);
-#else
-    rc = -1;
-#endif
-
-    return rc;
-}
-
-/**
- * XXX: This is only here for testing.
- */
-int 
-ble_hs_poll(void)
-{
-    int rc;
-
-#ifdef ARCH_sim
-    rc = ble_host_sim_poll();
-#else
-    rc = -1;
-#endif
-
-    return rc;
-}
-
 void
 ble_hs_task_handler(void *arg)
 {
@@ -138,14 +101,5 @@ ble_hs_init(void)
         return rc;
     }
 
-#ifdef ARCH_sim
-    if (ble_host_listen_enabled) {
-        int rc;
-
-        rc = ble_sim_listen(1);
-        assert(rc == 0);
-    }
-#endif
-
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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
new file mode 100644
index 0000000..aa7dbb0
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_ack.c
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+#include "nimble/ble.h"
+#include "nimble/hci_common.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);
+
+struct ble_hs_ack_cmd_complete_dispatch_entry {
+    uint8_t hac_ocf;
+    ble_hs_ack_rx_cmd_complete_fn *hac_fn;
+};
+
+static const struct ble_hs_ack_cmd_complete_dispatch_entry
+        ble_hs_ack_cmd_complete_dispatch[] = {
+    { 0, NULL }, /* XXX */
+};
+
+#define BLE_HS_ACK_CMD_COMPLETE_DISPATCH_SZ         \
+    (sizeof ble_hs_ack_cmd_complete_dispatch /      \
+     sizeof ble_hs_ack_cmd_complete_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)
+{
+    const struct ble_hs_ack_cmd_complete_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) {
+            return entry;
+        }
+    }
+
+    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)
+{
+    const struct ble_hs_ack_cmd_status_dispatch_entry *entry;
+    int rc;
+
+    entry = ble_hs_cmd_status_find_entry(ocf);
+    if (entry != NULL) {
+        rc = entry->hat_fn(ocf, status);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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
new file mode 100644
index 0000000..7129b1d
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_ack.h
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_HS_ACK_
+#define H_BLE_HS_ACK_
+
+#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);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/src/ble_hs_att_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att_cmd.c b/net/nimble/host/src/ble_hs_att_cmd.c
index aba7559..de1b0b6 100644
--- a/net/nimble/host/src/ble_hs_att_cmd.c
+++ b/net/nimble/host/src/ble_hs_att_cmd.c
@@ -1,3 +1,19 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #include <errno.h>
 #include "os/os.h"
 #include "nimble/ble.h"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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 0a1b5b8..254080a 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -25,19 +25,61 @@
 
 #define BLE_HS_CONN_MAX 16
 
-static SLIST_HEAD(, ble_hs_conn) ble_hs_conns =
-    SLIST_HEAD_INITIALIZER(ble_hs_conns); 
-
+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 {
-    unsigned bhcp_valid:1;
+    uint8_t bhcp_state;
 
-    uint8_t bhcp_addr[6];
+    uint8_t bhcp_addr[BLE_DEV_ADDR_LEN];
     unsigned bhcp_use_white:1;
-} ble_hs_conn_pending;
+} ble_hs_conn_cur;
 
-struct ble_hs_conn *
+void
+ble_hs_conn_lock(void)
+{
+    int rc;
+
+    rc = os_mutex_pend(&ble_hs_conn_mutex, 0xffffffff);
+    assert(rc == 0 || rc == OS_NOT_STARTED);
+}
+
+void
+ble_hs_conn_unlock(void)
+{
+    int rc;
+
+    rc = os_mutex_release(&ble_hs_conn_mutex);
+    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 *
 ble_hs_conn_alloc(void)
 {
     struct ble_l2cap_chan *chan;
@@ -58,11 +100,6 @@ ble_hs_conn_alloc(void)
     }
     SLIST_INSERT_HEAD(&conn->bhc_channels, chan, blc_next);
 
-    /* XXX: Allocated entries always go into the list.  Allocation and
-     * insertion may need to be split into separate operations.
-     */
-    SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
-
     return conn;
 
 err:
@@ -70,25 +107,15 @@ err:
     return NULL;
 }
 
-void
-ble_hs_conn_free(struct ble_hs_conn *conn)
+static void
+ble_hs_conn_insert(struct ble_hs_conn *conn)
 {
-    struct ble_l2cap_chan *chan;
-    int rc;
+    ble_hs_conn_lock();
 
-    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);
-    }
+    assert(ble_hs_conn_find(conn->bhc_handle) == NULL);
+    SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
 
-    rc = os_memblock_put(&ble_hs_conn_pool, conn);
-    assert(rc == 0);
+    ble_hs_conn_unlock();
 }
 
 struct ble_hs_conn *
@@ -115,49 +142,109 @@ ble_hs_conn_first(void)
     return SLIST_FIRST(&ble_hs_conns);
 }
 
-/**
- * Initiates a connection using the GAP Direct Connection Establishment
- * Procedure.
- * XXX: This will likely be moved.
- *
- * @return 0 on success; nonzero on failure.
- */
 int
-ble_hs_conn_initiate_direct(int addr_type, uint8_t *addr)
+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)
 {
-    struct hci_create_conn hcc;
     int rc;
 
-    /* Make sure no connection attempt is already in progress. */
-    if (ble_hs_conn_pending.bhcp_valid) {
-        return EALREADY;
+    ble_hs_conn_lock();
+
+    if (ble_hs_conn_pending()) {
+        rc = EALREADY;
+        goto done;
     }
 
-    hcc.scan_itvl = 0x0010;
-    hcc.scan_window = 0x0010;
-    hcc.filter_policy = BLE_HCI_CONN_FILT_NO_WL;
-    hcc.peer_addr_type = addr_type;
-    memcpy(hcc.peer_addr, addr, sizeof hcc.peer_addr);
-    hcc.own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
-    hcc.conn_itvl_min = 24;
-    hcc.conn_itvl_min = 40;
-    hcc.conn_latency = 0;
-    hcc.supervision_timeout = 0x0100; // XXX
-    hcc.min_ce_len = 0x0010; // XXX
-    hcc.min_ce_len = 0x0300; // XXX
-
-    ble_hs_conn_pending.bhcp_valid = 1;
-    memcpy(ble_hs_conn_pending.bhcp_addr, addr,
-           sizeof ble_hs_conn_pending.bhcp_addr);
-    ble_hs_conn_pending.bhcp_use_white = 0;
-
-    rc = host_hci_cmd_le_create_connection(&hcc);
+    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_pending.bhcp_valid = 0;
-        return rc;
+        ble_hs_conn_cur.bhcp_state = BLE_HS_CONN_STATE_NULL;
+        goto done;
     }
 
-    return 0;
+    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 
@@ -180,5 +267,12 @@ ble_hs_conn_init(void)
         return EINVAL; // XXX
     }
 
+    SLIST_INIT(&ble_hs_conns);
+
+    rc = os_mutex_init(&ble_hs_conn_mutex);
+    if (rc != 0) {
+        return EINVAL; // XXX
+    }
+
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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 746383e..b72388f 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -19,6 +19,8 @@
 
 #include "os/queue.h"
 #include "ble_l2cap.h"
+struct hci_le_conn_complete;
+struct hci_create_conn;
 
 struct ble_hs_conn *ble_host_find_connection(uint16_t con_handle);
 
@@ -27,15 +29,19 @@ struct ble_hs_conn {
     uint16_t bhc_handle;
     int bhc_fd; // XXX Temporary.
     uint16_t bhc_att_mtu;
+    uint8_t bhc_addr[BLE_DEV_ADDR_LEN];
 
     struct ble_l2cap_chan_list bhc_channels;
 };
 
-struct ble_hs_conn *ble_hs_conn_alloc(void);
-void ble_hs_conn_free(struct ble_hs_conn *conn);
+void ble_hs_conn_lock(void);
+void ble_hs_conn_unlock(void);
 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_initiate_direct(int addr_type, uint8_t *addr);
+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/8895970a/net/nimble/host/src/ble_hs_itf.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_itf.h b/net/nimble/host/src/ble_hs_itf.h
deleted file mode 100644
index 9f2dba5..0000000
--- a/net/nimble/host/src/ble_hs_itf.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef H_ITF_
-#define H_ITF_
-
-struct os_eventq;
-
-int ble_host_sim_send_data_connectionless(uint16_t con_handle, uint16_t cid,
-                                          uint8_t *data, uint16_t len);
-int ble_sim_listen(uint16_t con_handle);
-int ble_host_sim_poll(void);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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 a8f938c..8fe9f07 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -26,6 +26,14 @@
 #include "host_dbg.h"
 #include "ble_hs_conn.h"
 #include "ble_l2cap.h"
+#include "ble_hs_ack.h"
+
+static int 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);
+static int host_hci_rx_le_meta(uint8_t event_code, uint8_t *data, int len);
+static int host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data,
+                                        int len);
 
 #define HCI_CMD_BUFS        (8)
 #define HCI_CMD_BUF_SIZE    (260)       /* XXX: temporary, Fix later */
@@ -65,18 +73,29 @@ struct host_hci_event_dispatch_entry {
     host_hci_event_fn *hed_fn;
 };
 
-static int 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);
-
 static 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 },
 };
 
 #define HOST_HCI_EVENT_DISPATCH_SZ \
     (sizeof host_hci_event_dispatch / sizeof host_hci_event_dispatch[0])
 
+/** Dispatch table for incoming LE meta events.  Sorted by subevent field. */
+typedef int host_hci_le_event_fn(uint8_t subevent, uint8_t *data, int len);
+struct host_hci_le_event_dispatch_entry {
+    uint8_t hmd_subevent;
+    host_hci_le_event_fn *hmd_fn;
+};
+
+static 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 *
 host_hci_dispatch_entry_find(uint8_t event_code)
 {
@@ -93,13 +112,31 @@ host_hci_dispatch_entry_find(uint8_t event_code)
     return NULL;
 }
 
+static 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;
+    int i;
+
+    for (i = 0; i < HOST_HCI_EVENT_DISPATCH_SZ; i++) {
+        entry = host_hci_le_event_dispatch + i;
+        if (entry->hmd_subevent == event_code) {
+            return entry;
+        }
+    }
+
+    return NULL;
+}
+
 static int
 host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
 {
     uint16_t opcode;
     uint16_t ocf;
     uint8_t num_pkts;
-    uint8_t *parms;
+    uint8_t *params;
+    int param_len;
+    int rc;
 
     if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) {
         /* XXX: Increment stat. */
@@ -108,7 +145,7 @@ host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
 
     num_pkts = data[2];
     opcode = le16toh(data + 3);
-    parms = data + 4;
+    params = data + 4;
 
     /* XXX: Process num_pkts field. */
     (void)num_pkts;
@@ -121,13 +158,16 @@ host_hci_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len)
     }
 
     if (opcode == host_hci_outstanding_opcode) {
+        /* Mark the outstanding command as acked. */
         host_hci_outstanding_opcode = 0;
     }
 
     ocf = BLE_HCI_OCF(opcode);
-    /* XXX: Dispatch based on OCF. */
-    (void)parms;
-    (void)ocf;
+    param_len = len - BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN;
+    rc = ble_hs_ack_rx_cmd_complete(ocf, params, param_len);
+    if (rc != 0) {
+        return rc;
+    }
 
     return 0;
 }
@@ -139,6 +179,7 @@ host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len)
     uint16_t ocf;
     uint8_t num_pkts;
     uint8_t status;
+    int rc;
 
     if (len < BLE_HCI_EVENT_CMD_STATUS_LEN) {
         /* XXX: Increment stat. */
@@ -161,13 +202,69 @@ host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len)
     }
 
     if (opcode == host_hci_outstanding_opcode) {
+        /* Mark the outstanding command as acked. */
         host_hci_outstanding_opcode = 0;
     }
 
     ocf = BLE_HCI_OCF(opcode);
-    /* XXX: Dispatch based on OCF. */
-    (void)status;
-    (void)ocf;
+    rc = ble_hs_ack_rx_cmd_status(ocf, status);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+static int
+host_hci_rx_le_meta(uint8_t event_code, uint8_t *data, int len)
+{
+    struct host_hci_le_event_dispatch_entry *entry;
+    uint8_t subevent;
+    int rc;
+
+    if (len < BLE_HCI_EVENT_HDR_LEN + BLE_HCI_LE_MIN_LEN) {
+        /* XXX: Increment stat. */
+        return EMSGSIZE;
+    }
+
+    subevent = data[2];
+    entry = host_hci_le_dispatch_entry_find(subevent);
+    if (entry != NULL) {
+        rc = entry->hmd_fn(subevent, data + BLE_HCI_EVENT_HDR_LEN,
+                           len - BLE_HCI_EVENT_HDR_LEN);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    return 0;
+}
+
+static int
+host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
+{
+    struct hci_le_conn_complete evt;
+    int rc;
+
+    if (len < BLE_HCI_LE_CONN_COMPLETE_LEN) {
+        return 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];
+
+    rc = ble_hs_conn_rx_conn_complete(&evt);
+    if (rc != 0) {
+        return rc;
+    }
 
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/src/test/ble_host_hci_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_host_hci_test.c b/net/nimble/host/src/test/ble_host_hci_test.c
index 81d5890..803d18d 100644
--- a/net/nimble/host/src/test/ble_host_hci_test.c
+++ b/net/nimble/host/src/test/ble_host_hci_test.c
@@ -21,37 +21,12 @@
 #include "host/host_hci.h"
 #include "host/ble_hs.h"
 #include "host/ble_hs_test.h"
+#include "testutil/testutil.h"
 #include "ble_l2cap.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_att.h"
 #include "ble_hs_att_cmd.h"
-#include "testutil/testutil.h"
-
-static void
-ble_host_hci_test_misc_build_cmd_complete(uint8_t *dst, int len,
-                                          uint8_t param_len, uint8_t num_pkts,
-                                          uint16_t opcode)
-{
-    TEST_ASSERT(len >= BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN);
-
-    dst[0] = BLE_HCI_EVCODE_COMMAND_COMPLETE;
-    dst[1] = 5 + param_len;
-    dst[2] = num_pkts;
-    htole16(dst + 3, opcode);
-}
-
-static void
-ble_host_hci_test_misc_build_cmd_status(uint8_t *dst, int len,
-                                        uint8_t status, uint8_t num_pkts,
-                                        uint16_t opcode)
-{
-    TEST_ASSERT(len >= BLE_HCI_EVENT_CMD_STATUS_LEN);
-
-    dst[0] = BLE_HCI_EVCODE_COMMAND_STATUS;
-    dst[1] = BLE_HCI_EVENT_CMD_STATUS_LEN;
-    dst[2] = num_pkts;
-    htole16(dst + 3, opcode);
-}
+#include "ble_hs_test_util.h"
 
 TEST_CASE(ble_host_hci_test_event_bad)
 {
@@ -74,15 +49,28 @@ TEST_CASE(ble_host_hci_test_event_cmd_complete)
     TEST_ASSERT_FATAL(rc == 0);
 
     /*** Unsent OCF. */
-    ble_host_hci_test_misc_build_cmd_complete(buf, sizeof buf, 1, 1, 12345);
+    ble_hs_test_util_build_cmd_complete(buf, sizeof buf, 1, 1, 12345);
     rc = host_hci_event_rx(buf);
     TEST_ASSERT(rc == ENOENT);
 
     /*** No error on NOP. */
-    ble_host_hci_test_misc_build_cmd_complete(buf, sizeof buf, 1, 1,
+    ble_hs_test_util_build_cmd_complete(buf, sizeof buf, 1, 1,
                                               BLE_HCI_OPCODE_NOP);
     rc = host_hci_event_rx(buf);
     TEST_ASSERT(rc == 0);
+
+    /*** Acknowledge sent command. */
+    rc = host_hci_cmd_le_set_adv_enable(0);
+    TEST_ASSERT(rc == 0);
+    ble_hs_test_util_build_cmd_complete(
+        buf, sizeof buf, 1, 1,
+        (BLE_HCI_OGF_LE << 10) | BLE_HCI_OCF_LE_SET_ADV_ENABLE);
+    rc = host_hci_event_rx(buf);
+    TEST_ASSERT(rc == 0);
+
+    /*** Duplicate ack is error. */
+    rc = host_hci_event_rx(buf);
+    TEST_ASSERT(rc == ENOENT);
 }
 
 TEST_CASE(ble_host_hci_test_event_cmd_status)
@@ -94,15 +82,28 @@ TEST_CASE(ble_host_hci_test_event_cmd_status)
     TEST_ASSERT_FATAL(rc == 0);
 
     /*** Unsent OCF. */
-    ble_host_hci_test_misc_build_cmd_status(buf, sizeof buf, 0, 1, 12345);
+    ble_hs_test_util_build_cmd_status(buf, sizeof buf, 0, 1, 12345);
     rc = host_hci_event_rx(buf);
     TEST_ASSERT(rc == ENOENT);
 
     /*** No error on NOP. */
-    ble_host_hci_test_misc_build_cmd_complete(buf, sizeof buf, 0, 1,
+    ble_hs_test_util_build_cmd_complete(buf, sizeof buf, 0, 1,
                                               BLE_HCI_OPCODE_NOP);
     rc = host_hci_event_rx(buf);
     TEST_ASSERT(rc == 0);
+
+    /*** Acknowledge sent command. */
+    rc = host_hci_cmd_le_set_adv_enable(0);
+    TEST_ASSERT(rc == 0);
+    ble_hs_test_util_build_cmd_status(
+        buf, sizeof buf, BLE_ERR_SUCCESS, 1,
+        (BLE_HCI_OGF_LE << 10) | BLE_HCI_OCF_LE_SET_ADV_ENABLE);
+    rc = host_hci_event_rx(buf);
+    TEST_ASSERT(rc == 0);
+
+    /*** Duplicate ack is error. */
+    rc = host_hci_event_rx(buf);
+    TEST_ASSERT(rc == ENOENT);
 }
 
 TEST_SUITE(ble_host_hci_suite)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/src/test/ble_hs_att_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_att_test.c b/net/nimble/host/src/test/ble_hs_att_test.c
index c325f73..b33a3bb 100644
--- a/net/nimble/host/src/test/ble_hs_att_test.c
+++ b/net/nimble/host/src/test/ble_hs_att_test.c
@@ -20,11 +20,12 @@
 #include "nimble/hci_common.h"
 #include "host/ble_hs.h"
 #include "host/ble_hs_test.h"
+#include "testutil/testutil.h"
 #include "ble_l2cap.h"
+#include "ble_hs_test_util.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_att.h"
 #include "ble_hs_att_cmd.h"
-#include "testutil/testutil.h"
 
 static uint8_t *ble_hs_att_test_attr_1;
 static int ble_hs_att_test_attr_1_len;
@@ -147,7 +148,8 @@ TEST_CASE(ble_hs_att_test_read)
     rc = ble_hs_init();
     TEST_ASSERT_FATAL(rc == 0);
 
-    conn = ble_hs_conn_alloc();
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}));
+    conn = ble_hs_conn_find(2);
     TEST_ASSERT_FATAL(conn != NULL);
 
     chan = ble_l2cap_chan_find(conn, BLE_L2CAP_CID_ATT);
@@ -209,7 +211,8 @@ TEST_CASE(ble_hs_att_test_write)
     rc = ble_hs_init();
     TEST_ASSERT_FATAL(rc == 0);
 
-    conn = ble_hs_conn_alloc();
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}));
+    conn = ble_hs_conn_find(2);
     TEST_ASSERT_FATAL(conn != NULL);
 
     chan = ble_l2cap_chan_find(conn, BLE_L2CAP_CID_ATT);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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
new file mode 100644
index 0000000..29a90fd
--- /dev/null
+++ b/net/nimble/host/src/test/ble_hs_conn_test.c
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include "nimble/hci_common.h"
+#include "host/ble_hs.h"
+#include "host/ble_hs_test.h"
+#include "host/host_hci.h"
+#include "ble_l2cap.h"
+#include "ble_hs_att.h"
+#include "ble_hs_conn.h"
+#include "ble_gap_conn.h"
+#include "ble_hs_test_util.h"
+#include "testutil/testutil.h"
+
+TEST_CASE(ble_hs_conn_test_success)
+{
+    struct hci_le_conn_complete evt;
+    struct ble_hs_conn *conn;
+    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_hs_conn_pending());
+    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());
+
+    /* Receive command status event. */
+    rc = ble_hs_conn_rx_cmd_status_create_conn(BLE_HCI_OCF_LE_CREATE_CONN,
+                                               BLE_ERR_SUCCESS);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(ble_hs_conn_pending());
+
+    /* 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_hs_conn_rx_conn_complete(&evt);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(!ble_hs_conn_pending());
+
+    conn = ble_hs_conn_first();
+    TEST_ASSERT(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)
+{
+    struct hci_le_conn_complete evt;
+    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_hs_conn_pending());
+    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());
+
+    /* Receive connection complete event without intervening command status. */
+    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_hs_conn_rx_conn_complete(&evt);
+    TEST_ASSERT(rc != 0);
+    TEST_ASSERT(ble_hs_conn_pending());
+
+    /* Receive connection complete event. */
+    rc = ble_hs_conn_rx_cmd_status_create_conn(BLE_HCI_OCF_LE_CREATE_CONN,
+                                               BLE_ERR_SUCCESS);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(ble_hs_conn_pending());
+
+    /* Receive failure connection complete event. */
+    evt.status = BLE_ERR_UNSPECIFIED;
+    rc = ble_hs_conn_rx_conn_complete(&evt);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(!ble_hs_conn_pending());
+    TEST_ASSERT(ble_hs_conn_first() == NULL);
+}
+
+TEST_SUITE(conn_suite)
+{
+    ble_hs_conn_test_success();
+    ble_hs_conn_test_hci_errors();
+}
+
+int
+ble_hs_conn_test_all(void)
+{
+    conn_suite();
+
+    return tu_any_failed;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/src/test/ble_hs_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test.c b/net/nimble/host/src/test/ble_hs_test.c
index 3d517b1..b013044 100644
--- a/net/nimble/host/src/test/ble_hs_test.c
+++ b/net/nimble/host/src/test/ble_hs_test.c
@@ -28,6 +28,7 @@ main(void)
     l2cap_test_all();
     ble_hs_att_test_all();
     ble_host_hci_test_all();
+    ble_hs_conn_test_all();
 
     return tu_any_failed;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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
new file mode 100644
index 0000000..26c27df
--- /dev/null
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include "nimble/ble.h"
+#include "nimble/hci_common.h"
+#include "testutil/testutil.h"
+#include "ble_hs_conn.h"
+#include "ble_gap_conn.h"
+#include "ble_hs_test_util.h"
+
+void
+ble_hs_test_util_build_cmd_complete(uint8_t *dst, int len,
+                                    uint8_t param_len, uint8_t num_pkts,
+                                    uint16_t opcode)
+{
+    TEST_ASSERT(len >= BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN);
+
+    dst[0] = BLE_HCI_EVCODE_COMMAND_COMPLETE;
+    dst[1] = 5 + param_len;
+    dst[2] = num_pkts;
+    htole16(dst + 3, opcode);
+}
+
+void
+ble_hs_test_util_build_cmd_status(uint8_t *dst, int len,
+                                  uint8_t status, uint8_t num_pkts,
+                                  uint16_t opcode)
+{
+    TEST_ASSERT(len >= BLE_HCI_EVENT_CMD_STATUS_LEN);
+
+    dst[0] = BLE_HCI_EVCODE_COMMAND_STATUS;
+    dst[1] = BLE_HCI_EVENT_CMD_STATUS_LEN;
+    dst[2] = status;
+    dst[3] = num_pkts;
+    htole16(dst + 4, opcode);
+}
+
+void
+ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr)
+{
+    struct hci_le_conn_complete evt;
+    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);
+    TEST_ASSERT(rc == 0);
+
+    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_hs_conn_rx_conn_complete(&evt);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/src/test/ble_hs_test_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.h b/net/nimble/host/src/test/ble_hs_test_util.h
new file mode 100644
index 0000000..5f75aac
--- /dev/null
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_HS_TEST_UTIL_
+#define H_BLE_HS_TEST_UTIL_
+
+#include <inttypes.h>
+
+void ble_hs_test_util_build_cmd_complete(uint8_t *dst, int len,
+                                         uint8_t param_len, uint8_t num_pkts,
+                                         uint16_t opcode);
+void ble_hs_test_util_build_cmd_status(uint8_t *dst, int len,
+                                       uint8_t status, uint8_t num_pkts,
+                                       uint16_t opcode);
+void ble_hs_test_util_create_conn(uint16_t handle, uint8_t *addr);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/net/nimble/host/src/test/ble_l2cap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_l2cap_test.c b/net/nimble/host/src/test/ble_l2cap_test.c
index 26015fa..a1dd785 100644
--- a/net/nimble/host/src/test/ble_l2cap_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_test.c
@@ -20,6 +20,7 @@
 #include "host/ble_hs.h"
 #include "host/ble_hs_test.h"
 #include "ble_hs_conn.h"
+#include "ble_hs_test_util.h"
 #include "ble_l2cap.h"
 #include "testutil/testutil.h"
 
@@ -31,7 +32,11 @@ TEST_CASE(l2cap_test_bad_header)
     uint8_t pkt[8];
     int rc;
 
-    conn = ble_hs_conn_alloc();
+    rc = ble_hs_init();
+    TEST_ASSERT_FATAL(rc == 0);
+
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}));
+    conn = ble_hs_conn_find(2);
     TEST_ASSERT_FATAL(conn != NULL);
 
     hci_hdr.hdh_handle_pb_bc = 0;
@@ -54,17 +59,10 @@ TEST_CASE(l2cap_test_bad_header)
     TEST_ASSERT(rc == 0);
     rc = ble_l2cap_rx(conn, &hci_hdr, pkt);
     TEST_ASSERT(rc == ENOENT);
-
-    ble_hs_conn_free(conn);
 }
 
 TEST_SUITE(l2cap_gen)
 {
-    int rc;
-
-    rc = ble_hs_init();
-    TEST_ASSERT_FATAL(rc == 0);
-
     l2cap_test_bad_header();
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/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 0708487..41ffef7 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -260,9 +260,13 @@
 #define BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE  (0x0A)
 #define BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT     (0x0B)
 
+/* Generic event header */
+#define BLE_HCI_EVENT_HDR_LEN               (2)
+
 /* Event specific definitions */
 /* Event command complete */
-#define BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN  (6)
+#define BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN  (5)
+#define BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN  (6)
 
 #define BLE_HCI_EVENT_CMD_STATUS_LEN        (6)
 
@@ -273,6 +277,11 @@
 #define BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND  (3)
 #define BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP     (5)
 
+/* LE sub-event specific definitions */
+#define BLE_HCI_LE_MIN_LEN                  (1) /* Not including event hdr. */
+
+#define BLE_HCI_LE_CONN_COMPLETE_LEN        (19)
+
 /*--- Shared data structures ---*/
 
 /* set advertising parameters command (ocf = 0x0006) */
@@ -305,6 +314,21 @@ struct hci_create_conn
     uint16_t max_ce_len;
 };
 
+/* Connection complete LE meta subevent */
+struct hci_le_conn_complete
+{
+    uint8_t subevent_code;
+    uint8_t status;
+    uint16_t connection_handle;
+    uint8_t role;
+    uint8_t peer_addr_type;
+    uint8_t peer_addr[BLE_DEV_ADDR_LEN];
+    uint16_t conn_itvl;
+    uint16_t conn_latency;
+    uint16_t supervision_timeout;
+    uint8_t master_clk_acc;
+};
+
 #define BLE_HCI_DATA_HDR_SZ         4
 #define BLE_HCI_DATA_HANDLE(handle_pb_bc)   (((handle_pb_bc) & 0x0fff) >> 0)
 #define BLE_HCI_DATA_PB(handle_pb_bc)       (((handle_pb_bc) & 0x3000) >> 12)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/project/host_test/host_test.yml
----------------------------------------------------------------------
diff --git a/project/host_test/host_test.yml b/project/host_test/host_test.yml
deleted file mode 100644
index 75a63a2..0000000
--- a/project/host_test/host_test.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-project.name: host_test
-project.eggs: 
-    - libs/os 
-    - net/nimble/host
-    - libs/console/full

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8895970a/project/host_test/src/main.c
----------------------------------------------------------------------
diff --git a/project/host_test/src/main.c b/project/host_test/src/main.c
deleted file mode 100755
index 9e4b9ed..0000000
--- a/project/host_test/src/main.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include "os/os.h"
-#include "nimble/ble.h"
-#include "host/host_hci.h"
-#include "host/ble_hs.h"
-
-#define HOST_TASK_PRIO (1) 
-#define HOST_STACK_SIZE (OS_STACK_ALIGN(4096))
-
-static struct os_task host_task;
-static os_stack_t host_stack[HOST_STACK_SIZE];
-
-static void
-host_test_task_handler(void *arg)
-{
-    int rc;
-
-    ble_hs_init();
-
-    while (1) {
-        os_time_delay(1000);
-        if (!ble_host_listen_enabled) {
-            rc = ble_host_send_data_connectionless(1, 4, (uint8_t *)"BLAH", 4);
-            printf("ble_host_send_data_connectionless(); rc=%d\n", rc);
-        } else {
-            ble_hs_poll();
-        }
-    }
-}
-
-
-/**
- * init_tasks
- *  
- * Called by main.c after os_init(). This function performs initializations 
- * that are required before tasks are running. 
- *  
- * @return int 0 success; error otherwise.
- */
-int
-init_tasks(void)
-{
-    os_task_init(&host_task, "host", host_test_task_handler, NULL, 
-            HOST_TASK_PRIO, OS_WAIT_FOREVER, host_stack, HOST_STACK_SIZE);
-
-    return (0);
-}
-
-/**
- * main
- *  
- * The main function for the project. This function initializes the os, calls 
- * init_tasks to initialize tasks (and possibly other objects), then starts the 
- * OS. We should not return from os start. 
- *  
- * @return int NOTE: this function should never return!
- */
-int
-main(int argc, char **argv)
-{
-    /* Initialize OS */
-    os_init();
-
-    /* Init tasks */
-    init_tasks();
-
-    if (argc > 1 && strcmp(argv[1], "-l") == 0) {
-        ble_host_listen_enabled = 1;
-    }
-
-    /* Start the OS */
-    os_start();
-
-    /* os start should never return. If it does, this should be an error */
-    assert(0);
-
-    return (0);
-}