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 2016/07/15 04:29:58 UTC

[1/9] incubator-mynewt-core git commit: BLE Host - GATT procedures handled in wrong order.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop c487de2da -> b236e3982


BLE Host - GATT procedures handled in wrong order.

This was a problem when the application initiated two concurrent GATT
procedures with the same op code.  In this case, when a response was
received, it was paired with the incorrect GATT procedure when the
callback was executed.

The fix is to append GATT procedures to the tail of the stailq rather
than the head.


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

Branch: refs/heads/develop
Commit: 3326bba629e24c6f173ac46dd54c23d80f9373b9
Parents: a7437b2
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 17:42:08 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:09 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_gattc.c               |  2 +-
 net/nimble/host/src/test/ble_gatt_read_test.c | 52 ++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3326bba6/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index 6a5e8ec..c3cbd88 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -618,7 +618,7 @@ ble_gattc_proc_insert(struct ble_gattc_proc *proc)
     ble_gattc_dbg_assert_proc_not_inserted(proc);
 
     ble_hs_lock();
-    STAILQ_INSERT_HEAD(&ble_gattc_procs, proc, next);
+    STAILQ_INSERT_TAIL(&ble_gattc_procs, proc, next);
     ble_hs_unlock();
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3326bba6/net/nimble/host/src/test/ble_gatt_read_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatt_read_test.c b/net/nimble/host/src/test/ble_gatt_read_test.c
index d587702..606a554 100644
--- a/net/nimble/host/src/test/ble_gatt_read_test.c
+++ b/net/nimble/host/src/test/ble_gatt_read_test.c
@@ -723,12 +723,64 @@ TEST_CASE(ble_gatt_read_test_mult)
         } });
 }
 
+TEST_CASE(ble_gatt_read_test_concurrent)
+{
+    struct ble_gatt_attr attrs[3];
+    int rc;
+    int i;
+
+    ble_gatt_read_test_misc_init();
+    ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}),
+                                 NULL, NULL);
+
+    /***
+     * Perform three concurrent reads.  Assert that each response is correctly
+     * matched up with its corresponding GATT procedure.
+     */
+
+    attrs[0].handle = 1;
+    attrs[0].offset = 0;
+    attrs[0].value_len = 3;
+    attrs[0].value = (uint8_t[3]){ 1, 2, 3 };
+    rc = ble_gattc_read(2, attrs[0].handle, ble_gatt_read_test_cb, NULL);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    attrs[1].handle = 2;
+    attrs[1].offset = 0;
+    attrs[1].value_len = 4;
+    attrs[1].value = (uint8_t[4]){ 2, 3, 4, 5 };
+    rc = ble_gattc_read(2, attrs[1].handle, ble_gatt_read_test_cb, NULL);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    attrs[2].handle = 3;
+    attrs[2].offset = 0;
+    attrs[2].value_len = 5;
+    attrs[2].value = (uint8_t[5]){ 3, 4, 5, 6, 7 };
+    rc = ble_gattc_read(2, attrs[2].handle, ble_gatt_read_test_cb, NULL);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 0);
+    ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 1);
+    ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 2);
+
+    TEST_ASSERT(ble_gatt_read_test_num_attrs == 3);
+
+    for (i = 0; i < 3; i++) {
+        TEST_ASSERT(ble_gatt_read_test_attrs[i].handle == attrs[i].handle);
+        TEST_ASSERT(ble_gatt_read_test_attrs[i].value_len ==
+                    attrs[i].value_len);
+        TEST_ASSERT(memcmp(ble_gatt_read_test_attrs[i].value, attrs[i].value,
+                           attrs[i].value_len) == 0);
+    }
+}
+
 TEST_SUITE(ble_gatt_read_test_suite)
 {
     ble_gatt_read_test_by_handle();
     ble_gatt_read_test_by_uuid();
     ble_gatt_read_test_long();
     ble_gatt_read_test_mult();
+    ble_gatt_read_test_concurrent();
 }
 
 int


[6/9] incubator-mynewt-core git commit: BLE Host - Package for mandatory svcs (GAP & GATT)

Posted by cc...@apache.org.
BLE Host - Package for mandatory svcs (GAP & GATT)


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

Branch: refs/heads/develop
Commit: c5694893e3c3437e7f25f2b1ba1fa8197f0b3bff
Parents: cf06765
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 20:09:40 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:10 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gap.h          |   9 -
 net/nimble/host/include/host/ble_gatt.h         |   5 +-
 .../include/services/mandatory/ble_svc_gap.h    |  40 +++++
 .../include/services/mandatory/ble_svc_gatt.h   |  11 ++
 net/nimble/host/services/mandatory/pkg.yml      |  32 ++++
 .../host/services/mandatory/src/ble_svc_gap.c   | 172 +++++++++++++++++++
 .../host/services/mandatory/src/ble_svc_gatt.c  |  88 ++++++++++
 net/nimble/host/src/ble_gatt_priv.h             |   2 -
 net/nimble/host/src/ble_gatts.c                 |  21 +++
 9 files changed, 368 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/include/host/ble_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gap.h b/net/nimble/host/include/host/ble_gap.h
index e26a4c0..bb06ec4 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -86,15 +86,6 @@ struct hci_conn_update;
 #define BLE_GAP_INITIAL_CONN_MIN_CE_LEN     0x0010
 #define BLE_GAP_INITIAL_CONN_MAX_CE_LEN     0x0300
 
-#define BLE_GAP_SVC_UUID16                              0x1800
-#define BLE_GAP_CHR_UUID16_DEVICE_NAME                  0x2a00
-#define BLE_GAP_CHR_UUID16_APPEARANCE                   0x2a01
-#define BLE_GAP_CHR_UUID16_PERIPH_PRIV_FLAG             0x2a02
-#define BLE_GAP_CHR_UUID16_RECONNECT_ADDR               0x2a03
-#define BLE_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS      0x2a04
-
-#define BLE_GAP_APPEARANCE_GEN_COMPUTER                 128
-
 #define BLE_GAP_ADDR_TYPE_WL                0xff
 #define BLE_GAP_ADDR_TYPE_NONE              0xfe
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/include/host/ble_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gatt.h b/net/nimble/host/include/host/ble_gatt.h
index 5e798e7..76eae8a 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -24,13 +24,14 @@
 #include "host/ble_att.h"
 struct ble_hs_conn;
 struct ble_att_error_rsp;
+struct ble_hs_cfg;
 
 #define BLE_GATT_REGISTER_OP_SVC                        1
 #define BLE_GATT_REGISTER_OP_CHR                        2
 #define BLE_GATT_REGISTER_OP_DSC                        3
 
 #define BLE_GATT_SVC_UUID16                             0x1801
-#define BLE_GATT_CHR_SERVICE_CHANGED_UUID16             0x2a05
+#define BLE_GATT_DSC_CLT_CFG_UUID16                     0x2902
 
 #define BLE_GATT_CHR_PROP_BROADCAST                     0x01
 #define BLE_GATT_CHR_PROP_READ                          0x02
@@ -423,6 +424,8 @@ int ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs,
                             void *cb_arg);
 int ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
                               struct ble_gatt_resources *res);
+int ble_gatts_count_cfg(const struct ble_gatt_svc_def *defs,
+                        struct ble_hs_cfg *cfg);
 
 void ble_gatts_chr_updated(uint16_t chr_def_handle);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gap.h b/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gap.h
new file mode 100644
index 0000000..6076fdc
--- /dev/null
+++ b/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gap.h
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLE_SVC_GAP_
+#define H_BLE_SVC_GAP_
+
+struct ble_hs_cfg;
+
+#define BLE_SVC_GAP_UUID16                                  0x1800
+#define BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME                  0x2a00
+#define BLE_SVC_GAP_CHR_UUID16_APPEARANCE                   0x2a01
+#define BLE_SVC_GAP_CHR_UUID16_PERIPH_PRIV_FLAG             0x2a02
+#define BLE_SVC_GAP_CHR_UUID16_RECONNECT_ADDR               0x2a03
+#define BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS      0x2a04
+
+#define BLE_SVC_GAP_APPEARANCE_GEN_COMPUTER                 128
+
+const char *ble_svc_gap_device_name(void);
+int ble_svc_gap_device_name_set(const char *name);
+
+int ble_svc_gap_register(void);
+int ble_svc_gap_init(struct ble_hs_cfg *cfg);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gatt.h b/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gatt.h
new file mode 100644
index 0000000..a0ff6da
--- /dev/null
+++ b/net/nimble/host/services/mandatory/include/services/mandatory/ble_svc_gatt.h
@@ -0,0 +1,11 @@
+#ifndef H_BLE_SVC_GATT_
+#define H_BLE_SVC_GATT_
+
+struct ble_hs_cfg;
+
+#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16     0x2a05
+
+int ble_svc_gatt_register(void);
+int ble_svc_gatt_init(struct ble_hs_cfg *cfg);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/services/mandatory/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/services/mandatory/pkg.yml b/net/nimble/host/services/mandatory/pkg.yml
new file mode 100644
index 0000000..b63c634
--- /dev/null
+++ b/net/nimble/host/services/mandatory/pkg.yml
@@ -0,0 +1,32 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: net/nimble/host/services/mandatory
+pkg.description: Implements the two mandatory GATT services (GAP and GATT).
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - ble
+    - bluetooth
+    - nimble
+    - gatt
+    - gap
+
+pkg.deps:
+    - net/nimble/host

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/services/mandatory/src/ble_svc_gap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/services/mandatory/src/ble_svc_gap.c b/net/nimble/host/services/mandatory/src/ble_svc_gap.c
new file mode 100644
index 0000000..0afc5fc
--- /dev/null
+++ b/net/nimble/host/services/mandatory/src/ble_svc_gap.c
@@ -0,0 +1,172 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "host/ble_hs.h"
+#include "services/mandatory/ble_svc_gap.h"
+
+/* XXX: This should be configurable. */
+#define BLE_SVC_GAP_NAME_MAX_LEN    31
+
+static char ble_svc_gap_name[BLE_SVC_GAP_NAME_MAX_LEN + 1] = "nimble";
+static uint16_t ble_svc_gap_appearance;
+static uint8_t ble_svc_gap_privacy_flag;
+static uint8_t ble_svc_gap_reconnect_addr[6];
+static uint8_t ble_svc_gap_pref_conn_params[8];
+
+static int
+ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
+                   struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static const struct ble_gatt_svc_def ble_svc_gap_defs[] = {
+    {
+        /*** Service: GAP. */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(BLE_SVC_GAP_UUID16),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            /*** Characteristic: Device Name. */
+            .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME),
+            .access_cb = ble_svc_gap_access,
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            /*** Characteristic: Appearance. */
+            .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_APPEARANCE),
+            .access_cb = ble_svc_gap_access,
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            /*** Characteristic: Peripheral Privacy Flag. */
+            .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_PERIPH_PRIV_FLAG),
+            .access_cb = ble_svc_gap_access,
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            /*** Characteristic: Reconnection Address. */
+            .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_RECONNECT_ADDR),
+            .access_cb = ble_svc_gap_access,
+            .flags = BLE_GATT_CHR_F_WRITE,
+        }, {
+            /*** Characteristic: Peripheral Preferred Connection Parameters. */
+            .uuid128 =
+                BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS),
+            .access_cb = ble_svc_gap_access,
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            0, /* No more characteristics in this service. */
+        } },
+    },
+
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
+                   struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    uint16_t uuid16;
+
+    uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
+    assert(uuid16 != 0);
+
+    switch (uuid16) {
+    case BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME:
+        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->att->read.data = ble_svc_gap_name;
+        ctxt->att->read.len = strlen(ble_svc_gap_name);
+        break;
+
+    case BLE_SVC_GAP_CHR_UUID16_APPEARANCE:
+        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->att->read.data = &ble_svc_gap_appearance;
+        ctxt->att->read.len = sizeof ble_svc_gap_appearance;
+        break;
+
+    case BLE_SVC_GAP_CHR_UUID16_PERIPH_PRIV_FLAG:
+        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->att->read.data = &ble_svc_gap_privacy_flag;
+        ctxt->att->read.len = sizeof ble_svc_gap_privacy_flag;
+        break;
+
+    case BLE_SVC_GAP_CHR_UUID16_RECONNECT_ADDR:
+        assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR);
+        if (ctxt->att->write.len != sizeof ble_svc_gap_reconnect_addr) {
+            return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
+        }
+        memcpy(ble_svc_gap_reconnect_addr, ctxt->att->write.data,
+               sizeof ble_svc_gap_reconnect_addr);
+        break;
+
+    case BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS:
+        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+        ctxt->att->read.data = &ble_svc_gap_pref_conn_params;
+        ctxt->att->read.len = sizeof ble_svc_gap_pref_conn_params;
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+
+    return 0;
+}
+
+const char *
+ble_svc_gap_device_name(void)
+{
+    return ble_svc_gap_name;
+}
+
+int
+ble_svc_gap_device_name_set(const char *name)
+{
+    int len;
+
+    len = strlen(name);
+    if (len > BLE_SVC_GAP_NAME_MAX_LEN) {
+        return BLE_HS_EINVAL;
+    }
+
+    memcpy(ble_svc_gap_name, name, len);
+    ble_svc_gap_name[len] = '\0';
+
+    return 0;
+}
+
+int
+ble_svc_gap_register(void)
+{
+    int rc;
+
+    rc = ble_gatts_register_svcs(ble_svc_gap_defs, NULL, NULL);
+    return rc;
+}
+
+int
+ble_svc_gap_init(struct ble_hs_cfg *cfg)
+{
+    int rc;
+
+    rc = ble_gatts_count_cfg(ble_svc_gap_defs, cfg);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/services/mandatory/src/ble_svc_gatt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/services/mandatory/src/ble_svc_gatt.c b/net/nimble/host/services/mandatory/src/ble_svc_gatt.c
new file mode 100644
index 0000000..566efd8
--- /dev/null
+++ b/net/nimble/host/services/mandatory/src/ble_svc_gatt.c
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+
+#include "host/ble_hs.h"
+#include "services/mandatory/ble_svc_gatt.h"
+
+static int
+ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
+                    struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = {
+    {
+        /*** Service: GATT */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(BLE_GATT_SVC_UUID16),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16),
+            .access_cb = ble_svc_gatt_access,
+            .flags = BLE_GATT_CHR_F_INDICATE,
+        }, {
+            0, /* No more characteristics in this service. */
+        } },
+    },
+
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
+                    struct ble_gatt_access_ctxt *ctxt, void *arg)
+{
+    /* The only operation allowed for this characteristic is indicate.  This
+     * access callback gets called by the stack when it needs to read the
+     * characteristic value to populate the outgoing indication command.
+     * Therefore, this callback should only get called during an attempt to
+     * read the characteristic.
+     */
+    assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+    assert(ctxt->chr == &ble_svc_gatt_defs[0].characteristics[0]);
+
+    /* XXX: For now, always respond with 0 (unchanged). */
+    ctxt->att->read.buf[0] = 0;
+    ctxt->att->read.len = 1;
+
+    return 0;
+}
+
+int
+ble_svc_gatt_register(void)
+{
+    int rc;
+
+    rc = ble_gatts_register_svcs(ble_svc_gatt_defs, NULL, NULL);
+    return rc;
+}
+
+int
+ble_svc_gatt_init(struct ble_hs_cfg *cfg)
+{
+    int rc;
+
+    rc = ble_gatts_count_cfg(ble_svc_gatt_defs, cfg);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/src/ble_gatt_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt_priv.h b/net/nimble/host/src/ble_gatt_priv.h
index 9b4ae8a..071f20f 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -84,8 +84,6 @@ extern STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats;
 #define BLE_GATT_CHR_DECL_SZ_16     5
 #define BLE_GATT_CHR_DECL_SZ_128    19
 
-#define BLE_GATT_DSC_CLT_CFG_UUID16 0x2902
-
 typedef uint8_t ble_gatts_conn_flags;
 
 struct ble_gatts_conn {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5694893/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index b2ead0d..f8c7b03 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -1714,6 +1714,27 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
     return 0;
 }
 
+int
+ble_gatts_count_cfg(const struct ble_gatt_svc_def *defs,
+                    struct ble_hs_cfg *cfg)
+{
+    struct ble_gatt_resources res = { 0 };
+    int rc;
+
+    rc = ble_gatts_count_resources(defs, &res);
+    if (rc != 0) {
+        return rc;
+    }
+
+    cfg->max_services += res.svcs;
+    cfg->max_attrs += res.attrs;
+
+    /* Reserve an extra CCCD for the cache. */
+    cfg->max_client_configs += res.cccds * (cfg->max_connections + 1);
+
+    return 0;
+}
+
 static void
 ble_gatts_free_mem(void)
 {


[5/9] incubator-mynewt-core git commit: bletiny / bleprph - Use mandatory svcs pkg.

Posted by cc...@apache.org.
bletiny / bleprph - Use mandatory svcs pkg.


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

Branch: refs/heads/develop
Commit: 35d4eb8f2d4d4d67a83a2c97469700a54f5cc5dd
Parents: c569489
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 20:09:49 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:10 2016 -0700

----------------------------------------------------------------------
 apps/bleprph/pkg.yml        |   1 +
 apps/bleprph/src/bleprph.h  |  13 +--
 apps/bleprph/src/gatt_svr.c | 154 ++++--------------------------------
 apps/bleprph/src/main.c     |  53 ++++++++-----
 apps/bletiny/pkg.yml        |   1 +
 apps/bletiny/src/bletiny.h  |  14 +---
 apps/bletiny/src/gatt_svr.c | 167 ++++++---------------------------------
 apps/bletiny/src/main.c     |  50 +++++++-----
 8 files changed, 114 insertions(+), 339 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bleprph/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bleprph/pkg.yml b/apps/bleprph/pkg.yml
index 0cef560..a63f8ea 100644
--- a/apps/bleprph/pkg.yml
+++ b/apps/bleprph/pkg.yml
@@ -27,6 +27,7 @@ pkg.deps:
     - sys/log
     - net/nimble/controller
     - net/nimble/host
+    - net/nimble/host/services/mandatory
     - net/nimble/host/store/ram
     - libs/console/full
     - libs/baselibc

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bleprph/src/bleprph.h
----------------------------------------------------------------------
diff --git a/apps/bleprph/src/bleprph.h b/apps/bleprph/src/bleprph.h
index 0dba232..901e885 100644
--- a/apps/bleprph/src/bleprph.h
+++ b/apps/bleprph/src/bleprph.h
@@ -25,13 +25,6 @@ struct ble_hs_cfg;
 
 extern struct log bleprph_log;
 
-extern const char *bleprph_device_name;
-extern const uint16_t bleprph_appearance;
-extern const uint8_t bleprph_privacy_flag;
-extern uint8_t bleprph_reconnect_addr[6];
-extern uint8_t bleprph_pref_conn_params[8];
-extern uint8_t bleprph_gatt_service_changed[4];
-
 /* bleprph uses the first "peruser" log module. */
 #define BLEPRPH_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
 
@@ -46,11 +39,9 @@ extern uint8_t bleprph_gatt_service_changed[4];
 #define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID   0x2A48
 #define GATT_SVR_CHR_UNR_ALERT_STAT_UUID      0x2A45
 #define GATT_SVR_CHR_ALERT_NOT_CTRL_PT        0x2A44
-extern const uint8_t gatt_svr_svc_bleprph[16];
-extern const uint8_t gatt_svr_chr_bleprph_read[16];
-extern const uint8_t gatt_svr_chr_bleprph_write[16];
 
-void gatt_svr_init(void);
+int gatt_svr_register(void);
+int gatt_svr_init(struct ble_hs_cfg *cfg);
 
 /** Misc. */
 void print_bytes(const uint8_t *bytes, int len);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bleprph/src/gatt_svr.c
----------------------------------------------------------------------
diff --git a/apps/bleprph/src/gatt_svr.c b/apps/bleprph/src/gatt_svr.c
index 346bb88..7722df4 100644
--- a/apps/bleprph/src/gatt_svr.c
+++ b/apps/bleprph/src/gatt_svr.c
@@ -55,12 +55,6 @@ const uint8_t gatt_svr_chr_sec_test_static_uuid[16] = {
 static uint8_t gatt_svr_sec_test_static_val;
 
 static int
-gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle,
-                        struct ble_gatt_access_ctxt *ctxt, void *arg);
-static int
-gatt_svr_chr_access_gatt(uint16_t conn_handle, uint16_t attr_handle,
-                         struct ble_gatt_access_ctxt *ctxt, void *arg);
-static int
 gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
                           struct ble_gatt_access_ctxt *ctxt,
                           void *arg);
@@ -72,53 +66,6 @@ gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
 
 static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
     {
-        /*** Service: GAP. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid128 = BLE_UUID16(BLE_GAP_SVC_UUID16),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            /*** Characteristic: Device Name. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_DEVICE_NAME),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            /*** Characteristic: Appearance. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_APPEARANCE),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            /*** Characteristic: Peripheral Privacy Flag. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_PERIPH_PRIV_FLAG),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            /*** Characteristic: Reconnection Address. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_RECONNECT_ADDR),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_WRITE,
-        }, {
-            /*** Characteristic: Peripheral Preferred Connection Parameters. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
-        /*** Service: GATT */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid128 = BLE_UUID16(BLE_GATT_SVC_UUID16),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            .uuid128 = BLE_UUID16(BLE_GATT_CHR_SERVICE_CHANGED_UUID16),
-            .access_cb = gatt_svr_chr_access_gatt,
-            .flags = BLE_GATT_CHR_F_INDICATE,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
         /*** Alert Notification Service. */
         .type = BLE_GATT_SVC_TYPE_PRIMARY,
         .uuid128 = BLE_UUID16(GATT_SVR_SVC_ALERT_UUID),
@@ -192,88 +139,6 @@ gatt_svr_chr_write(uint8_t op, struct ble_gatt_access_ctxt *ctxt,
     return 0;
 }
 
-static int
-gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle,
-                        struct ble_gatt_access_ctxt *ctxt, void *arg)
-{
-    uint16_t uuid16;
-
-    uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
-    assert(uuid16 != 0);
-
-    switch (uuid16) {
-    case BLE_GAP_CHR_UUID16_DEVICE_NAME:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = bleprph_device_name;
-        ctxt->att->read.len = strlen(bleprph_device_name);
-        break;
-
-    case BLE_GAP_CHR_UUID16_APPEARANCE:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = &bleprph_appearance;
-        ctxt->att->read.len = sizeof bleprph_appearance;
-        break;
-
-    case BLE_GAP_CHR_UUID16_PERIPH_PRIV_FLAG:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = &bleprph_privacy_flag;
-        ctxt->att->read.len = sizeof bleprph_privacy_flag;
-        break;
-
-    case BLE_GAP_CHR_UUID16_RECONNECT_ADDR:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR);
-        if (ctxt->att->write.len != sizeof bleprph_reconnect_addr) {
-            return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-        }
-        memcpy(bleprph_reconnect_addr, ctxt->att->write.data,
-               sizeof bleprph_reconnect_addr);
-        break;
-
-    case BLE_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = &bleprph_pref_conn_params;
-        ctxt->att->read.len = sizeof bleprph_pref_conn_params;
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-gatt_svr_chr_access_gatt(uint16_t conn_handle, uint16_t attr_handle,
-                         struct ble_gatt_access_ctxt *ctxt, void *arg)
-{
-    uint16_t uuid16;
-
-    uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
-    assert(uuid16 != 0);
-
-    switch (uuid16) {
-    case BLE_GATT_CHR_SERVICE_CHANGED_UUID16:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            if (ctxt->att->write.len != sizeof bleprph_gatt_service_changed) {
-                return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-            }
-            memcpy(bleprph_gatt_service_changed, ctxt->att->write.data,
-                   sizeof bleprph_gatt_service_changed);
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            ctxt->att->read.data = &bleprph_gatt_service_changed;
-            ctxt->att->read.len = sizeof bleprph_gatt_service_changed;
-        }
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-
-    return 0;
-}
-
 #define GATT_SVR_NEW_ALERT_VAL_MAX_LEN    64
 
 static const uint8_t gatt_svr_new_alert_cat = 0x01; /* Simple alert. */
@@ -455,11 +320,24 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
     }
 }
 
