NuMaker connection with AWS IoT thru MQTT/HTTPS (Mbed OS 6)

Dependencies:   MQTT

Committer:
ccli8
Date:
Tue Oct 29 10:59:34 2019 +0800
Revision:
29:e890b0fdce53
Child:
41:b878d7cd7035
Update to mbed-os 5.14.2 and related modifications

1. Provide custom entropy source on targets without real TRNG
The targets below don't have real TRNG and cannot annouce TRNG support. A custom entropy source with EADC seeded PRNG is given to remedy it:
- NUMAKER_PFM_NUC47
- NUMAKER_PFM_M487
- NUMAKER_IOT_M487
2. Override mbed_main() for:
(1) Simulating provision process
(2) Handling host command via event queue
3. Remove memory statistics printing at end of main(). Printed via host command instead.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ccli8 29:e890b0fdce53 1 /*
ccli8 29:e890b0fdce53 2 * Copyright (c) 2019 Nuvoton Technology Corporation
ccli8 29:e890b0fdce53 3 *
ccli8 29:e890b0fdce53 4 * SPDX-License-Identifier: Apache-2.0
ccli8 29:e890b0fdce53 5 *
ccli8 29:e890b0fdce53 6 * Licensed under the Apache License, Version 2.0 (the "License");
ccli8 29:e890b0fdce53 7 * you may not use this file except in compliance with the License.
ccli8 29:e890b0fdce53 8 * You may obtain a copy of the License at
ccli8 29:e890b0fdce53 9 *
ccli8 29:e890b0fdce53 10 * http://www.apache.org/licenses/LICENSE-2.0
ccli8 29:e890b0fdce53 11 *
ccli8 29:e890b0fdce53 12 * Unless required by applicable law or agreed to in writing, software
ccli8 29:e890b0fdce53 13 * distributed under the License is distributed on an "AS IS" BASIS,
ccli8 29:e890b0fdce53 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ccli8 29:e890b0fdce53 15 * See the License for the specific language governing permissions and
ccli8 29:e890b0fdce53 16 * limitations under the License.
ccli8 29:e890b0fdce53 17 */
ccli8 29:e890b0fdce53 18
ccli8 29:e890b0fdce53 19 #include "mbed.h"
ccli8 29:e890b0fdce53 20 #include "mbedtls/config.h"
ccli8 29:e890b0fdce53 21 #include "entropy_poll.h"
ccli8 29:e890b0fdce53 22 #include "psa/crypto.h"
ccli8 29:e890b0fdce53 23 #include "kvstore_global_api.h"
ccli8 29:e890b0fdce53 24 #include "KVStore.h"
ccli8 29:e890b0fdce53 25 #include "TDBStore.h"
ccli8 29:e890b0fdce53 26 #include "KVMap.h"
ccli8 29:e890b0fdce53 27 #include "kv_config.h"
ccli8 29:e890b0fdce53 28
ccli8 29:e890b0fdce53 29 #ifndef __STDC_FORMAT_MACROS
ccli8 29:e890b0fdce53 30 #define __STDC_FORMAT_MACROS
ccli8 29:e890b0fdce53 31 #endif
ccli8 29:e890b0fdce53 32 #include <inttypes.h>
ccli8 29:e890b0fdce53 33
ccli8 29:e890b0fdce53 34 /* Simulate provision process for development
ccli8 29:e890b0fdce53 35 *
ccli8 29:e890b0fdce53 36 * 1. Reset kvstore
ccli8 29:e890b0fdce53 37 * 2. Inject entropy seed (if no entropy source)
ccli8 29:e890b0fdce53 38 * 3. Initialize user filesystem (if enabled)
ccli8 29:e890b0fdce53 39 * 4. Mark the device as provisioned
ccli8 29:e890b0fdce53 40 *
ccli8 29:e890b0fdce53 41 * WARNING: For mass production, remove this file and run real provision process.
ccli8 29:e890b0fdce53 42 */
ccli8 29:e890b0fdce53 43
ccli8 29:e890b0fdce53 44 /* Check weak reference/definition at the link:
ccli8 29:e890b0fdce53 45 * http://www.keil.com/support/man/docs/ARMLINK/armlink_pge1362065917715.htm */
ccli8 29:e890b0fdce53 46
ccli8 29:e890b0fdce53 47 extern "C" {
ccli8 29:e890b0fdce53 48 MBED_USED void provision(void);
ccli8 29:e890b0fdce53 49 }
ccli8 29:e890b0fdce53 50
ccli8 29:e890b0fdce53 51 /* Stringize */
ccli8 29:e890b0fdce53 52 #define STR_EXPAND(tok) #tok
ccli8 29:e890b0fdce53 53 #define STR(tok) STR_EXPAND(tok)
ccli8 29:e890b0fdce53 54
ccli8 29:e890b0fdce53 55 #define _GET_FILESYSTEM_concat(dev, ...) _get_filesystem_##dev(__VA_ARGS__)
ccli8 29:e890b0fdce53 56 #define GET_FILESYSTEM(dev, ...) _GET_FILESYSTEM_concat(dev, __VA_ARGS__)
ccli8 29:e890b0fdce53 57
ccli8 29:e890b0fdce53 58 /* Key for the device provisioned */
ccli8 29:e890b0fdce53 59 #define KV_KEY_PROVISION "provision"
ccli8 29:e890b0fdce53 60
ccli8 29:e890b0fdce53 61 void provision(void)
ccli8 29:e890b0fdce53 62 {
ccli8 29:e890b0fdce53 63 int kv_reset(const char *kvstore_path);
ccli8 29:e890b0fdce53 64
ccli8 29:e890b0fdce53 65 /* Initialize kvstore */
ccli8 29:e890b0fdce53 66 int kv_status = kv_init_storage_config();
ccli8 29:e890b0fdce53 67 if (kv_status != MBED_SUCCESS) {
ccli8 29:e890b0fdce53 68 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Initialize kvstore failed", kv_status);
ccli8 29:e890b0fdce53 69 }
ccli8 29:e890b0fdce53 70
ccli8 29:e890b0fdce53 71 /* Get kvstore internal storage */
ccli8 29:e890b0fdce53 72 KVMap &kv_map = KVMap::get_instance();
ccli8 29:e890b0fdce53 73 KVStore *inner_store = kv_map.get_internal_kv_instance(NULL);
ccli8 29:e890b0fdce53 74 if (inner_store == NULL) {
ccli8 29:e890b0fdce53 75 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "kvstore internal storage failed");
ccli8 29:e890b0fdce53 76 }
ccli8 29:e890b0fdce53 77
ccli8 29:e890b0fdce53 78 /* Check if the device has provisioned */
ccli8 29:e890b0fdce53 79 KVStore::info_t kv_info;
ccli8 29:e890b0fdce53 80 kv_status = inner_store->get_info(KV_KEY_PROVISION, &kv_info);
ccli8 29:e890b0fdce53 81 if (kv_status == MBED_SUCCESS) {
ccli8 29:e890b0fdce53 82 do {
ccli8 29:e890b0fdce53 83 /* Get KV_KEY_PROVISION key */
ccli8 29:e890b0fdce53 84 char buffer[4];
ccli8 29:e890b0fdce53 85 size_t actual_size = 0;
ccli8 29:e890b0fdce53 86 int kv_status = inner_store->get(KV_KEY_PROVISION, buffer, sizeof(buffer), &actual_size);
ccli8 29:e890b0fdce53 87 if (kv_status != MBED_SUCCESS) {
ccli8 29:e890b0fdce53 88 printf("Get \'%s\' failed: %d\r\n", KV_KEY_PROVISION, kv_status);
ccli8 29:e890b0fdce53 89 break;
ccli8 29:e890b0fdce53 90 }
ccli8 29:e890b0fdce53 91 /* Check KV_KEY_PROVISION key's value */
ccli8 29:e890b0fdce53 92 if (actual_size != 1 || buffer[0] != '1') {
ccli8 29:e890b0fdce53 93 printf("\"%s\" not equal \"%s\"\r\n", KV_KEY_PROVISION, "1");
ccli8 29:e890b0fdce53 94 break;
ccli8 29:e890b0fdce53 95 }
ccli8 29:e890b0fdce53 96
ccli8 29:e890b0fdce53 97 printf("The device has provisioned. Skip provision process\r\n");
ccli8 29:e890b0fdce53 98 return;
ccli8 29:e890b0fdce53 99 } while (0);
ccli8 29:e890b0fdce53 100 } else if (kv_status == MBED_ERROR_ITEM_NOT_FOUND) {
ccli8 29:e890b0fdce53 101 /* Not provisioned yet */
ccli8 29:e890b0fdce53 102 printf("The device has not provisioned yet. Try to provision it...\r\n");
ccli8 29:e890b0fdce53 103 } else {
ccli8 29:e890b0fdce53 104 printf("Get \'%s\' key failed: %d\r\n", KV_KEY_PROVISION, kv_status);
ccli8 29:e890b0fdce53 105 }
ccli8 29:e890b0fdce53 106
ccli8 29:e890b0fdce53 107 /* Provision from here */
ccli8 29:e890b0fdce53 108 printf("Provision for development...\r\n");
ccli8 29:e890b0fdce53 109
ccli8 29:e890b0fdce53 110 printf("Reset kvstore...\r\n");
ccli8 29:e890b0fdce53 111
ccli8 29:e890b0fdce53 112 /* Reset kvstore for clean kvstore */
ccli8 29:e890b0fdce53 113 kv_status = kv_reset("/" STR(MBED_CONF_STORAGE_DEFAULT_KV) "/");
ccli8 29:e890b0fdce53 114 if (kv_status != MBED_SUCCESS) {
ccli8 29:e890b0fdce53 115 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "kv_reset() failed", kv_status);
ccli8 29:e890b0fdce53 116 }
ccli8 29:e890b0fdce53 117
ccli8 29:e890b0fdce53 118 printf("\rReset kvstore...OK\r\n");
ccli8 29:e890b0fdce53 119
ccli8 29:e890b0fdce53 120 #if !DEVICE_TRNG && !TARGET_PSA
ccli8 29:e890b0fdce53 121 #if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
ccli8 29:e890b0fdce53 122 /* Inject trivial seed for development */
ccli8 29:e890b0fdce53 123
ccli8 29:e890b0fdce53 124 printf("Inject NV seed...\r\n");
ccli8 29:e890b0fdce53 125
ccli8 29:e890b0fdce53 126 psa_status_t psa_status;
ccli8 29:e890b0fdce53 127 uint8_t seed[SEED_SIZE] = { 0 };
ccli8 29:e890b0fdce53 128
ccli8 29:e890b0fdce53 129 /* First inject seed, expect OK or seed has injected by some provision process */
ccli8 29:e890b0fdce53 130 psa_status = mbedtls_psa_inject_entropy(seed, sizeof(seed));
ccli8 29:e890b0fdce53 131 if (psa_status != PSA_SUCCESS && psa_status != PSA_ERROR_NOT_PERMITTED) {
ccli8 29:e890b0fdce53 132 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Inject entropy failed", psa_status);
ccli8 29:e890b0fdce53 133 }
ccli8 29:e890b0fdce53 134
ccli8 29:e890b0fdce53 135 /* Second inject seed, expect seed has injected above or by some provision process */
ccli8 29:e890b0fdce53 136 psa_status = mbedtls_psa_inject_entropy(seed, sizeof(seed));
ccli8 29:e890b0fdce53 137 if (psa_status != PSA_ERROR_NOT_PERMITTED) {
ccli8 29:e890b0fdce53 138 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Re-jnject entropy expects PSA_ERROR_NOT_PERMITTED", psa_status);
ccli8 29:e890b0fdce53 139 }
ccli8 29:e890b0fdce53 140
ccli8 29:e890b0fdce53 141 printf("\rInject NV seed...OK\r\n");
ccli8 29:e890b0fdce53 142 #endif /* !defined(MBEDTLS_ENTROPY_HARDWARE_ALT) */
ccli8 29:e890b0fdce53 143 #endif /* #if !DEVICE_TRNG && !TARGET_PSA */
ccli8 29:e890b0fdce53 144
ccli8 29:e890b0fdce53 145 /* Mark the device as provisioned */
ccli8 29:e890b0fdce53 146 kv_status = inner_store->set(KV_KEY_PROVISION, "1", 1, KVStore::WRITE_ONCE_FLAG);
ccli8 29:e890b0fdce53 147 if (kv_status != MBED_SUCCESS) {
ccli8 29:e890b0fdce53 148 MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNKNOWN), "Mark the device as provisioned failed", kv_status);
ccli8 29:e890b0fdce53 149 }
ccli8 29:e890b0fdce53 150
ccli8 29:e890b0fdce53 151 printf("Provision for development...OK\r\n");
ccli8 29:e890b0fdce53 152 }