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:30:05 UTC
[8/9] incubator-mynewt-core git commit: BLE Host - RAM persistence
layer package.
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;
+ }
+}