-void
-gatt_svr_init(void)
+int
+gatt_svr_register(void)
 {
     int rc;
 
     rc = ble_gatts_register_svcs(gatt_svr_svcs, gatt_svr_register_cb, NULL);
-    assert(rc == 0);
+    return rc;
+}
+
+int
+gatt_svr_init(struct ble_hs_cfg *cfg)
+{
+    int rc;
+
+    rc = ble_gatts_count_cfg(gatt_svr_svcs, cfg);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bleprph/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c
index 4342dc8..22ad0e3 100755
--- a/apps/bleprph/src/main.c
+++ b/apps/bleprph/src/main.c
@@ -44,9 +44,12 @@
 /* RAM persistence layer. */
 #include "store/ram/ble_store_ram.h"
 
-#include "bleprph.h"
+/* Mandatory services. */
+#include "services/mandatory/ble_svc_gap.h"
+#include "services/mandatory/ble_svc_gatt.h"
 
-#define BSWAP16(x)  ((uint16_t)(((x) << 8) | (((x) & 0xff00) >> 8)))
+/* Application-specified header. */
+#include "bleprph.h"
 
 /** Mbuf settings. */
 #define MBUF_NUM_MBUFS      (12)
@@ -79,16 +82,6 @@ uint8_t g_dev_addr[BLE_DEV_ADDR_LEN] = {0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a};
 /** Our random address (in case we need it) */
 uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
 
-/** Device name - included in advertisements and exposed by GAP service. */
-const char *bleprph_device_name = "nimble-bleprph";
-
-/** Device properties - exposed by GAP service. */
-const uint16_t bleprph_appearance = BSWAP16(BLE_GAP_APPEARANCE_GEN_COMPUTER);
-const uint8_t bleprph_privacy_flag = 0;
-uint8_t bleprph_reconnect_addr[6];
-uint8_t bleprph_pref_conn_params[8];
-uint8_t bleprph_gatt_service_changed[4];
-
 static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
 
 /**
@@ -128,6 +121,7 @@ bleprph_advertise(void)
 {
     struct ble_gap_adv_params adv_params;
     struct ble_hs_adv_fields fields;
+    const char *name;
     int rc;
 
     /**
@@ -153,8 +147,9 @@ bleprph_advertise(void)
     fields.tx_pwr_lvl_is_present = 1;
     fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
 
-    fields.name = (uint8_t *)bleprph_device_name;
-    fields.name_len = strlen(bleprph_device_name);
+    name = ble_svc_gap_device_name();
+    fields.name = (uint8_t *)name;
+    fields.name_len = strlen(name);
     fields.name_is_complete = 1;
 
     fields.uuids16 = (uint16_t[]){ GATT_SVR_SVC_ALERT_UUID };
@@ -336,9 +331,6 @@ main(void)
     cfg = ble_hs_cfg_dflt;
     cfg.max_hci_bufs = 3;
     cfg.max_connections = 1;
-    cfg.max_attrs = 42;
-    cfg.max_services = 5;
-    cfg.max_client_configs = 6;
     cfg.max_gattc_procs = 2;
     cfg.max_l2cap_chans = 3;
     cfg.max_l2cap_sig_procs = 1;
@@ -348,6 +340,20 @@ main(void)
     cfg.store_read_cb = ble_store_ram_read;
     cfg.store_write_cb = ble_store_ram_write;
 
+    /* Populate config with the required GATT server settings. */
+    cfg.max_attrs = 0;
+    cfg.max_services = 0;
+    cfg.max_client_configs = 0;
+
+    rc = ble_svc_gap_init(&cfg);
+    assert(rc == 0);
+
+    rc = ble_svc_gatt_init(&cfg);
+    assert(rc == 0);
+
+    rc = gatt_svr_init(&cfg);
+    assert(rc == 0);
+
     /* Initialize eventq */
     os_eventq_init(&bleprph_evq);
 
@@ -361,7 +367,18 @@ main(void)
     /* Register GATT attributes (services, characteristics, and
      * descriptors).
      */
-    gatt_svr_init();
+    rc = ble_svc_gap_register();
+    assert(rc == 0);
+
+    rc = ble_svc_gatt_register();
+    assert(rc == 0);
+
+    rc = gatt_svr_register();
+    assert(rc == 0);
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set("nimble-bleprph");
+    assert(rc == 0);
 
     /* Start the OS */
     os_start();

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bletiny/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bletiny/pkg.yml b/apps/bletiny/pkg.yml
index 9fab33e..a3c6ee7 100644
--- a/apps/bletiny/pkg.yml
+++ b/apps/bletiny/pkg.yml
@@ -27,6 +27,7 @@ pkg.deps:
     - sys/log
     - net/nimble/controller
     - net/nimble/host
+    - net/nimble/host/services/mandatory
     - net/nimble/host/store/ram
     - libs/console/full
     - libs/shell

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bletiny/src/bletiny.h
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/bletiny.h b/apps/bletiny/src/bletiny.h
index 4910121..64bce88 100644
--- a/apps/bletiny/src/bletiny.h
+++ b/apps/bletiny/src/bletiny.h
@@ -81,14 +81,6 @@ struct bletiny_conn {
 extern struct bletiny_conn bletiny_conns[NIMBLE_OPT(MAX_CONNECTIONS)];
 extern int bletiny_num_conns;
 
-extern const char *bletiny_device_name;
-extern const uint16_t bletiny_appearance;
-extern const uint8_t bletiny_privacy_flag;
-extern uint8_t bletiny_reconnect_addr[6];
-extern uint8_t bletiny_pref_conn_params[8];
-extern uint8_t bletiny_gatt_service_changed[4];
-
-extern struct nmgr_transport nm_ble_transport;
 extern uint16_t nm_attr_val_handle;
 
 extern struct log bletiny_log;
@@ -195,11 +187,9 @@ int bletiny_rssi(uint16_t conn_handle, int8_t *out_rssi);
 #define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID   0x2A48
 #define GATT_SVR_CHR_UNR_ALERT_STAT_UUID      0x2A45
 #define GATT_SVR_CHR_ALERT_NOT_CTRL_PT        0x2A44
-extern const uint8_t gatt_svr_svc_bleprph[16];
-extern const uint8_t gatt_svr_chr_bleprph_read[16];
-extern const uint8_t gatt_svr_chr_bleprph_write[16];
 
-void gatt_svr_init(void);
+int gatt_svr_register(void);
+int gatt_svr_init(struct ble_hs_cfg *cfg);
 
 /** Misc. */
 void print_bytes(const uint8_t *bytes, int len);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bletiny/src/gatt_svr.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/gatt_svr.c b/apps/bletiny/src/gatt_svr.c
index a89673e..964cb25 100644
--- a/apps/bletiny/src/gatt_svr.c
+++ b/apps/bletiny/src/gatt_svr.c
@@ -55,67 +55,17 @@ const uint8_t gatt_svr_chr_sec_test_static_uuid[16] = {
 static uint8_t gatt_svr_sec_test_static_val;
 
 static int
-gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle,
-                        struct ble_gatt_access_ctxt *ctxt, void *arg);
-static int
-gatt_svr_chr_access_gatt(uint16_t conn_handle, uint16_t attr_handle,
-                         struct ble_gatt_access_ctxt *ctxt, void *arg);
-static int
 gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
-                          struct ble_gatt_access_ctxt *ctxt, void *arg);
+                          struct ble_gatt_access_ctxt *ctxt,
+                          void *arg);
+
 static int
 gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt, void *arg);
+                             struct ble_gatt_access_ctxt *ctxt,
+                             void *arg);
 
 static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
     {
-        /*** Service: GAP. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid128 = BLE_UUID16(BLE_GAP_SVC_UUID16),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            /*** Characteristic: Device Name. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_DEVICE_NAME),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            /*** Characteristic: Appearance. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_APPEARANCE),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            /*** Characteristic: Peripheral Privacy Flag. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_PERIPH_PRIV_FLAG),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            /*** Characteristic: Reconnection Address. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_RECONNECT_ADDR),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_WRITE,
-        }, {
-            /*** Characteristic: Peripheral Preferred Connection Parameters. */
-            .uuid128 = BLE_UUID16(BLE_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS),
-            .access_cb = gatt_svr_chr_access_gap,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
-        /*** Service: GATT */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid128 = BLE_UUID16(BLE_GATT_SVC_UUID16),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            .uuid128 = BLE_UUID16(BLE_GATT_CHR_SERVICE_CHANGED_UUID16),
-            .access_cb = gatt_svr_chr_access_gatt,
-            .flags = BLE_GATT_CHR_F_INDICATE,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
         /*** Alert Notification Service. */
         .type = BLE_GATT_SVC_TYPE_PRIMARY,
         .uuid128 = BLE_UUID16(GATT_SVR_SVC_ALERT_UUID),
@@ -189,88 +139,6 @@ gatt_svr_chr_write(uint8_t op, struct ble_gatt_access_ctxt *ctxt,
     return 0;
 }
 
-static int
-gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle,
-                        struct ble_gatt_access_ctxt *ctxt, void *arg)
-{
-    uint16_t uuid16;
-
-    uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
-    assert(uuid16 != 0);
-
-    switch (uuid16) {
-    case BLE_GAP_CHR_UUID16_DEVICE_NAME:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = bletiny_device_name;
-        ctxt->att->read.len = strlen(bletiny_device_name);
-        break;
-
-    case BLE_GAP_CHR_UUID16_APPEARANCE:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = &bletiny_appearance;
-        ctxt->att->read.len = sizeof bletiny_appearance;
-        break;
-
-    case BLE_GAP_CHR_UUID16_PERIPH_PRIV_FLAG:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = &bletiny_privacy_flag;
-        ctxt->att->read.len = sizeof bletiny_privacy_flag;
-        break;
-
-    case BLE_GAP_CHR_UUID16_RECONNECT_ADDR:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR);
-        if (ctxt->att->write.len != sizeof bletiny_reconnect_addr) {
-            return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-        }
-        memcpy(bletiny_reconnect_addr, ctxt->att->write.data,
-               sizeof bletiny_reconnect_addr);
-        break;
-
-    case BLE_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        ctxt->att->read.data = &bletiny_pref_conn_params;
-        ctxt->att->read.len = sizeof bletiny_pref_conn_params;
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-gatt_svr_chr_access_gatt(uint16_t conn_handle, uint16_t attr_handle,
-                         struct ble_gatt_access_ctxt *ctxt, void *arg)
-{
-    uint16_t uuid16;
-
-    uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
-    assert(uuid16 != 0);
-
-    switch (uuid16) {
-    case BLE_GATT_CHR_SERVICE_CHANGED_UUID16:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            if (ctxt->att->write.len != sizeof bletiny_gatt_service_changed) {
-                return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-            }
-            memcpy(bletiny_gatt_service_changed, ctxt->att->write.data,
-                   sizeof bletiny_gatt_service_changed);
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            ctxt->att->read.data = &bletiny_gatt_service_changed;
-            ctxt->att->read.len = sizeof bletiny_gatt_service_changed;
-        }
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-
-    return 0;
-}
-
 #define GATT_SVR_NEW_ALERT_VAL_MAX_LEN    64
 
 static const uint8_t gatt_svr_new_alert_cat = 0x01; /* Simple alert. */
@@ -282,7 +150,8 @@ static uint16_t gatt_svr_alert_not_ctrl_pt;
 
 static int
 gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
-                          struct ble_gatt_access_ctxt *ctxt, void *arg)
+                          struct ble_gatt_access_ctxt *ctxt,
+                          void *arg)
 {
     uint16_t uuid16;
     int rc;
@@ -345,7 +214,8 @@ gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
 
 static int
 gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt, void *arg)
+                             struct ble_gatt_access_ctxt *ctxt,
+                             void *arg)
 {
     const void *uuid128;
     int rand_num;
@@ -450,11 +320,24 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
     }
 }
 
