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/12/09 03:42:55 UTC

[1/3] incubator-mynewt-larva git commit: Console: only print timestamp at start of line.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 8df6025e8 -> d114269af


Console: only print timestamp at start of line.


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

Branch: refs/heads/master
Commit: 984a4b47bb125cfc98095bd8ab20483779916043
Parents: 8df6025
Author: Christopher Collins <cc...@gmail.com>
Authored: Tue Dec 8 18:10:42 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Tue Dec 8 18:10:42 2015 -0800

----------------------------------------------------------------------
 libs/console/full/src/cons_fmt.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/984a4b47/libs/console/full/src/cons_fmt.c
----------------------------------------------------------------------
diff --git a/libs/console/full/src/cons_fmt.c b/libs/console/full/src/cons_fmt.c
index 064018f..252f553 100644
--- a/libs/console/full/src/cons_fmt.c
+++ b/libs/console/full/src/cons_fmt.c
@@ -20,6 +20,9 @@
 
 #define CONS_OUTPUT_MAX_LINE	128
 
+/** Indicates whether the previous line of output was completed. */
+static int console_is_midline;
+
 int
 console_vprintf(const char *fmt, va_list args)
 {
@@ -31,6 +34,10 @@ console_vprintf(const char *fmt, va_list args)
         len = sizeof(buf) - 1;
     }
     console_write(buf, len);
+
+    if (len > 0) {
+        console_is_midline = buf[len - 1] != '\n';
+    }
     return len;
 }
 
@@ -41,8 +48,11 @@ console_printf(const char *fmt, ...)
     char buf[24];
     int len;
 
-    len = snprintf(buf, sizeof(buf), "%lu:", (unsigned long)os_time_get());
-    console_write(buf, len);
+    /* Prefix each line with a timestamp. */
+    if (!console_is_midline) {
+        len = snprintf(buf, sizeof(buf), "%lu:", (unsigned long)os_time_get());
+        console_write(buf, len);
+    }
 
     va_start(args, fmt);
     len = console_vprintf(fmt, args);


[3/3] incubator-mynewt-larva git commit: Project to test host code on actual hardware.

Posted by cc...@apache.org.
Project to test host code on actual hardware.


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

Branch: refs/heads/master
Commit: d114269af1717b06730800b404b1f7fb91ae2d70
Parents: c1ac77c
Author: Christopher Collins <cc...@gmail.com>
Authored: Tue Dec 8 18:41:06 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Tue Dec 8 18:42:16 2015 -0800

----------------------------------------------------------------------
 project/hostctlrtest/hostctlrtest.yml |   7 +
 project/hostctlrtest/src/main.c       | 324 +++++++++++++++++++++++++++++
 2 files changed, 331 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d114269a/project/hostctlrtest/hostctlrtest.yml
