NuMaker Pelion Device Management example

Fork of mbed-os-example-pelion by cc li

Revision:
4:e564fd8be648
Child:
14:0e7b5aeba173
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pre-main/provision.cpp	Fri Nov 22 11:16:39 2019 +0800
@@ -0,0 +1,152 @@
+/* 
+ * Copyright (c) 2019 Nuvoton Technology Corporation
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mbed.h"
+#include "mbedtls/config.h"
+#include "entropy_poll.h"
+#include "psa/crypto.h"
+#include "kvstore_global_api.h"
+#include "KVStore.h"
+#include "TDBStore.h"
+#include "KVMap.h"
+#include "kv_config.h"
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+#include <inttypes.h>
+
+/* Simulate provision process for development
+ *
+ * 1. Reset kvstore
+ * 2. Inject entropy seed (if no entropy source)
+ * 3. Initialize user filesystem (if enabled)
+ * 4. Mark the device as provisioned
+ *
+ * WARNING: For mass production, remove this file and run real provision process.
+ */
+
+/* Check weak reference/definition at the link:
+ * http://www.keil.com/support/man/docs/ARMLINK/armlink_pge1362065917715.htm */
+
+extern "C" {
+    MBED_USED void provision(void);
+}
+
+/* Stringize */
+#define STR_EXPAND(tok) #tok
+#define STR(tok) STR_EXPAND(tok)
+
+#define _GET_FILESYSTEM_concat(dev, ...) _get_filesystem_##dev(__VA_ARGS__)
+#define GET_FILESYSTEM(dev, ...) _GET_FILESYSTEM_concat(dev, __VA_ARGS__)
+
+/* Key for the device provisioned */
+#define KV_KEY_PROVISION    "provision"
+
+void provision(void)
+{
+    int kv_reset(const char *kvstore_path);
+    
+    /* Initialize kvstore */
+    int kv_status = kv_init_storage_config();
+    if (kv_status != MBED_SUCCESS) {
+        MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Initialize kvstore failed", kv_status);
+    }
+
+    /* Get kvstore internal storage */
+    KVMap &kv_map = KVMap::get_instance();
+    KVStore *inner_store = kv_map.get_internal_kv_instance(NULL);
+    if (inner_store == NULL) {
+        MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "kvstore internal storage failed");
+    }
+
+    /* Check if the device has provisioned */
+    KVStore::info_t kv_info;
+    kv_status = inner_store->get_info(KV_KEY_PROVISION, &kv_info);
+    if (kv_status == MBED_SUCCESS) {
+        do {
+            /* Get KV_KEY_PROVISION key */
+            char buffer[4];
+            size_t actual_size = 0;
+            int kv_status = inner_store->get(KV_KEY_PROVISION, buffer, sizeof(buffer), &actual_size);
+            if (kv_status != MBED_SUCCESS) {
+                printf("Get \'%s\' failed: %d\r\n", KV_KEY_PROVISION, kv_status);
+                break;
+            }
+            /* Check KV_KEY_PROVISION key's value */
+            if (actual_size != 1 || buffer[0] != '1') {
+                printf("\"%s\" not equal \"%s\"\r\n", KV_KEY_PROVISION, "1");
+                break;
+            }
+
+            printf("The device has provisioned. Skip provision process\r\n");
+            return;
+        } while (0);
+    } else if (kv_status == MBED_ERROR_ITEM_NOT_FOUND) {
+        /* Not provisioned yet */
+        printf("The device has not provisioned yet. Try to provision it...\r\n");
+    } else {
+        printf("Get \'%s\' key failed: %d\r\n", KV_KEY_PROVISION, kv_status);
+    }
+
+    /* Provision from here */
+    printf("Provision for development...\r\n");
+    
+    printf("Reset kvstore...\r\n");
+
+    /* Reset kvstore for clean kvstore */
+    kv_status = kv_reset("/" STR(MBED_CONF_STORAGE_DEFAULT_KV) "/");
+    if (kv_status != MBED_SUCCESS) {
+        MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "kv_reset() failed", kv_status);
+    }
+
+    printf("\rReset kvstore...OK\r\n");
+
+#if !DEVICE_TRNG && !TARGET_PSA
+#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+    /* Inject trivial seed for development */
+
+    printf("Inject NV seed...\r\n");
+
+    psa_status_t psa_status;
+    uint8_t seed[SEED_SIZE] = { 0 };
+
+    /* First inject seed, expect OK or seed has injected by some provision process */
+    psa_status = mbedtls_psa_inject_entropy(seed, sizeof(seed));
+    if (psa_status != PSA_SUCCESS && psa_status != PSA_ERROR_NOT_PERMITTED) {
+        MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Inject entropy failed", psa_status);
+    }
+
+    /* Second inject seed, expect seed has injected above or by some provision process */
+    psa_status = mbedtls_psa_inject_entropy(seed, sizeof(seed));
+    if (psa_status != PSA_ERROR_NOT_PERMITTED) {
+        MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Re-jnject entropy expects PSA_ERROR_NOT_PERMITTED", psa_status);
+    }
+
+    printf("\rInject NV seed...OK\r\n");
+#endif  /* !defined(MBEDTLS_ENTROPY_HARDWARE_ALT) */
+#endif  /* #if !DEVICE_TRNG && !TARGET_PSA */
+
+    /* Mark the device as provisioned */
+    kv_status = inner_store->set(KV_KEY_PROVISION, "1", 1, KVStore::WRITE_ONCE_FLAG);
+    if (kv_status != MBED_SUCCESS) {
+        MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Mark the device as provisioned failed", kv_status);
+    }
+
+    printf("Provision for development...OK\r\n");
+}