-void
-gatt_svr_init(void)
+int
+gatt_svr_register(void)
 {
     int rc;
 
     rc = ble_gatts_register_svcs(gatt_svr_svcs, gatt_svr_register_cb, NULL);
-    assert(rc == 0);
+    return rc;
+}
+
+int
+gatt_svr_init(struct ble_hs_cfg *cfg)
+{
+    int rc;
+
+    rc = ble_gatts_count_cfg(gatt_svr_svcs, cfg);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/35d4eb8f/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index b397b65..568e41f 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -50,6 +50,10 @@
 /* RAM persistence layer. */
 #include "store/ram/ble_store_ram.h"
 
+/* Mandatory services. */
+#include "services/mandatory/ble_svc_gap.h"
+#include "services/mandatory/ble_svc_gatt.h"
+
 /* XXX: An app should not include private headers from a library.  The bletiny
  * app uses some of nimble's internal details for logging.
  */
@@ -57,8 +61,6 @@
 #include "../src/ble_hs_atomic_priv.h"
 #include "../src/ble_hci_priv.h"
 
-#define BSWAP16(x)  ((uint16_t)(((x) << 8) | (((x) & 0xff00) >> 8)))
-
 /* Nimble task priorities */
 #define BLE_LL_TASK_PRI         (OS_TASK_PRI_HIGHEST)
 
@@ -123,13 +125,6 @@ static struct os_mempool bletiny_chr_pool;
 static void *bletiny_dsc_mem;
 static struct os_mempool bletiny_dsc_pool;
 
-const char *bletiny_device_name = "nimble-bletiny";
-const uint16_t bletiny_appearance = BSWAP16(BLE_GAP_APPEARANCE_GEN_COMPUTER);
-const uint8_t bletiny_privacy_flag = 0;
-uint8_t bletiny_reconnect_addr[6];
-uint8_t bletiny_pref_conn_params[8];
-uint8_t bletiny_gatt_service_changed[4];
-
 static struct os_callout_func bletiny_tx_timer;
 struct bletiny_tx_data_s
 {
@@ -1652,15 +1647,26 @@ main(void)
     /* Initialize the BLE host. */
     cfg = ble_hs_cfg_dflt;
     cfg.max_hci_bufs = 3;
-    cfg.max_attrs = 36;
-    cfg.max_services = 5;
-    cfg.max_client_configs = (NIMBLE_OPT(MAX_CONNECTIONS) + 1) * 3;
     cfg.max_gattc_procs = 2;
     cfg.max_l2cap_chans = NIMBLE_OPT(MAX_CONNECTIONS) * 3;
     cfg.max_l2cap_sig_procs = 2;
     cfg.store_read_cb = ble_store_ram_read;
     cfg.store_write_cb = ble_store_ram_write;
 
+    /* Populate config with the required GATT server settings. */
+    cfg.max_attrs = 0;
+    cfg.max_services = 0;
+    cfg.max_client_configs = 0;
+
+    rc = ble_svc_gap_init(&cfg);
+    assert(rc == 0);
+
+    rc = ble_svc_gatt_init(&cfg);
+    assert(rc == 0);
+
+    rc = gatt_svr_init(&cfg);
+    assert(rc == 0);
+
     rc = ble_hs_init(&bletiny_evq, &cfg);
     assert(rc == 0);
 
@@ -1671,13 +1677,21 @@ main(void)
     rc = cmd_init();
     assert(rc == 0);
 
-    /* Initialize the preferred parameters. */
-    htole16(bletiny_pref_conn_params + 0, BLE_GAP_INITIAL_CONN_ITVL_MIN);
-    htole16(bletiny_pref_conn_params + 2, BLE_GAP_INITIAL_CONN_ITVL_MAX);
-    htole16(bletiny_pref_conn_params + 4, 0);
-    htole16(bletiny_pref_conn_params + 6, BSWAP16(0x100));
+    /* Register GATT attributes (services, characteristics, and
+     * descriptors).
+     */
+    rc = ble_svc_gap_register();
+    assert(rc == 0);
+
+    rc = ble_svc_gatt_register();
+    assert(rc == 0);
+
+    rc = gatt_svr_register();
+    assert(rc == 0);
 
-    gatt_svr_init();
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set("nimble-bletiny");
+    assert(rc == 0);
 
     os_callout_func_init(&bletiny_tx_timer, &bletiny_evq, bletiny_tx_timer_cb,
                          NULL);


[9/9] incubator-mynewt-core git commit: blecent - Example app: NimBLE central.

Posted by cc...@apache.org.
blecent - Example app: NimBLE central.


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

Branch: refs/heads/develop
Commit: b236e39822877754d407c86caa174dab373d5396
Parents: 35d4eb8
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 21:24:00 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:29:49 2016 -0700

----------------------------------------------------------------------
 apps/blecent/pkg.yml       |  37 ++
 apps/blecent/src/blecent.h | 116 ++++++
 apps/blecent/src/main.c    | 590 ++++++++++++++++++++++++++++++
 apps/blecent/src/misc.c    | 220 ++++++++++++
 apps/blecent/src/peer.c    | 772 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 1735 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b236e398/apps/blecent/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/blecent/pkg.yml b/apps/blecent/pkg.yml
new file mode 100644
index 0000000..b1710aa
--- /dev/null
+++ b/apps/blecent/pkg.yml
@@ -0,0 +1,37 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+pkg.name: apps/blecent
+pkg.type: app
+pkg.description: Simple BLE central application.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps: 
+    - libs/os 
+    - sys/log
+    - net/nimble/controller
+    - net/nimble/host
+    - net/nimble/host/services/mandatory
+    - net/nimble/host/store/ram
+    - libs/console/full
+    - libs/baselibc
+
+pkg.cflags:
+    # DEBUG logging is a bit noisy; use INFO.
+    - "-DLOG_LEVEL=1"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b236e398/apps/blecent/src/blecent.h
----------------------------------------------------------------------
diff --git a/apps/blecent/src/blecent.h b/apps/blecent/src/blecent.h
new file mode 100644
index 0000000..c2a2aee
--- /dev/null
+++ b/apps/blecent/src/blecent.h
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLECENT_
+#define H_BLECENT_
+
+#include "os/queue.h"
+#include "log/log.h"
+struct ble_hs_adv_fields;
+struct ble_gap_conn_desc;
+struct ble_hs_cfg;
+union ble_store_value;
+union ble_store_key;
+
+extern struct log blecent_log;
+
+/* blecent uses the first "peruser" log module. */
+#define BLECENT_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
+
+/* Convenience macro for logging to the blecent module. */
+#define BLECENT_LOG(lvl, ...) \
+    LOG_ ## lvl(&blecent_log, BLECENT_LOG_MODULE, __VA_ARGS__)
+
+#define BLECENT_SVC_ALERT_UUID              0x1811
+#define BLECENT_CHR_SUP_NEW_ALERT_CAT_UUID  0x2A47
+#define BLECENT_CHR_NEW_ALERT               0x2A46
+#define BLECENT_CHR_SUP_UNR_ALERT_CAT_UUID  0x2A48
+#define BLECENT_CHR_UNR_ALERT_STAT_UUID     0x2A45
+#define BLECENT_CHR_ALERT_NOT_CTRL_PT       0x2A44
+
+/** GATT server. */
+void gatt_svr_register(void);
+void gatt_svr_init_cfg(struct ble_hs_cfg *cfg);
+
+
+/** Misc. */
+void print_bytes(const uint8_t *bytes, int len);
+char *addr_str(const void *addr);
+void print_uuid(const void *uuid128);
+void print_conn_desc(const struct ble_gap_conn_desc *desc);
+void print_adv_fields(const struct ble_hs_adv_fields *fields);
+
+/** Peer. */
+struct peer_dsc {
+    SLIST_ENTRY(peer_dsc) next;
+    struct ble_gatt_dsc dsc;
+};
+SLIST_HEAD(peer_dsc_list, peer_dsc);
+
+struct peer_chr {
+    SLIST_ENTRY(peer_chr) next;
+    struct ble_gatt_chr chr;
+
+    struct peer_dsc_list dscs;
+};
+SLIST_HEAD(peer_chr_list, peer_chr);
+
+struct peer_svc {
+    SLIST_ENTRY(peer_svc) next;
+    struct ble_gatt_svc svc;
+
+    struct peer_chr_list chrs;
+};
+SLIST_HEAD(peer_svc_list, peer_svc);
+
+struct peer;
+typedef void peer_disc_fn(const struct peer *peer, int status, void *arg);
+
+struct peer {
+    SLIST_ENTRY(peer) next;
+
+    uint16_t conn_handle;
+
+    /** List of discovered GATT services. */
+    struct peer_svc_list svcs;
+
+    /** Keeps track of where we are in the service discovery process. */
+    uint16_t disc_prev_chr_val;
+    struct peer_svc *cur_svc;
+
+    /** Callback that gets executed when service discovery completes. */
+    peer_disc_fn *disc_cb;
+    void *disc_cb_arg;
+};
+
+int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb,
+                  void *disc_cb_arg);
+const struct peer_dsc *
+peer_dsc_find_uuid(const struct peer *peer, const uint8_t *svc_uuid128,
+                   const uint8_t *chr_uuid128, const uint8_t *dsc_uuid128);
+const struct peer_chr *
+peer_chr_find_uuid(const struct peer *peer, const uint8_t *svc_uuid128,
+                   const uint8_t *chr_uuid128);
+const struct peer_svc *
+peer_svc_find_uuid(const struct peer *peer, const uint8_t *uuid128);
+int peer_delete(uint16_t conn_handle);
+int peer_add(uint16_t conn_handle);
+int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b236e398/apps/blecent/src/main.c
----------------------------------------------------------------------
diff --git a/apps/blecent/src/main.c b/apps/blecent/src/main.c
new file mode 100755
index 0000000..a86f11a
--- /dev/null
+++ b/apps/blecent/src/main.c
@@ -0,0 +1,590 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "bsp/bsp.h"
+#include "os/os.h"
+#include "hal/hal_cputime.h"
+#include "console/console.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "controller/ble_ll.h"
+#include "host/host_hci.h"
+#include "host/ble_hs.h"
+
+/* RAM persistence layer. */
+#include "store/ram/ble_store_ram.h"
+
+/* Mandatory services. */
+#include "services/mandatory/ble_svc_gap.h"
+#include "services/mandatory/ble_svc_gatt.h"
+
+/* Application-specified header. */
+#include "blecent.h"
+
+#define BSWAP16(x)  ((uint16_t)(((x) << 8) | (((x) & 0xff00) >> 8)))
+
+/** Mbuf settings. */
+#define MBUF_NUM_MBUFS      (12)
+#define MBUF_BUF_SIZE       OS_ALIGN(BLE_MBUF_PAYLOAD_SIZE, 4)
+#define MBUF_MEMBLOCK_SIZE  (MBUF_BUF_SIZE + BLE_MBUF_MEMBLOCK_OVERHEAD)
+#define MBUF_MEMPOOL_SIZE   OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE)
+
+static os_membuf_t blecent_mbuf_mpool_data[MBUF_MEMPOOL_SIZE];
+struct os_mbuf_pool blecent_mbuf_pool;
+struct os_mempool blecent_mbuf_mpool;
+
+/** Log data. */
+static struct log_handler blecent_log_console_handler;
+struct log blecent_log;
+
+/** Priority of the nimble host and controller tasks. */
+#define BLE_LL_TASK_PRI             (OS_TASK_PRI_HIGHEST)
+
+/** blecent task settings. */
+#define BLECENT_TASK_PRIO           1
+#define BLECENT_STACK_SIZE          (OS_STACK_ALIGN(336))
+
+struct os_eventq blecent_evq;
+struct os_task blecent_task;
+bssnz_t os_stack_t blecent_stack[BLECENT_STACK_SIZE];
+
+/** Our global device address (public) */
+uint8_t g_dev_addr[BLE_DEV_ADDR_LEN] = {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c};
+
+/** Our random address (in case we need it) */
+uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
+
+static int blecent_gap_event(struct ble_gap_event *event, void *arg);
+
+/**
+ * Application callback.  Called when the read of the ANS Supported New Alert
+ * Category characteristic has completed.
+ */
+static int
+blecent_on_read(uint16_t conn_handle,
+                const struct ble_gatt_error *error,
+                const struct ble_gatt_attr *attr,
+                void *arg)
+{
+    BLECENT_LOG(INFO, "Read complete; status=%d conn_handle=%d", error->status,
+                conn_handle);
+    if (error->status == 0) {
+        BLECENT_LOG(INFO, " attr_handle=%d value=", attr->handle);
+        print_bytes(attr->value, attr->value_len);
+    }
+    BLECENT_LOG(INFO, "\n");
+
+    return 0;
+}
+
+/**
+ * Application callback.  Called when the write to the ANS Alert Notification
+ * Control Point characteristic has completed.
+ */
+static int
+blecent_on_write(uint16_t conn_handle,
+                 const struct ble_gatt_error *error,
+                 const struct ble_gatt_attr *attr,
+                 void *arg)
+{
+    BLECENT_LOG(INFO, "Write complete; status=%d conn_handle=%d "
+                      "attr_handle=%d\n",
+                error->status, conn_handle, attr->handle);
+
+    return 0;
+}
+
+/**
+ * Application callback.  Called when the attempt to subscribe to notifications
+ * for the ANS Unread Alert Status characteristic has completed.
+ */
+static int
+blecent_on_subscribe(uint16_t conn_handle,
+                     const struct ble_gatt_error *error,
+                     const struct ble_gatt_attr *attr,
+                     void *arg)
+{
+    BLECENT_LOG(INFO, "Subscribe complete; status=%d conn_handle=%d "
+                      "attr_handle=%d\n",
+                error->status, conn_handle, attr->handle);
+
+    /* Now that notifications have been enabled, we can terminate the
+     * connection.
+     */
+    BLECENT_LOG(INFO, "Terminating the connection; conn_handle=%d\n",
+                conn_handle);
+    ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+
+    return 0;
+}
+
+/**
+ * Performs three concurrent GATT operations against the specified peer:
+ * 1. Reads the ANS Supported New Alert Category characteristic.
+ * 2. Writes the ANS Alert Notification Control Point characteristic.
+ * 3. Subscribes to notifications for the ANS Unread Alert Status
+ *    characteristic.
+ *
+ * If the peer does not support a required service, characteristic, or
+ * descriptor, then the peer lied when it claimed support for the alert
+ * notification service!  When this happens, or if a GATT procedure fails, this
+ * function immediately terminates the connection.
+ *
+ * When all three procedures have completed, the connection is terminated (this
+ * happens in the subscribe callback, not in this function).
+ */
+static void
+blecent_read_write_subscribe(const struct peer *peer)
+{
+    const struct peer_chr *chr;
+    const struct peer_dsc *dsc;
+    uint8_t value[2];
+    int rc;
+
+    /* Read the supported-new-alert-category characteristic. */
+    chr = peer_chr_find_uuid(peer,
+                             BLE_UUID16(BLECENT_SVC_ALERT_UUID),
+                             BLE_UUID16(BLECENT_CHR_SUP_NEW_ALERT_CAT_UUID));
+    if (chr == NULL) {
+        BLECENT_LOG(ERROR, "Error: Peer doesn't support the Supported New "
+                           "Alert Category characteristic\n");
+        goto err;
+    }
+
+    rc = ble_gattc_read(peer->conn_handle, chr->chr.val_handle,
+                        blecent_on_read, NULL);
+    if (rc != 0) {
+        BLECENT_LOG(ERROR, "Error: Failed to read characteristic; rc=%d\n",
+                    rc);
+        goto err;
+    }
+
+    /* Write two bytes (99, 100) to the alert-notification-control-point
+     * characteristic.
+     */
+    chr = peer_chr_find_uuid(peer,
+                             BLE_UUID16(BLECENT_SVC_ALERT_UUID),
+                             BLE_UUID16(BLECENT_CHR_ALERT_NOT_CTRL_PT));
+    if (chr == NULL) {
+        BLECENT_LOG(ERROR, "Error: Peer doesn't support the Alert "
+                           "Notification Control Point characteristic\n");
+        goto err;
+    }
+
+    value[0] = 99;
+    value[1] = 100;
+    rc = ble_gattc_write(peer->conn_handle, chr->chr.val_handle, 
+                         value, sizeof value, blecent_on_write, NULL);
+    if (rc != 0) {
+        BLECENT_LOG(ERROR, "Error: Failed to write characteristic; rc=%d\n",
+                    rc);
+    }
+
+    /* Subscribe to notifications for the Unread Alert Status characteristic.
+     * A central enables notifications by writing two bytes (1, 0) to the
+     * characteristic's client-characteristic-configuration-descriptor (CCCD).
+     */
+    dsc = peer_dsc_find_uuid(peer,
+                             BLE_UUID16(BLECENT_SVC_ALERT_UUID),
+                             BLE_UUID16(BLECENT_CHR_UNR_ALERT_STAT_UUID),
+                             BLE_UUID16(BLE_GATT_DSC_CLT_CFG_UUID16));
+    if (dsc == NULL) {
+        BLECENT_LOG(ERROR, "Error: Peer lacks a CCCD for the Unread Alert "
+                           "Status characteristic\n");
+        goto err;
+    }
+
+    value[0] = 1;
+    value[1] = 0;
+    rc = ble_gattc_write(peer->conn_handle, dsc->dsc.handle,
+                         value, sizeof value, blecent_on_subscribe, NULL);
+    if (rc != 0) {
+        BLECENT_LOG(ERROR, "Error: Failed to subscribe to characteristic; "
+                           "rc=%d\n", rc);
+        goto err;
+    }
+
+    return;
+
+err:
+    /* Terminate the connection. */
+    ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+}
+
+/**
+ * Called when service discovery of the specified peer has completed.
+ */
+static void
+blecent_on_disc_complete(const struct peer *peer, int status, void *arg)
+{
+
+    if (status != 0) {
+        /* Service discovery failed.  Terminate the connection. */
+        BLECENT_LOG(ERROR, "Error: Service discovery failed; status=%d "
+                           "conn_handle=%d\n", status, peer->conn_handle);
+        ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+        return;
+    }
+
+    /* Service discovery has completed successfully.  Now we have a complete
+     * list of services, characteristics, and descriptors that the peer
+     * supports.
+     */
+    BLECENT_LOG(ERROR, "Service discovery complete; status=%d "
+                       "conn_handle=%d\n", status, peer->conn_handle);
+
+    /* Now perform three concurrent GATT procedures against the peer: read,
+     * write, and subscribe to notifications.
+     */
+    blecent_read_write_subscribe(peer);
+}
+
+/**
+ * Initiates the GAP general discovery procedure.
+ */
+static void
+blecent_scan(void)
+{
+    struct ble_gap_disc_params disc_params;
+    int rc;
+
+    /* Tell the controller to filter duplicates; we don't want to process
+     * repeated advertisements from the same device.
+     */
+    disc_params.filter_duplicates = 1;
+
+    /**
+     * Perform a passive scan.  I.e., don't send follow-up scan requests to
+     * each advertiser.
+     */
+    disc_params.passive = 1;
+
+    /* Use defaults for the rest of the parameters. */
+    disc_params.itvl = 0;
+    disc_params.window = 0;
+    disc_params.filter_policy = 0;
+    disc_params.limited = 0;
+
+    rc = ble_gap_disc(BLE_ADDR_TYPE_PUBLIC, BLE_HS_FOREVER, &disc_params,
+                      blecent_gap_event, NULL);
+    if (rc != 0) {
+        BLECENT_LOG(ERROR, "Error initiating GAP discovery procedure; rc=%d\n",
+                    rc);
+    }
+}
+
+/**
+ * Indicates whether we should tre to connect to the sender of the specified
+ * advertisement.  The function returns a positive result if the device
+ * advertises connectability and support for the Alert Notification service.
+ */
+static int
+blecent_should_connect(const struct ble_gap_disc_desc *disc)
+{
+    int i;
+
+    /* The device has to be advertising connectability. */
+    if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
+        disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
+
+        return 0;
+    }
+
+    /* The device has to advertise support for the Alert Notification
+     * service (0x1811).
+     */
+    for (i = 0; i < disc->fields->num_uuids16; i++) {
+        if (disc->fields->uuids16[i] == BLECENT_SVC_ALERT_UUID) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Connects to the sender of the specified advertisement of it looks
+ * interesting.  A device is "interesting" if it advertises connectability and
+ * support for the Alert Notification service.
+ */
+static void
+blecent_connect_if_interesting(const struct ble_gap_disc_desc *disc)
+{
+    int rc;
+
+    /* Don't do anything if we don't care about this advertiser. */
+    if (!blecent_should_connect(disc)) {
+        return;
+    }
+
+    /* Scanning must be stopped before a connection can be initiated. */
+    rc = ble_gap_disc_cancel();
+    if (rc != 0) {
+        BLECENT_LOG(DEBUG, "Failed to cancel scan; rc=%d\n", rc);
+        return;
+    }
+
+    /* Try to connect the the advertiser.  Allow 30 seconds (30000 ms) for
+     * timeout.
+     */
+    rc = ble_gap_connect(BLE_ADDR_TYPE_PUBLIC, disc->addr_type, disc->addr,
+                         30000, NULL, blecent_gap_event, NULL);
+    if (rc != 0) {
+        BLECENT_LOG(ERROR, "Error: Failed to connect to device; addr_type=%d "
+                           "addr=%s\n", disc->addr_type, addr_str(disc->addr));
+        return;
+    }
+}
+
+/**
+ * The nimble host executes this callback when a GAP event occurs.  The
+ * application associates a GAP event callback with each connection that is
+ * established.  blecent uses the same callback for all connections.
+ *
+ * @param event                 The event being signalled.
+ * @param arg                   Application-specified argument; unused by
+ *                                  blecent.
+ *
+ * @return                      0 if the application successfully handled the
+ *                                  event; nonzero on failure.  The semantics
+ *                                  of the return code is specific to the
+ *                                  particular GAP event being signalled.
+ */
+static int
+blecent_gap_event(struct ble_gap_event *event, void *arg)
+{
+    int rc;
+
+    switch (event->type) {
+    case BLE_GAP_EVENT_DISC:
+        /* An advertisment report was received during GAP discovery. */
+        print_adv_fields(event->disc.fields);
+
+        /* Try to connect to the advertiser if it looks interesting. */
+        blecent_connect_if_interesting(&event->disc);
+        return 0;
+
+    case BLE_GAP_EVENT_CONNECT:
+        /* A new connection was established or a connection attempt failed. */
+        BLECENT_LOG(INFO, "connection %s; status=%d ",
+                    event->connect.status == 0 ? "established" : "failed",
+                    event->connect.status);
+        print_conn_desc(&event->connect.conn);
+        BLECENT_LOG(INFO, "\n");
+
+        if (event->connect.status != 0) {
+            /* Connection attempt failed; resume scanning. */
+            blecent_scan();
+        } else {
+            /* Connection successfully established. */
+
+            /* Remember peer. */
+            rc = peer_add(event->connect.conn.conn_handle);
+            if (rc != 0) {
+                BLECENT_LOG(ERROR, "Failed to add peer; rc=%d\n", rc);
+                return 0;
+            }
+
+            /* Perform service discovery. */
+            rc = peer_disc_all(event->connect.conn.conn_handle,
+                               blecent_on_disc_complete, NULL);
+            if (rc != 0) {
+                BLECENT_LOG(ERROR, "Failed to discover services; rc=%d\n", rc);
+                return 0;
+            }
+        }
+
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        /* Connection terminated. */
+        BLECENT_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        print_conn_desc(&event->disconnect.conn);
+        BLECENT_LOG(INFO, "\n");
+
+        /* Forget about peer. */
+        peer_delete(event->disconnect.conn.conn_handle);
+
+        /* Resume scanning. */
+        blecent_scan();
+        return 0;
+
+    case BLE_GAP_EVENT_ENC_CHANGE:
+        /* Encryption has been enabled or disabled for this connection. */
+        BLECENT_LOG(INFO, "encryption change event; status=%d ",
+                    event->enc_change.status);
+        print_conn_desc(&event->enc_change.conn);
+        BLECENT_LOG(INFO, "\n");
+        return 0;
+
+    default:
+        return 0;
+    }
+}
+
+/**
+ * Event loop for the main blecent task.
+ */
+static void
+blecent_task_handler(void *unused)
+{
+    struct os_event *ev;
+    struct os_callout_func *cf;
+    int rc;
+
+    /* Activate the host.  This causes the host to synchronize with the
+     * controller.
+     */
+    rc = ble_hs_start();
+    assert(rc == 0);
+
+    /* Begin scanning for a peripheral to connect to. */
+    blecent_scan();
+
+    while (1) {
+        ev = os_eventq_get(&blecent_evq);
+        switch (ev->ev_type) {
+        case OS_EVENT_T_TIMER:
+            cf = (struct os_callout_func *)ev;
+            assert(cf->cf_func);
+            cf->cf_func(CF_ARG(cf));
+            break;
+
+        default:
+            assert(0);
+            break;
+        }
+    }
+}
+
+/**
+ * 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)
+{
+    struct ble_hs_cfg cfg;
+    uint32_t seed;
+    int rc;
+    int i;
+
+    /* Initialize OS */
+    os_init();
+
+    /* Set cputime to count at 1 usec increments */
+    rc = cputime_init(1000000);
+    assert(rc == 0);
+
+    /* 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);
+
+    /* Initialize msys mbufs. */
+    rc = os_mempool_init(&blecent_mbuf_mpool, MBUF_NUM_MBUFS,
+                         MBUF_MEMBLOCK_SIZE, blecent_mbuf_mpool_data,
+                         "blecent_mbuf_data");
+    assert(rc == 0);
+
+    rc = os_mbuf_pool_init(&blecent_mbuf_pool, &blecent_mbuf_mpool,
+                           MBUF_MEMBLOCK_SIZE, MBUF_NUM_MBUFS);
+    assert(rc == 0);
+
+    rc = os_msys_register(&blecent_mbuf_pool);
+    assert(rc == 0);
+
+    /* Initialize the console (for log output). */
+    rc = console_init(NULL);
+    assert(rc == 0);
+
+    /* Initialize the logging system. */
+    log_init();
+    log_console_handler_init(&blecent_log_console_handler);
+    log_register("blecent", &blecent_log, &blecent_log_console_handler);
+
+    os_task_init(&blecent_task, "blecent", blecent_task_handler,
+                 NULL, BLECENT_TASK_PRIO, OS_WAIT_FOREVER,
+                 blecent_stack, BLECENT_STACK_SIZE);
+
+    /* Initialize the eventq for the application task. */
+    os_eventq_init(&blecent_evq);
+
+    /* Initialize the BLE LL */
+    rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE);
+    assert(rc == 0);
+
+    /* Configure the host. */
+    cfg = ble_hs_cfg_dflt;
+    cfg.max_hci_bufs = 3;
+    cfg.max_connections = 1;
+    cfg.max_gattc_procs = 5;
+    cfg.max_l2cap_chans = 3;
+    cfg.max_l2cap_sig_procs = 1;
+    cfg.sm_bonding = 1;
+    cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
+    cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
+    cfg.store_read_cb = ble_store_ram_read;
+    cfg.store_write_cb = ble_store_ram_write;
+
+    /* Populate config with the required GATT server settings. */
+    cfg.max_attrs = 0;
+    cfg.max_services = 0;
+    cfg.max_client_configs = 0;
+    ble_svc_gap_init(&cfg);
+    ble_svc_gatt_init(&cfg);
+
+    /* Initialize the BLE host. */
+    rc = ble_hs_init(&blecent_evq, &cfg);
+    assert(rc == 0);
+
+    rc = peer_init(cfg.max_connections, 64, 64, 64);
+    assert(rc == 0);
+
+    /* Register GATT attributes (services, characteristics, and
+     * descriptors).
+     */
+    ble_svc_gap_register();
+    ble_svc_gatt_register();
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set("nimble-blecent");
+    assert(rc == 0);
+
+    /* Start the OS */
+    os_start();
+
+    /* os start should never return. If it does, this should be an error */
+    assert(0);
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b236e398/apps/blecent/src/misc.c
----------------------------------------------------------------------
diff --git a/apps/blecent/src/misc.c b/apps/blecent/src/misc.c
new file mode 100644
index 0000000..8371b14
--- /dev/null
+++ b/apps/blecent/src/misc.c
@@ -0,0 +1,220 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "host/ble_hs.h"
+#include "blecent.h"
+
+/**
+ * Utility function to log an array of bytes.
+ */
+void
+print_bytes(const uint8_t *bytes, int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        BLECENT_LOG(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
+    }
+}
+
+char *
+addr_str(const void *addr)
+{
+    static char buf[6 * 2 + 5 + 1];
+    const uint8_t *u8p;
+
+    u8p = addr;
+    sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+            u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
+
+    return buf;
+}
+
+void
+print_uuid(const void *uuid128)
+{
+    uint16_t uuid16;
+    const uint8_t *u8p;
+
+    uuid16 = ble_uuid_128_to_16(uuid128);
+    if (uuid16 != 0) {
+        BLECENT_LOG(DEBUG, "0x%04x", uuid16);
+        return;
+    }
+
+    u8p = uuid128;
+
+    /* 00001101-0000-1000-8000-00805f9b34fb */
+    BLECENT_LOG(DEBUG, "%02x%02x%02x%02x-", u8p[15], u8p[14], u8p[13],
+                u8p[12]);
+    BLECENT_LOG(DEBUG, "%02x%02x-%02x%02x-", u8p[11], u8p[10], u8p[9], u8p[8]);
+    BLECENT_LOG(DEBUG, "%02x%02x%02x%02x%02x%02x%02x%02x",
+                   u8p[7], u8p[6], u8p[5], u8p[4],
+                   u8p[3], u8p[2], u8p[1], u8p[0]);
+}
+
+/**
+ * Logs information about a connection to the console.
+ */
+void
+print_conn_desc(const struct ble_gap_conn_desc *desc)
+{
+    BLECENT_LOG(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ",
+                desc->conn_handle, desc->our_ota_addr_type,
+                addr_str(desc->our_ota_addr));
+    BLECENT_LOG(DEBUG, "our_id_addr_type=%d our_id_addr=%s ",
+                desc->our_id_addr_type, addr_str(desc->our_id_addr));
+    BLECENT_LOG(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ",
+                desc->peer_ota_addr_type, addr_str(desc->peer_ota_addr));
+    BLECENT_LOG(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ",
+                desc->peer_id_addr_type, addr_str(desc->peer_id_addr));
+    BLECENT_LOG(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d "
+                "encrypted=%d authenticated=%d bonded=%d\n",
+                desc->conn_itvl, desc->conn_latency,
+                desc->supervision_timeout,
+                desc->sec_state.encrypted,
+                desc->sec_state.authenticated,
+                desc->sec_state.bonded);
+}
+
+
+void
+print_adv_fields(const struct ble_hs_adv_fields *fields)
+{
+    char s[BLE_HCI_MAX_ADV_DATA_LEN];
+    const uint8_t *u8p;
+    int i;
+
+    if (fields->flags_is_present) {
+        BLECENT_LOG(DEBUG, "    flags=0x%02x\n", fields->flags);
+    }
+
+    if (fields->uuids16 != NULL) {
+        BLECENT_LOG(DEBUG, "    uuids16(%scomplete)=",
+                    fields->uuids16_is_complete ? "" : "in");
+        for (i = 0; i < fields->num_uuids16; i++) {
+            BLECENT_LOG(DEBUG, "0x%04x ", fields->uuids16[i]);
+        }
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->uuids32 != NULL) {
+        BLECENT_LOG(DEBUG, "    uuids32(%scomplete)=",
+                    fields->uuids32_is_complete ? "" : "in");
+        for (i = 0; i < fields->num_uuids32; i++) {
+            BLECENT_LOG(DEBUG, "0x%08x ", fields->uuids32[i]);
+        }
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->uuids128 != NULL) {
+        BLECENT_LOG(DEBUG, "    uuids128(%scomplete)=",
+                    fields->uuids128_is_complete ? "" : "in");
+        u8p = fields->uuids128;
+        for (i = 0; i < fields->num_uuids128; i++) {
+            print_uuid(u8p);
+            BLECENT_LOG(DEBUG, " ");
+            u8p += 16;
+        }
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->name != NULL) {
+        assert(fields->name_len < sizeof s - 1);
+        memcpy(s, fields->name, fields->name_len);
+        s[fields->name_len] = '\0';
+        BLECENT_LOG(DEBUG, "    name(%scomplete)=%s\n",
+                    fields->name_is_complete ? "" : "in", s);
+    }
+
+    if (fields->tx_pwr_lvl_is_present) {
+        BLECENT_LOG(DEBUG, "    tx_pwr_lvl=%d\n", fields->tx_pwr_lvl);
+    }
+
+    if (fields->device_class != NULL) {
+        BLECENT_LOG(DEBUG, "    device_class=");
+        print_bytes(fields->device_class, BLE_HS_ADV_DEVICE_CLASS_LEN);
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->slave_itvl_range != NULL) {
+        BLECENT_LOG(DEBUG, "    slave_itvl_range=");
+        print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->svc_data_uuid16 != NULL) {
+        BLECENT_LOG(DEBUG, "    svc_data_uuid16=");
+        print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len);
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->public_tgt_addr != NULL) {
+        BLECENT_LOG(DEBUG, "    public_tgt_addr=");
+        u8p = fields->public_tgt_addr;
+        for (i = 0; i < fields->num_public_tgt_addrs; i++) {
+            BLECENT_LOG(DEBUG, "public_tgt_addr=%s ", addr_str(u8p));
+            u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
+        }
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->appearance_is_present) {
+        BLECENT_LOG(DEBUG, "    appearance=0x%04x\n", fields->appearance);
+    }
+
+    if (fields->adv_itvl_is_present) {
+        BLECENT_LOG(DEBUG, "    adv_itvl=0x%04x\n", fields->adv_itvl);
+    }
+
+    if (fields->le_addr != NULL) {
+        BLECENT_LOG(DEBUG, "    le_addr=%s\n", addr_str(fields->le_addr));
+    }
+
+    if (fields->le_role_is_present) {
+        BLECENT_LOG(DEBUG, "    le_role=0x%02x\n", fields->le_role);
+    }
+
+    if (fields->svc_data_uuid32 != NULL) {
+        BLECENT_LOG(DEBUG, "    svc_data_uuid32=");
+        print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len);
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->svc_data_uuid128 != NULL) {
+        BLECENT_LOG(DEBUG, "    svc_data_uuid128=");
+        print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len);
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->uri != NULL) {
+        BLECENT_LOG(DEBUG, "    uri=");
+        print_bytes(fields->uri, fields->uri_len);
+        BLECENT_LOG(DEBUG, "\n");
+    }
+
+    if (fields->mfg_data != NULL) {
+        BLECENT_LOG(DEBUG, "    mfg_data=");
+        print_bytes(fields->mfg_data, fields->mfg_data_len);
+        BLECENT_LOG(DEBUG, "\n");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b236e398/apps/blecent/src/peer.c
----------------------------------------------------------------------
diff --git a/apps/blecent/src/peer.c b/apps/blecent/src/peer.c
new file mode 100644
index 0000000..4520b1b
--- /dev/null
+++ b/apps/blecent/src/peer.c
@@ -0,0 +1,772 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "host/ble_hs.h"
+#include "blecent.h"
+
+static void *peer_svc_mem;
+static struct os_mempool peer_svc_pool;
+
+static void *peer_chr_mem;
+static struct os_mempool peer_chr_pool;
+
+static void *peer_dsc_mem;
+static struct os_mempool peer_dsc_pool;
+
+static void *peer_mem;
+static struct os_mempool peer_pool;
+static SLIST_HEAD(, peer) peers;
+
+static struct peer_svc *
+peer_svc_find_range(struct peer *peer, uint16_t attr_handle);
+static struct peer_svc *
+peer_svc_find(struct peer *peer, uint16_t svc_start_handle,
+              struct peer_svc **out_prev);
+int
+peer_svc_is_empty(const struct peer_svc *svc);
+
+uint16_t
+chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr);
+int
+chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr);
+static struct peer_chr *
+peer_chr_find(const struct peer_svc *svc, uint16_t chr_def_handle,
+              struct peer_chr **out_prev);
+static void
+peer_disc_chrs(struct peer *peer);
+
+static int
+peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                uint16_t chr_def_handle, const struct ble_gatt_dsc *dsc,
+                void *arg);
+
+static struct peer *
+peer_find(uint16_t conn_handle)
+{
+    struct peer *peer;
+
+    SLIST_FOREACH(peer, &peers, next) {
+        if (peer->conn_handle == conn_handle) {
+            return peer;
+        }
+    }
+
+    return NULL;
+}
+
+static void
+peer_full_disc_complete(struct peer *peer, int rc)
+{
+    peer->disc_prev_chr_val = 0;
+
+    /* Notify caller that discovery has completed. */
+    if (peer->disc_cb != NULL) {
+        peer->disc_cb(peer, rc, peer->disc_cb_arg);
+    }
+}
+
+static struct peer_dsc *
+peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle)
+{
+    struct peer_dsc *prev;
+    struct peer_dsc *dsc;
+
+    prev = NULL;
+    SLIST_FOREACH(dsc, &chr->dscs, next) {
+        if (dsc->dsc.handle >= dsc_handle) {
+            break;
+        }
+
+        prev = dsc;
+    }
+
+    return prev;
+}
+
+static struct peer_dsc *
+peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle,
+              struct peer_dsc **out_prev)
+{
+    struct peer_dsc *prev;
+    struct peer_dsc *dsc;
+
+    prev = peer_dsc_find_prev(chr, dsc_handle);
+    if (prev == NULL) {
+        dsc = SLIST_FIRST(&chr->dscs);
+    } else {
+        dsc = SLIST_NEXT(prev, next);
+    }
+
+    if (dsc != NULL && dsc->dsc.handle != dsc_handle) {
+        dsc = NULL;
+    }
+
+    if (out_prev != NULL) {
+        *out_prev = prev;
+    }
+    return dsc;
+}
+
+static struct peer_dsc *
+peer_dsc_add(struct peer *peer, uint16_t chr_val_handle,
+             const struct ble_gatt_dsc *gatt_dsc)
+{
+    struct peer_dsc *prev;
+    struct peer_dsc *dsc;
+    struct peer_svc *svc;
+    struct peer_chr *chr;
+
+    svc = peer_svc_find_range(peer, chr_val_handle);
+    if (svc == NULL) {
+        /* Can't find service for discovered descriptor; this shouldn't
+         * happen.
+         */
+        assert(0);
+        return NULL;
+    }
+
+    chr = peer_chr_find(svc, chr_val_handle, NULL);
+    if (chr == NULL) {
+        /* Can't find characteristic for discovered descriptor; this shouldn't
+         * happen.
+         */
+        assert(0);
+        return NULL;
+    }
+
+    dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev);
+    if (dsc != NULL) {
+        /* Descriptor already discovered. */
+        return dsc;
+    }
+
+    dsc = os_memblock_get(&peer_dsc_pool);
+    if (dsc == NULL) {
+        /* Out of memory. */
+        return NULL;
+    }
+    memset(dsc, 0, sizeof *dsc);
+
+    dsc->dsc = *gatt_dsc;
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&chr->dscs, dsc, next);
+    } else {
+        SLIST_NEXT(prev, next) = dsc;
+    }
+
+    return dsc;
+}
+
+static void
+peer_disc_dscs(struct peer *peer)
+{
+    struct peer_chr *chr;
+    struct peer_svc *svc;
+    int rc;
+
+    /* Search through the list of discovered characteristics for the first
+     * characteristic that contains undiscovered descriptors.  Then, discover
+     * all descriptors belonging to that characteristic.
+     */
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        SLIST_FOREACH(chr, &svc->chrs, next) {
+            if (!chr_is_empty(svc, chr) &&
+                SLIST_EMPTY(&chr->dscs) &&
+                peer->disc_prev_chr_val <= chr->chr.def_handle) {
+
+                rc = ble_gattc_disc_all_dscs(peer->conn_handle,
+                                             chr->chr.val_handle,
+                                             chr_end_handle(svc, chr),
+                                             peer_dsc_disced, peer);
+                if (rc != 0) {
+                    peer_full_disc_complete(peer, rc);
+                }
+
+                peer->disc_prev_chr_val = chr->chr.val_handle;
+                return;
+            }
+        }
+    }
+
+    /* All descriptors discovered. */
+    peer_full_disc_complete(peer, 0);
+}
+
+static int
+peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
+                void *arg)
+{
+    struct peer *peer;
+
+    peer = arg;
+    assert(peer->conn_handle == conn_handle);
+
+    switch (error->status) {
+    case 0:
+        peer_dsc_add(peer, chr_val_handle, dsc);
+        break;
+
+    case BLE_HS_EDONE:
+        if (peer->disc_prev_chr_val > 0) {
+            peer_disc_dscs(peer);
+        }
+        break;
+
+    default:
+        /* Error. */
+        break;
+    }
+
+    return 0;
+}
+
+uint16_t
+chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr)
+{
+    const struct peer_chr *next_chr;
+
+    next_chr = SLIST_NEXT(chr, next);
+    if (next_chr != NULL) {
+        return next_chr->chr.def_handle - 1;
+    } else {
+        return svc->svc.end_handle;
+    }
+}
+
+int
+chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr)
+{
+    return chr_end_handle(svc, chr) <= chr->chr.val_handle;
+}
+
+static struct peer_chr *
+peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle)
+{
+    struct peer_chr *prev;
+    struct peer_chr *chr;
+
+    prev = NULL;
+    SLIST_FOREACH(chr, &svc->chrs, next) {
+        if (chr->chr.val_handle >= chr_val_handle) {
+            break;
+        }
+
+        prev = chr;
+    }
+
+    return prev;
+}
+
+static struct peer_chr *
+peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle,
+              struct peer_chr **out_prev)
+{
+    struct peer_chr *prev;
+    struct peer_chr *chr;
+
+    prev = peer_chr_find_prev(svc, chr_val_handle);
+    if (prev == NULL) {
+        chr = SLIST_FIRST(&svc->chrs);
+    } else {
+        chr = SLIST_NEXT(prev, next);
+    }
+
+    if (chr != NULL && chr->chr.val_handle != chr_val_handle) {
+        chr = NULL;
+    }
+
+    if (out_prev != NULL) {
+        *out_prev = prev;
+    }
+    return chr;
+}
+
+static void
+peer_chr_delete(struct peer_chr *chr)
+{
+    struct peer_dsc *dsc;
+
+    while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) {
+        SLIST_REMOVE_HEAD(&chr->dscs, next);
+        os_memblock_put(&peer_dsc_pool, dsc);
+    }
+
+    os_memblock_put(&peer_chr_pool, chr);
+}
+
+static struct peer_chr *
+peer_chr_add(struct peer *peer,  uint16_t svc_start_handle,
+             const struct ble_gatt_chr *gatt_chr)
+{
+    struct peer_chr *prev;
+    struct peer_chr *chr;
+    struct peer_svc *svc;
+
+    svc = peer_svc_find(peer, svc_start_handle, NULL);
+    if (svc == NULL) {
+        /* Can't find service for discovered characteristic; this shouldn't
+         * happen.
+         */
+        assert(0);
+        return NULL;
+    }
+
+    chr = peer_chr_find(svc, gatt_chr->def_handle, &prev);
+    if (chr != NULL) {
+        /* Characteristic already discovered. */
+        return chr;
+    }
+
+    chr = os_memblock_get(&peer_chr_pool);
+    if (chr == NULL) {
+        /* Out of memory. */
+        return NULL;
+    }
+    memset(chr, 0, sizeof *chr);
+
+    chr->chr = *gatt_chr;
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&svc->chrs, chr, next);
+    } else {
+        SLIST_NEXT(prev, next) = chr;
+    }
+
+    return chr;
+}
+
+static int
+peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                const struct ble_gatt_chr *chr, void *arg)
+{
+    struct peer *peer;
+
+    peer = arg;
+    assert(peer->conn_handle == conn_handle);
+
+    switch (error->status) {
+    case 0:
+        peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr);
+        break;
+
+    case BLE_HS_EDONE:
+        if (peer->disc_prev_chr_val > 0) {
+            peer_disc_chrs(peer);
+        }
+        break;
+
+    default:
+        /* Error. */
+        break;
+    }
+
+    return 0;
+}
+
+static void
+peer_disc_chrs(struct peer *peer)
+{
+    struct peer_svc *svc;
+    int rc;
+
+    /* Search through the list of discovered service for the first service that
+     * contains undiscovered characteristics.  Then, discover all
+     * characteristics belonging to that service.
+     */
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) {
+            peer->cur_svc = svc;
+            rc = ble_gattc_disc_all_chrs(peer->conn_handle,
+                                         svc->svc.start_handle,
+                                         svc->svc.end_handle,
+                                         peer_chr_disced, peer);
+            if (rc != 0) {
+                peer_full_disc_complete(peer, rc);
+            }
+            return;
+        }
+    }
+
+    /* All characteristics discovered. */
+    peer_disc_dscs(peer);
+}
+
+int
+peer_svc_is_empty(const struct peer_svc *svc)
+{
+    return svc->svc.end_handle < svc->svc.start_handle;
+}
+
+static struct peer_svc *
+peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle)
+{
+    struct peer_svc *prev;
+    struct peer_svc *svc;
+
+    prev = NULL;
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (svc->svc.start_handle >= svc_start_handle) {
+            break;
+        }
+
+        prev = svc;
+    }
+
+    return prev;
+}
+
+static struct peer_svc *
+peer_svc_find(struct peer *peer, uint16_t svc_start_handle,
+              struct peer_svc **out_prev)
+{
+    struct peer_svc *prev;
+    struct peer_svc *svc;
+
+    prev = peer_svc_find_prev(peer, svc_start_handle);
+    if (prev == NULL) {
+        svc = SLIST_FIRST(&peer->svcs);
+    } else {
+        svc = SLIST_NEXT(prev, next);
+    }
+
+    if (svc != NULL && svc->svc.start_handle != svc_start_handle) {
+        svc = NULL;
+    }
+
+    if (out_prev != NULL) {
+        *out_prev = prev;
+    }
+    return svc;
+}
+
+static struct peer_svc *
+peer_svc_find_range(struct peer *peer, uint16_t attr_handle)
+{
+    struct peer_svc *svc;
+
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (svc->svc.start_handle <= attr_handle &&
+            svc->svc.end_handle >= attr_handle) {
+
+            return svc;
+        }
+    }
+
+    return NULL;
+}
+
+const struct peer_svc *
+peer_svc_find_uuid(const struct peer *peer, const uint8_t *uuid128)
+{
+    const struct peer_svc *svc;
+
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (memcmp(svc->svc.uuid128, uuid128, 16) == 0) {
+            return svc;
+        }
+    }
+
+    return NULL;
+}
+
+const struct peer_chr *
+peer_chr_find_uuid(const struct peer *peer, const uint8_t *svc_uuid128,
+                   const uint8_t *chr_uuid128)
+{
+    const struct peer_svc *svc;
+    const struct peer_chr *chr;
+
+    svc = peer_svc_find_uuid(peer, svc_uuid128);
+    if (svc == NULL) {
+        return NULL;
+    }
+
+    SLIST_FOREACH(chr, &svc->chrs, next) {
+        if (memcmp(chr->chr.uuid128, chr_uuid128, 16) == 0) {
+            return chr;
+        }
+    }
+
+    return NULL;
+}
+
+const struct peer_dsc *
+peer_dsc_find_uuid(const struct peer *peer, const uint8_t *svc_uuid128,
+                   const uint8_t *chr_uuid128, const uint8_t *dsc_uuid128)
+{
+    const struct peer_chr *chr;
+    const struct peer_dsc *dsc;
+
+    chr = peer_chr_find_uuid(peer, svc_uuid128, chr_uuid128);
+    if (chr == NULL) {
+        return NULL;
+    }
+
+    SLIST_FOREACH(dsc, &chr->dscs, next) {
+        if (memcmp(dsc->dsc.uuid128, dsc_uuid128, 16) == 0) {
+            return dsc;
+        }
+    }
+
+    return NULL;
+}
+
+static struct peer_svc *
+peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc)
+{
+    struct peer_svc *prev;
+    struct peer_svc *svc;
+
+    svc = peer_svc_find(peer, gatt_svc->start_handle, &prev);
+    if (svc != NULL) {
+        /* Service already discovered. */
+        return svc;
+    }
+
+    svc = os_memblock_get(&peer_svc_pool);
+    if (svc == NULL) {
+        /* Out of memory. */
+        return NULL;
+    }
+    memset(svc, 0, sizeof *svc);
+
+    svc->svc = *gatt_svc;
+    SLIST_INIT(&svc->chrs);
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&peer->svcs, svc, next);
+    } else {
+        SLIST_INSERT_AFTER(prev, svc, next);
+    }
+
+    return svc;
+}
+
+static void
+peer_svc_delete(struct peer_svc *svc)
+{
+    struct peer_chr *chr;
+
+    while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) {
+        SLIST_REMOVE_HEAD(&svc->chrs, next);
+        peer_chr_delete(chr);
+    }
+
+    os_memblock_put(&peer_svc_pool, svc);
+}
+
+static int
+peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                const struct ble_gatt_svc *service, void *arg)
+{
+    struct peer *peer;
+
+    peer = arg;
+    assert(peer->conn_handle == conn_handle);
+
+    switch (error->status) {
+    case 0:
+        peer_svc_add(peer, service);
+        break;
+
+    case BLE_HS_EDONE:
+        if (peer->disc_prev_chr_val > 0) {
+            peer_disc_chrs(peer);
+        }
+        break;
+
+    default:
+        /* Error */
+        break;
+    }
+
+    return 0;
+}
+
+
+int
+peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg)
+{
+    struct peer_svc *svc;
+    struct peer *peer;
+    int rc;
+
+    peer = peer_find(conn_handle);
+    if (peer == NULL) {
+        return BLE_HS_ENOTCONN;
+    }
+
+    /* Undiscover everything first. */
+    while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
+        SLIST_REMOVE_HEAD(&peer->svcs, next);
+        peer_svc_delete(svc);
+    }
+
+    peer->disc_prev_chr_val = 1;
+    peer->disc_cb = disc_cb;
+    peer->disc_cb_arg = disc_cb_arg;
+
+    rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+int
+peer_delete(uint16_t conn_handle)
+{
+    struct peer *peer;
+    int rc;
+
+    peer = peer_find(conn_handle);
+    if (peer == NULL) {
+        return BLE_HS_ENOTCONN;
+    }
+
+    SLIST_REMOVE(&peers, peer, peer, next);
+
+    rc = os_memblock_put(&peer_pool, peer);
+    if (rc != 0) {
+        return BLE_HS_EOS;
+    }
+
+    return 0;
+}
+
+int
+peer_add(uint16_t conn_handle)
+{
+    struct peer *peer;
+
+    /* Make sure the connection handle is unique. */
+    peer = peer_find(conn_handle);
+    if (peer != NULL) {
+        return BLE_HS_EALREADY;
+    }
+
+    peer = os_memblock_get(&peer_pool);
+    if (peer == NULL) {
+        /* Out of memory. */
+        return BLE_HS_ENOMEM;
+    }
+
+    memset(peer, 0, sizeof *peer);
+    peer->conn_handle = conn_handle;
+
+    SLIST_INSERT_HEAD(&peers, peer, next);
+
+    return 0;
+}
+
+static void
+peer_free_mem(void)
+{
+    free(peer_mem);
+    peer_mem = NULL;
+
+    free(peer_svc_mem);
+    peer_svc_mem = NULL;
+
+    free(peer_chr_mem);
+    peer_chr_mem = NULL;
+
+    free(peer_dsc_mem);
+    peer_dsc_mem = NULL;
+}
+
+int
+peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs)
+{
+    int rc;
+
+    /* Free memory first in case this function gets called more than once. */
+    peer_free_mem();
+
+    peer_mem = malloc(
+        OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer)));
+    if (peer_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_pool, max_peers,
+                         sizeof (struct peer), peer_mem,
+                         "peer_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    peer_svc_mem = malloc(
+        OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc)));
+    if (peer_svc_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_svc_pool, max_svcs,
+                         sizeof (struct peer_svc), peer_svc_mem,
+                         "peer_svc_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    peer_chr_mem = malloc(
+        OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr)));
+    if (peer_chr_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_chr_pool, max_chrs,
+                         sizeof (struct peer_chr), peer_chr_mem,
+                         "peer_chr_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    peer_dsc_mem = malloc(
+        OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc)));
+    if (peer_dsc_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_dsc_pool, max_dscs,
+                         sizeof (struct peer_dsc), peer_dsc_mem,
+                         "peer_dsc_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    return 0;
+
+err:
+    peer_free_mem();
+    return rc;
+}