----------------------------------------------------------------------
diff --git a/project/hostctlrtest/hostctlrtest.yml b/project/hostctlrtest/hostctlrtest.yml
new file mode 100644
index 0000000..af5cb9c
--- /dev/null
+++ b/project/hostctlrtest/hostctlrtest.yml
@@ -0,0 +1,7 @@
+project.name: hostctlrtest
+project.eggs: 
+    - libs/os 
+    - net/nimble/controller
+    - net/nimble/host
+    - libs/console/full
+    - libs/baselibc

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d114269a/project/hostctlrtest/src/main.c
----------------------------------------------------------------------
diff --git a/project/hostctlrtest/src/main.c b/project/hostctlrtest/src/main.c
new file mode 100755
index 0000000..71997c4
--- /dev/null
+++ b/project/hostctlrtest/src/main.c
@@ -0,0 +1,324 @@
+/**
+ * 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.
+ */
+#define HOSTCTLRTEST_ROLE_INITIATOR          (0)
+#define HOSTCTLRTEST_ROLE_SCANNER            (1)
+#define HOSTCTLRTEST_ROLE_ADVERTISER         (2)
+
+#define HOSTCTLRTEST_CFG_ROLE                (2)
+
+#include <assert.h>
+#include <string.h>
+#include "os/os.h"
+#include "bsp/bsp.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_cputime.h"
+#include "console/console.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/host_hci.h"
+#include "host/ble_hs.h"
+#include "host/ble_hs_uuid.h"
+#include "host/ble_att.h"
+#include "host/ble_gap.h"
+#include "host/ble_gatt.h"
+#include "controller/ble_ll.h"
+
+/* Init all tasks */
+volatile int tasks_initialized;
+
+/* Task 1 */
+#define HOST_TASK_PRIO      (1)
+
+/* For LED toggling */
+int g_led_pin;
+
+/* Our global device address (public) */
+uint8_t g_dev_addr[BLE_DEV_ADDR_LEN];
+
+/* Our random address (in case we need it) */
+uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
+
+/* A buffer for host advertising data */
+uint8_t g_host_adv_data[BLE_HCI_MAX_ADV_DATA_LEN];
+uint8_t g_host_adv_len;
+
+static uint8_t hostctlrtest_slv_addr[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
+static uint8_t hostctlrtest_mst_addr[6] = {0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a};
+
+/* Create a mbuf pool of BLE mbufs */
+#define MBUF_NUM_MBUFS      (16)
+#define MBUF_BUF_SIZE       (256 + sizeof(struct hci_data_hdr))
+#define MBUF_MEMBLOCK_SIZE  (MBUF_BUF_SIZE + BLE_MBUF_PKT_OVERHEAD)
+
+#define MBUF_MEMPOOL_SIZE   OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE)
+
+struct os_mbuf_pool g_mbuf_pool; 
+struct os_mempool g_mbuf_mempool;
+os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE];
+
+/* Some application configurations */
+#define HOSTCTLRTEST_CFG_FILT_DUP_ADV        (0)
+#define HOSTCTLRTEST_CFG_ADV_ITVL            (500000 / BLE_HCI_ADV_ITVL)
+#define HOSTCTLRTEST_CFG_ADV_TYPE            BLE_HCI_ADV_TYPE_ADV_IND
+#define HOSTCTLRTEST_CFG_ADV_FILT_POLICY     (BLE_HCI_ADV_FILT_NONE)
+#define HOSTCTLRTEST_CFG_SCAN_ITVL           (700000 / BLE_HCI_SCAN_ITVL)
+#define HOSTCTLRTEST_CFG_SCAN_WINDOW         (650000 / BLE_HCI_SCAN_ITVL)
+#define HOSTCTLRTEST_CFG_SCAN_TYPE           (BLE_HCI_SCAN_TYPE_ACTIVE)
+#define HOSTCTLRTEST_CFG_SCAN_FILT_POLICY    (BLE_HCI_SCAN_FILT_NO_WL)
+#define HOSTCTLRTEST_CFG_CONN_ITVL           (1000)  /* 1250 msecs */           
+#define HOSTCTLRTEST_CFG_SLAVE_LATENCY       (0)
+#define HOSTCTLRTEST_CFG_INIT_FILTER_POLICY  (BLE_HCI_CONN_FILT_NO_WL)
+#define HOSTCTLRTEST_CFG_CONN_SPVN_TMO       (1000)  /* 10 seconds */
+#define HOSTCTLRTEST_CFG_MIN_CE_LEN          (1000)    
+#define HOSTCTLRTEST_CFG_MAX_CE_LEN          (HOSTCTLRTEST_CFG_CONN_ITVL * 2)
+
+/* HOSTCTLRTEST variables */
+#define HOSTCTLRTEST_STACK_SIZE              (256)
+#define HOSTCTLRTEST_TASK_PRIO               (HOST_TASK_PRIO + 1)
+uint32_t g_next_os_time;
+int g_hostctlrtest_state;
+struct os_eventq g_hostctlrtest_evq;
+struct os_task hostctlrtest_task;
+os_stack_t hostctlrtest_stack[HOSTCTLRTEST_STACK_SIZE];
+
+void
+bletest_inc_adv_pkt_num(void) { }
+
+
+#if HOSTCTLRTEST_CFG_ROLE == HOSTCTLRTEST_ROLE_ADVERTISER
+static int
+hostctlrtest_on_disc(uint16_t conn_handle, int status,
+                     struct ble_gatt_service *service, void *arg)
+{
+    int i;
+
+    if (status != 0) {
+        console_printf("service discovery failure: status=%d\n", status);
+        return 0;
+    }
+
+    if (service == NULL) {
+        return 0;
+    }
+
+    console_printf("service discovered: start_handle=%d end_handle=%d, uuid=",
+                   service->start_handle, service->end_handle);
+    for (i = 0; i < 16; i++) {
+        if (i != 0) {
+            console_printf(":");
+        }
+        console_printf("%02x", service->uuid128[i]);
+    }
+    console_printf("\n");
+
+    return 0;
+}
+#endif
+
+#if HOSTCTLRTEST_CFG_ROLE == HOSTCTLRTEST_ROLE_INITIATOR
+static int
+hostctlrtest_attr_cb(struct ble_att_svr_entry *entry, uint8_t op,
+                     union ble_att_svr_handle_arg *arg)
+{
+    static uint8_t buf[128];
+
+    assert(op == BLE_ATT_OP_READ_REQ);
+
+    htole16(buf, 0x1234);
+
+    arg->aha_read.attr_data = buf;
+    arg->aha_read.attr_len = 2;
+
+    return 0;
+}
+
+static void
+hostctlrtest_register_attrs(void)
+{
+    uint8_t uuid128[16];
+    uint16_t handle_id;
+    int rc;
+
+    rc = ble_hs_uuid_from_16bit(0x2800, uuid128);
+    assert(rc == 0);
+
+    ble_att_svr_register(uuid128, 0, &handle_id, hostctlrtest_attr_cb);
+}
+#endif
+
+static void
+hostctlrtest_on_connect(struct ble_gap_connect_desc *desc, void *arg)
+{
+    console_printf("connection complete; handle=%d status=%d "
+                   "peer_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
+                   desc->handle, desc->status, desc->peer_addr[0],
+                   desc->peer_addr[1], desc->peer_addr[2], desc->peer_addr[3],
+                   desc->peer_addr[4], desc->peer_addr[5]);
+
+#if HOSTCTLRTEST_CFG_ROLE == HOSTCTLRTEST_ROLE_ADVERTISER
+    ble_gatt_disc_all_services(desc->handle, hostctlrtest_on_disc, NULL);
+#endif
+}
+
+/**
+ * BLE test task 
+ * 
+ * @param arg 
+ */
+void
+hostctlrtest_task_handler(void *arg)
+{
+    struct os_event *ev;
+    struct os_callout_func *cf;
+    int rc;
+
+    /* We are initialized */
+    console_printf("Starting BLE test task\n");
+
+    /* Initialize eventq */
+    os_eventq_init(&g_hostctlrtest_evq);
+
+    /* Init hostctlrtest variables */
+    g_hostctlrtest_state = 0;
+    g_next_os_time = os_time_get();
+    
+    ble_gap_set_connect_cb(hostctlrtest_on_connect, NULL);
+
+#if HOSTCTLRTEST_CFG_ROLE == HOSTCTLRTEST_ROLE_ADVERTISER
+    console_printf("ble_gap_directed_connectable\n");
+    rc = ble_gap_directed_connectable(BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+                                      hostctlrtest_mst_addr);
+#else
+    hostctlrtest_register_attrs();
+    console_printf("ble_gap_direct_connection_establishment\n");
+    rc = ble_gap_direct_connection_establishment(BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+                                                 hostctlrtest_slv_addr);
+#endif
+    assert(rc == 0);
+
+    while (1) {
+        ev = os_eventq_get(&g_hostctlrtest_evq);
+        switch (ev->ev_type) {
+        case OS_EVENT_T_TIMER:
+            cf = (struct os_callout_func *)ev;
+            assert(cf->cf_func);
+            cf->cf_func(cf->cf_arg);
+            break;
+        default:
+            assert(0);
+            break;
+        }
+    }
+}
+
+/**
+ * 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.
+ */
+static int
+init_tasks(void)
+{
+    int rc;
+
+    os_task_init(&hostctlrtest_task, "hostctlrtest", hostctlrtest_task_handler,
+                 NULL, HOSTCTLRTEST_TASK_PRIO, OS_WAIT_FOREVER,
+                 hostctlrtest_stack, HOSTCTLRTEST_STACK_SIZE);
+
+    tasks_initialized = 1;
+
+    /* Initialize host HCI */
+    rc = ble_hs_init(HOST_TASK_PRIO);
+    assert(rc == 0);
+
+    /* Initialize the BLE LL */
+    ble_ll_init();
+
+    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(void)
+{
+    int i;
+    int rc;
+    uint32_t seed;
+
+    /* Initialize OS */
+    os_init();
+
+    /* Set cputime to count at 1 usec increments */
+    rc = cputime_init(1000000);
+    assert(rc == 0);
+
+    rc = os_mempool_init(&g_mbuf_mempool, MBUF_NUM_MBUFS, 
+            MBUF_MEMBLOCK_SIZE, &g_mbuf_buffer[0], "mbuf_pool");
+
+    rc = os_mbuf_pool_init(&g_mbuf_pool, &g_mbuf_mempool, MBUF_MEMBLOCK_SIZE, 
+                           MBUF_NUM_MBUFS);
+    assert(rc == 0);
+
+    /* Dummy device address */
+#if HOSTCTLRTEST_CFG_ROLE == HOSTCTLRTEST_ROLE_ADVERTISER
+    memcpy(g_dev_addr, hostctlrtest_slv_addr, 6);
+#else
+    memcpy(g_dev_addr, hostctlrtest_mst_addr, 6);
+#endif
+
+    /* 
+     * Seed random number generator with least significant bytes of device
+     * address.
+     */ 
+    seed = 0;
+    for (i = 0; i < 4; ++i) {
+        seed |= g_dev_addr[i];
+        seed <<= 8;
+    }
+    srand(seed);
+
+    /* Set the led pin as an output */
+    g_led_pin = LED_BLINK_PIN;
+    gpio_init_out(g_led_pin, 1);
+
+    /* Init the console */
+    rc = console_init(NULL);
+    assert(rc == 0);
+
+    /* Init tasks */
+    init_tasks();
+
+    /* Start the OS */
+    os_start();
+
+    /* os start should never return. If it does, this should be an error */
+    assert(0);
+
+    return rc;
+}
+


[2/3] incubator-mynewt-larva git commit: ATT read by group type; fix bugs.

Posted by cc...@apache.org.
ATT read by group type; fix bugs.


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

Branch: refs/heads/master
Commit: c1ac77ce1231b259ea0283745fe145f83143d4a5
Parents: 984a4b4
Author: Christopher Collins <cc...@gmail.com>
Authored: Tue Dec 8 18:37:57 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Tue Dec 8 18:42:06 2015 -0800

----------------------------------------------------------------------
 compiler/arm-none-eabi-m4/compiler.yml      |   2 +-
 net/nimble/host/include/host/ble_att.h      |  63 +++--
 net/nimble/host/src/ble_att.c               |  21 ++
 net/nimble/host/src/ble_att_clt.c           | 107 ++++----
 net/nimble/host/src/ble_att_cmd.h           |   2 +
 net/nimble/host/src/ble_att_priv.h          |   4 +
 net/nimble/host/src/ble_att_svr.c           | 301 ++++++++++++++++++++++-
 net/nimble/host/src/ble_gatt.c              |   3 -
 net/nimble/host/src/ble_hs.c                |   2 +-
 net/nimble/host/src/ble_hs_uuid.c           |   2 +-
 net/nimble/host/src/ble_l2cap.c             |   4 +-
 net/nimble/host/src/host_hci.c              |  21 +-
 net/nimble/host/src/test/ble_hs_test_util.c |   3 +-
 net/nimble/host/src/test/ble_l2cap_test.c   |   2 +-
 14 files changed, 446 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/compiler/arm-none-eabi-m4/compiler.yml
----------------------------------------------------------------------
diff --git a/compiler/arm-none-eabi-m4/compiler.yml b/compiler/arm-none-eabi-m4/compiler.yml
index 8cde544..29a9bcf 100644
--- a/compiler/arm-none-eabi-m4/compiler.yml
+++ b/compiler/arm-none-eabi-m4/compiler.yml
@@ -24,7 +24,7 @@ compiler.path.objcopy: arm-none-eabi-objcopy
 
 compiler.flags.default: -mcpu=cortex-m4 -mthumb-interwork -mthumb -Wall -Werror -fno-exceptions
 compiler.flags.optimized: [compiler.flags.default, -Os -ggdb] 
-compiler.flags.debug: [compiler.flags.default, -O1 -ggdb]
+compiler.flags.debug: [compiler.flags.default, -O0 -ggdb]
 
 compiler.ld.flags: -static -lgcc 
 compiler.ld.resolve_circular_deps: true

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/include/host/ble_att.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_att.h b/net/nimble/host/include/host/ble_att.h
index 18ee5cd..f8375d5 100644
--- a/net/nimble/host/include/host/ble_att.h
+++ b/net/nimble/host/include/host/ble_att.h
@@ -1,21 +1,42 @@
+/**
+ * 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_ATT_
 #define H_BLE_ATT_
 
-#define BLE_ATT_OP_ERROR_RSP             0x01
-#define BLE_ATT_OP_MTU_REQ               0x02
-#define BLE_ATT_OP_MTU_RSP               0x03
-#define BLE_ATT_OP_FIND_INFO_REQ         0x04
-#define BLE_ATT_OP_FIND_INFO_RSP         0x05
-#define BLE_ATT_OP_FIND_TYPE_VALUE_REQ   0x06
-#define BLE_ATT_OP_FIND_TYPE_VALUE_RSP   0x07
-#define BLE_ATT_OP_READ_TYPE_REQ         0x08
-#define BLE_ATT_OP_READ_TYPE_RSP         0x09
-#define BLE_ATT_OP_READ_REQ              0x0a
-#define BLE_ATT_OP_READ_RSP              0x0b
-#define BLE_ATT_OP_READ_GROUP_TYPE_REQ   0x10
-#define BLE_ATT_OP_READ_GROUP_TYPE_RSP   0x11
-#define BLE_ATT_OP_WRITE_REQ             0x12
-#define BLE_ATT_OP_WRITE_RSP             0x13
+#define BLE_ATT_UUID_PRIMARY_SERVICE        0x2800
+#define BLE_ATT_UUID_SECONDARY_SERVICE      0x2801
+#define BLE_ATT_UUID_INCLUDE                0x2802
+#define BLE_ATT_UUID_CHARACTERISTIC         0x2803
+
+#define BLE_ATT_OP_ERROR_RSP                0x01
+#define BLE_ATT_OP_MTU_REQ                  0x02
+#define BLE_ATT_OP_MTU_RSP                  0x03
+#define BLE_ATT_OP_FIND_INFO_REQ            0x04
+#define BLE_ATT_OP_FIND_INFO_RSP            0x05
+#define BLE_ATT_OP_FIND_TYPE_VALUE_REQ      0x06
+#define BLE_ATT_OP_FIND_TYPE_VALUE_RSP      0x07
+#define BLE_ATT_OP_READ_TYPE_REQ            0x08
+#define BLE_ATT_OP_READ_TYPE_RSP            0x09
+#define BLE_ATT_OP_READ_REQ                 0x0a
+#define BLE_ATT_OP_READ_RSP                 0x0b
+#define BLE_ATT_OP_READ_GROUP_TYPE_REQ      0x10
+#define BLE_ATT_OP_READ_GROUP_TYPE_RSP      0x11
+#define BLE_ATT_OP_WRITE_REQ                0x12
+#define BLE_ATT_OP_WRITE_RSP                0x13
 
 union ble_att_svr_handle_arg {
     struct {
@@ -29,12 +50,12 @@ union ble_att_svr_handle_arg {
     } aha_write;
 };
 
-#define HA_FLAG_PERM_READ            (1 << 0)
-#define HA_FLAG_PERM_WRITE           (1 << 1) 
-#define HA_FLAG_PERM_RW              (1 << 2)
-#define HA_FLAG_ENC_REQ              (1 << 3)
-#define HA_FLAG_AUTHENTICATION_REQ   (1 << 4)
-#define HA_FLAG_AUTHORIZATION_REQ    (1 << 5)
+#define HA_FLAG_PERM_READ                   (1 << 0)
+#define HA_FLAG_PERM_WRITE                  (1 << 1)
+#define HA_FLAG_PERM_RW                     (1 << 2)
+#define HA_FLAG_ENC_REQ                     (1 << 3)
+#define HA_FLAG_AUTHENTICATION_REQ          (1 << 4)
+#define HA_FLAG_AUTHORIZATION_REQ           (1 << 5)
 
 struct ble_att_svr_entry;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c
index 7ef6424..1398d39 100644
--- a/net/nimble/host/src/ble_att.c
+++ b/net/nimble/host/src/ble_att.c
@@ -16,6 +16,7 @@
 
 #include <stddef.h>
 #include <errno.h>
+#include "host/ble_hs.h"
 #include "ble_l2cap.h"
 #include "ble_att_cmd.h"
 #include "ble_att_priv.h"
@@ -41,6 +42,7 @@ static struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = {
     { BLE_ATT_OP_READ_TYPE_RSP,        ble_att_clt_rx_read_type },
     { BLE_ATT_OP_READ_REQ,             ble_att_svr_rx_read },
     { BLE_ATT_OP_READ_RSP,             ble_att_clt_rx_read },
+    { BLE_ATT_OP_READ_GROUP_TYPE_REQ,  ble_att_svr_rx_read_group_type },
     { BLE_ATT_OP_READ_GROUP_TYPE_RSP,  ble_att_clt_rx_read_group_type },
     { BLE_ATT_OP_WRITE_REQ,            ble_att_svr_rx_write },
 };
@@ -121,3 +123,22 @@ ble_att_create_chan(void)
 
     return chan;
 }
+
+/**
+ * Allocates an mbuf for use as an ATT request or response.
+ */
+struct os_mbuf *
+ble_att_get_pkthdr(void)
+{
+    struct os_mbuf *om;
+
+    om = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    if (om == NULL) {
+        return NULL;
+    }
+
+    /* Make room in the buffer for various headers.  XXX Check this number. */
+    om->om_data += 8;
+
+    return om;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c
index e78b337..ae90413 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -37,15 +37,12 @@ ble_att_clt_prep_req(struct ble_hs_conn *conn, struct ble_l2cap_chan **chan,
     *chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
     assert(*chan != NULL);
 
-    *txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    *txom = ble_att_get_pkthdr();
     if (*txom == NULL) {
         rc = ENOMEM;
         goto err;
     }
 
-    /* Make room in the buffer for various headers.  XXX Check this number. */
-    (*txom)->om_data += 8;
-
     buf = os_mbuf_extend(*txom, initial_sz);
     if (buf == NULL) {
         rc = ENOMEM;
@@ -358,54 +355,6 @@ done:
 }
 
 int
-ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn,
-                               struct ble_att_read_group_type_req *req,
-                               void *uuid128)
-{
-    struct ble_l2cap_chan *chan;
-    struct os_mbuf *txom;
-    int rc;
-
-    txom = NULL;
-
-    if (req->bagq_start_handle == 0 ||
-        req->bagq_start_handle > req->bagq_end_handle) {
-
-        rc = EINVAL;
-        goto err;
-    }
-
-    rc = ble_att_clt_prep_req(conn, &chan, &txom,
-                              BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ);
-    if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_att_read_group_type_req_write(txom->om_data, txom->om_len,
-                                              req);
-    if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_hs_uuid_append(txom, uuid128);
-    if (rc != 0) {
-        goto err;
-    }
-
-    rc = ble_l2cap_tx(conn, chan, txom);
-    txom = NULL;
-    if (rc != 0) {
-        goto err;
-    }
-
-    return 0;
-
-err:
-    os_mbuf_free_chain(txom);
-    return rc;
-}
-
-int
 ble_att_clt_tx_read(struct ble_hs_conn *conn, struct ble_att_read_req *req)
 {
     struct ble_l2cap_chan *chan;
@@ -475,10 +424,62 @@ done:
     return rc;
 }
 
+int
+ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn,
+                               struct ble_att_read_group_type_req *req,
+                               void *uuid128)
+{
+    struct ble_l2cap_chan *chan;
+    struct os_mbuf *txom;
+    int rc;
+
+    txom = NULL;
+
+    if (req->bagq_start_handle == 0 ||
+        req->bagq_start_handle > req->bagq_end_handle) {
+
+        rc = EINVAL;
+        goto err;
+    }
+
+    rc = ble_att_clt_prep_req(conn, &chan, &txom,
+                              BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_att_read_group_type_req_write(txom->om_data, txom->om_len,
+                                              req);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_hs_uuid_append(txom, uuid128);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = ble_l2cap_tx(conn, chan, txom);
+    txom = NULL;
+    if (rc != 0) {
+        goto err;
+    }
+
+    return 0;
+
+err:
+    os_mbuf_free_chain(txom);
+    return rc;
+}
+
 static int
 ble_att_clt_parse_group_attribute_data(struct os_mbuf **om, int data_len,
-                                 struct ble_att_clt_adata *adata)
+                                       struct ble_att_clt_adata *adata)
 {
+    if (data_len < BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 1) {
+        return EMSGSIZE;
+    }
+
     *om = os_mbuf_pullup(*om, data_len);
     if (*om == NULL) {
         return ENOMEM;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_cmd.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_cmd.h b/net/nimble/host/src/ble_att_cmd.h
index cd757d6..499aebf 100644
--- a/net/nimble/host/src/ble_att_cmd.h
+++ b/net/nimble/host/src/ble_att_cmd.h
@@ -175,6 +175,8 @@ struct ble_att_read_group_type_rsp {
 };
 
 #define BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ   4
+#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16     6
+#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128    20
 
 /**
  * | Parameter                          | Size (octets)     |

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_priv.h b/net/nimble/host/src/ble_att_priv.h
index f8d7539..b8bcec2 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -72,6 +72,7 @@ SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry);
 /*** @gen */
 struct ble_l2cap_chan *ble_att_create_chan(void);
 void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
+struct os_mbuf *ble_att_get_pkthdr(void);
 
 /*** @svr */
 int ble_att_svr_rx_mtu(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
@@ -85,6 +86,9 @@ int ble_att_svr_rx_find_type_value(struct ble_hs_conn *conn,
 int ble_att_svr_rx_read_type(struct ble_hs_conn *conn,
                              struct ble_l2cap_chan *chan,
                              struct os_mbuf **rxom);
+int ble_att_svr_rx_read_group_type(struct ble_hs_conn *conn,
+                                   struct ble_l2cap_chan *chan,
+                                   struct os_mbuf **rxom);
 int ble_att_svr_rx_read(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                         struct os_mbuf **rxom);
 int ble_att_svr_rx_write(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c
index 611c0e9..7b688d3 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -273,7 +273,7 @@ ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     void *dst;
     int rc;
 
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    txom = ble_att_get_pkthdr();
     if (txom == NULL) {
         rc = BLE_ATT_ERR_INSUFFICIENT_RES;
         goto err;
@@ -318,7 +318,7 @@ ble_att_svr_tx_mtu_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     assert(op == BLE_ATT_OP_MTU_REQ || op == BLE_ATT_OP_MTU_RSP);
     assert(mtu >= BLE_ATT_MTU_DFLT);
 
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    txom = ble_att_get_pkthdr();
     if (txom == NULL) {
         rc = BLE_ATT_ERR_INSUFFICIENT_RES;
         goto err;
@@ -528,7 +528,7 @@ ble_att_svr_rx_find_info(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
         goto err;
     }
 
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    txom = ble_att_get_pkthdr();
     if (txom == NULL) {
         rc = BLE_ATT_ERR_INSUFFICIENT_RES;
         goto err;
@@ -815,7 +815,7 @@ ble_att_svr_rx_find_type_value(struct ble_hs_conn *conn,
         goto err;
     }
 
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    txom = ble_att_get_pkthdr();
     if (txom == NULL) {
         rc = BLE_ATT_ERR_INSUFFICIENT_RES;
         goto err;
@@ -868,7 +868,7 @@ ble_att_svr_tx_read_type_rsp(struct ble_hs_conn *conn,
     int attr_len;
     int rc;
 
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    txom = ble_att_get_pkthdr();
     if (txom == NULL) {
         rc = BLE_ATT_ERR_INSUFFICIENT_RES;
         goto err;
@@ -1017,7 +1017,7 @@ ble_att_svr_tx_read_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     uint8_t op;
     int rc;
 
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    txom = ble_att_get_pkthdr();
     if (txom == NULL) {
         rc = BLE_ATT_ERR_INSUFFICIENT_RES;
         goto err;
@@ -1109,13 +1109,300 @@ err:
 }
 
 static int
+ble_att_svr_is_valid_group_type(uint8_t *uuid128)
+{
+    uint16_t uuid16;
+
+    uuid16 = ble_hs_uuid_16bit(uuid128);
+
+    return uuid16 == BLE_ATT_UUID_PRIMARY_SERVICE ||
+           uuid16 == BLE_ATT_UUID_SECONDARY_SERVICE;
+}
+
+static int
+ble_att_svr_is_valid_group_member(uint8_t *uuid128)
+{
+    uint16_t uuid16;
+
+    /* Assumes the group type is primary or secondary service. */
+
+    uuid16 = ble_hs_uuid_16bit(uuid128);
+
+    return uuid16 == BLE_ATT_UUID_INCLUDE ||
+           uuid16 == BLE_ATT_UUID_CHARACTERISTIC;
+}
+
+static int
+ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, uint16_t *uuid16,
+                         uint8_t *uuid128)
+{
+    union ble_att_svr_handle_arg arg;
+    int rc;
+
+    rc = entry->ha_fn(entry, BLE_ATT_OP_READ_REQ, &arg);
+    if (rc != 0) {
+        return rc;
+    }
+
+    switch (arg.aha_read.attr_len) {
+    case 16:
+        *uuid16 = 0;
+        memcpy(uuid128, arg.aha_read.attr_data, 16);
+        return 0;
+
+    case 2:
+        *uuid16 = le16toh(arg.aha_read.attr_data);
+        if (*uuid16 == 0) {
+            return EINVAL;
+        }
+        return 0;
+
+    default:
+        return EINVAL;
+    }
+}
+
+static int
+ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu,
+                                        uint16_t start_group_handle,
+                                        uint16_t end_group_handle,
+                                        uint16_t service_uuid16,
+                                        uint8_t *service_uuid128)
+{
+    uint8_t *buf;
+    int len;
+
+    if (service_uuid16 != 0) {
+        len = BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16;
+    } else {
+        len = BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128;
+    }
+    if (OS_MBUF_PKTLEN(om) + len > mtu) {
+        return EMSGSIZE;
+    }
+
+    buf = os_mbuf_extend(om, len);
+    if (buf == NULL) {
+        return ENOMEM;
+    }
+
+    htole16(buf + 0, start_group_handle);
+    htole16(buf + 2, end_group_handle);
+    if (service_uuid16 != 0) {
+        htole16(buf + 4, service_uuid16);
+    } else {
+        memcpy(buf + 4, service_uuid128, 16);
+    }
+
+    return 0;
+}
+
+static int
+ble_att_svr_tx_read_group_type(struct ble_hs_conn *conn,
+                               struct ble_l2cap_chan *chan,
+                               struct ble_att_read_group_type_req *req,
+                               uint8_t *group_uuid128, uint16_t *err_handle)
+{
+    struct ble_att_read_group_type_rsp rsp;
+    struct ble_att_svr_entry *entry;
+    struct os_mbuf *txom;
+    uint16_t start_group_handle;
+    uint16_t end_group_handle;
+    uint16_t service_uuid16;
+    uint8_t service_uuid128[16];
+    void *rsp_buf;
+    int rc;
+
+    *err_handle = req->bagq_start_handle;
+
+    txom = ble_att_get_pkthdr();
+    if (txom == NULL) {
+        rc = BLE_ATT_ERR_INSUFFICIENT_RES;
+        goto done;
+    }
+
+    /* Reserve space for the response base. */
+    rsp_buf = os_mbuf_extend(txom, BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ);
+    if (rsp_buf == NULL) {
+        rc = BLE_ATT_ERR_INSUFFICIENT_RES;
+        goto done;
+    }
+
+    start_group_handle = 0;
+    rsp.bagp_length = 0;
+    STAILQ_FOREACH(entry, &ble_att_svr_list, ha_next) {
+        if (entry->ha_handle_id < req->bagq_start_handle) {
+            continue;
+        }
+        if (entry->ha_handle_id > req->bagq_end_handle) {
+            /* The full input range has been searched. */
+            rc = 0;
+            goto done;
+        }
+
+        if (start_group_handle != 0) {
+            /* We have already found the start of a group. */
+            if (ble_att_svr_is_valid_group_member(entry->ha_uuid)) {
+                /* This attribute is part of the current group. */ 
+                end_group_handle = entry->ha_handle_id;
+            } else {
+                /* This attribute marks the end of the group.  Write an entry
+                 * representing the group to the response.
+                 */
+                rc = ble_att_svr_read_group_type_entry_write(
+                    txom, ble_l2cap_chan_mtu(chan),
+                    start_group_handle, end_group_handle,
+                    service_uuid16, service_uuid128);
+                start_group_handle = 0;
+                end_group_handle = 0;
+                if (rc != 0) {
+                    *err_handle = entry->ha_handle_id;
+                    goto done;
+                }
+            }
+        }
+
+        if (start_group_handle == 0) {
+            /* We are looking for the start of a group. */
+            if (memcmp(entry->ha_uuid, group_uuid128, 16) == 0) {
+                /* Found a group start.  Read the group UUID. */
+                rc = ble_att_svr_service_uuid(entry, &service_uuid16,
+                                              service_uuid128);
+                if (rc != 0) {
+                    *err_handle = entry->ha_handle_id;
+                    rc = BLE_ATT_ERR_UNLIKELY;
+                    goto done;
+                }
+
+                /* Make sure the group UUID lengths are consistent.  If this
+                 * group has a different length UUID, then cut the response
+                 * short.
+                 */
+                switch (rsp.bagp_length) {
+                case 0:
+                    if (service_uuid16 != 0) {
+                        rsp.bagp_length =
+                            BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 2;
+                    } else {
+                        rsp.bagp_length =
+                            BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 16;
+                    }
+                    break;
+
+                case BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 2:
+                    if (service_uuid16 == 0) {
+                        rc = 0;
+                        goto done;
+                    }
+                    break;
+
+                case BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 16:
+                    if (service_uuid16 != 0) {
+                        rc = 0;
+                        goto done;
+                    }
+                    break;
+
+                default:
+                    assert(0);
+                    goto done;
+                }
+
+                start_group_handle = entry->ha_handle_id;
+                end_group_handle = entry->ha_handle_id;
+            }
+        }
+    }
+
+    rc = 0;
+
+done:
+    if (rc == 0) {
+        if (start_group_handle != 0) {
+            /* A group was being processed.  Add its corresponding entry to the
+             * response.
+             */
+            rc = ble_att_svr_read_group_type_entry_write(
+                txom, ble_l2cap_chan_mtu(chan),
+                start_group_handle, end_group_handle,
+                service_uuid16, service_uuid128);
+        } else {
+            rc = BLE_ATT_ERR_ATTR_NOT_FOUND;
+        }
+    }
+
+    if (rc == 0 || rc == EMSGSIZE) {
+        rc = ble_att_read_group_type_rsp_write(
+            rsp_buf, BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ, &rsp);
+        assert(rc == 0);
+
+        rc = ble_l2cap_tx(conn, chan, txom);
+    } else {
+        os_mbuf_free_chain(txom);
+    }
+
+    return rc;
+}
+
+
+int
+ble_att_svr_rx_read_group_type(struct ble_hs_conn *conn,
+                               struct ble_l2cap_chan *chan,
+                               struct os_mbuf **rxom)
+{
+    struct ble_att_read_group_type_req req;
+    uint16_t err_handle;
+    uint8_t uuid128[16];
+    int rc;
+
+    err_handle = 0;
+
+    *rxom = os_mbuf_pullup(*rxom, OS_MBUF_PKTLEN(*rxom));
+    if (*rxom == NULL) {
+        rc = ENOMEM;
+        goto err;
+    }
+
+    rc = ble_att_read_group_type_req_parse((*rxom)->om_data, (*rxom)->om_len,
+                                           &req);
+    if (rc != 0) {
+        goto err;
+    }
+    err_handle = req.bagq_start_handle;
+
+    rc = ble_hs_uuid_extract(*rxom, BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ,
+                             uuid128);
+    if (rc != 0) {
+        goto err;
+    }
+
+    if (!ble_att_svr_is_valid_group_type(uuid128)) {
+        rc = EINVAL; // XXX
+        goto err;
+    }
+
+    rc = ble_att_svr_tx_read_group_type(conn, chan, &req, uuid128,
+                                        &err_handle);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return 0;
+
+err:
+    ble_att_svr_tx_error_rsp(conn, chan, BLE_ATT_OP_READ_GROUP_TYPE_REQ,
+                             err_handle, rc);
+    return rc;
+}
+
+static int
 ble_att_svr_tx_write_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan)
 {
     struct os_mbuf *txom;
     uint8_t *dst;
     int rc;
 
-    txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0);
+    txom = ble_att_get_pkthdr();
     if (txom == NULL) {
         rc = BLE_ATT_ERR_INSUFFICIENT_RES;
         goto err;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_gatt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt.c b/net/nimble/host/src/ble_gatt.c
index d8575c4..55e4b0b 100644
--- a/net/nimble/host/src/ble_gatt.c
+++ b/net/nimble/host/src/ble_gatt.c
@@ -28,9 +28,6 @@
 #include "ble_att_cmd.h"
 #include "ble_att_priv.h"
 
-#define BLE_ATT_UUID_PRIMARY_SERVICE    0x2800
-#define BLE_ATT_UUID_CHARACTERISTIC     0x2803
-
 struct ble_gatt_entry {
     STAILQ_ENTRY(ble_gatt_entry) next;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/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 b6800e3..b196f78 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -39,7 +39,7 @@
 static struct os_task ble_hs_task;
 static os_stack_t ble_hs_stack[BLE_HS_STACK_SIZE];
 
-#define HCI_CMD_BUFS        (8)
+#define HCI_CMD_BUFS        (6)
 #define HCI_CMD_BUF_SIZE    (260)       /* XXX: temporary, Fix later */
 struct os_mempool g_hci_cmd_pool;
 static os_membuf_t g_hci_cmd_buf[OS_MEMPOOL_BYTES(HCI_CMD_BUFS,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_hs_uuid.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_uuid.c b/net/nimble/host/src/ble_hs_uuid.c
index fe2dfae..eb3d943 100644
--- a/net/nimble/host/src/ble_hs_uuid.c
+++ b/net/nimble/host/src/ble_hs_uuid.c
@@ -114,7 +114,7 @@ ble_hs_uuid_extract(struct os_mbuf *om, int off, void *uuid128)
     int remlen;
     int rc;
 
-    remlen = OS_MBUF_PKTHDR(om)->omp_len;
+    remlen = OS_MBUF_PKTHDR(om)->omp_len - off;
     switch (remlen) {
     case 2:
         rc = os_mbuf_copydata(om, off, 2, &uuid16);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_l2cap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c
index 2a4e81b..f75e91d 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -147,7 +147,8 @@ ble_l2cap_rx(struct ble_hs_conn *conn,
     int rc;
 
     /* XXX: HCI-fragmentation unsupported. */
-    assert(BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc) == BLE_HCI_PB_FULL);
+    assert(BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc) ==
+                           BLE_HCI_PB_FIRST_FLUSH);
 
     rc = ble_l2cap_parse_hdr(om, 0, &l2cap_hdr);
     if (rc != 0) {
@@ -196,6 +197,7 @@ ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     }
 
     rc = host_hci_data_tx(conn, om);
+    om = NULL;
     if (rc != 0) {
         goto err;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/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 67d3def..7ff42de 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -413,6 +413,19 @@ host_hci_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *hdr)
     return 0;
 }
 
+static void
+host_hci_log_pkt(struct os_mbuf *om)
+{
+    uint8_t u8;
+    int i;
+
+    for (i = 0; i < OS_MBUF_PKTLEN(om); i++) {
+        os_mbuf_copydata(om, i, 1, &u8);
+        console_printf("0x%02x ", u8);
+    }
+    console_printf("\n");
+}
+
 /**
  * Called when a data packet is received from the controller.  This function
  * consumes the supplied mbuf, regardless of the outcome.
@@ -430,6 +443,9 @@ host_hci_data_rx(struct os_mbuf *om)
     uint16_t handle;
     int rc;
 
+    console_printf("host_hci_data_rx(): ");
+    host_hci_log_pkt(om);
+
     rc = host_hci_data_hdr_strip(om, &hci_hdr);
     if (rc != 0) {
         goto done;
@@ -501,11 +517,14 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om)
      * requirements.  For now, never fragment.
      */
     om = host_hci_data_hdr_prepend(om, connection->bhc_handle,
-                                   BLE_HCI_PB_FULL);
+                                   BLE_HCI_PB_FIRST_NON_FLUSH);
     if (om == NULL) {
         return ENOMEM;
     }
 
+    console_printf("host_hci_data_tx(): ");
+    host_hci_log_pkt(om);
+
     rc = ble_hs_tx_data(om);
     if (rc != 0) {
         return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/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 488e0d4..d7b6d3c 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -142,7 +142,8 @@ ble_hs_test_util_l2cap_rx_payload_flat(struct ble_hs_conn *conn,
     TEST_ASSERT_FATAL(om != NULL);
 
     hci_hdr.hdh_handle_pb_bc =
-        host_hci_handle_pb_bc_join(conn->bhc_handle, BLE_HCI_PB_FULL, 0);
+        host_hci_handle_pb_bc_join(conn->bhc_handle,
+                                   BLE_HCI_PB_FIRST_FLUSH, 0);
     hci_hdr.hdh_len = OS_MBUF_PKTHDR(om)->omp_len;
 
     rc = ble_l2cap_rx(conn, &hci_hdr, om);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/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 48fb259..a1fe064 100644
--- a/net/nimble/host/src/test/ble_l2cap_test.c
+++ b/net/nimble/host/src/test/ble_l2cap_test.c
@@ -39,7 +39,7 @@ TEST_CASE(l2cap_test_bad_header)
     TEST_ASSERT_FATAL(conn != NULL);
 
     hci_hdr.hdh_handle_pb_bc =
-        host_hci_handle_pb_bc_join(0, BLE_HCI_PB_FULL, 0);
+        host_hci_handle_pb_bc_join(0, BLE_HCI_PB_FIRST_FLUSH, 0);
     hci_hdr.hdh_len = 10;
 
     /*** HCI header indicates a length of 10, but L2CAP header has a length