[2/9] incubator-mynewt-core git commit: bleprph / bletiny - Use new adv data API.

Posted by cc...@apache.org.
bleprph / bletiny - Use new adv data API.


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

Branch: refs/heads/develop
Commit: a7437b202a13d5b38c123b7f7d3e6884b3c8bb26
Parents: 938d3ce
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 19:24:51 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:09 2016 -0700

----------------------------------------------------------------------
 apps/bletiny/src/main.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a7437b20/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index e3a13d2..7c898ff 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -162,8 +162,6 @@ bletiny_print_error(char *msg, uint16_t conn_handle,
 static void
 bletiny_print_adv_fields(const struct ble_hs_adv_fields *fields)
 {
-    uint32_t u32;
-    uint16_t u16;
     uint8_t *u8p;
     int i;
 
@@ -174,10 +172,8 @@ bletiny_print_adv_fields(const struct ble_hs_adv_fields *fields)
     if (fields->uuids16 != NULL) {
         console_printf("    uuids16(%scomplete)=",
                        fields->uuids16_is_complete ? "" : "in");
-        u8p = fields->uuids16;
         for (i = 0; i < fields->num_uuids16; i++) {
-            memcpy(&u16, u8p + i * 2, 2);
-            console_printf("0x%04x ", u16);
+            console_printf("0x%04x ", fields->uuids16[i]);
         }
         console_printf("\n");
     }
@@ -185,10 +181,8 @@ bletiny_print_adv_fields(const struct ble_hs_adv_fields *fields)
     if (fields->uuids32 != NULL) {
         console_printf("    uuids32(%scomplete)=",
                        fields->uuids32_is_complete ? "" : "in");
-        u8p = fields->uuids32;
         for (i = 0; i < fields->num_uuids32; i++) {
-            memcpy(&u32, u8p + i * 4, 4);
-            console_printf("0x%08x ", (unsigned)u32);
+            console_printf("0x%08x ", (unsigned int)fields->uuids32[i]);
         }
         console_printf("\n");
     }
@@ -484,7 +478,6 @@ bletiny_chr_find(const struct bletiny_svc *svc, uint16_t chr_def_handle,
     return chr;
 }
 
-
 static struct bletiny_chr *
 bletiny_chr_add(uint16_t conn_handle,  uint16_t svc_start_handle,
                 const struct ble_gatt_chr *gatt_chr)
@@ -1183,7 +1176,11 @@ bletiny_read(uint16_t conn_handle, uint16_t attr_handle)
 {
     int rc;
 
-    rc = ble_gattc_read(conn_handle, attr_handle, bletiny_on_read, NULL);
+    if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
+        rc = ble_att_svr_read_local(attr_handle, NULL, NULL);
+    } else {
+        rc = ble_gattc_read(conn_handle, attr_handle, bletiny_on_read, NULL);
+    }
     return rc;
 }
 


[3/9] incubator-mynewt-core git commit: BLE Host - rxed adv: UUIDs directly accessible.

Posted by cc...@apache.org.
BLE Host - rxed adv: UUIDs directly accessible.

Prior to this change, the uuids16 and uuids32 fields were just void
pointers which pointed to the raw data.  This is inconvenient for the
user for two reasons:
    * Data is not necessarily aligned for uint16 or uint32 reads.
    * UUIDs are in little-endian, not host byte order.

Now the host allocates a bit of space up front where it can store more
easily accessible UUIDs.


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

Branch: refs/heads/develop
Commit: 938d3ce8f39f006c0d12d368b39fde545d5519ff
Parents: 621629d
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 12:03:35 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:09 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_hs_adv.h |  4 +-
 net/nimble/host/src/ble_hs_adv.c          | 82 ++++++++++++++++++++------
 2 files changed, 66 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/938d3ce8/net/nimble/host/include/host/ble_hs_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs_adv.h b/net/nimble/host/include/host/ble_hs_adv.h
index 1ce456d..cbbb468 100644
--- a/net/nimble/host/include/host/ble_hs_adv.h
+++ b/net/nimble/host/include/host/ble_hs_adv.h
@@ -28,12 +28,12 @@ struct ble_hs_adv_fields {
     unsigned flags_is_present:1;
 
     /*** 0x02,0x03 - 16-bit service class UUIDs. */
-    void *uuids16;
+    uint16_t *uuids16;
     uint8_t num_uuids16;
     unsigned uuids16_is_complete:1;
 
     /*** 0x04,0x05 - 32-bit service class UUIDs. */
-    void *uuids32;
+    uint32_t *uuids32;
     uint8_t num_uuids32;
     unsigned uuids32_is_complete:1;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/938d3ce8/net/nimble/host/src/ble_hs_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_adv.c b/net/nimble/host/src/ble_hs_adv.c
index 74dd393..4fdc529 100644
--- a/net/nimble/host/src/ble_hs_adv.c
+++ b/net/nimble/host/src/ble_hs_adv.c
@@ -23,6 +23,11 @@
 #include "host/ble_hs_adv.h"
 #include "ble_hs_priv.h"
 
+#define BLE_HS_ADV_MAX_FIELD_SZ     (BLE_HCI_MAX_ADV_DATA_LEN - 3)
+
+static uint16_t ble_hs_adv_uuids16[BLE_HS_ADV_MAX_FIELD_SZ / 2];
+static uint32_t ble_hs_adv_uuids32[BLE_HS_ADV_MAX_FIELD_SZ / 4];
+
 static int
 ble_hs_adv_set_hdr(uint8_t type, uint8_t data_len, uint8_t max_len,
                    uint8_t *dst, uint8_t *dst_len)
@@ -358,12 +363,53 @@ ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields,
 }
 
 static int
+ble_hs_adv_parse_uuids16(struct ble_hs_adv_fields *adv_fields,
+                         const uint8_t *data, uint8_t data_len)
+{
+    int i;
+
+    if (data_len % 2 != 0) {
+        return BLE_HS_EBADDATA;
+    }
+
+    adv_fields->uuids16 = ble_hs_adv_uuids16;
+    adv_fields->num_uuids16 = data_len / 2;
+
+    for (i = 0; i < adv_fields->num_uuids16; i++) {
+        adv_fields->uuids16[i] = le16toh(data + i * 2);
+    }
+
+    return 0;
+}
+
+static int
+ble_hs_adv_parse_uuids32(struct ble_hs_adv_fields *adv_fields,
+                         const uint8_t *data, uint8_t data_len)
+{
+    int i;
+
+    if (data_len % 4 != 0) {
+        return BLE_HS_EBADDATA;
+    }
+
+    adv_fields->uuids32 = ble_hs_adv_uuids32;
+    adv_fields->num_uuids32 = data_len / 4;
+
+    for (i = 0; i < adv_fields->num_uuids32; i++) {
+        adv_fields->uuids32[i] = le32toh(data + i * 4);
+    }
+
+    return 0;
+}
+
+static int
 ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields,
                            uint8_t *total_len, uint8_t *src, uint8_t src_len)
 {
     uint8_t data_len;
     uint8_t type;
     uint8_t *data;
+    int rc;
 
     if (src_len < 1) {
         return BLE_HS_EMSGSIZE;
@@ -378,6 +424,10 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields,
     data = src + 2;
     data_len = *total_len - 2;
 
+    if (data_len > BLE_HS_ADV_MAX_FIELD_SZ) {
+        return BLE_HS_EBADDATA;
+    }
+
     switch (type) {
     case BLE_HS_ADV_TYPE_FLAGS:
         if (data_len != BLE_HS_ADV_FLAGS_LEN) {
@@ -388,39 +438,35 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields,
         break;
 
     case BLE_HS_ADV_TYPE_INCOMP_UUIDS16:
-        if (data_len % 2 != 0) {
-            return BLE_HS_EBADDATA;
+        rc = ble_hs_adv_parse_uuids16(adv_fields, data, data_len);
+        if (rc != 0) {
+            return rc;
         }
-        adv_fields->uuids16 = data;
-        adv_fields->num_uuids16 = data_len / 2;
         adv_fields->uuids16_is_complete = 0;
         break;
 
     case BLE_HS_ADV_TYPE_COMP_UUIDS16:
-        if (data_len % 2 != 0) {
-            return BLE_HS_EBADDATA;
+        rc = ble_hs_adv_parse_uuids16(adv_fields, data, data_len);
+        if (rc != 0) {
+            return rc;
         }
-        adv_fields->uuids16 = data;
-        adv_fields->num_uuids16 = data_len / 2;
         adv_fields->uuids16_is_complete = 1;
         break;
 
     case BLE_HS_ADV_TYPE_INCOMP_UUIDS32:
-        if (data_len % 4 != 0) {
-            return BLE_HS_EBADDATA;
+        rc = ble_hs_adv_parse_uuids32(adv_fields, data, data_len);
+        if (rc != 0) {
+            return rc;
         }
-        adv_fields->uuids32 = data;
-        adv_fields->num_uuids32 = data_len / 4;
-        adv_fields->uuids32_is_complete = 0;
+        adv_fields->uuids16_is_complete = 0;
         break;
 
     case BLE_HS_ADV_TYPE_COMP_UUIDS32:
-        if (data_len % 4 != 0) {
-            return BLE_HS_EBADDATA;
+        rc = ble_hs_adv_parse_uuids32(adv_fields, data, data_len);
+        if (rc != 0) {
+            return rc;
         }
-        adv_fields->uuids32 = data;
-        adv_fields->num_uuids32 = data_len / 4;
-        adv_fields->uuids32_is_complete = 1;
+        adv_fields->uuids16_is_complete = 1;
         break;
 
     case BLE_HS_ADV_TYPE_INCOMP_UUIDS128:


[7/9] incubator-mynewt-core git commit: bletiny / bleprph - Use RAM persistence layer pkg.

Posted by cc...@apache.org.
bletiny / bleprph - Use RAM persistence layer pkg.


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

Branch: refs/heads/develop
Commit: cf0676581926f1777ae58a851dc494085734cc11
Parents: db4ca38
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 19:34:36 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:10 2016 -0700

----------------------------------------------------------------------
 apps/bleprph/pkg.yml       |   1 +
 apps/bleprph/src/bleprph.h |   8 +-
 apps/bleprph/src/main.c    |   7 +-
 apps/bletiny/pkg.yml       |   1 +
 apps/bletiny/src/bletiny.h |   5 -
 apps/bletiny/src/main.c    |   7 +-
 apps/bletiny/src/store.c   | 399 ----------------------------------------
 7 files changed, 13 insertions(+), 415 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cf067658/apps/bleprph/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bleprph/pkg.yml b/apps/bleprph/pkg.yml
index df57ac2..0cef560 100644
--- a/apps/bleprph/pkg.yml
+++ b/apps/bleprph/pkg.yml
@@ -27,5 +27,6 @@ pkg.deps:
     - sys/log
     - net/nimble/controller
     - net/nimble/host
+    - net/nimble/host/store/ram
     - libs/console/full
     - libs/baselibc

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cf067658/apps/bleprph/src/bleprph.h
----------------------------------------------------------------------
diff --git a/apps/bleprph/src/bleprph.h b/apps/bleprph/src/bleprph.h
index 6a7ffd4..0dba232 100644
--- a/apps/bleprph/src/bleprph.h
+++ b/apps/bleprph/src/bleprph.h
@@ -21,8 +21,7 @@
 #define H_BLEPRPH_
 
 #include "log/log.h"
-union ble_store_value;
-union ble_store_key;
+struct ble_hs_cfg;
 
 extern struct log bleprph_log;
 
@@ -53,11 +52,6 @@ extern const uint8_t gatt_svr_chr_bleprph_write[16];
 
 void gatt_svr_init(void);
 
-/** Store. */
-int store_read(int obj_type, union ble_store_key *key,
-               union ble_store_value *dst);
-int store_write(int obj_type, union ble_store_value *val);
-
 /** Misc. */
 void print_bytes(const uint8_t *bytes, int len);
 void print_addr(const void *addr);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cf067658/apps/bleprph/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c
index f73f2bf..4342dc8 100755
--- a/apps/bleprph/src/main.c
+++ b/apps/bleprph/src/main.c
@@ -41,6 +41,9 @@
 #include "host/ble_sm.h"
 #include "controller/ble_ll.h"
 
+/* RAM persistence layer. */
+#include "store/ram/ble_store_ram.h"
+
 #include "bleprph.h"
 
 #define BSWAP16(x)  ((uint16_t)(((x) << 8) | (((x) & 0xff00) >> 8)))
@@ -342,8 +345,8 @@ main(void)
     cfg.sm_bonding = 1;
     cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
     cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
-    cfg.store_read_cb = store_read;
-    cfg.store_write_cb = store_write;
+    cfg.store_read_cb = ble_store_ram_read;
+    cfg.store_write_cb = ble_store_ram_write;
 
     /* Initialize eventq */
     os_eventq_init(&bleprph_evq);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cf067658/apps/bletiny/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bletiny/pkg.yml b/apps/bletiny/pkg.yml
index 3b7ca3d..9fab33e 100644
--- a/apps/bletiny/pkg.yml
+++ b/apps/bletiny/pkg.yml
@@ -27,6 +27,7 @@ pkg.deps:
     - sys/log
     - net/nimble/controller
     - net/nimble/host
+    - net/nimble/host/store/ram
     - libs/console/full
     - libs/shell
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cf067658/apps/bletiny/src/bletiny.h
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/bletiny.h b/apps/bletiny/src/bletiny.h
index cb5206b..4910121 100644
--- a/apps/bletiny/src/bletiny.h
+++ b/apps/bletiny/src/bletiny.h
@@ -201,11 +201,6 @@ extern const uint8_t gatt_svr_chr_bleprph_write[16];
 
 void gatt_svr_init(void);
 
-/** Store. */
-int store_read(int obj_type, union ble_store_key *key,
-               union ble_store_value *dst);
-int store_write(int obj_type, union ble_store_value *val);
-
 /** Misc. */
 void print_bytes(const uint8_t *bytes, int len);
 void print_addr(const void *addr);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cf067658/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index 7c898ff..b397b65 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -47,6 +47,9 @@
 #include "host/ble_sm.h"
 #include "controller/ble_ll.h"
 
+/* RAM persistence layer. */
+#include "store/ram/ble_store_ram.h"
+
 /* XXX: An app should not include private headers from a library.  The bletiny
  * app uses some of nimble's internal details for logging.
  */
@@ -1655,8 +1658,8 @@ main(void)
     cfg.max_gattc_procs = 2;
     cfg.max_l2cap_chans = NIMBLE_OPT(MAX_CONNECTIONS) * 3;
     cfg.max_l2cap_sig_procs = 2;
-    cfg.store_read_cb = store_read;
-    cfg.store_write_cb = store_write;
+    cfg.store_read_cb = ble_store_ram_read;
+    cfg.store_write_cb = ble_store_ram_write;
 
     rc = ble_hs_init(&bletiny_evq, &cfg);
     assert(rc == 0);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/cf067658/apps/bletiny/src/store.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/store.c b/apps/bletiny/src/store.c
deleted file mode 100644
index 2cf4682..0000000
--- a/apps/bletiny/src/store.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * This file implements a simple in-RAM key database for long-term keys.  A key
- * is inserted into the database immediately after a successful pairing
- * procedure.  A key is retrieved from the database when the central performs
- * the encryption procedure (bonding).
- *
- * As this database is only stored in RAM, its contents are lost if bleprph is
- * restarted.
- */
-
-#include <inttypes.h>
-#include <string.h>
-#include <assert.h>
-
-#include "console/console.h"
-#include "host/ble_hs.h"
-
-#include "bletiny.h"
-
-#define STORE_MAX_SLV_LTKS   4
-#define STORE_MAX_MST_LTKS   4
-#define STORE_MAX_CCCDS      16
-
-static struct ble_store_value_sec store_our_secs[STORE_MAX_SLV_LTKS];
-static int store_num_our_secs;
-
-static struct ble_store_value_sec store_peer_secs[STORE_MAX_MST_LTKS];
-static int store_num_peer_secs;
-
-static struct ble_store_value_cccd store_cccds[STORE_MAX_CCCDS];
-static int store_num_cccds;
-
-/*****************************************************************************
- * $sec                                                                      *
- *****************************************************************************/
-
-static void
-store_print_value_sec(struct ble_store_value_sec *sec)
-{
-    if (sec->ltk_present) {
-        console_printf("ediv=%u rand=%llu authenticated=%d ltk=",
-                       sec->ediv, sec->rand_num, sec->authenticated);
-        print_bytes(sec->ltk, 16);
-        console_printf(" ");
-    }
-    if (sec->irk_present) {
-        console_printf("irk=");
-        print_bytes(sec->irk, 16);
-        console_printf(" ");
-    }
-    if (sec->csrk_present) {
-        console_printf("csrk=");
-        print_bytes(sec->csrk, 16);
-        console_printf(" ");
-    }
-
-    console_printf("\n");
-}
-
-static void
-store_print_key_sec(struct ble_store_key_sec *key_sec)
-{
-    if (key_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
-        console_printf("peer_addr_type=%d peer_addr=",
-                       key_sec->peer_addr_type);
-        print_bytes(key_sec->peer_addr, 6);
-        console_printf(" ");
-    }
-    if (key_sec->ediv_rand_present) {
-        console_printf("ediv=0x%02x rand=0x%llx ",
-                       key_sec->ediv, key_sec->rand_num);
-    }
-}
-
-static void
-store_log_sec_lookup(int obj_type, struct ble_store_key_sec *key_sec)
-{
-    char *obj_name;
-
-    if (key_sec->peer_addr_type == BLE_STORE_ADDR_TYPE_NONE &&
-       !key_sec->ediv_rand_present) {
-
-        return;
-    }
-
-    switch (obj_type) {
-    case BLE_STORE_OBJ_TYPE_PEER_SEC:
-        obj_name = "peer sec";
-        break;
-    case BLE_STORE_OBJ_TYPE_OUR_SEC:
-        obj_name = "our sec";
-        break;
-    default:
-        assert(0);
-        return;
-    }
-
-    console_printf("looking up %s; ", obj_name);
-    store_print_key_sec(key_sec);
-    console_printf("\n");
-}
-
-static int
-store_find_sec(struct ble_store_key_sec *key_sec,
-               struct ble_store_value_sec *value_secs, int num_value_secs)
-{
-    struct ble_store_value_sec *cur;
-    int skipped;
-    int i;
-
-    skipped = 0;
-
-    for (i = 0; i < num_value_secs; i++) {
-        cur = value_secs + i;
-
-        if (key_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
-            if (cur->peer_addr_type != key_sec->peer_addr_type) {
-                continue;
-            }
-
-            if (memcmp(cur->peer_addr, key_sec->peer_addr,
-                       sizeof cur->peer_addr) != 0) {
-                continue;
-            }
-        }
-
-        if (key_sec->ediv_rand_present) {
-            if (cur->ediv != key_sec->ediv) {
-                continue;
-            }
-
-            if (cur->rand_num != key_sec->rand_num) {
-                continue;
-            }
-        }
-
-        if (key_sec->idx > skipped) {
-            skipped++;
-            continue;
-        }
-
-        return i;
-    }
-
-    return -1;
-}
-
-static int
-store_read_our_sec(struct ble_store_key_sec *key_sec,
-                   struct ble_store_value_sec *value_sec)
-{
-    int idx;
-
-    idx = store_find_sec(key_sec, store_our_secs, store_num_our_secs);
-    if (idx == -1) {
-        return BLE_HS_ENOENT;
-    }
-
-    *value_sec = store_our_secs[idx];
-    return 0;
-}
-
-static int
-store_write_our_sec(struct ble_store_value_sec *value_sec)
-{
-    struct ble_store_key_sec key_sec;
-    int idx;
-
-    console_printf("persisting our sec; ");
-    store_print_value_sec(value_sec);
-
-    ble_store_key_from_value_sec(&key_sec, value_sec);
-    idx = store_find_sec(&key_sec, store_our_secs, store_num_our_secs);
-    if (idx == -1) {
-        if (store_num_our_secs >= STORE_MAX_SLV_LTKS) {
-            console_printf("error persisting our sec; too many entries (%d)\n",
-                           store_num_our_secs);
-            return BLE_HS_ENOMEM;
-        }
-
-        idx = store_num_our_secs;
-        store_num_our_secs++;
-    }
-
-    store_our_secs[idx] = *value_sec;
-    return 0;
-}
-
-static int
-store_read_peer_sec(struct ble_store_key_sec *key_sec,
-                   struct ble_store_value_sec *value_sec)
-{
-    int idx;
-
-    idx = store_find_sec(key_sec, store_peer_secs, store_num_peer_secs);
-    if (idx == -1) {
-        return BLE_HS_ENOENT;
-    }
-
-    *value_sec = store_peer_secs[idx];
-    return 0;
-}
-
-static int
-store_write_peer_sec(struct ble_store_value_sec *value_sec)
-{
-    struct ble_store_key_sec key_sec;
-    int idx;
-
-    console_printf("persisting peer sec; ");
-    store_print_value_sec(value_sec);
-
-    ble_store_key_from_value_sec(&key_sec, value_sec);
-    idx = store_find_sec(&key_sec, store_peer_secs, store_num_peer_secs);
-    if (idx == -1) {
-        if (store_num_peer_secs >= STORE_MAX_MST_LTKS) {
-            console_printf("error persisting peer sec; too many entries "
-                           "(%d)\n", store_num_peer_secs);
-            return BLE_HS_ENOMEM;
-        }
-
-        idx = store_num_peer_secs;
-        store_num_peer_secs++;
-    }
-
-    store_peer_secs[idx] = *value_sec;
-    return 0;
-}
-
-/*****************************************************************************
- * $cccd                                                                     *
- *****************************************************************************/
-
-static int
-store_find_cccd(struct ble_store_key_cccd *key)
-{
-    struct ble_store_value_cccd *cccd;
-    int skipped;
-    int i;
-
-    skipped = 0;
-    for (i = 0; i < store_num_cccds; i++) {
-        cccd = store_cccds + i;
-
-        if (key->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
-            if (cccd->peer_addr_type != key->peer_addr_type) {
-                continue;
-            }
-
-            if (memcmp(cccd->peer_addr, key->peer_addr, 6) != 0) {
-                continue;
-            }
-        }
-
-        if (key->chr_val_handle != 0) {
-            if (cccd->chr_val_handle != key->chr_val_handle) {
-                continue;
-            }
-        }
-
-        if (key->idx > skipped) {
-            skipped++;
-            continue;
-        }
-
-        return i;
-    }
-
-    return -1;
-}
-
-static int
-store_read_cccd(struct ble_store_key_cccd *key_cccd,
-                struct ble_store_value_cccd *value_cccd)
-{
-    int idx;
-
-    idx = store_find_cccd(key_cccd);
-    if (idx == -1) {
-        return BLE_HS_ENOENT;
-    }
-
-    *value_cccd = store_cccds[idx];
-    return 0;
-}
-
-static int
-store_write_cccd(struct ble_store_value_cccd *value_cccd)
-{
-    struct ble_store_key_cccd key_cccd;
-    int idx;
-
-    ble_store_key_from_value_cccd(&key_cccd, value_cccd);
-    idx = store_find_cccd(&key_cccd);
-    if (idx == -1) {
-        if (store_num_cccds >= STORE_MAX_SLV_LTKS) {
-            console_printf("error persisting cccd; too many entries (%d)\n",
-                           store_num_cccds);
-            return BLE_HS_ENOMEM;
-        }
-
-        idx = store_num_cccds;
-        store_num_cccds++;
-    }
-
-    store_cccds[idx] = *value_cccd;
-    return 0;
-}
-
-/*****************************************************************************
- * $api                                                                      *
- *****************************************************************************/
-
-/**
- * Searches the database for an object matching the specified criteria.
- *
- * @return                      0 if a key was found; else BLE_HS_ENOENT.
- */
-int
-store_read(int obj_type, union ble_store_key *key,
-           union ble_store_value *value)
-{
-    int rc;
-
-    switch (obj_type) {
-    case BLE_STORE_OBJ_TYPE_PEER_SEC:
-        /* An encryption procedure (bonding) is being attempted.  The nimble
-         * stack is asking us to look in our key database for a long-term key
-         * corresponding to the specified ediv and random number.
-         *
-         * Perform a key lookup and populate the context object with the
-         * result.  The nimble stack will use this key if this function returns
-         * success.
-         */
-        store_log_sec_lookup(BLE_STORE_OBJ_TYPE_PEER_SEC, &key->sec);
-        rc = store_read_peer_sec(&key->sec, &value->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_OUR_SEC:
-        store_log_sec_lookup(BLE_STORE_OBJ_TYPE_OUR_SEC, &key->sec);
-        rc = store_read_our_sec(&key->sec, &value->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_CCCD:
-        rc = store_read_cccd(&key->cccd, &value->cccd);
-        return rc;
-
-    default:
-        return BLE_HS_ENOTSUP;
-    }
-}
-
-/**
- * Adds the specified object to the database.
- *
- * @return                      0 on success; BLE_HS_ENOMEM if the database is
- *                                  full.
- */
-int
-store_write(int obj_type, union ble_store_value *val)
-{
-    int rc;
-
-    switch (obj_type) {
-    case BLE_STORE_OBJ_TYPE_PEER_SEC:
-        rc = store_write_peer_sec(&val->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_OUR_SEC:
-        rc = store_write_our_sec(&val->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_CCCD:
-        rc = store_write_cccd(&val->cccd);
-        return rc;
-
-    default:
-        return BLE_HS_ENOTSUP;
-    }
-}


[8/9] incubator-mynewt-core git commit: BLE Host - RAM persistence layer package.

Posted by cc...@apache.org.
BLE Host - RAM persistence layer package.


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

Branch: refs/heads/develop
Commit: db4ca38aad14bec43325580a49343f3f45b8414e
Parents: 3326bba
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 19:33:56 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:10 2016 -0700

----------------------------------------------------------------------
 apps/bleprph/src/store.c                        | 374 -------------------
 .../store/ram/include/store/ram/ble_store_ram.h |  30 ++
 net/nimble/host/store/ram/pkg.yml               |  31 ++
 net/nimble/host/store/ram/src/ble_store_ram.c   | 372 ++++++++++++++++++
 4 files changed, 433 insertions(+), 374 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/db4ca38a/apps/bleprph/src/store.c
----------------------------------------------------------------------
diff --git a/apps/bleprph/src/store.c b/apps/bleprph/src/store.c
deleted file mode 100644
index 5b3ae13..0000000
--- a/apps/bleprph/src/store.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * This file implements a simple in-RAM key database for long-term keys.  A key
- * is inserted into the database immediately after a successful pairing
- * procedure.  A key is retrieved from the database when the central performs
- * the encryption procedure (bonding).
- *
- * As this database is only stored in RAM, its contents are lost if bleprph is
- * restarted.
- */
-
-#include <inttypes.h>
-#include <string.h>
-
-#include "console/console.h"
-#include "host/ble_hs.h"
-
-#include "bleprph.h"
-
-#define STORE_MAX_SLV_LTKS   4
-#define STORE_MAX_MST_LTKS   4
-#define STORE_MAX_CCCDS      16
-
-static struct ble_store_value_sec store_our_secs[STORE_MAX_SLV_LTKS];
-static int store_num_our_secs;
-
-static struct ble_store_value_sec store_peer_secs[STORE_MAX_MST_LTKS];
-static int store_num_peer_secs;
-
-static struct ble_store_value_cccd store_cccds[STORE_MAX_CCCDS];
-static int store_num_cccds;
-
-/*****************************************************************************
- * $sec                                                                      *
- *****************************************************************************/
-
-static void
-store_print_value_sec(struct ble_store_value_sec *sec)
-{
-    if (sec->ltk_present) {
-        BLEPRPH_LOG(INFO, "ediv=%u rand=%llu authenticated=%d ltk=",
-                       sec->ediv, sec->rand_num, sec->authenticated);
-        print_bytes(sec->ltk, 16);
-        BLEPRPH_LOG(INFO, " ");
-    }
-    if (sec->irk_present) {
-        BLEPRPH_LOG(INFO, "irk=");
-        print_bytes(sec->irk, 16);
-        BLEPRPH_LOG(INFO, " ");
-    }
-    if (sec->csrk_present) {
-        BLEPRPH_LOG(INFO, "csrk=");
-        print_bytes(sec->csrk, 16);
-        BLEPRPH_LOG(INFO, " ");
-    }
-
-    BLEPRPH_LOG(INFO, "\n");
-}
-
-static void
-store_print_key_sec(struct ble_store_key_sec *key_sec)
-{
-    if (key_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
-        BLEPRPH_LOG(INFO, "peer_addr_type=%d peer_addr=",
-                       key_sec->peer_addr_type);
-        print_bytes(key_sec->peer_addr, 6);
-        BLEPRPH_LOG(INFO, " ");
-    }
-    if (key_sec->ediv_rand_present) {
-        BLEPRPH_LOG(INFO, "ediv=0x%02x rand=0x%llx ",
-                       key_sec->ediv, key_sec->rand_num);
-    }
-}
-
-static int
-store_find_sec(struct ble_store_key_sec *key_sec,
-               struct ble_store_value_sec *value_secs, int num_value_secs)
-{
-    struct ble_store_value_sec *cur;
-    int skipped;
-    int i;
-
-    skipped = 0;
-
-    for (i = 0; i < num_value_secs; i++) {
-        cur = value_secs + i;
-
-        if (key_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
-            if (cur->peer_addr_type != key_sec->peer_addr_type) {
-                continue;
-            }
-
-            if (memcmp(cur->peer_addr, key_sec->peer_addr,
-                       sizeof cur->peer_addr) != 0) {
-                continue;
-            }
-        }
-
-        if (key_sec->ediv_rand_present) {
-            if (cur->ediv != key_sec->ediv) {
-                continue;
-            }
-
-            if (cur->rand_num != key_sec->rand_num) {
-                continue;
-            }
-        }
-
-        if (key_sec->idx > skipped) {
-            skipped++;
-            continue;
-        }
-
-        return i;
-    }
-
-    return -1;
-}
-
-static int
-store_read_our_sec(struct ble_store_key_sec *key_sec,
-                   struct ble_store_value_sec *value_sec)
-{
-    int idx;
-
-    idx = store_find_sec(key_sec, store_our_secs, store_num_our_secs);
-    if (idx == -1) {
-        return BLE_HS_ENOENT;
-    }
-
-    *value_sec = store_our_secs[idx];
-    return 0;
-}
-
-static int
-store_write_our_sec(struct ble_store_value_sec *value_sec)
-{
-    struct ble_store_key_sec key_sec;
-    int idx;
-
-    BLEPRPH_LOG(INFO, "persisting our sec; ");
-    store_print_value_sec(value_sec);
-
-    ble_store_key_from_value_sec(&key_sec, value_sec);
-    idx = store_find_sec(&key_sec, store_our_secs, store_num_our_secs);
-    if (idx == -1) {
-        if (store_num_our_secs >= STORE_MAX_SLV_LTKS) {
-            BLEPRPH_LOG(INFO, "error persisting our sec; too many entries "
-                              "(%d)\n", store_num_our_secs);
-            return BLE_HS_ENOMEM;
-        }
-
-        idx = store_num_our_secs;
-        store_num_our_secs++;
-    }
-
-    store_our_secs[idx] = *value_sec;
-    return 0;
-}
-
-static int
-store_read_peer_sec(struct ble_store_key_sec *key_sec,
-                   struct ble_store_value_sec *value_sec)
-{
-    int idx;
-
-    idx = store_find_sec(key_sec, store_peer_secs, store_num_peer_secs);
-    if (idx == -1) {
-        return BLE_HS_ENOENT;
-    }
-
-    *value_sec = store_peer_secs[idx];
-    return 0;
-}
-
-static int
-store_write_peer_sec(struct ble_store_value_sec *value_sec)
-{
-    struct ble_store_key_sec key_sec;
-    int idx;
-
-    BLEPRPH_LOG(INFO, "persisting peer sec; ");
-    store_print_value_sec(value_sec);
-
-    ble_store_key_from_value_sec(&key_sec, value_sec);
-    idx = store_find_sec(&key_sec, store_peer_secs, store_num_peer_secs);
-    if (idx == -1) {
-        if (store_num_peer_secs >= STORE_MAX_MST_LTKS) {
-            BLEPRPH_LOG(INFO, "error persisting peer sec; too many entries "
-                           "(%d)\n", store_num_peer_secs);
-            return BLE_HS_ENOMEM;
-        }
-
-        idx = store_num_peer_secs;
-        store_num_peer_secs++;
-    }
-
-    store_peer_secs[idx] = *value_sec;
-    return 0;
-}
-
-/*****************************************************************************
- * $cccd                                                                     *
- *****************************************************************************/
-
-static int
-store_find_cccd(struct ble_store_key_cccd *key)
-{
-    struct ble_store_value_cccd *cccd;
-    int skipped;
-    int i;
-
-    skipped = 0;
-    for (i = 0; i < store_num_cccds; i++) {
-        cccd = store_cccds + i;
-
-        if (key->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
-            if (cccd->peer_addr_type != key->peer_addr_type) {
-                continue;
-            }
-
-            if (memcmp(cccd->peer_addr, key->peer_addr, 6) != 0) {
-                continue;
-            }
-        }
-
-        if (key->chr_val_handle != 0) {
-            if (cccd->chr_val_handle != key->chr_val_handle) {
-                continue;
-            }
-        }
-
-        if (key->idx > skipped) {
-            skipped++;
-            continue;
-        }
-
-        return i;
-    }
-
-    return -1;
-}
-
-static int
-store_read_cccd(struct ble_store_key_cccd *key_cccd,
-                struct ble_store_value_cccd *value_cccd)
-{
-    int idx;
-
-    idx = store_find_cccd(key_cccd);
-    if (idx == -1) {
-        return BLE_HS_ENOENT;
-    }
-
-    *value_cccd = store_cccds[idx];
-    return 0;
-}
-
-static int
-store_write_cccd(struct ble_store_value_cccd *value_cccd)
-{
-    struct ble_store_key_cccd key_cccd;
-    int idx;
-
-    ble_store_key_from_value_cccd(&key_cccd, value_cccd);
-    idx = store_find_cccd(&key_cccd);
-    if (idx == -1) {
-        if (store_num_cccds >= STORE_MAX_SLV_LTKS) {
-            BLEPRPH_LOG(INFO, "error persisting cccd; too many entries (%d)\n",
-                        store_num_cccds);
-            return BLE_HS_ENOMEM;
-        }
-
-        idx = store_num_cccds;
-        store_num_cccds++;
-    }
-
-    store_cccds[idx] = *value_cccd;
-    return 0;
-}
-
-/*****************************************************************************
- * $api                                                                      *
- *****************************************************************************/
-
-/**
- * Searches the database for an object matching the specified criteria.
- *
- * @return                      0 if a key was found; else BLE_HS_ENOENT.
- */
-int
-store_read(int obj_type, union ble_store_key *key,
-           union ble_store_value *value)
-{
-    int rc;
-
-    switch (obj_type) {
-    case BLE_STORE_OBJ_TYPE_PEER_SEC:
-        /* An encryption procedure (bonding) is being attempted.  The nimble
-         * stack is asking us to look in our key database for a long-term key
-         * corresponding to the specified ediv and random number.
-         *
-         * Perform a key lookup and populate the context object with the
-         * result.  The nimble stack will use this key if this function returns
-         * success.
-         */
-        BLEPRPH_LOG(INFO, "looking up peer sec; ");
-        store_print_key_sec(&key->sec);
-        BLEPRPH_LOG(INFO, "\n");
-        rc = store_read_peer_sec(&key->sec, &value->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_OUR_SEC:
-        BLEPRPH_LOG(INFO, "looking up our sec; ");
-        store_print_key_sec(&key->sec);
-        BLEPRPH_LOG(INFO, "\n");
-        rc = store_read_our_sec(&key->sec, &value->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_CCCD:
-        rc = store_read_cccd(&key->cccd, &value->cccd);
-        return rc;
-
-    default:
-        return BLE_HS_ENOTSUP;
-    }
-}
-
-/**
- * Adds the specified object to the database.
- *
- * @return                      0 on success; BLE_HS_ENOMEM if the database is
- *                                  full.
- */
-int
-store_write(int obj_type, union ble_store_value *val)
-{
-    int rc;
-
-    switch (obj_type) {
-    case BLE_STORE_OBJ_TYPE_PEER_SEC:
-        rc = store_write_peer_sec(&val->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_OUR_SEC:
-        rc = store_write_our_sec(&val->sec);
-        return rc;
-
-    case BLE_STORE_OBJ_TYPE_CCCD:
-        rc = store_write_cccd(&val->cccd);
-        return rc;
-
-    default:
-        return BLE_HS_ENOTSUP;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/db4ca38a/net/nimble/host/store/ram/include/store/ram/ble_store_ram.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/store/ram/include/store/ram/ble_store_ram.h b/net/nimble/host/store/ram/include/store/ram/ble_store_ram.h
new file mode 100644
index 0000000..b9529c5
--- /dev/null
+++ b/net/nimble/host/store/ram/include/store/ram/ble_store_ram.h
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLE_STORE_RAM_
+#define H_BLE_STORE_RAM_
+
+union ble_store_key;
+union ble_store_value;
+
+int ble_store_ram_read(int obj_type, union ble_store_key *key,
+                       union ble_store_value *value);
+int ble_store_ram_write(int obj_type, union ble_store_value *val);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/db4ca38a/net/nimble/host/store/ram/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/store/ram/pkg.yml b/net/nimble/host/store/ram/pkg.yml
new file mode 100644
index 0000000..f43e7a5
--- /dev/null
+++ b/net/nimble/host/store/ram/pkg.yml
@@ -0,0 +1,31 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: net/nimble/host/store/ram
+pkg.description: RAM-based persistence layer for the NimBLE host.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - ble
+    - bluetooth
+    - nimble
+    - persistence
+
+pkg.deps:
+    - net/nimble/host

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/db4ca38a/net/nimble/host/store/ram/src/ble_store_ram.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/store/ram/src/ble_store_ram.c b/net/nimble/host/store/ram/src/ble_store_ram.c
new file mode 100644
index 0000000..d1e41b4
--- /dev/null
+++ b/net/nimble/host/store/ram/src/ble_store_ram.c
@@ -0,0 +1,372 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This file implements a simple in-RAM key database for BLE host security
+ * material and CCCDs.  As this database is only ble_store_ramd in RAM, its
+ * contents are lost when the application terminates.
+ */
+
+#include <inttypes.h>
+#include <string.h>
+
+#include "host/ble_hs.h"
+#include "store/ram/ble_store_ram.h"
+
+/* XXX: This should be configurable. */
+#define STORE_MAX_SLV_LTKS   4
+#define STORE_MAX_MST_LTKS   4
+#define STORE_MAX_CCCDS      16
+
+static struct ble_store_value_sec ble_store_ram_our_secs[STORE_MAX_SLV_LTKS];
+static int ble_store_ram_num_our_secs;
+
+static struct ble_store_value_sec ble_store_ram_peer_secs[STORE_MAX_MST_LTKS];
+static int ble_store_ram_num_peer_secs;
+
+static struct ble_store_value_cccd ble_store_ram_cccds[STORE_MAX_CCCDS];
+static int ble_store_ram_num_cccds;
+
+/*****************************************************************************
+ * $sec                                                                      *
+ *****************************************************************************/
+
+static void
+ble_store_ram_print_value_sec(struct ble_store_value_sec *sec)
+{
+    if (sec->ltk_present) {
+        BLE_HS_LOG(DEBUG, "ediv=%u rand=%llu authenticated=%d ltk=",
+                       sec->ediv, sec->rand_num, sec->authenticated);
+        ble_hs_log_flat_buf(sec->ltk, 16);
+        BLE_HS_LOG(DEBUG, " ");
+    }
+    if (sec->irk_present) {
+        BLE_HS_LOG(DEBUG, "irk=");
+        ble_hs_log_flat_buf(sec->irk, 16);
+        BLE_HS_LOG(DEBUG, " ");
+    }
+    if (sec->csrk_present) {
+        BLE_HS_LOG(DEBUG, "csrk=");
+        ble_hs_log_flat_buf(sec->csrk, 16);
+        BLE_HS_LOG(DEBUG, " ");
+    }
+
+    BLE_HS_LOG(DEBUG, "\n");
+}
+
+static void
+ble_store_ram_print_key_sec(struct ble_store_key_sec *key_sec)
+{
+    if (key_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
+        BLE_HS_LOG(DEBUG, "peer_addr_type=%d peer_addr=",
+                       key_sec->peer_addr_type);
+        ble_hs_log_flat_buf(key_sec->peer_addr, 6);
+        BLE_HS_LOG(DEBUG, " ");
+    }
+    if (key_sec->ediv_rand_present) {
+        BLE_HS_LOG(DEBUG, "ediv=0x%02x rand=0x%llx ",
+                       key_sec->ediv, key_sec->rand_num);
+    }
+}
+
+static int
+ble_store_ram_find_sec(struct ble_store_key_sec *key_sec,
+                   struct ble_store_value_sec *value_secs, int num_value_secs)
+{
+    struct ble_store_value_sec *cur;
+    int skipped;
+    int i;
+
+    skipped = 0;
+
+    for (i = 0; i < num_value_secs; i++) {
+        cur = value_secs + i;
+
+        if (key_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
+            if (cur->peer_addr_type != key_sec->peer_addr_type) {
+                continue;
+            }
+
+            if (memcmp(cur->peer_addr, key_sec->peer_addr,
+                       sizeof cur->peer_addr) != 0) {
+                continue;
+            }
+        }
+
+        if (key_sec->ediv_rand_present) {
+            if (cur->ediv != key_sec->ediv) {
+                continue;
+            }
+
+            if (cur->rand_num != key_sec->rand_num) {
+                continue;
+            }
+        }
+
+        if (key_sec->idx > skipped) {
+            skipped++;
+            continue;
+        }
+
+        return i;
+    }
+
+    return -1;
+}
+
+static int
+ble_store_ram_read_our_sec(struct ble_store_key_sec *key_sec,
+                       struct ble_store_value_sec *value_sec)
+{
+    int idx;
+
+    idx = ble_store_ram_find_sec(key_sec, ble_store_ram_our_secs, ble_store_ram_num_our_secs);
+    if (idx == -1) {
+        return BLE_HS_ENOENT;
+    }
+
+    *value_sec = ble_store_ram_our_secs[idx];
+    return 0;
+}
+
+static int
+ble_store_ram_write_our_sec(struct ble_store_value_sec *value_sec)
+{
+    struct ble_store_key_sec key_sec;
+    int idx;
+
+    BLE_HS_LOG(DEBUG, "persisting our sec; ");
+    ble_store_ram_print_value_sec(value_sec);
+
+    ble_store_key_from_value_sec(&key_sec, value_sec);
+    idx = ble_store_ram_find_sec(&key_sec, ble_store_ram_our_secs,
+                             ble_store_ram_num_our_secs);
+    if (idx == -1) {
+        if (ble_store_ram_num_our_secs >= STORE_MAX_SLV_LTKS) {
+            BLE_HS_LOG(DEBUG, "error persisting our sec; too many entries "
+                              "(%d)\n", ble_store_ram_num_our_secs);
+            return BLE_HS_ENOMEM;
+        }
+
+        idx = ble_store_ram_num_our_secs;
+        ble_store_ram_num_our_secs++;
+    }
+
+    ble_store_ram_our_secs[idx] = *value_sec;
+    return 0;
+}
+
+static int
+ble_store_ram_read_peer_sec(struct ble_store_key_sec *key_sec,
+                        struct ble_store_value_sec *value_sec)
+{
+    int idx;
+
+    idx = ble_store_ram_find_sec(key_sec, ble_store_ram_peer_secs,
+                             ble_store_ram_num_peer_secs);
+    if (idx == -1) {
+        return BLE_HS_ENOENT;
+    }
+
+    *value_sec = ble_store_ram_peer_secs[idx];
+    return 0;
+}
+
+static int
+ble_store_ram_write_peer_sec(struct ble_store_value_sec *value_sec)
+{
+    struct ble_store_key_sec key_sec;
+    int idx;
+
+    BLE_HS_LOG(DEBUG, "persisting peer sec; ");
+    ble_store_ram_print_value_sec(value_sec);
+
+    ble_store_key_from_value_sec(&key_sec, value_sec);
+    idx = ble_store_ram_find_sec(&key_sec, ble_store_ram_peer_secs,
+                             ble_store_ram_num_peer_secs);
+    if (idx == -1) {
+        if (ble_store_ram_num_peer_secs >= STORE_MAX_MST_LTKS) {
+            BLE_HS_LOG(DEBUG, "error persisting peer sec; too many entries "
+                             "(%d)\n", ble_store_ram_num_peer_secs);
+            return BLE_HS_ENOMEM;
+        }
+
+        idx = ble_store_ram_num_peer_secs;
+        ble_store_ram_num_peer_secs++;
+    }
+
+    ble_store_ram_peer_secs[idx] = *value_sec;
+    return 0;
+}
+
+/*****************************************************************************
+ * $cccd                                                                     *
+ *****************************************************************************/
+
+static int
+ble_store_ram_find_cccd(struct ble_store_key_cccd *key)
+{
+    struct ble_store_value_cccd *cccd;
+    int skipped;
+    int i;
+
+    skipped = 0;
+    for (i = 0; i < ble_store_ram_num_cccds; i++) {
+        cccd = ble_store_ram_cccds + i;
+
+        if (key->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) {
+            if (cccd->peer_addr_type != key->peer_addr_type) {
+                continue;
+            }
+
+            if (memcmp(cccd->peer_addr, key->peer_addr, 6) != 0) {
+                continue;
+            }
+        }
+
+        if (key->chr_val_handle != 0) {
+            if (cccd->chr_val_handle != key->chr_val_handle) {
+                continue;
+            }
+        }
+
+        if (key->idx > skipped) {
+            skipped++;
+            continue;
+        }
+
+        return i;
+    }
+
+    return -1;
+}
+
+static int
+ble_store_ram_read_cccd(struct ble_store_key_cccd *key_cccd,
+                struct ble_store_value_cccd *value_cccd)
+{
+    int idx;
+
+    idx = ble_store_ram_find_cccd(key_cccd);
+    if (idx == -1) {
+        return BLE_HS_ENOENT;
+    }
+
+    *value_cccd = ble_store_ram_cccds[idx];
+    return 0;
+}
+
+static int
+ble_store_ram_write_cccd(struct ble_store_value_cccd *value_cccd)
+{
+    struct ble_store_key_cccd key_cccd;
+    int idx;
+
+    ble_store_key_from_value_cccd(&key_cccd, value_cccd);
+    idx = ble_store_ram_find_cccd(&key_cccd);
+    if (idx == -1) {
+        if (ble_store_ram_num_cccds >= STORE_MAX_SLV_LTKS) {
+            BLE_HS_LOG(DEBUG, "error persisting cccd; too many entries (%d)\n",
+                       ble_store_ram_num_cccds);
+            return BLE_HS_ENOMEM;
+        }
+
+        idx = ble_store_ram_num_cccds;
+        ble_store_ram_num_cccds++;
+    }
+
+    ble_store_ram_cccds[idx] = *value_cccd;
+    return 0;
+}
+
+/*****************************************************************************
+ * $api                                                                      *
+ *****************************************************************************/
+
+/**
+ * Searches the database for an object matching the specified criteria.
+ *
+ * @return                      0 if a key was found; else BLE_HS_ENOENT.
+ */
+int
+ble_store_ram_read(int obj_type, union ble_store_key *key,
+               union ble_store_value *value)
+{
+    int rc;
+
+    switch (obj_type) {
+    case BLE_STORE_OBJ_TYPE_PEER_SEC:
+        /* An encryption procedure (bonding) is being attempted.  The nimble
+         * stack is asking us to look in our key database for a long-term key
+         * corresponding to the specified ediv and random number.
+         *
+         * Perform a key lookup and populate the context object with the
+         * result.  The nimble stack will use this key if this function returns
+         * success.
+         */
+        BLE_HS_LOG(DEBUG, "looking up peer sec; ");
+        ble_store_ram_print_key_sec(&key->sec);
+        BLE_HS_LOG(DEBUG, "\n");
+        rc = ble_store_ram_read_peer_sec(&key->sec, &value->sec);
+        return rc;
+
+    case BLE_STORE_OBJ_TYPE_OUR_SEC:
+        BLE_HS_LOG(DEBUG, "looking up our sec; ");
+        ble_store_ram_print_key_sec(&key->sec);
+        BLE_HS_LOG(DEBUG, "\n");
+        rc = ble_store_ram_read_our_sec(&key->sec, &value->sec);
+        return rc;
+
+    case BLE_STORE_OBJ_TYPE_CCCD:
+        rc = ble_store_ram_read_cccd(&key->cccd, &value->cccd);
+        return rc;
+
+    default:
+        return BLE_HS_ENOTSUP;
+    }
+}
+
+/**
+ * Adds the specified object to the database.
+ *
+ * @return                      0 on success; BLE_HS_ENOMEM if the database is
+ *                                  full.
+ */
+int
+ble_store_ram_write(int obj_type, union ble_store_value *val)
+{
+    int rc;
+
+    switch (obj_type) {
+    case BLE_STORE_OBJ_TYPE_PEER_SEC:
+        rc = ble_store_ram_write_peer_sec(&val->sec);
+        return rc;
+
+    case BLE_STORE_OBJ_TYPE_OUR_SEC:
+        rc = ble_store_ram_write_our_sec(&val->sec);
+        return rc;
+
+    case BLE_STORE_OBJ_TYPE_CCCD:
+        rc = ble_store_ram_write_cccd(&val->cccd);
+        return rc;
+
+    default:
+        return BLE_HS_ENOTSUP;
+    }
+}


[4/9] incubator-mynewt-core git commit: BLE Host - Move logging into separate file.

Posted by cc...@apache.org.
BLE Host - Move logging into separate file.


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

Branch: refs/heads/develop
Commit: 621629d6782b5af120006a818f75f1d131f21f17
Parents: c487de2
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Jul 14 12:02:57 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Thu Jul 14 21:26:09 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_hs.h     |  5 ++-
 net/nimble/host/include/host/ble_hs_log.h | 39 +++++++++++++++++++++
 net/nimble/host/src/ble_hs.c              |  1 -
 net/nimble/host/src/ble_hs_log.c          | 47 ++++++++++++++++++++++++++
 net/nimble/host/src/ble_hs_misc.c         | 24 -------------
 net/nimble/host/src/ble_hs_priv.h         | 12 -------
 net/nimble/host/src/ble_l2cap_sig.c       |  2 +-
 net/nimble/host/src/ble_sm_alg.c          | 36 ++++++++++----------
 net/nimble/host/src/ble_sm_cmd.c          | 16 ++++-----
 net/nimble/host/src/ble_sm_sc.c           |  8 ++---
 net/nimble/host/src/host_hci.c            |  4 +--
 net/nimble/host/src/host_hci_cmd.c        |  2 +-
 12 files changed, 124 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/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 61900b6..dbc8a5b 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -25,9 +25,12 @@
 #include "host/ble_gap.h"
 #include "host/ble_gatt.h"
 #include "host/ble_hs.h"
+#include "host/ble_hs_adv.h"
+#include "host/ble_hs_log.h"
 #include "host/ble_hs_test.h"
-#include "host/ble_uuid.h"
+#include "host/ble_sm.h"
 #include "host/ble_store.h"
+#include "host/ble_uuid.h"
 #include "host/host_hci.h"
 struct os_eventq;
 struct os_event;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/include/host/ble_hs_log.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs_log.h b/net/nimble/host/include/host/ble_hs_log.h
new file mode 100644
index 0000000..fd10ddb
--- /dev/null
+++ b/net/nimble/host/include/host/ble_hs_log.h
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLE_HS_LOG_
+#define H_BLE_HS_LOG_
+
+#include "log/log.h"
+struct os_mbuf;
+
+extern struct log ble_hs_log;
+
+#define BLE_HS_LOG(lvl, ...) \
+    LOG_ ## lvl(&ble_hs_log, LOG_MODULE_NIMBLE_HOST, __VA_ARGS__)
+
+#define BLE_HS_LOG_ADDR(lvl, addr)                      \
+    BLE_HS_LOG(lvl, "%02x:%02x:%02x:%02x:%02x:%02x",    \
+               (addr)[5], (addr)[4], (addr)[3],         \
+               (addr)[2], (addr)[1], (addr)[0])
+
+void ble_hs_log_mbuf(const struct os_mbuf *om);
+void ble_hs_log_flat_buf(const void *data, int len);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/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 8f3cd1b..e3f83f2 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -37,7 +37,6 @@
 #define BLE_HS_MAX_EVS_IN_A_ROW 2
 
 static struct log_handler ble_hs_log_console_handler;
-struct log ble_hs_log;
 
 struct os_mempool g_hci_evt_pool;
 static void *ble_hs_hci_evt_buf;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/ble_hs_log.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_log.c b/net/nimble/host/src/ble_hs_log.c
new file mode 100644
index 0000000..3929483
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_log.c
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "os/os.h"
+#include "host/ble_hs.h"
+
+struct log ble_hs_log;
+
+void
+ble_hs_log_mbuf(const 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);
+        BLE_HS_LOG(DEBUG, "0x%02x ", u8);
+    }
+}
+
+void
+ble_hs_log_flat_buf(const void *data, int len)
+{
+    const uint8_t *u8ptr;
+    int i;
+
+    u8ptr = data;
+    for (i = 0; i < len; i++) {
+        BLE_HS_LOG(DEBUG, "0x%02x ", u8ptr[i]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/ble_hs_misc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_misc.c b/net/nimble/host/src/ble_hs_misc.c
index b893cd3..616b0b5 100644
--- a/net/nimble/host/src/ble_hs_misc.c
+++ b/net/nimble/host/src/ble_hs_misc.c
@@ -45,30 +45,6 @@ ble_hs_misc_malloc_mempool(void **mem, struct os_mempool *pool,
     return 0;
 }
 
-void
-ble_hs_misc_log_mbuf(const 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);
-        BLE_HS_LOG(DEBUG, "0x%02x ", u8);
-    }
-}
-
-void
-ble_hs_misc_log_flat_buf(const void *data, int len)
-{
-    const uint8_t *u8ptr;
-    int i;
-
-    u8ptr = data;
-    for (i = 0; i < len; i++) {
-        BLE_HS_LOG(DEBUG, "0x%02x ", u8ptr[i]);
-    }
-}
-
 /**
  * Allocates an mbuf for use by the nimble host.
  */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h
index e6fe55e..bb78b5e 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -40,7 +40,6 @@
 #include "ble_hs_id_priv.h"
 #include "ble_uuid_priv.h"
 #include "host/ble_hs.h"
-#include "log/log.h"
 #include "nimble/nimble_opt.h"
 #include "stats/stats.h"
 struct ble_hs_conn;
@@ -62,7 +61,6 @@ extern STATS_SECT_DECL(ble_hs_stats) ble_hs_stats;
 
 extern struct ble_hs_cfg ble_hs_cfg;
 extern struct os_mbuf_pool ble_hs_mbuf_pool;
-extern struct log ble_hs_log;
 
 extern const uint8_t ble_hs_misc_null_addr[6];
 
@@ -72,8 +70,6 @@ int ble_hs_tx_data(struct os_mbuf *om);
 
 int ble_hs_misc_malloc_mempool(void **mem, struct os_mempool *pool,
                                int num_entries, int entry_size, char *name);
-void ble_hs_misc_log_mbuf(const struct os_mbuf *om);
-void ble_hs_misc_log_flat_buf(const void *data, int len);
 int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid,
                                struct ble_hs_conn **out_conn,
                                struct ble_l2cap_chan **out_chan);
@@ -94,14 +90,6 @@ struct os_mbuf *ble_hs_misc_pkthdr(void);
 
 int ble_hs_misc_pullup_base(struct os_mbuf **om, int base_len);
 
-#define BLE_HS_LOG(lvl, ...) \
-    LOG_ ## lvl(&ble_hs_log, LOG_MODULE_NIMBLE_HOST, __VA_ARGS__)
-
-#define BLE_HS_LOG_ADDR(lvl, addr)                      \
-    BLE_HS_LOG(lvl, "%02x:%02x:%02x:%02x:%02x:%02x",    \
-               (addr)[5], (addr)[4], (addr)[3],         \
-               (addr)[2], (addr)[1], (addr)[0])
-
 #if LOG_LEVEL <= LOG_LEVEL_DEBUG
 
 #define BLE_HS_LOG_CMD(is_tx, cmd_type, cmd_name, conn_handle,                \

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.c b/net/nimble/host/src/ble_l2cap_sig.c
index e75f06f..dd418f2 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -479,7 +479,7 @@ ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
 
     STATS_INC(ble_l2cap_stats, sig_rx);
     BLE_HS_LOG(DEBUG, "L2CAP - rxed signalling msg: ");
-    ble_hs_misc_log_mbuf(*om);
+    ble_hs_log_mbuf(*om);
     BLE_HS_LOG(DEBUG, "\n");
 
     rc = ble_hs_misc_pullup_base(om, BLE_L2CAP_SIG_HDR_SZ);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/ble_sm_alg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_alg.c b/net/nimble/host/src/ble_sm_alg.c
index b8e8530..3aac60d 100644
--- a/net/nimble/host/src/ble_sm_alg.c
+++ b/net/nimble/host/src/ble_sm_alg.c
@@ -72,7 +72,7 @@ static void
 ble_sm_alg_log_buf(const char *name, const uint8_t *buf, int len)
 {
     BLE_HS_LOG(DEBUG, "    %s=", name);
-    ble_hs_misc_log_flat_buf(buf, len);
+    ble_hs_log_flat_buf(buf, len);
     BLE_HS_LOG(DEBUG, "\n");
 }
 
@@ -166,13 +166,13 @@ ble_sm_alg_s1(uint8_t *k, uint8_t *r1, uint8_t *r2, uint8_t *out)
     }
 
     BLE_HS_LOG(DEBUG, "ble_sm_alg_s1()\n    k=");
-    ble_hs_misc_log_flat_buf(k, 16);
+    ble_hs_log_flat_buf(k, 16);
     BLE_HS_LOG(DEBUG, "\n    r1=");
-    ble_hs_misc_log_flat_buf(r1, 16);
+    ble_hs_log_flat_buf(r1, 16);
     BLE_HS_LOG(DEBUG, "\n    r2=");
-    ble_hs_misc_log_flat_buf(r2, 16);
+    ble_hs_log_flat_buf(r2, 16);
     BLE_HS_LOG(DEBUG, "\n    out=");
-    ble_hs_misc_log_flat_buf(out, 16);
+    ble_hs_log_flat_buf(out, 16);
     BLE_HS_LOG(DEBUG, "\n");
 
     return 0;
@@ -189,18 +189,18 @@ ble_sm_alg_c1(uint8_t *k, uint8_t *r,
     int rc;
 
     BLE_HS_LOG(DEBUG, "ble_sm_alg_c1()\n    k=");
-    ble_hs_misc_log_flat_buf(k, 16);
+    ble_hs_log_flat_buf(k, 16);
     BLE_HS_LOG(DEBUG, "\n    r=");
-    ble_hs_misc_log_flat_buf(r, 16);
+    ble_hs_log_flat_buf(r, 16);
     BLE_HS_LOG(DEBUG, "\n    iat=%d rat=%d", iat, rat);
     BLE_HS_LOG(DEBUG, "\n    ia=");
-    ble_hs_misc_log_flat_buf(ia, 6);
+    ble_hs_log_flat_buf(ia, 6);
     BLE_HS_LOG(DEBUG, "\n    ra=");
-    ble_hs_misc_log_flat_buf(ra, 6);
+    ble_hs_log_flat_buf(ra, 6);
     BLE_HS_LOG(DEBUG, "\n    preq=");
-    ble_hs_misc_log_flat_buf(preq, 7);
+    ble_hs_log_flat_buf(preq, 7);
     BLE_HS_LOG(DEBUG, "\n    pres=");
-    ble_hs_misc_log_flat_buf(pres, 7);
+    ble_hs_log_flat_buf(pres, 7);
 
     /* pres, preq, rat and iat are concatenated to generate p1 */
     p1[0] = iat;
@@ -209,7 +209,7 @@ ble_sm_alg_c1(uint8_t *k, uint8_t *r,
     memcpy(p1 + 9, pres, 7);
 
     BLE_HS_LOG(DEBUG, "\n    p1=");
-    ble_hs_misc_log_flat_buf(p1, sizeof p1);
+    ble_hs_log_flat_buf(p1, sizeof p1);
 
     /* c1 = e(k, e(k, r XOR p1) XOR p2) */
 
@@ -228,7 +228,7 @@ ble_sm_alg_c1(uint8_t *k, uint8_t *r,
     memset(p2 + 12, 0, 4);
 
     BLE_HS_LOG(DEBUG, "\n    p2=");
-    ble_hs_misc_log_flat_buf(p2, sizeof p2);
+    ble_hs_log_flat_buf(p2, sizeof p2);
 
     ble_sm_alg_xor_128(out_enc_data, p2, out_enc_data);
 
@@ -239,7 +239,7 @@ ble_sm_alg_c1(uint8_t *k, uint8_t *r,
     }
 
     BLE_HS_LOG(DEBUG, "\n    out_enc_data=");
-    ble_hs_misc_log_flat_buf(out_enc_data, 16);
+    ble_hs_log_flat_buf(out_enc_data, 16);
 
     rc = 0;
 
@@ -257,11 +257,11 @@ ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z,
     int rc;
 
     BLE_HS_LOG(DEBUG, "ble_sm_alg_f4()\n    u=");
-    ble_hs_misc_log_flat_buf(u, 32);
+    ble_hs_log_flat_buf(u, 32);
     BLE_HS_LOG(DEBUG, "\n    v=");
-    ble_hs_misc_log_flat_buf(v, 32);
+    ble_hs_log_flat_buf(v, 32);
     BLE_HS_LOG(DEBUG, "\n    x=");
-    ble_hs_misc_log_flat_buf(x, 16);
+    ble_hs_log_flat_buf(x, 16);
     BLE_HS_LOG(DEBUG, "\n    z=0x%02x\n", z);
 
     /*
@@ -287,7 +287,7 @@ ble_sm_alg_f4(uint8_t *u, uint8_t *v, uint8_t *x, uint8_t z,
     swap_in_place(out_enc_data, 16);
 
     BLE_HS_LOG(DEBUG, "    out_enc_data=");
-    ble_hs_misc_log_flat_buf(out_enc_data, 16);
+    ble_hs_log_flat_buf(out_enc_data, 16);
     BLE_HS_LOG(DEBUG, "\n");
 
     return 0;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/ble_sm_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_cmd.c b/net/nimble/host/src/ble_sm_cmd.c
index 3d506b2..5f5026f 100644
--- a/net/nimble/host/src/ble_sm_cmd.c
+++ b/net/nimble/host/src/ble_sm_cmd.c
@@ -226,7 +226,7 @@ void
 ble_sm_pair_confirm_log(struct ble_sm_pair_confirm *cmd)
 {
     BLE_HS_LOG(DEBUG, "value=");
-    ble_hs_misc_log_flat_buf(cmd->value, sizeof cmd->value);
+    ble_hs_log_flat_buf(cmd->value, sizeof cmd->value);
 }
 
 void
@@ -279,7 +279,7 @@ void
 ble_sm_pair_random_log(struct ble_sm_pair_random *cmd)
 {
     BLE_HS_LOG(DEBUG, "value=");
-    ble_hs_misc_log_flat_buf(cmd->value, sizeof cmd->value);
+    ble_hs_log_flat_buf(cmd->value, sizeof cmd->value);
 }
 
 void
@@ -388,7 +388,7 @@ void
 ble_sm_enc_info_log(struct ble_sm_enc_info *cmd)
 {
     BLE_HS_LOG(DEBUG, "ltk=");
-    ble_hs_misc_log_flat_buf(cmd->ltk, sizeof cmd->ltk);
+    ble_hs_log_flat_buf(cmd->ltk, sizeof cmd->ltk);
 }
 
 void
@@ -499,7 +499,7 @@ void
 ble_sm_id_info_log(struct ble_sm_id_info *cmd)
 {
     BLE_HS_LOG(DEBUG, "irk=");
-    ble_hs_misc_log_flat_buf(cmd->irk, sizeof cmd->irk);
+    ble_hs_log_flat_buf(cmd->irk, sizeof cmd->irk);
 }
 
 void
@@ -605,7 +605,7 @@ void
 ble_sm_sign_info_log(struct ble_sm_sign_info *cmd)
 {
     BLE_HS_LOG(DEBUG, "sig_key=");
-    ble_hs_misc_log_flat_buf(cmd->sig_key, sizeof cmd->sig_key);
+    ble_hs_log_flat_buf(cmd->sig_key, sizeof cmd->sig_key);
 }
 
 void
@@ -725,9 +725,9 @@ void
 ble_sm_public_key_log(struct ble_sm_public_key *cmd)
 {
     BLE_HS_LOG(DEBUG, "x=");
-    ble_hs_misc_log_flat_buf(cmd->x, sizeof cmd->x);
+    ble_hs_log_flat_buf(cmd->x, sizeof cmd->x);
     BLE_HS_LOG(DEBUG, "y=");
-    ble_hs_misc_log_flat_buf(cmd->y, sizeof cmd->y);
+    ble_hs_log_flat_buf(cmd->y, sizeof cmd->y);
 }
 
 void
@@ -786,7 +786,7 @@ void
 ble_sm_dhkey_check_log(struct ble_sm_dhkey_check *cmd)
 {
     BLE_HS_LOG(DEBUG, "value=");
-    ble_hs_misc_log_flat_buf(cmd->value, sizeof cmd->value);
+    ble_hs_log_flat_buf(cmd->value, sizeof cmd->value);
 }
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/ble_sm_sc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_sc.c b/net/nimble/host/src/ble_sm_sc.c
index bb92a19..c2980b6 100644
--- a/net/nimble/host/src/ble_sm_sc.c
+++ b/net/nimble/host/src/ble_sm_sc.c
@@ -153,10 +153,10 @@ ble_sm_sc_ensure_keys_generated(void)
     }
 
     BLE_HS_LOG(DEBUG, "our pubkey=");
-    ble_hs_misc_log_flat_buf(&ble_sm_sc_pub_key, 64);
+    ble_hs_log_flat_buf(&ble_sm_sc_pub_key, 64);
     BLE_HS_LOG(DEBUG, "\n");
     BLE_HS_LOG(DEBUG, "our privkey=");
-    ble_hs_misc_log_flat_buf(&ble_sm_sc_priv_key, 32);
+    ble_hs_log_flat_buf(&ble_sm_sc_priv_key, 32);
     BLE_HS_LOG(DEBUG, "\n");
 
     return 0;
@@ -363,7 +363,7 @@ ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res)
         ble_sm_sc_responder_verifies_random(proc)) {
 
         BLE_HS_LOG(DEBUG, "tk=");
-        ble_hs_misc_log_flat_buf(proc->tk, 32);
+        ble_hs_log_flat_buf(proc->tk, 32);
         BLE_HS_LOG(DEBUG, "\n");
 
         rc = ble_sm_alg_f4(proc->pub_key_peer.x, ble_sm_sc_pub_key.u8,
@@ -646,7 +646,7 @@ ble_sm_dhkey_check_process(struct ble_sm_proc *proc,
     }
 
     BLE_HS_LOG(DEBUG, "tk=");
-    ble_hs_misc_log_flat_buf(proc->tk, 32);
+    ble_hs_log_flat_buf(proc->tk, 32);
     BLE_HS_LOG(DEBUG, "\n");
 
     res->app_status = ble_sm_alg_f6(proc->mackey,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/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 ce483cd..86e77c5 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -707,7 +707,7 @@ host_hci_data_rx(struct os_mbuf *om)
                BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc), 
                BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc), 
                hci_hdr.hdh_len);
-    ble_hs_misc_log_mbuf(om);
+    ble_hs_log_mbuf(om);
     BLE_HS_LOG(DEBUG, "\n");
 #endif
 
@@ -875,7 +875,7 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om)
         pb = BLE_HCI_PB_MIDDLE;
 
         BLE_HS_LOG(DEBUG, "host_hci_data_tx(): ");
-        ble_hs_misc_log_mbuf(frag);
+        ble_hs_log_mbuf(frag);
         BLE_HS_LOG(DEBUG, "\n");
 
         rc = ble_hs_tx_data(frag);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/621629d6/net/nimble/host/src/host_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c
index 8787d5d..9dbb036 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -89,7 +89,7 @@ host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, const void *cmddata)
 
     BLE_HS_LOG(DEBUG, "host_hci_cmd_send: ogf=0x%02x ocf=0x%02x len=%d\n",
                ogf, ocf, len);
-    ble_hs_misc_log_flat_buf(host_hci_cmd_buf, len + BLE_HCI_CMD_HDR_LEN);
+    ble_hs_log_flat_buf(host_hci_cmd_buf, len + BLE_HCI_CMD_HDR_LEN);
     BLE_HS_LOG(DEBUG, "\n");
     rc = host_hci_cmd_transport(host_hci_cmd_buf);