leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Committer:
leothedragon
Date:
Tue May 04 08:55:12 2021 +0000
Revision:
0:8f0bb79ddd48
nmn

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leothedragon 0:8f0bb79ddd48 1 // ----------------------------------------------------------------------------
leothedragon 0:8f0bb79ddd48 2 // Copyright 2016-2017 ARM Ltd.
leothedragon 0:8f0bb79ddd48 3 //
leothedragon 0:8f0bb79ddd48 4 // SPDX-License-Identifier: Apache-2.0
leothedragon 0:8f0bb79ddd48 5 //
leothedragon 0:8f0bb79ddd48 6 // Licensed under the Apache License, Version 2.0 (the "License");
leothedragon 0:8f0bb79ddd48 7 // you may not use this file except in compliance with the License.
leothedragon 0:8f0bb79ddd48 8 // You may obtain a copy of the License at
leothedragon 0:8f0bb79ddd48 9 //
leothedragon 0:8f0bb79ddd48 10 // http://www.apache.org/licenses/LICENSE-2.0
leothedragon 0:8f0bb79ddd48 11 //
leothedragon 0:8f0bb79ddd48 12 // Unless required by applicable law or agreed to in writing, software
leothedragon 0:8f0bb79ddd48 13 // distributed under the License is distributed on an "AS IS" BASIS,
leothedragon 0:8f0bb79ddd48 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
leothedragon 0:8f0bb79ddd48 15 // See the License for the specific language governing permissions and
leothedragon 0:8f0bb79ddd48 16 // limitations under the License.
leothedragon 0:8f0bb79ddd48 17 // ----------------------------------------------------------------------------
leothedragon 0:8f0bb79ddd48 18
leothedragon 0:8f0bb79ddd48 19 // fixup the compilation on ARMCC for PRId32
leothedragon 0:8f0bb79ddd48 20 #define __STDC_FORMAT_MACROS
leothedragon 0:8f0bb79ddd48 21 #include <inttypes.h>
leothedragon 0:8f0bb79ddd48 22
leothedragon 0:8f0bb79ddd48 23 #include "include/ConnectorClient.h"
leothedragon 0:8f0bb79ddd48 24 #include "include/CloudClientStorage.h"
leothedragon 0:8f0bb79ddd48 25 #include "include/CertificateParser.h"
leothedragon 0:8f0bb79ddd48 26
leothedragon 0:8f0bb79ddd48 27 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 28 #include "include/EstClient.h"
leothedragon 0:8f0bb79ddd48 29 #endif // !MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 30
leothedragon 0:8f0bb79ddd48 31 #include "MbedCloudClient.h"
leothedragon 0:8f0bb79ddd48 32 #include "mbed-client/m2mconstants.h"
leothedragon 0:8f0bb79ddd48 33 #include "mbed-client/m2minterfacefactory.h"
leothedragon 0:8f0bb79ddd48 34 #include "mbed-client/m2mdevice.h"
leothedragon 0:8f0bb79ddd48 35 #include "mbed-client/m2mconstants.h"
leothedragon 0:8f0bb79ddd48 36 #include "mbed-trace/mbed_trace.h"
leothedragon 0:8f0bb79ddd48 37 #include "factory_configurator_client.h"
leothedragon 0:8f0bb79ddd48 38 #include "key_config_manager.h"
leothedragon 0:8f0bb79ddd48 39 #include "mbed-client/uriqueryparser.h"
leothedragon 0:8f0bb79ddd48 40 #include "randLIB.h"
leothedragon 0:8f0bb79ddd48 41
leothedragon 0:8f0bb79ddd48 42 #include <assert.h>
leothedragon 0:8f0bb79ddd48 43 #include <string.h>
leothedragon 0:8f0bb79ddd48 44 #include <stdio.h>
leothedragon 0:8f0bb79ddd48 45
leothedragon 0:8f0bb79ddd48 46 #include "ns_hal_init.h"
leothedragon 0:8f0bb79ddd48 47
leothedragon 0:8f0bb79ddd48 48 #ifdef MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE
leothedragon 0:8f0bb79ddd48 49 #define MBED_CLIENT_EVENT_LOOP_SIZE MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE
leothedragon 0:8f0bb79ddd48 50 #else
leothedragon 0:8f0bb79ddd48 51 #define MBED_CLIENT_EVENT_LOOP_SIZE 1024
leothedragon 0:8f0bb79ddd48 52 #endif
leothedragon 0:8f0bb79ddd48 53
leothedragon 0:8f0bb79ddd48 54 #define TRACE_GROUP "mClt"
leothedragon 0:8f0bb79ddd48 55
leothedragon 0:8f0bb79ddd48 56 #define INTERNAL_ENDPOINT_PARAM "&iep="
leothedragon 0:8f0bb79ddd48 57 #define DEFAULT_ENDPOINT "endpoint"
leothedragon 0:8f0bb79ddd48 58 #define INTERFACE_ERROR "Client interface is not created. Restart"
leothedragon 0:8f0bb79ddd48 59 #define CREDENTIAL_ERROR "Failed to read credentials from storage"
leothedragon 0:8f0bb79ddd48 60 #define DEVICE_NOT_PROVISIONED "Device not provisioned"
leothedragon 0:8f0bb79ddd48 61 #define CONNECTOR_ERROR_NO_MEMORY "Not enough memory to store LWM2M credentials"
leothedragon 0:8f0bb79ddd48 62 #define CONNECTOR_BOOTSTRAP_AGAIN "Re-bootstrapping"
leothedragon 0:8f0bb79ddd48 63
leothedragon 0:8f0bb79ddd48 64 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 65 #define ERROR_EST_ENROLLMENT_REQUEST_FAILED "EST enrollment request failed"
leothedragon 0:8f0bb79ddd48 66 #define LWM2M_CSR_SUBJECT_FORMAT "L=%s,OU=%s,CN=%s"
leothedragon 0:8f0bb79ddd48 67 #endif // !MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 68
leothedragon 0:8f0bb79ddd48 69 #define MAX_REBOOTSTRAP_TIMEOUT 21600 // 6 hours
leothedragon 0:8f0bb79ddd48 70
leothedragon 0:8f0bb79ddd48 71 // XXX: nothing here yet
leothedragon 0:8f0bb79ddd48 72 class EventData {
leothedragon 0:8f0bb79ddd48 73
leothedragon 0:8f0bb79ddd48 74 };
leothedragon 0:8f0bb79ddd48 75
leothedragon 0:8f0bb79ddd48 76 static int read_callback_helper(const char *key, void *buffer, size_t *buffer_len)
leothedragon 0:8f0bb79ddd48 77 {
leothedragon 0:8f0bb79ddd48 78 size_t cert_size = 0;
leothedragon 0:8f0bb79ddd48 79 if (strcmp(key, g_fcc_lwm2m_device_private_key_name) == 0 ||
leothedragon 0:8f0bb79ddd48 80 strcmp(key, g_fcc_bootstrap_device_private_key_name) == 0) {
leothedragon 0:8f0bb79ddd48 81 if (ccs_item_size(key, buffer_len, CCS_PRIVATE_KEY_ITEM) != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 82 *buffer_len = 0;
leothedragon 0:8f0bb79ddd48 83 return CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 84 }
leothedragon 0:8f0bb79ddd48 85
leothedragon 0:8f0bb79ddd48 86 if (ccs_get_item(key, (uint8_t*)buffer, *buffer_len, &cert_size, CCS_PRIVATE_KEY_ITEM) != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 87 *buffer_len = 0;
leothedragon 0:8f0bb79ddd48 88 return CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 89 }
leothedragon 0:8f0bb79ddd48 90 } else {
leothedragon 0:8f0bb79ddd48 91 if (ccs_item_size(key, buffer_len, CCS_CERTIFICATE_ITEM) != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 92 *buffer_len = 0;
leothedragon 0:8f0bb79ddd48 93 return CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 94 }
leothedragon 0:8f0bb79ddd48 95
leothedragon 0:8f0bb79ddd48 96 if (ccs_get_item(key, (uint8_t*)buffer, *buffer_len, &cert_size, CCS_CERTIFICATE_ITEM) != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 97 *buffer_len = 0;
leothedragon 0:8f0bb79ddd48 98 return CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 99 }
leothedragon 0:8f0bb79ddd48 100 }
leothedragon 0:8f0bb79ddd48 101
leothedragon 0:8f0bb79ddd48 102 *buffer_len = cert_size;
leothedragon 0:8f0bb79ddd48 103
leothedragon 0:8f0bb79ddd48 104 return CCS_STATUS_SUCCESS;
leothedragon 0:8f0bb79ddd48 105 }
leothedragon 0:8f0bb79ddd48 106
leothedragon 0:8f0bb79ddd48 107 static bool write_security_object_data_to_kcm(const M2MResourceBase& resource, const uint8_t *buffer, const size_t buffer_size, void */*client_args*/)
leothedragon 0:8f0bb79ddd48 108 {
leothedragon 0:8f0bb79ddd48 109 ccs_status_e status = CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 110 uint32_t resource_id = resource.name_id();
leothedragon 0:8f0bb79ddd48 111 uint16_t object_instance_id = resource.object_instance_id();
leothedragon 0:8f0bb79ddd48 112
leothedragon 0:8f0bb79ddd48 113 switch (resource_id) {
leothedragon 0:8f0bb79ddd48 114 case M2MSecurity::PublicKey:
leothedragon 0:8f0bb79ddd48 115 if (object_instance_id == M2MSecurity::Bootstrap) {
leothedragon 0:8f0bb79ddd48 116 ccs_delete_item(g_fcc_bootstrap_device_certificate_name, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 117 status = ccs_set_item(g_fcc_bootstrap_device_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 118 } else {
leothedragon 0:8f0bb79ddd48 119 ccs_delete_item(g_fcc_lwm2m_device_certificate_name, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 120 status = ccs_set_item(g_fcc_lwm2m_device_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 121 }
leothedragon 0:8f0bb79ddd48 122 break;
leothedragon 0:8f0bb79ddd48 123
leothedragon 0:8f0bb79ddd48 124 case M2MSecurity::ServerPublicKey:
leothedragon 0:8f0bb79ddd48 125 if (object_instance_id == M2MSecurity::Bootstrap) {
leothedragon 0:8f0bb79ddd48 126 ccs_delete_item(g_fcc_bootstrap_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 127 status = ccs_set_item(g_fcc_bootstrap_server_ca_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 128 } else {
leothedragon 0:8f0bb79ddd48 129 ccs_delete_item(g_fcc_lwm2m_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 130 status = ccs_set_item(g_fcc_lwm2m_server_ca_certificate_name, buffer, buffer_size, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 131 }
leothedragon 0:8f0bb79ddd48 132 break;
leothedragon 0:8f0bb79ddd48 133
leothedragon 0:8f0bb79ddd48 134 case M2MSecurity::Secretkey:
leothedragon 0:8f0bb79ddd48 135 if (object_instance_id == M2MSecurity::Bootstrap) {
leothedragon 0:8f0bb79ddd48 136 ccs_delete_item(g_fcc_bootstrap_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
leothedragon 0:8f0bb79ddd48 137 status = ccs_set_item(g_fcc_bootstrap_device_private_key_name, buffer, buffer_size, CCS_PRIVATE_KEY_ITEM);
leothedragon 0:8f0bb79ddd48 138 } else {
leothedragon 0:8f0bb79ddd48 139 ccs_delete_item(g_fcc_lwm2m_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
leothedragon 0:8f0bb79ddd48 140 status = ccs_set_item(g_fcc_lwm2m_device_private_key_name, buffer, buffer_size, CCS_PRIVATE_KEY_ITEM);
leothedragon 0:8f0bb79ddd48 141 }
leothedragon 0:8f0bb79ddd48 142 break;
leothedragon 0:8f0bb79ddd48 143
leothedragon 0:8f0bb79ddd48 144 default:
leothedragon 0:8f0bb79ddd48 145 break;
leothedragon 0:8f0bb79ddd48 146 }
leothedragon 0:8f0bb79ddd48 147
leothedragon 0:8f0bb79ddd48 148 return (status == CCS_STATUS_SUCCESS) ? true : false;
leothedragon 0:8f0bb79ddd48 149 }
leothedragon 0:8f0bb79ddd48 150
leothedragon 0:8f0bb79ddd48 151 static int read_security_object_data_from_kcm(const M2MResourceBase& resource, void *buffer, size_t *buffer_len, void */*client_args*/)
leothedragon 0:8f0bb79ddd48 152 {
leothedragon 0:8f0bb79ddd48 153 uint32_t resource_id = resource.name_id();
leothedragon 0:8f0bb79ddd48 154 uint16_t object_instance_id = resource.object_instance_id();
leothedragon 0:8f0bb79ddd48 155 switch (resource_id) {
leothedragon 0:8f0bb79ddd48 156 case M2MSecurity::PublicKey:
leothedragon 0:8f0bb79ddd48 157 if (object_instance_id == M2MSecurity::Bootstrap) {
leothedragon 0:8f0bb79ddd48 158 return read_callback_helper(g_fcc_bootstrap_device_certificate_name, buffer, buffer_len);
leothedragon 0:8f0bb79ddd48 159 } else {
leothedragon 0:8f0bb79ddd48 160 return read_callback_helper(g_fcc_lwm2m_device_certificate_name, buffer, buffer_len);
leothedragon 0:8f0bb79ddd48 161 }
leothedragon 0:8f0bb79ddd48 162
leothedragon 0:8f0bb79ddd48 163 case M2MSecurity::ServerPublicKey:
leothedragon 0:8f0bb79ddd48 164 if (object_instance_id == M2MSecurity::Bootstrap) {
leothedragon 0:8f0bb79ddd48 165 return read_callback_helper(g_fcc_bootstrap_server_ca_certificate_name, buffer, buffer_len);
leothedragon 0:8f0bb79ddd48 166 } else {
leothedragon 0:8f0bb79ddd48 167 return read_callback_helper(g_fcc_lwm2m_server_ca_certificate_name, buffer, buffer_len);
leothedragon 0:8f0bb79ddd48 168 }
leothedragon 0:8f0bb79ddd48 169
leothedragon 0:8f0bb79ddd48 170 case M2MSecurity::Secretkey:
leothedragon 0:8f0bb79ddd48 171 if (object_instance_id == M2MSecurity::Bootstrap) {
leothedragon 0:8f0bb79ddd48 172 return read_callback_helper(g_fcc_bootstrap_device_private_key_name, buffer, buffer_len);
leothedragon 0:8f0bb79ddd48 173 } else {
leothedragon 0:8f0bb79ddd48 174 return read_callback_helper(g_fcc_lwm2m_device_private_key_name, buffer, buffer_len);
leothedragon 0:8f0bb79ddd48 175 }
leothedragon 0:8f0bb79ddd48 176
leothedragon 0:8f0bb79ddd48 177 default:
leothedragon 0:8f0bb79ddd48 178 break;
leothedragon 0:8f0bb79ddd48 179 }
leothedragon 0:8f0bb79ddd48 180
leothedragon 0:8f0bb79ddd48 181 return CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 182 }
leothedragon 0:8f0bb79ddd48 183
leothedragon 0:8f0bb79ddd48 184 static int open_certificate_chain_callback(const M2MResourceBase& resource, void */*buffer*/, size_t *chain_size, void *client_args)
leothedragon 0:8f0bb79ddd48 185 {
leothedragon 0:8f0bb79ddd48 186 void *handle = NULL;
leothedragon 0:8f0bb79ddd48 187 uint16_t object_instance_id = resource.object_instance_id();
leothedragon 0:8f0bb79ddd48 188 ConnectorClient *client = (ConnectorClient*)client_args;
leothedragon 0:8f0bb79ddd48 189 if (object_instance_id == M2MSecurity::Bootstrap) {
leothedragon 0:8f0bb79ddd48 190 handle = ccs_open_certificate_chain(g_fcc_bootstrap_device_certificate_name, chain_size);
leothedragon 0:8f0bb79ddd48 191 client->set_certificate_chain_handle(handle);
leothedragon 0:8f0bb79ddd48 192 } else {
leothedragon 0:8f0bb79ddd48 193 handle = ccs_open_certificate_chain(g_fcc_lwm2m_device_certificate_name, chain_size);
leothedragon 0:8f0bb79ddd48 194 client->set_certificate_chain_handle(handle);
leothedragon 0:8f0bb79ddd48 195 }
leothedragon 0:8f0bb79ddd48 196
leothedragon 0:8f0bb79ddd48 197 return (handle) ? CCS_STATUS_SUCCESS : CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 198 }
leothedragon 0:8f0bb79ddd48 199
leothedragon 0:8f0bb79ddd48 200 static int read_certificate_chain_callback(const M2MResourceBase& /*resource*/, void *buffer, size_t *buffer_len, void *client_args)
leothedragon 0:8f0bb79ddd48 201 {
leothedragon 0:8f0bb79ddd48 202 ConnectorClient *client = (ConnectorClient*) client_args;
leothedragon 0:8f0bb79ddd48 203 ccs_status_e status = CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 204 if (client->certificate_chain_handle()) {
leothedragon 0:8f0bb79ddd48 205 status = ccs_get_next_cert_chain(client->certificate_chain_handle(), buffer, buffer_len);
leothedragon 0:8f0bb79ddd48 206 }
leothedragon 0:8f0bb79ddd48 207
leothedragon 0:8f0bb79ddd48 208 return status;
leothedragon 0:8f0bb79ddd48 209 }
leothedragon 0:8f0bb79ddd48 210
leothedragon 0:8f0bb79ddd48 211 static int close_certificate_chain_callback(const M2MResourceBase& /*resource*/, void */*buffer*/, size_t *, void *client_args)
leothedragon 0:8f0bb79ddd48 212 {
leothedragon 0:8f0bb79ddd48 213 ccs_status_e status = CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 214 ConnectorClient *client = (ConnectorClient*) client_args;
leothedragon 0:8f0bb79ddd48 215 if (client->certificate_chain_handle()) {
leothedragon 0:8f0bb79ddd48 216 status = ccs_close_certificate_chain(client->certificate_chain_handle());
leothedragon 0:8f0bb79ddd48 217 client->set_certificate_chain_handle(NULL);
leothedragon 0:8f0bb79ddd48 218 }
leothedragon 0:8f0bb79ddd48 219 return status;
leothedragon 0:8f0bb79ddd48 220 }
leothedragon 0:8f0bb79ddd48 221
leothedragon 0:8f0bb79ddd48 222 ConnectorClient::ConnectorClient(ConnectorClientCallback* callback)
leothedragon 0:8f0bb79ddd48 223 : _callback(callback),
leothedragon 0:8f0bb79ddd48 224 _current_state(State_Bootstrap_Start),
leothedragon 0:8f0bb79ddd48 225 _event_generated(false), _state_engine_running(false),
leothedragon 0:8f0bb79ddd48 226 _setup_complete(false),
leothedragon 0:8f0bb79ddd48 227 _interface(NULL), _security(NULL),
leothedragon 0:8f0bb79ddd48 228 _endpoint_info(M2MSecurity::Certificate), _client_objs(NULL),
leothedragon 0:8f0bb79ddd48 229 _rebootstrap_timer(*this), _bootstrap_security_instance(1),
leothedragon 0:8f0bb79ddd48 230 _lwm2m_security_instance(0), _certificate_chain_handle(NULL)
leothedragon 0:8f0bb79ddd48 231 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 232 ,_est_client(*this)
leothedragon 0:8f0bb79ddd48 233 #endif // !MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 234
leothedragon 0:8f0bb79ddd48 235 {
leothedragon 0:8f0bb79ddd48 236 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 237
leothedragon 0:8f0bb79ddd48 238 _rebootstrap_time = randLIB_get_random_in_range(1, 10);
leothedragon 0:8f0bb79ddd48 239 }
leothedragon 0:8f0bb79ddd48 240
leothedragon 0:8f0bb79ddd48 241
leothedragon 0:8f0bb79ddd48 242 ConnectorClient::~ConnectorClient()
leothedragon 0:8f0bb79ddd48 243 {
leothedragon 0:8f0bb79ddd48 244 uninitialize_storage();
leothedragon 0:8f0bb79ddd48 245 M2MDevice::delete_instance();
leothedragon 0:8f0bb79ddd48 246 M2MSecurity::delete_instance();
leothedragon 0:8f0bb79ddd48 247 delete _interface;
leothedragon 0:8f0bb79ddd48 248 }
leothedragon 0:8f0bb79ddd48 249
leothedragon 0:8f0bb79ddd48 250 bool ConnectorClient::setup()
leothedragon 0:8f0bb79ddd48 251 {
leothedragon 0:8f0bb79ddd48 252 // the setup() may be called again after connection has been closed so let's avoid leaks
leothedragon 0:8f0bb79ddd48 253 if (_setup_complete == false) {
leothedragon 0:8f0bb79ddd48 254
leothedragon 0:8f0bb79ddd48 255 // The ns_hal_init() needs to be called by someone before create_interface(),
leothedragon 0:8f0bb79ddd48 256 // as it will also initialize the tasklet.
leothedragon 0:8f0bb79ddd48 257 ns_hal_init(NULL, MBED_CLIENT_EVENT_LOOP_SIZE, NULL, NULL);
leothedragon 0:8f0bb79ddd48 258
leothedragon 0:8f0bb79ddd48 259 // Create the lwm2m server security object we need always
leothedragon 0:8f0bb79ddd48 260 M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 261 M2MInterface *interface = M2MInterfaceFactory::create_interface(*this,
leothedragon 0:8f0bb79ddd48 262 DEFAULT_ENDPOINT, // endpoint name string
leothedragon 0:8f0bb79ddd48 263 MBED_CLOUD_CLIENT_ENDPOINT_TYPE, // endpoint type string
leothedragon 0:8f0bb79ddd48 264 MBED_CLOUD_CLIENT_LIFETIME, // lifetime
leothedragon 0:8f0bb79ddd48 265 MBED_CLOUD_CLIENT_LISTEN_PORT, // listen port
leothedragon 0:8f0bb79ddd48 266 _endpoint_info.account_id, // domain string
leothedragon 0:8f0bb79ddd48 267 transport_mode(), // binding mode
leothedragon 0:8f0bb79ddd48 268 M2MInterface::LwIP_IPv4); // network stack
leothedragon 0:8f0bb79ddd48 269
leothedragon 0:8f0bb79ddd48 270 if ((security == NULL) || (interface == NULL)) {
leothedragon 0:8f0bb79ddd48 271 M2MSecurity::delete_instance();
leothedragon 0:8f0bb79ddd48 272 delete interface;
leothedragon 0:8f0bb79ddd48 273 } else {
leothedragon 0:8f0bb79ddd48 274 if (initialize_storage() == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 275 _security = security;
leothedragon 0:8f0bb79ddd48 276 _interface = interface;
leothedragon 0:8f0bb79ddd48 277 _setup_complete = true;
leothedragon 0:8f0bb79ddd48 278 }
leothedragon 0:8f0bb79ddd48 279 }
leothedragon 0:8f0bb79ddd48 280 }
leothedragon 0:8f0bb79ddd48 281
leothedragon 0:8f0bb79ddd48 282 return _setup_complete;
leothedragon 0:8f0bb79ddd48 283 }
leothedragon 0:8f0bb79ddd48 284
leothedragon 0:8f0bb79ddd48 285 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 286 const EstClient &ConnectorClient::est_client()
leothedragon 0:8f0bb79ddd48 287 {
leothedragon 0:8f0bb79ddd48 288 return _est_client;
leothedragon 0:8f0bb79ddd48 289 }
leothedragon 0:8f0bb79ddd48 290 #endif // !MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 291
leothedragon 0:8f0bb79ddd48 292 void ConnectorClient::start_bootstrap()
leothedragon 0:8f0bb79ddd48 293 {
leothedragon 0:8f0bb79ddd48 294 tr_debug("ConnectorClient::start_bootstrap()");
leothedragon 0:8f0bb79ddd48 295
leothedragon 0:8f0bb79ddd48 296 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 297 assert(_setup_complete);
leothedragon 0:8f0bb79ddd48 298
leothedragon 0:8f0bb79ddd48 299 init_security_object();
leothedragon 0:8f0bb79ddd48 300 // Stop rebootstrap timer if it was running
leothedragon 0:8f0bb79ddd48 301 _rebootstrap_timer.stop_timer();
leothedragon 0:8f0bb79ddd48 302
leothedragon 0:8f0bb79ddd48 303 if (create_bootstrap_object()) {
leothedragon 0:8f0bb79ddd48 304 _interface->update_endpoint(_endpoint_info.endpoint_name);
leothedragon 0:8f0bb79ddd48 305 _interface->update_domain(_endpoint_info.account_id);
leothedragon 0:8f0bb79ddd48 306 internal_event(State_Bootstrap_Start);
leothedragon 0:8f0bb79ddd48 307 } else {
leothedragon 0:8f0bb79ddd48 308 tr_error("ConnectorClient::start_bootstrap() - bootstrap object fail");
leothedragon 0:8f0bb79ddd48 309 }
leothedragon 0:8f0bb79ddd48 310 state_engine();
leothedragon 0:8f0bb79ddd48 311 }
leothedragon 0:8f0bb79ddd48 312
leothedragon 0:8f0bb79ddd48 313 void ConnectorClient::start_registration(M2MBaseList* client_objs)
leothedragon 0:8f0bb79ddd48 314 {
leothedragon 0:8f0bb79ddd48 315 tr_debug("ConnectorClient::start_registration()");
leothedragon 0:8f0bb79ddd48 316
leothedragon 0:8f0bb79ddd48 317 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 318 assert(_setup_complete);
leothedragon 0:8f0bb79ddd48 319
leothedragon 0:8f0bb79ddd48 320 init_security_object();
leothedragon 0:8f0bb79ddd48 321 _client_objs = client_objs;
leothedragon 0:8f0bb79ddd48 322
leothedragon 0:8f0bb79ddd48 323 // XXX: actually this call should be external_event() to match the pattern used in other m2m classes
leothedragon 0:8f0bb79ddd48 324 if (create_register_object()) {
leothedragon 0:8f0bb79ddd48 325 if(_security->get_security_instance_id(M2MSecurity::M2MServer) >= 0) {
leothedragon 0:8f0bb79ddd48 326 _interface->update_endpoint(_endpoint_info.endpoint_name);
leothedragon 0:8f0bb79ddd48 327 _interface->update_domain(_endpoint_info.account_id);
leothedragon 0:8f0bb79ddd48 328 internal_event(State_Registration_Start);
leothedragon 0:8f0bb79ddd48 329 } else {
leothedragon 0:8f0bb79ddd48 330 tr_error("ConnectorClient::start_registration(): failed to create objs");
leothedragon 0:8f0bb79ddd48 331 _callback->connector_error(M2MInterface::InvalidParameters, INTERFACE_ERROR);
leothedragon 0:8f0bb79ddd48 332 }
leothedragon 0:8f0bb79ddd48 333 } else {
leothedragon 0:8f0bb79ddd48 334 tr_error("ConnectorClient::start_registration - failed to read credentials");
leothedragon 0:8f0bb79ddd48 335 _callback->connector_error((M2MInterface::Error)MbedCloudClient::ConnectorFailedToReadCredentials, CREDENTIAL_ERROR);
leothedragon 0:8f0bb79ddd48 336 }
leothedragon 0:8f0bb79ddd48 337 state_engine();
leothedragon 0:8f0bb79ddd48 338 }
leothedragon 0:8f0bb79ddd48 339
leothedragon 0:8f0bb79ddd48 340 M2MInterface * ConnectorClient::m2m_interface()
leothedragon 0:8f0bb79ddd48 341 {
leothedragon 0:8f0bb79ddd48 342 return _interface;
leothedragon 0:8f0bb79ddd48 343 }
leothedragon 0:8f0bb79ddd48 344
leothedragon 0:8f0bb79ddd48 345 void ConnectorClient::update_registration()
leothedragon 0:8f0bb79ddd48 346 {
leothedragon 0:8f0bb79ddd48 347 if(_interface && _security && _security->get_security_instance_id(M2MSecurity::M2MServer) >= 0) {
leothedragon 0:8f0bb79ddd48 348 if (_client_objs != NULL) {
leothedragon 0:8f0bb79ddd48 349 _interface->update_registration(_security, *_client_objs);
leothedragon 0:8f0bb79ddd48 350 }
leothedragon 0:8f0bb79ddd48 351 else {
leothedragon 0:8f0bb79ddd48 352 _interface->update_registration(_security);
leothedragon 0:8f0bb79ddd48 353 }
leothedragon 0:8f0bb79ddd48 354 }
leothedragon 0:8f0bb79ddd48 355 }
leothedragon 0:8f0bb79ddd48 356
leothedragon 0:8f0bb79ddd48 357 // generates an internal event. called from within a state
leothedragon 0:8f0bb79ddd48 358 // function to transition to a new state
leothedragon 0:8f0bb79ddd48 359 void ConnectorClient::internal_event(StartupSubStateRegistration new_state)
leothedragon 0:8f0bb79ddd48 360 {
leothedragon 0:8f0bb79ddd48 361 tr_debug("ConnectorClient::internal_event: state: %d -> %d", _current_state, new_state);
leothedragon 0:8f0bb79ddd48 362 _event_generated = true;
leothedragon 0:8f0bb79ddd48 363 _current_state = new_state;
leothedragon 0:8f0bb79ddd48 364
leothedragon 0:8f0bb79ddd48 365 // Avoid recursive chain which eats too much of stack
leothedragon 0:8f0bb79ddd48 366 if (!_state_engine_running) {
leothedragon 0:8f0bb79ddd48 367 state_engine();
leothedragon 0:8f0bb79ddd48 368 }
leothedragon 0:8f0bb79ddd48 369 }
leothedragon 0:8f0bb79ddd48 370
leothedragon 0:8f0bb79ddd48 371 // the state engine executes the state machine states
leothedragon 0:8f0bb79ddd48 372 void ConnectorClient::state_engine(void)
leothedragon 0:8f0bb79ddd48 373 {
leothedragon 0:8f0bb79ddd48 374 tr_debug("ConnectorClient::state_engine");
leothedragon 0:8f0bb79ddd48 375
leothedragon 0:8f0bb79ddd48 376 // this simple flagging gets rid of recursive calls to this method
leothedragon 0:8f0bb79ddd48 377 _state_engine_running = true;
leothedragon 0:8f0bb79ddd48 378
leothedragon 0:8f0bb79ddd48 379 // while events are being generated keep executing states
leothedragon 0:8f0bb79ddd48 380 while (_event_generated) {
leothedragon 0:8f0bb79ddd48 381 _event_generated = false; // event used up, reset flag
leothedragon 0:8f0bb79ddd48 382
leothedragon 0:8f0bb79ddd48 383 state_function(_current_state);
leothedragon 0:8f0bb79ddd48 384 }
leothedragon 0:8f0bb79ddd48 385
leothedragon 0:8f0bb79ddd48 386 _state_engine_running = false;
leothedragon 0:8f0bb79ddd48 387 }
leothedragon 0:8f0bb79ddd48 388
leothedragon 0:8f0bb79ddd48 389 void ConnectorClient::state_function(StartupSubStateRegistration current_state)
leothedragon 0:8f0bb79ddd48 390 {
leothedragon 0:8f0bb79ddd48 391 switch (current_state) {
leothedragon 0:8f0bb79ddd48 392 case State_Bootstrap_Start:
leothedragon 0:8f0bb79ddd48 393 state_bootstrap_start();
leothedragon 0:8f0bb79ddd48 394 break;
leothedragon 0:8f0bb79ddd48 395 case State_Bootstrap_Started:
leothedragon 0:8f0bb79ddd48 396 state_bootstrap_started();
leothedragon 0:8f0bb79ddd48 397 break;
leothedragon 0:8f0bb79ddd48 398 case State_Bootstrap_Success:
leothedragon 0:8f0bb79ddd48 399 state_bootstrap_success();
leothedragon 0:8f0bb79ddd48 400 break;
leothedragon 0:8f0bb79ddd48 401 case State_Bootstrap_Failure:
leothedragon 0:8f0bb79ddd48 402 state_bootstrap_failure();
leothedragon 0:8f0bb79ddd48 403 break;
leothedragon 0:8f0bb79ddd48 404 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 405 case State_EST_Start:
leothedragon 0:8f0bb79ddd48 406 state_est_start();
leothedragon 0:8f0bb79ddd48 407 break;
leothedragon 0:8f0bb79ddd48 408 case State_EST_Started:
leothedragon 0:8f0bb79ddd48 409 state_est_started();
leothedragon 0:8f0bb79ddd48 410 break;
leothedragon 0:8f0bb79ddd48 411 case State_EST_Success:
leothedragon 0:8f0bb79ddd48 412 state_est_success();
leothedragon 0:8f0bb79ddd48 413 break;
leothedragon 0:8f0bb79ddd48 414 case State_EST_Failure:
leothedragon 0:8f0bb79ddd48 415 state_est_failure();
leothedragon 0:8f0bb79ddd48 416 break;
leothedragon 0:8f0bb79ddd48 417 #endif // !MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 418 case State_Registration_Start:
leothedragon 0:8f0bb79ddd48 419 state_registration_start();
leothedragon 0:8f0bb79ddd48 420 break;
leothedragon 0:8f0bb79ddd48 421 case State_Registration_Started:
leothedragon 0:8f0bb79ddd48 422 state_registration_started();
leothedragon 0:8f0bb79ddd48 423 break;
leothedragon 0:8f0bb79ddd48 424 case State_Registration_Success:
leothedragon 0:8f0bb79ddd48 425 state_registration_success();
leothedragon 0:8f0bb79ddd48 426 break;
leothedragon 0:8f0bb79ddd48 427 case State_Registration_Failure:
leothedragon 0:8f0bb79ddd48 428 state_registration_failure();
leothedragon 0:8f0bb79ddd48 429 break;
leothedragon 0:8f0bb79ddd48 430 case State_Unregistered:
leothedragon 0:8f0bb79ddd48 431 state_unregistered();
leothedragon 0:8f0bb79ddd48 432 break;
leothedragon 0:8f0bb79ddd48 433 default:
leothedragon 0:8f0bb79ddd48 434 break;
leothedragon 0:8f0bb79ddd48 435 }
leothedragon 0:8f0bb79ddd48 436 }
leothedragon 0:8f0bb79ddd48 437
leothedragon 0:8f0bb79ddd48 438 /*
leothedragon 0:8f0bb79ddd48 439 * Creates register server object with mbed device server address and other parameters
leothedragon 0:8f0bb79ddd48 440 * required for client to connect to mbed device server.
leothedragon 0:8f0bb79ddd48 441 */
leothedragon 0:8f0bb79ddd48 442 bool ConnectorClient::create_register_object()
leothedragon 0:8f0bb79ddd48 443 {
leothedragon 0:8f0bb79ddd48 444 tr_debug("ConnectorClient::create_register_object()");
leothedragon 0:8f0bb79ddd48 445 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 446 if (m2m_id == -1) {
leothedragon 0:8f0bb79ddd48 447 init_security_object();
leothedragon 0:8f0bb79ddd48 448 }
leothedragon 0:8f0bb79ddd48 449
leothedragon 0:8f0bb79ddd48 450 m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 451 if (m2m_id == -1) {
leothedragon 0:8f0bb79ddd48 452 tr_error("ConnectorClient::create_register_object() - failed to read security object!");
leothedragon 0:8f0bb79ddd48 453 return false;
leothedragon 0:8f0bb79ddd48 454 }
leothedragon 0:8f0bb79ddd48 455
leothedragon 0:8f0bb79ddd48 456 // Allocate scratch buffer, this will be used to copy parameters from storage to security object
leothedragon 0:8f0bb79ddd48 457 const int max_size = MAX_CERTIFICATE_SIZE;
leothedragon 0:8f0bb79ddd48 458 uint8_t *buffer = (uint8_t*)malloc(max_size);
leothedragon 0:8f0bb79ddd48 459 size_t real_size = 0;
leothedragon 0:8f0bb79ddd48 460 bool success = false;
leothedragon 0:8f0bb79ddd48 461
leothedragon 0:8f0bb79ddd48 462 if (_security->set_resource_value(M2MSecurity::BootstrapServer, M2MSecurity::M2MServer, m2m_id)) {
leothedragon 0:8f0bb79ddd48 463 success = true;
leothedragon 0:8f0bb79ddd48 464 }
leothedragon 0:8f0bb79ddd48 465
leothedragon 0:8f0bb79ddd48 466 // Add ResourceID's and values to the security ObjectID/ObjectInstance
leothedragon 0:8f0bb79ddd48 467 if (success) {
leothedragon 0:8f0bb79ddd48 468 success = false;
leothedragon 0:8f0bb79ddd48 469 if (_security->set_resource_value(M2MSecurity::SecurityMode, _endpoint_info.mode, m2m_id)) {
leothedragon 0:8f0bb79ddd48 470 success = true;
leothedragon 0:8f0bb79ddd48 471 }
leothedragon 0:8f0bb79ddd48 472 }
leothedragon 0:8f0bb79ddd48 473
leothedragon 0:8f0bb79ddd48 474 if (success && buffer == NULL) {
leothedragon 0:8f0bb79ddd48 475 success = false;
leothedragon 0:8f0bb79ddd48 476 }
leothedragon 0:8f0bb79ddd48 477
leothedragon 0:8f0bb79ddd48 478 // Endpoint
leothedragon 0:8f0bb79ddd48 479 if (success) {
leothedragon 0:8f0bb79ddd48 480 success = false;
leothedragon 0:8f0bb79ddd48 481 char device_id[64];
leothedragon 0:8f0bb79ddd48 482
leothedragon 0:8f0bb79ddd48 483 size_t cert_size = max_size;
leothedragon 0:8f0bb79ddd48 484 uint8_t certificate[MAX_CERTIFICATE_SIZE];
leothedragon 0:8f0bb79ddd48 485 uint8_t *certificate_ptr = (uint8_t*)&certificate;
leothedragon 0:8f0bb79ddd48 486
leothedragon 0:8f0bb79ddd48 487 // TODO! Update to use chain api
leothedragon 0:8f0bb79ddd48 488 if (_security->resource_value_buffer(M2MSecurity::PublicKey, certificate_ptr, m2m_id, &cert_size) == 0) {
leothedragon 0:8f0bb79ddd48 489 real_size = cert_size;
leothedragon 0:8f0bb79ddd48 490 if (extract_field_from_certificate((uint8_t*)certificate, real_size, "CN", device_id)) {
leothedragon 0:8f0bb79ddd48 491 tr_info("ConnectorClient::create_register_object - CN - endpoint_name : %s", device_id);
leothedragon 0:8f0bb79ddd48 492 _endpoint_info.endpoint_name = String(device_id);
leothedragon 0:8f0bb79ddd48 493 success = true;
leothedragon 0:8f0bb79ddd48 494 } else {
leothedragon 0:8f0bb79ddd48 495 tr_error("KEY_ENDPOINT_NAME failed.");
leothedragon 0:8f0bb79ddd48 496 }
leothedragon 0:8f0bb79ddd48 497 }
leothedragon 0:8f0bb79ddd48 498 }
leothedragon 0:8f0bb79ddd48 499
leothedragon 0:8f0bb79ddd48 500 // Connector URL
leothedragon 0:8f0bb79ddd48 501 if (success) {
leothedragon 0:8f0bb79ddd48 502 success = false;
leothedragon 0:8f0bb79ddd48 503 if (ccs_get_item(g_fcc_lwm2m_server_uri_name, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 504 tr_info("ConnectorClient::create_register_object - M2MServerUri %.*s", (int)real_size, buffer);
leothedragon 0:8f0bb79ddd48 505 if (_security->set_resource_value(M2MSecurity::M2MServerUri, buffer, (uint32_t)real_size, m2m_id)) {
leothedragon 0:8f0bb79ddd48 506 success = true;
leothedragon 0:8f0bb79ddd48 507 }
leothedragon 0:8f0bb79ddd48 508 #ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION
leothedragon 0:8f0bb79ddd48 509 _endpoint_info.lwm2m_server_uri = _security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id);
leothedragon 0:8f0bb79ddd48 510 #endif
leothedragon 0:8f0bb79ddd48 511 }
leothedragon 0:8f0bb79ddd48 512 else {
leothedragon 0:8f0bb79ddd48 513 tr_error("KEY_CONNECTOR_URL failed.");
leothedragon 0:8f0bb79ddd48 514 }
leothedragon 0:8f0bb79ddd48 515 }
leothedragon 0:8f0bb79ddd48 516
leothedragon 0:8f0bb79ddd48 517 // Try to get internal endpoint name
leothedragon 0:8f0bb79ddd48 518 if (success) {
leothedragon 0:8f0bb79ddd48 519 if (ccs_get_item(KEY_INTERNAL_ENDPOINT, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 520 _endpoint_info.internal_endpoint_name = String((const char*)buffer, real_size);
leothedragon 0:8f0bb79ddd48 521 tr_info("ConnectorClient::create_register_object - internal endpoint name : %s", _endpoint_info.internal_endpoint_name.c_str());
leothedragon 0:8f0bb79ddd48 522 }
leothedragon 0:8f0bb79ddd48 523 else {
leothedragon 0:8f0bb79ddd48 524 tr_debug("KEY_INTERNAL_ENDPOINT failed.");
leothedragon 0:8f0bb79ddd48 525 }
leothedragon 0:8f0bb79ddd48 526 }
leothedragon 0:8f0bb79ddd48 527
leothedragon 0:8f0bb79ddd48 528 if (success) {
leothedragon 0:8f0bb79ddd48 529 success = false;
leothedragon 0:8f0bb79ddd48 530 if (ccs_get_item(KEY_ACCOUNT_ID, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 531 tr_info("ConnectorClient::create_register_object - AccountId %.*s", (int)real_size, buffer);
leothedragon 0:8f0bb79ddd48 532 _endpoint_info.account_id = String((const char*)buffer, real_size);
leothedragon 0:8f0bb79ddd48 533 success = true;
leothedragon 0:8f0bb79ddd48 534 } else {
leothedragon 0:8f0bb79ddd48 535 if (ccs_get_item(g_fcc_lwm2m_server_uri_name, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 536 String address((const char*)buffer, real_size);
leothedragon 0:8f0bb79ddd48 537 if (address.size() > 0) {
leothedragon 0:8f0bb79ddd48 538 const char *aid = NULL;
leothedragon 0:8f0bb79ddd48 539 const int aid_size = parse_query_parameter_value_from_uri((const char*)address.c_str(), QUERY_PARAM_AID, &aid);
leothedragon 0:8f0bb79ddd48 540 if (aid_size > 0) {
leothedragon 0:8f0bb79ddd48 541 _endpoint_info.account_id.clear();
leothedragon 0:8f0bb79ddd48 542 _endpoint_info.account_id.append_raw(aid, aid_size);
leothedragon 0:8f0bb79ddd48 543 if (ccs_set_item(KEY_ACCOUNT_ID,
leothedragon 0:8f0bb79ddd48 544 (const uint8_t*)_endpoint_info.account_id.c_str(),
leothedragon 0:8f0bb79ddd48 545 (size_t)_endpoint_info.account_id.size(), CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 546 success = true;
leothedragon 0:8f0bb79ddd48 547 tr_info("ConnectorClient::create_register_object - aid from uri %s", _endpoint_info.account_id.c_str());
leothedragon 0:8f0bb79ddd48 548 } else {
leothedragon 0:8f0bb79ddd48 549 tr_error("ConnectorClient::create_register_object - failed to store aid");
leothedragon 0:8f0bb79ddd48 550 }
leothedragon 0:8f0bb79ddd48 551
leothedragon 0:8f0bb79ddd48 552 }
leothedragon 0:8f0bb79ddd48 553 }
leothedragon 0:8f0bb79ddd48 554 }
leothedragon 0:8f0bb79ddd48 555 }
leothedragon 0:8f0bb79ddd48 556 }
leothedragon 0:8f0bb79ddd48 557
leothedragon 0:8f0bb79ddd48 558 free(buffer);
leothedragon 0:8f0bb79ddd48 559
leothedragon 0:8f0bb79ddd48 560 return success;
leothedragon 0:8f0bb79ddd48 561 }
leothedragon 0:8f0bb79ddd48 562
leothedragon 0:8f0bb79ddd48 563 /*
leothedragon 0:8f0bb79ddd48 564 * Creates bootstrap server object with bootstrap server address and other parameters
leothedragon 0:8f0bb79ddd48 565 * required for connecting to mbed Cloud bootstrap server.
leothedragon 0:8f0bb79ddd48 566 */
leothedragon 0:8f0bb79ddd48 567 bool ConnectorClient::create_bootstrap_object()
leothedragon 0:8f0bb79ddd48 568 {
leothedragon 0:8f0bb79ddd48 569 tr_debug("ConnectorClient::create_bootstrap_object");
leothedragon 0:8f0bb79ddd48 570 bool success = false;
leothedragon 0:8f0bb79ddd48 571
leothedragon 0:8f0bb79ddd48 572 // Check if bootstrap credentials are already stored in KCM
leothedragon 0:8f0bb79ddd48 573 if (bootstrap_credentials_stored_in_kcm() && _security) {
leothedragon 0:8f0bb79ddd48 574 int32_t bs_id = _security->get_security_instance_id(M2MSecurity::Bootstrap);
leothedragon 0:8f0bb79ddd48 575 if (_security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate, bs_id)) {
leothedragon 0:8f0bb79ddd48 576 success = true;
leothedragon 0:8f0bb79ddd48 577 }
leothedragon 0:8f0bb79ddd48 578
leothedragon 0:8f0bb79ddd48 579 tr_info("ConnectorClient::create_bootstrap_object - bs_id = %" PRId32, bs_id);
leothedragon 0:8f0bb79ddd48 580 tr_info("ConnectorClient::create_bootstrap_object - use credentials from storage");
leothedragon 0:8f0bb79ddd48 581
leothedragon 0:8f0bb79ddd48 582 // Allocate scratch buffer, this will be used to copy parameters from storage to security object
leothedragon 0:8f0bb79ddd48 583 size_t real_size = 0;
leothedragon 0:8f0bb79ddd48 584 const int max_size = MAX_CERTIFICATE_SIZE;
leothedragon 0:8f0bb79ddd48 585 uint8_t *buffer = NULL;
leothedragon 0:8f0bb79ddd48 586 if (success) {
leothedragon 0:8f0bb79ddd48 587 success = false;
leothedragon 0:8f0bb79ddd48 588 buffer = (uint8_t*)malloc(max_size);
leothedragon 0:8f0bb79ddd48 589 if (buffer != NULL) {
leothedragon 0:8f0bb79ddd48 590 success = true;
leothedragon 0:8f0bb79ddd48 591 }
leothedragon 0:8f0bb79ddd48 592 }
leothedragon 0:8f0bb79ddd48 593
leothedragon 0:8f0bb79ddd48 594 // Read internal endpoint name if it exists, we need to append
leothedragon 0:8f0bb79ddd48 595 // it to bootstrap uri if device already bootstrapped
leothedragon 0:8f0bb79ddd48 596 uint8_t *iep = NULL;
leothedragon 0:8f0bb79ddd48 597 if (success && ccs_get_string_item(KEY_INTERNAL_ENDPOINT, buffer, max_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 598 iep = (uint8_t*)malloc(strlen((const char*)buffer) + strlen(INTERNAL_ENDPOINT_PARAM) + 1);
leothedragon 0:8f0bb79ddd48 599 if (iep != NULL) {
leothedragon 0:8f0bb79ddd48 600 strcpy((char*)iep, INTERNAL_ENDPOINT_PARAM);
leothedragon 0:8f0bb79ddd48 601 strcat((char*)iep, (const char*)buffer);
leothedragon 0:8f0bb79ddd48 602 tr_info("ConnectorClient::create_bootstrap_object - iep: %s", buffer);
leothedragon 0:8f0bb79ddd48 603 }
leothedragon 0:8f0bb79ddd48 604 //TODO: Should handle error if iep exists but allocation fails?
leothedragon 0:8f0bb79ddd48 605 }
leothedragon 0:8f0bb79ddd48 606
leothedragon 0:8f0bb79ddd48 607 // Bootstrap URI
leothedragon 0:8f0bb79ddd48 608 if (success) {
leothedragon 0:8f0bb79ddd48 609 success = false;
leothedragon 0:8f0bb79ddd48 610 if (ccs_get_string_item(g_fcc_bootstrap_server_uri_name, buffer, max_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 611 real_size = strlen((const char*)buffer);
leothedragon 0:8f0bb79ddd48 612
leothedragon 0:8f0bb79ddd48 613 // Append iep if we 1. have it 2. it doesn't already exist in uri 3. it fits
leothedragon 0:8f0bb79ddd48 614 if (iep &&
leothedragon 0:8f0bb79ddd48 615 strstr((const char*)buffer, (const char*)iep) == NULL &&
leothedragon 0:8f0bb79ddd48 616 (real_size + strlen((const char*)iep) + 1) <= max_size) {
leothedragon 0:8f0bb79ddd48 617 strcat((char*)buffer, (const char*)iep);
leothedragon 0:8f0bb79ddd48 618 real_size += strlen((const char*)iep) + 1;
leothedragon 0:8f0bb79ddd48 619 }
leothedragon 0:8f0bb79ddd48 620
leothedragon 0:8f0bb79ddd48 621 tr_info("ConnectorClient::create_bootstrap_object - M2MServerUri %.*s", (int)real_size, buffer);
leothedragon 0:8f0bb79ddd48 622 if (_security->set_resource_value(M2MSecurity::M2MServerUri, buffer, real_size, bs_id)) {
leothedragon 0:8f0bb79ddd48 623 success = true;
leothedragon 0:8f0bb79ddd48 624 }
leothedragon 0:8f0bb79ddd48 625 }
leothedragon 0:8f0bb79ddd48 626 }
leothedragon 0:8f0bb79ddd48 627
leothedragon 0:8f0bb79ddd48 628 free(iep);
leothedragon 0:8f0bb79ddd48 629
leothedragon 0:8f0bb79ddd48 630 // Endpoint
leothedragon 0:8f0bb79ddd48 631 if (success) {
leothedragon 0:8f0bb79ddd48 632 success = false;
leothedragon 0:8f0bb79ddd48 633 if (ccs_get_item(g_fcc_endpoint_parameter_name, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 634 success = true;
leothedragon 0:8f0bb79ddd48 635 _endpoint_info.endpoint_name = String((const char*)buffer, real_size);
leothedragon 0:8f0bb79ddd48 636 tr_info("ConnectorClient::create_bootstrap_object - Endpoint %s", _endpoint_info.endpoint_name.c_str());
leothedragon 0:8f0bb79ddd48 637 }
leothedragon 0:8f0bb79ddd48 638 }
leothedragon 0:8f0bb79ddd48 639
leothedragon 0:8f0bb79ddd48 640 // Account ID, not mandatory
leothedragon 0:8f0bb79ddd48 641 if (success) {
leothedragon 0:8f0bb79ddd48 642 if (ccs_get_item(KEY_ACCOUNT_ID, buffer, max_size, &real_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 643 _endpoint_info.account_id = String((const char*)buffer, real_size);
leothedragon 0:8f0bb79ddd48 644 tr_info("ConnectorClient::create_bootstrap_object - AccountId %s", _endpoint_info.account_id.c_str());
leothedragon 0:8f0bb79ddd48 645 }
leothedragon 0:8f0bb79ddd48 646 }
leothedragon 0:8f0bb79ddd48 647
leothedragon 0:8f0bb79ddd48 648 free(buffer);
leothedragon 0:8f0bb79ddd48 649
leothedragon 0:8f0bb79ddd48 650 if (!success) {
leothedragon 0:8f0bb79ddd48 651 tr_error("ConnectorClient::create_bootstrap_object - Failed to read credentials");
leothedragon 0:8f0bb79ddd48 652 _callback->connector_error((M2MInterface::Error)MbedCloudClient::ConnectorFailedToReadCredentials,CREDENTIAL_ERROR);
leothedragon 0:8f0bb79ddd48 653 _security->remove_object_instance(bs_id);
leothedragon 0:8f0bb79ddd48 654 }
leothedragon 0:8f0bb79ddd48 655 } else {
leothedragon 0:8f0bb79ddd48 656 success = true;
leothedragon 0:8f0bb79ddd48 657 tr_info("ConnectorClient::create_bootstrap_object - bootstrap object already done");
leothedragon 0:8f0bb79ddd48 658 }
leothedragon 0:8f0bb79ddd48 659
leothedragon 0:8f0bb79ddd48 660
leothedragon 0:8f0bb79ddd48 661 return success;
leothedragon 0:8f0bb79ddd48 662 }
leothedragon 0:8f0bb79ddd48 663
leothedragon 0:8f0bb79ddd48 664 void ConnectorClient::state_bootstrap_start()
leothedragon 0:8f0bb79ddd48 665 {
leothedragon 0:8f0bb79ddd48 666 tr_info("ConnectorClient::state_bootstrap_start()");
leothedragon 0:8f0bb79ddd48 667 assert(_interface != NULL);
leothedragon 0:8f0bb79ddd48 668 assert(_security != NULL);
leothedragon 0:8f0bb79ddd48 669
leothedragon 0:8f0bb79ddd48 670 _interface->bootstrap(_security);
leothedragon 0:8f0bb79ddd48 671
leothedragon 0:8f0bb79ddd48 672 internal_event(State_Bootstrap_Started);
leothedragon 0:8f0bb79ddd48 673 }
leothedragon 0:8f0bb79ddd48 674
leothedragon 0:8f0bb79ddd48 675 void ConnectorClient::state_bootstrap_started()
leothedragon 0:8f0bb79ddd48 676 {
leothedragon 0:8f0bb79ddd48 677 // this state may be useful only for verifying the callbacks?
leothedragon 0:8f0bb79ddd48 678 }
leothedragon 0:8f0bb79ddd48 679
leothedragon 0:8f0bb79ddd48 680 void ConnectorClient::state_bootstrap_success()
leothedragon 0:8f0bb79ddd48 681 {
leothedragon 0:8f0bb79ddd48 682 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 683 // Parse internal endpoint name from mDS cert
leothedragon 0:8f0bb79ddd48 684 _callback->registration_process_result(State_Bootstrap_Success);
leothedragon 0:8f0bb79ddd48 685 }
leothedragon 0:8f0bb79ddd48 686
leothedragon 0:8f0bb79ddd48 687 void ConnectorClient::state_bootstrap_failure()
leothedragon 0:8f0bb79ddd48 688 {
leothedragon 0:8f0bb79ddd48 689 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 690 // maybe some additional canceling and/or leanup is needed here?
leothedragon 0:8f0bb79ddd48 691 _callback->registration_process_result(State_Bootstrap_Failure);
leothedragon 0:8f0bb79ddd48 692 }
leothedragon 0:8f0bb79ddd48 693
leothedragon 0:8f0bb79ddd48 694 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 695 void ConnectorClient::state_est_start()
leothedragon 0:8f0bb79ddd48 696 {
leothedragon 0:8f0bb79ddd48 697 // - Generate CSR from data during bootstrap phase
leothedragon 0:8f0bb79ddd48 698 // - Call EST enrollment API from InterfaceImpl
leothedragon 0:8f0bb79ddd48 699
leothedragon 0:8f0bb79ddd48 700 // Update the internal endpoint name and account id to endpoint info structure
leothedragon 0:8f0bb79ddd48 701 // as we get those during bootstrap phase
leothedragon 0:8f0bb79ddd48 702 _endpoint_info.internal_endpoint_name = _interface->internal_endpoint_name();
leothedragon 0:8f0bb79ddd48 703
leothedragon 0:8f0bb79ddd48 704 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 705 int32_t sec_mode = M2MSecurity::SecurityNotSet;
leothedragon 0:8f0bb79ddd48 706 if (m2m_id >= 0) {
leothedragon 0:8f0bb79ddd48 707 sec_mode = _security->resource_value_int(M2MSecurity::SecurityMode, m2m_id);
leothedragon 0:8f0bb79ddd48 708
leothedragon 0:8f0bb79ddd48 709 // We need to parse account id from lwm2m server uri query if it is not yet
leothedragon 0:8f0bb79ddd48 710 // set in endpoint info structure
leothedragon 0:8f0bb79ddd48 711 if (_endpoint_info.account_id.length() <= 0) {
leothedragon 0:8f0bb79ddd48 712 String address = _security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id);
leothedragon 0:8f0bb79ddd48 713 tr_debug("ConnectorClient::state_est_start - address: %s", address.c_str());
leothedragon 0:8f0bb79ddd48 714 if (address.size() > 0) {
leothedragon 0:8f0bb79ddd48 715 const char *aid = NULL;
leothedragon 0:8f0bb79ddd48 716 const int aid_size = parse_query_parameter_value_from_uri((const char*)address.c_str(), QUERY_PARAM_AID, &aid);
leothedragon 0:8f0bb79ddd48 717 if (aid_size > 0) {
leothedragon 0:8f0bb79ddd48 718 _endpoint_info.account_id.append_raw(aid, aid_size);
leothedragon 0:8f0bb79ddd48 719 }
leothedragon 0:8f0bb79ddd48 720 }
leothedragon 0:8f0bb79ddd48 721 }
leothedragon 0:8f0bb79ddd48 722 }
leothedragon 0:8f0bb79ddd48 723
leothedragon 0:8f0bb79ddd48 724 tr_debug("ConnectorClient::state_est_start - security instance id: %" PRId32, m2m_id);
leothedragon 0:8f0bb79ddd48 725 tr_debug("ConnectorClient::state_est_start - ep: %s", _endpoint_info.internal_endpoint_name.c_str());
leothedragon 0:8f0bb79ddd48 726 tr_debug("ConnectorClient::state_est_start - iep: %s", _endpoint_info.endpoint_name.c_str());
leothedragon 0:8f0bb79ddd48 727 tr_debug("ConnectorClient::state_est_start - aid: %s", _endpoint_info.account_id.c_str());
leothedragon 0:8f0bb79ddd48 728
leothedragon 0:8f0bb79ddd48 729 // Check EST required parameters are in place
leothedragon 0:8f0bb79ddd48 730 if (m2m_id < 0 ||
leothedragon 0:8f0bb79ddd48 731 _endpoint_info.endpoint_name.length() <= 0 ||
leothedragon 0:8f0bb79ddd48 732 _endpoint_info.internal_endpoint_name.length() <= 0 ||
leothedragon 0:8f0bb79ddd48 733 _endpoint_info.account_id.length() <= 0) {
leothedragon 0:8f0bb79ddd48 734 tr_error("ConnectorClient::state_est_start - Missing parameters for EST enrollment!");
leothedragon 0:8f0bb79ddd48 735 internal_event(State_EST_Failure);
leothedragon 0:8f0bb79ddd48 736 return;
leothedragon 0:8f0bb79ddd48 737 }
leothedragon 0:8f0bb79ddd48 738
leothedragon 0:8f0bb79ddd48 739 uint32_t is_bs_server = _security->resource_value_int(M2MSecurity::BootstrapServer, m2m_id);
leothedragon 0:8f0bb79ddd48 740 size_t public_key_size = MAX_CERTIFICATE_SIZE;
leothedragon 0:8f0bb79ddd48 741 size_t server_key_size = MAX_CERTIFICATE_SIZE;
leothedragon 0:8f0bb79ddd48 742 size_t private_key_size = MAX_CERTIFICATE_SIZE;
leothedragon 0:8f0bb79ddd48 743
leothedragon 0:8f0bb79ddd48 744 // Temp buffer for storing CSR and certificates
leothedragon 0:8f0bb79ddd48 745 uint8_t *buffer = (uint8_t*)malloc(MAX_CERTIFICATE_SIZE);
leothedragon 0:8f0bb79ddd48 746 size_t real_size = 0;
leothedragon 0:8f0bb79ddd48 747 if (buffer == NULL) {
leothedragon 0:8f0bb79ddd48 748 tr_error("ConnectorClient::state_est_start - Allocating temp buffer failed!");
leothedragon 0:8f0bb79ddd48 749 internal_event(State_EST_Failure);
leothedragon 0:8f0bb79ddd48 750 return;
leothedragon 0:8f0bb79ddd48 751 }
leothedragon 0:8f0bb79ddd48 752 uint8_t *buffer_ptr = buffer;
leothedragon 0:8f0bb79ddd48 753
leothedragon 0:8f0bb79ddd48 754 // TODO! Update to use chain api
leothedragon 0:8f0bb79ddd48 755 if (_security->resource_value_buffer(M2MSecurity::PublicKey, buffer_ptr, m2m_id, &public_key_size) != 0) {
leothedragon 0:8f0bb79ddd48 756 public_key_size = 0;
leothedragon 0:8f0bb79ddd48 757 }
leothedragon 0:8f0bb79ddd48 758 if (_security->resource_value_buffer(M2MSecurity::ServerPublicKey, buffer_ptr, m2m_id, &server_key_size) != 0) {
leothedragon 0:8f0bb79ddd48 759 server_key_size = 0;
leothedragon 0:8f0bb79ddd48 760 }
leothedragon 0:8f0bb79ddd48 761 if (_security->resource_value_buffer(M2MSecurity::Secretkey, buffer_ptr, m2m_id, &private_key_size) != 0) {
leothedragon 0:8f0bb79ddd48 762 private_key_size = 0;
leothedragon 0:8f0bb79ddd48 763 }
leothedragon 0:8f0bb79ddd48 764
leothedragon 0:8f0bb79ddd48 765 tr_info("est check - is bs server /0/1: %" PRIu32, is_bs_server);
leothedragon 0:8f0bb79ddd48 766 tr_info("est check - Security Mode /0/2: %" PRIu32, sec_mode);
leothedragon 0:8f0bb79ddd48 767 tr_info("est check - Public key size /0/3: %lu", (unsigned long)public_key_size);
leothedragon 0:8f0bb79ddd48 768 tr_info("est check - Server Public key size /0/4: %lu", (unsigned long)server_key_size);
leothedragon 0:8f0bb79ddd48 769 tr_info("est check - Secret key size /0/5: %lu", (unsigned long)private_key_size);
leothedragon 0:8f0bb79ddd48 770
leothedragon 0:8f0bb79ddd48 771 // Configure CSR params
leothedragon 0:8f0bb79ddd48 772 kcm_csr_params_s csr_params;
leothedragon 0:8f0bb79ddd48 773 int subject_size = snprintf(NULL, 0, LWM2M_CSR_SUBJECT_FORMAT,
leothedragon 0:8f0bb79ddd48 774 _endpoint_info.internal_endpoint_name.c_str(),
leothedragon 0:8f0bb79ddd48 775 _endpoint_info.account_id.c_str(),
leothedragon 0:8f0bb79ddd48 776 _endpoint_info.endpoint_name.c_str());
leothedragon 0:8f0bb79ddd48 777 if (subject_size <= 0) {
leothedragon 0:8f0bb79ddd48 778 tr_error("ConnectorClient::state_est_start - CSR Subject formatting failed!");
leothedragon 0:8f0bb79ddd48 779 free(buffer);
leothedragon 0:8f0bb79ddd48 780 internal_event(State_EST_Failure);
leothedragon 0:8f0bb79ddd48 781 return;
leothedragon 0:8f0bb79ddd48 782 }
leothedragon 0:8f0bb79ddd48 783
leothedragon 0:8f0bb79ddd48 784 // For null-terminator
leothedragon 0:8f0bb79ddd48 785 subject_size++;
leothedragon 0:8f0bb79ddd48 786
leothedragon 0:8f0bb79ddd48 787 csr_params.subject = (char*)malloc(subject_size);
leothedragon 0:8f0bb79ddd48 788 if (csr_params.subject == NULL) {
leothedragon 0:8f0bb79ddd48 789 tr_error("ConnectorClient::state_est_start - CSR Subject formatting failed!");
leothedragon 0:8f0bb79ddd48 790 free(buffer);
leothedragon 0:8f0bb79ddd48 791 internal_event(State_EST_Failure);
leothedragon 0:8f0bb79ddd48 792 return;
leothedragon 0:8f0bb79ddd48 793 }
leothedragon 0:8f0bb79ddd48 794
leothedragon 0:8f0bb79ddd48 795 snprintf(csr_params.subject, subject_size, LWM2M_CSR_SUBJECT_FORMAT,
leothedragon 0:8f0bb79ddd48 796 _endpoint_info.internal_endpoint_name.c_str(),
leothedragon 0:8f0bb79ddd48 797 _endpoint_info.account_id.c_str(),
leothedragon 0:8f0bb79ddd48 798 _endpoint_info.endpoint_name.c_str());
leothedragon 0:8f0bb79ddd48 799
leothedragon 0:8f0bb79ddd48 800 csr_params.md_type = KCM_MD_SHA256;
leothedragon 0:8f0bb79ddd48 801 csr_params.key_usage = KCM_CSR_KU_NONE;
leothedragon 0:8f0bb79ddd48 802 csr_params.ext_key_usage = KCM_CSR_EXT_KU_NONE;
leothedragon 0:8f0bb79ddd48 803
leothedragon 0:8f0bb79ddd48 804 // Delete existing keys
leothedragon 0:8f0bb79ddd48 805 ccs_delete_item(g_fcc_lwm2m_device_certificate_name, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 806 ccs_delete_item(g_fcc_lwm2m_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
leothedragon 0:8f0bb79ddd48 807
leothedragon 0:8f0bb79ddd48 808 kcm_status_e status = kcm_generate_keys_and_csr(KCM_SCHEME_EC_SECP256R1,
leothedragon 0:8f0bb79ddd48 809 (const uint8_t*)g_fcc_lwm2m_device_private_key_name,
leothedragon 0:8f0bb79ddd48 810 strlen(g_fcc_lwm2m_device_private_key_name),
leothedragon 0:8f0bb79ddd48 811 NULL,
leothedragon 0:8f0bb79ddd48 812 0,
leothedragon 0:8f0bb79ddd48 813 false,
leothedragon 0:8f0bb79ddd48 814 &csr_params,
leothedragon 0:8f0bb79ddd48 815 buffer,
leothedragon 0:8f0bb79ddd48 816 MAX_CERTIFICATE_SIZE,
leothedragon 0:8f0bb79ddd48 817 &real_size,
leothedragon 0:8f0bb79ddd48 818 NULL);
leothedragon 0:8f0bb79ddd48 819
leothedragon 0:8f0bb79ddd48 820 free(csr_params.subject);
leothedragon 0:8f0bb79ddd48 821
leothedragon 0:8f0bb79ddd48 822 if (status != KCM_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 823 tr_error("ConnectorClient::state_est_start - Generating keys and csr failed!");
leothedragon 0:8f0bb79ddd48 824 free(buffer);
leothedragon 0:8f0bb79ddd48 825 internal_event(State_EST_Failure);
leothedragon 0:8f0bb79ddd48 826 return;
leothedragon 0:8f0bb79ddd48 827 }
leothedragon 0:8f0bb79ddd48 828
leothedragon 0:8f0bb79ddd48 829 // Update state and start the enrollment by sending the enroll request
leothedragon 0:8f0bb79ddd48 830 internal_event(State_EST_Started);
leothedragon 0:8f0bb79ddd48 831 est_status_e est_status = _est_client.est_request_enrollment(NULL,
leothedragon 0:8f0bb79ddd48 832 0,
leothedragon 0:8f0bb79ddd48 833 buffer,
leothedragon 0:8f0bb79ddd48 834 real_size,
leothedragon 0:8f0bb79ddd48 835 ConnectorClient::est_enrollment_result,
leothedragon 0:8f0bb79ddd48 836 this);
leothedragon 0:8f0bb79ddd48 837
leothedragon 0:8f0bb79ddd48 838 if (est_status != EST_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 839 tr_error("ConnectorClient::state_est_start - EST enrollment failed with error %d", (int)est_status);
leothedragon 0:8f0bb79ddd48 840 internal_event(State_EST_Failure);
leothedragon 0:8f0bb79ddd48 841 }
leothedragon 0:8f0bb79ddd48 842
leothedragon 0:8f0bb79ddd48 843 free(buffer);
leothedragon 0:8f0bb79ddd48 844 }
leothedragon 0:8f0bb79ddd48 845
leothedragon 0:8f0bb79ddd48 846 void ConnectorClient::state_est_started()
leothedragon 0:8f0bb79ddd48 847 {
leothedragon 0:8f0bb79ddd48 848 }
leothedragon 0:8f0bb79ddd48 849
leothedragon 0:8f0bb79ddd48 850 void ConnectorClient::state_est_success()
leothedragon 0:8f0bb79ddd48 851 {
leothedragon 0:8f0bb79ddd48 852 tr_info("ConnectorClient::state_est_success()");
leothedragon 0:8f0bb79ddd48 853 _interface->finish_bootstrap();
leothedragon 0:8f0bb79ddd48 854 }
leothedragon 0:8f0bb79ddd48 855
leothedragon 0:8f0bb79ddd48 856 void ConnectorClient::state_est_failure()
leothedragon 0:8f0bb79ddd48 857 {
leothedragon 0:8f0bb79ddd48 858 tr_info("ConnectorClient::state_est_failure()");
leothedragon 0:8f0bb79ddd48 859 internal_event(State_Bootstrap_Failure);
leothedragon 0:8f0bb79ddd48 860 //Failed to store credentials, bootstrap failed
leothedragon 0:8f0bb79ddd48 861 _callback->connector_error(M2MInterface::ESTEnrollmentFailed, ERROR_EST_ENROLLMENT_REQUEST_FAILED); // Translated to error code ConnectMemoryConnectFail
leothedragon 0:8f0bb79ddd48 862 }
leothedragon 0:8f0bb79ddd48 863 #endif /* !MBED_CLIENT_DISABLE_EST_FEATURE */
leothedragon 0:8f0bb79ddd48 864
leothedragon 0:8f0bb79ddd48 865 void ConnectorClient::state_registration_start()
leothedragon 0:8f0bb79ddd48 866 {
leothedragon 0:8f0bb79ddd48 867 tr_info("ConnectorClient::state_registration_start()");
leothedragon 0:8f0bb79ddd48 868 assert(_interface != NULL);
leothedragon 0:8f0bb79ddd48 869 assert(_security != NULL);
leothedragon 0:8f0bb79ddd48 870 _interface->register_object(_security, *_client_objs);
leothedragon 0:8f0bb79ddd48 871 internal_event(State_Registration_Started);
leothedragon 0:8f0bb79ddd48 872 }
leothedragon 0:8f0bb79ddd48 873
leothedragon 0:8f0bb79ddd48 874 void ConnectorClient::state_registration_started()
leothedragon 0:8f0bb79ddd48 875 {
leothedragon 0:8f0bb79ddd48 876 // this state may be useful only for verifying the callbacks?
leothedragon 0:8f0bb79ddd48 877 }
leothedragon 0:8f0bb79ddd48 878
leothedragon 0:8f0bb79ddd48 879 void ConnectorClient::state_registration_success()
leothedragon 0:8f0bb79ddd48 880 {
leothedragon 0:8f0bb79ddd48 881 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 882 _endpoint_info.internal_endpoint_name = _interface->internal_endpoint_name();
leothedragon 0:8f0bb79ddd48 883
leothedragon 0:8f0bb79ddd48 884 //The endpoint is maximum 32 character long, we put bigger buffer for future extensions
leothedragon 0:8f0bb79ddd48 885 const int max_size = 64;
leothedragon 0:8f0bb79ddd48 886 uint8_t *buffer = NULL;
leothedragon 0:8f0bb79ddd48 887 buffer = (uint8_t*)malloc(max_size);
leothedragon 0:8f0bb79ddd48 888
leothedragon 0:8f0bb79ddd48 889 if(!buffer) {
leothedragon 0:8f0bb79ddd48 890 _callback->registration_process_result(State_Registration_Failure);
leothedragon 0:8f0bb79ddd48 891 return;
leothedragon 0:8f0bb79ddd48 892 }
leothedragon 0:8f0bb79ddd48 893 bool no_param_update = true;
leothedragon 0:8f0bb79ddd48 894
leothedragon 0:8f0bb79ddd48 895 if(ccs_get_string_item(KEY_INTERNAL_ENDPOINT, buffer, max_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 896 if (strcmp((const char*)buffer, _endpoint_info.internal_endpoint_name.c_str()) != 0) {
leothedragon 0:8f0bb79ddd48 897 // Update is required as the stored KCM entry is different than _endpoint_info.internal_endpoint_name.
leothedragon 0:8f0bb79ddd48 898 no_param_update = false;
leothedragon 0:8f0bb79ddd48 899 }
leothedragon 0:8f0bb79ddd48 900 }
leothedragon 0:8f0bb79ddd48 901 free(buffer);
leothedragon 0:8f0bb79ddd48 902
leothedragon 0:8f0bb79ddd48 903 // Update INTERNAL_ENDPOINT setting only if there is no such entry or the value is not matching the
leothedragon 0:8f0bb79ddd48 904 // _endpoint_info.internal_endpoint_name.
leothedragon 0:8f0bb79ddd48 905 if(!no_param_update) {
leothedragon 0:8f0bb79ddd48 906 ccs_delete_item(KEY_INTERNAL_ENDPOINT, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 907 ccs_set_item(KEY_INTERNAL_ENDPOINT, (const uint8_t*)_endpoint_info.internal_endpoint_name.c_str(),
leothedragon 0:8f0bb79ddd48 908 (size_t)_endpoint_info.internal_endpoint_name.size(),
leothedragon 0:8f0bb79ddd48 909 CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 910 }
leothedragon 0:8f0bb79ddd48 911
leothedragon 0:8f0bb79ddd48 912 _rebootstrap_time = randLIB_get_random_in_range(1, 10);
leothedragon 0:8f0bb79ddd48 913 _callback->registration_process_result(State_Registration_Success);
leothedragon 0:8f0bb79ddd48 914 }
leothedragon 0:8f0bb79ddd48 915
leothedragon 0:8f0bb79ddd48 916 void ConnectorClient::state_registration_failure()
leothedragon 0:8f0bb79ddd48 917 {
leothedragon 0:8f0bb79ddd48 918 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 919 // maybe some additional canceling and/or leanup is needed here?
leothedragon 0:8f0bb79ddd48 920 _callback->registration_process_result(State_Registration_Failure);
leothedragon 0:8f0bb79ddd48 921 }
leothedragon 0:8f0bb79ddd48 922
leothedragon 0:8f0bb79ddd48 923 void ConnectorClient::state_unregistered()
leothedragon 0:8f0bb79ddd48 924 {
leothedragon 0:8f0bb79ddd48 925 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 926 _callback->registration_process_result(State_Unregistered);
leothedragon 0:8f0bb79ddd48 927 }
leothedragon 0:8f0bb79ddd48 928
leothedragon 0:8f0bb79ddd48 929 void ConnectorClient::bootstrap_data_ready(M2MSecurity *security_object)
leothedragon 0:8f0bb79ddd48 930 {
leothedragon 0:8f0bb79ddd48 931 tr_info("ConnectorClient::bootstrap_data_ready");
leothedragon 0:8f0bb79ddd48 932 if(security_object) {
leothedragon 0:8f0bb79ddd48 933 // Update bootstrap credentials (we could skip this if we knew whether they were updated)
leothedragon 0:8f0bb79ddd48 934 // This will also update the address in case of first to claim
leothedragon 0:8f0bb79ddd48 935 ccs_status_e status = set_bootstrap_credentials(security_object);
leothedragon 0:8f0bb79ddd48 936 if (status != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 937 // TODO: what now?
leothedragon 0:8f0bb79ddd48 938 tr_error("ConnectorClient::bootstrap_data_ready - could not store bootstrap credentials");
leothedragon 0:8f0bb79ddd48 939 }
leothedragon 0:8f0bb79ddd48 940
leothedragon 0:8f0bb79ddd48 941 // Clear the first to claim flag if it's active
leothedragon 0:8f0bb79ddd48 942 if (is_first_to_claim()) {
leothedragon 0:8f0bb79ddd48 943 status = clear_first_to_claim();
leothedragon 0:8f0bb79ddd48 944 if (status != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 945 // TODO: what now?
leothedragon 0:8f0bb79ddd48 946 tr_error("ConnectorClient::bootstrap_data_ready - couldn't clear first to claim flag!");
leothedragon 0:8f0bb79ddd48 947 }
leothedragon 0:8f0bb79ddd48 948 }
leothedragon 0:8f0bb79ddd48 949
leothedragon 0:8f0bb79ddd48 950 // Bootstrap might delete m2mserver security object instance completely to force bootstrap
leothedragon 0:8f0bb79ddd48 951 // with new credentials, in that case delete the stored lwm2m credentials as well and re-bootstrap
leothedragon 0:8f0bb79ddd48 952 if (security_object->get_security_instance_id(M2MSecurity::M2MServer) == -1) {
leothedragon 0:8f0bb79ddd48 953 bootstrap_again();
leothedragon 0:8f0bb79ddd48 954 return;
leothedragon 0:8f0bb79ddd48 955 }
leothedragon 0:8f0bb79ddd48 956 // Bootstrap wrote M2MServer credentials, store them and also update first to claim status if it's configured
leothedragon 0:8f0bb79ddd48 957 else {
leothedragon 0:8f0bb79ddd48 958 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 959 int32_t m2m_id = _security->get_security_instance_id(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 960 if (m2m_id >= 0 &&
leothedragon 0:8f0bb79ddd48 961 _security->resource_value_int(M2MSecurity::SecurityMode, m2m_id) == M2MSecurity::EST) {
leothedragon 0:8f0bb79ddd48 962 // If EST is supported, continue to EST state to start EST enrollment
leothedragon 0:8f0bb79ddd48 963 tr_info("ConnectorClient::bootstrap_data_ready() - Continue to EST enrollment");
leothedragon 0:8f0bb79ddd48 964 internal_event(State_EST_Start);
leothedragon 0:8f0bb79ddd48 965 return;
leothedragon 0:8f0bb79ddd48 966 }
leothedragon 0:8f0bb79ddd48 967 #endif // MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 968 // Security mode was not EST, in that case just store the received credentials
leothedragon 0:8f0bb79ddd48 969 tr_info("ConnectorClient::bootstrap_data_ready() - Storing lwm2m credentials");
leothedragon 0:8f0bb79ddd48 970 status = set_connector_credentials(security_object);
leothedragon 0:8f0bb79ddd48 971 }
leothedragon 0:8f0bb79ddd48 972
leothedragon 0:8f0bb79ddd48 973 if (status != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 974 internal_event(State_Bootstrap_Failure);
leothedragon 0:8f0bb79ddd48 975 //Failed to store credentials, bootstrap failed
leothedragon 0:8f0bb79ddd48 976 _callback->connector_error(M2MInterface::MemoryFail, CONNECTOR_ERROR_NO_MEMORY); // Translated to error code ConnectMemoryConnectFail
leothedragon 0:8f0bb79ddd48 977 return;
leothedragon 0:8f0bb79ddd48 978 } else {
leothedragon 0:8f0bb79ddd48 979 tr_info("ConnectorClient::bootstrap_data_ready - set_credentials status %d", status);
leothedragon 0:8f0bb79ddd48 980 }
leothedragon 0:8f0bb79ddd48 981 }
leothedragon 0:8f0bb79ddd48 982 }
leothedragon 0:8f0bb79ddd48 983
leothedragon 0:8f0bb79ddd48 984 void ConnectorClient::bootstrap_done(M2MSecurity *security_object)
leothedragon 0:8f0bb79ddd48 985 {
leothedragon 0:8f0bb79ddd48 986 tr_info("ConnectorClient::bootstrap_done");
leothedragon 0:8f0bb79ddd48 987 internal_event(State_Bootstrap_Success);
leothedragon 0:8f0bb79ddd48 988 }
leothedragon 0:8f0bb79ddd48 989
leothedragon 0:8f0bb79ddd48 990 void ConnectorClient::object_registered(M2MSecurity *security_object, const M2MServer &server_object)
leothedragon 0:8f0bb79ddd48 991 {
leothedragon 0:8f0bb79ddd48 992 internal_event(State_Registration_Success);
leothedragon 0:8f0bb79ddd48 993 }
leothedragon 0:8f0bb79ddd48 994
leothedragon 0:8f0bb79ddd48 995 void ConnectorClient::object_unregistered(M2MSecurity *server_object)
leothedragon 0:8f0bb79ddd48 996 {
leothedragon 0:8f0bb79ddd48 997 internal_event(State_Unregistered);
leothedragon 0:8f0bb79ddd48 998 }
leothedragon 0:8f0bb79ddd48 999
leothedragon 0:8f0bb79ddd48 1000 void ConnectorClient::registration_updated(M2MSecurity *security_object, const M2MServer & server_object)
leothedragon 0:8f0bb79ddd48 1001 {
leothedragon 0:8f0bb79ddd48 1002 _callback->registration_process_result(State_Registration_Updated);
leothedragon 0:8f0bb79ddd48 1003 }
leothedragon 0:8f0bb79ddd48 1004
leothedragon 0:8f0bb79ddd48 1005 void ConnectorClient::error(M2MInterface::Error error)
leothedragon 0:8f0bb79ddd48 1006 {
leothedragon 0:8f0bb79ddd48 1007 tr_error("ConnectorClient::error() - error: %d", error);
leothedragon 0:8f0bb79ddd48 1008 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 1009
leothedragon 0:8f0bb79ddd48 1010 if (_current_state >= State_Registration_Start &&
leothedragon 0:8f0bb79ddd48 1011 use_bootstrap() &&
leothedragon 0:8f0bb79ddd48 1012 (error == M2MInterface::SecureConnectionFailed ||
leothedragon 0:8f0bb79ddd48 1013 error == M2MInterface::InvalidParameters)) {
leothedragon 0:8f0bb79ddd48 1014 tr_info("ConnectorClient::error() - Error during lwm2m registration");
leothedragon 0:8f0bb79ddd48 1015
leothedragon 0:8f0bb79ddd48 1016 // Delete the lwm2m security instance
leothedragon 0:8f0bb79ddd48 1017 int32_t id = _security->get_security_instance_id(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 1018 if (id >= 0) {
leothedragon 0:8f0bb79ddd48 1019 _security->remove_object_instance(id);
leothedragon 0:8f0bb79ddd48 1020 }
leothedragon 0:8f0bb79ddd48 1021
leothedragon 0:8f0bb79ddd48 1022 bootstrap_again();
leothedragon 0:8f0bb79ddd48 1023 }
leothedragon 0:8f0bb79ddd48 1024 else {
leothedragon 0:8f0bb79ddd48 1025 _callback->connector_error(error, _interface->error_description());
leothedragon 0:8f0bb79ddd48 1026 }
leothedragon 0:8f0bb79ddd48 1027 }
leothedragon 0:8f0bb79ddd48 1028
leothedragon 0:8f0bb79ddd48 1029 void ConnectorClient::value_updated(M2MBase *base, M2MBase::BaseType type)
leothedragon 0:8f0bb79ddd48 1030 {
leothedragon 0:8f0bb79ddd48 1031 assert(_callback != NULL);
leothedragon 0:8f0bb79ddd48 1032 _callback->value_updated(base, type);
leothedragon 0:8f0bb79ddd48 1033 }
leothedragon 0:8f0bb79ddd48 1034
leothedragon 0:8f0bb79ddd48 1035 bool ConnectorClient::connector_credentials_available()
leothedragon 0:8f0bb79ddd48 1036 {
leothedragon 0:8f0bb79ddd48 1037 tr_debug("ConnectorClient::connector_credentials_available");
leothedragon 0:8f0bb79ddd48 1038 if (ccs_check_item(g_fcc_lwm2m_server_uri_name, CCS_CONFIG_ITEM) != CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1039 return false;
leothedragon 0:8f0bb79ddd48 1040 }
leothedragon 0:8f0bb79ddd48 1041 return true;
leothedragon 0:8f0bb79ddd48 1042 }
leothedragon 0:8f0bb79ddd48 1043
leothedragon 0:8f0bb79ddd48 1044 bool ConnectorClient::use_bootstrap()
leothedragon 0:8f0bb79ddd48 1045 {
leothedragon 0:8f0bb79ddd48 1046 tr_debug("ConnectorClient::use_bootstrap");
leothedragon 0:8f0bb79ddd48 1047 size_t real_size = 0;
leothedragon 0:8f0bb79ddd48 1048 uint8_t data[CONFIG_BOOLEAN_ITEM_SIZE] = {0};
leothedragon 0:8f0bb79ddd48 1049 uint32_t value = 0;
leothedragon 0:8f0bb79ddd48 1050 ccs_status_e status = ccs_get_item(g_fcc_use_bootstrap_parameter_name, data, CONFIG_BOOLEAN_ITEM_SIZE, &real_size, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1051 if (status == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1052 memcpy(&value, data, CONFIG_BOOLEAN_ITEM_SIZE);
leothedragon 0:8f0bb79ddd48 1053 // Return true if use_bootstrap is set
leothedragon 0:8f0bb79ddd48 1054 if (value == 1) {
leothedragon 0:8f0bb79ddd48 1055 return true;
leothedragon 0:8f0bb79ddd48 1056 }
leothedragon 0:8f0bb79ddd48 1057 }
leothedragon 0:8f0bb79ddd48 1058 return false;
leothedragon 0:8f0bb79ddd48 1059 }
leothedragon 0:8f0bb79ddd48 1060
leothedragon 0:8f0bb79ddd48 1061
leothedragon 0:8f0bb79ddd48 1062 bool ConnectorClient::get_key(const char *key, const char *endpoint, char *&key_name)
leothedragon 0:8f0bb79ddd48 1063 {
leothedragon 0:8f0bb79ddd48 1064 if(key_name) {
leothedragon 0:8f0bb79ddd48 1065 free(key_name);
leothedragon 0:8f0bb79ddd48 1066 key_name = NULL;
leothedragon 0:8f0bb79ddd48 1067 }
leothedragon 0:8f0bb79ddd48 1068
leothedragon 0:8f0bb79ddd48 1069 key_name = (char*)malloc(strlen(key)+strlen(endpoint)+1);
leothedragon 0:8f0bb79ddd48 1070 if(key_name) {
leothedragon 0:8f0bb79ddd48 1071 strcpy(key_name, key);
leothedragon 0:8f0bb79ddd48 1072 strcat(key_name, endpoint);
leothedragon 0:8f0bb79ddd48 1073 tr_debug("key %s", key_name);
leothedragon 0:8f0bb79ddd48 1074 return true;
leothedragon 0:8f0bb79ddd48 1075 }
leothedragon 0:8f0bb79ddd48 1076 return false;
leothedragon 0:8f0bb79ddd48 1077 }
leothedragon 0:8f0bb79ddd48 1078
leothedragon 0:8f0bb79ddd48 1079 ccs_status_e ConnectorClient::set_connector_credentials(M2MSecurity *security)
leothedragon 0:8f0bb79ddd48 1080 {
leothedragon 0:8f0bb79ddd48 1081 tr_debug("ConnectorClient::set_connector_credentials");
leothedragon 0:8f0bb79ddd48 1082 ccs_status_e status = CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 1083
leothedragon 0:8f0bb79ddd48 1084 int32_t m2m_id = security->get_security_instance_id(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 1085 if (m2m_id == -1) {
leothedragon 0:8f0bb79ddd48 1086 return status;
leothedragon 0:8f0bb79ddd48 1087 }
leothedragon 0:8f0bb79ddd48 1088
leothedragon 0:8f0bb79ddd48 1089 size_t buffer_size = MAX_CERTIFICATE_SIZE;
leothedragon 0:8f0bb79ddd48 1090 uint8_t public_key[MAX_CERTIFICATE_SIZE];
leothedragon 0:8f0bb79ddd48 1091 uint8_t *public_key_ptr = (uint8_t*)&public_key;
leothedragon 0:8f0bb79ddd48 1092
leothedragon 0:8f0bb79ddd48 1093 // TODO! Update to use chain api
leothedragon 0:8f0bb79ddd48 1094 if (security->resource_value_buffer(M2MSecurity::PublicKey, public_key_ptr, m2m_id, &buffer_size) != 0) {
leothedragon 0:8f0bb79ddd48 1095 return status;
leothedragon 0:8f0bb79ddd48 1096 }
leothedragon 0:8f0bb79ddd48 1097
leothedragon 0:8f0bb79ddd48 1098 char device_id[64];
leothedragon 0:8f0bb79ddd48 1099 memset(device_id, 0, 64);
leothedragon 0:8f0bb79ddd48 1100 if (extract_field_from_certificate(public_key, buffer_size, "L", device_id)) {
leothedragon 0:8f0bb79ddd48 1101 tr_info("ConnectorClient::set_connector_credentials - L internal_endpoint_name : %s", device_id);
leothedragon 0:8f0bb79ddd48 1102 _endpoint_info.internal_endpoint_name = String(device_id);
leothedragon 0:8f0bb79ddd48 1103 ccs_delete_item(KEY_INTERNAL_ENDPOINT, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1104 status = ccs_set_item(KEY_INTERNAL_ENDPOINT,(uint8_t*)device_id, strlen(device_id), CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1105 }
leothedragon 0:8f0bb79ddd48 1106
leothedragon 0:8f0bb79ddd48 1107 memset(device_id, 0, 64);
leothedragon 0:8f0bb79ddd48 1108 if (extract_field_from_certificate(public_key, buffer_size, "CN", device_id)) {
leothedragon 0:8f0bb79ddd48 1109 tr_info("ConnectorClient::set_connector_credentials - CN endpoint_name : %s", device_id);
leothedragon 0:8f0bb79ddd48 1110 _endpoint_info.endpoint_name = String(device_id);
leothedragon 0:8f0bb79ddd48 1111 }
leothedragon 0:8f0bb79ddd48 1112
leothedragon 0:8f0bb79ddd48 1113 if(status == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1114 ccs_delete_item(KEY_ACCOUNT_ID, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1115 // AccountID optional so don't fail if unable to store
leothedragon 0:8f0bb79ddd48 1116 ccs_set_item(KEY_ACCOUNT_ID,
leothedragon 0:8f0bb79ddd48 1117 (const uint8_t*)_endpoint_info.account_id.c_str(),
leothedragon 0:8f0bb79ddd48 1118 (size_t)_endpoint_info.account_id.size(),
leothedragon 0:8f0bb79ddd48 1119 CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1120 }
leothedragon 0:8f0bb79ddd48 1121
leothedragon 0:8f0bb79ddd48 1122 if (status == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1123 #ifdef MBED_CLOUD_CLIENT_EDGE_EXTENSION
leothedragon 0:8f0bb79ddd48 1124 _endpoint_info.lwm2m_server_uri = security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id);
leothedragon 0:8f0bb79ddd48 1125 #endif
leothedragon 0:8f0bb79ddd48 1126 ccs_delete_item(g_fcc_lwm2m_server_uri_name, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1127 status = ccs_set_item(g_fcc_lwm2m_server_uri_name,
leothedragon 0:8f0bb79ddd48 1128 (const uint8_t*)security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id).c_str(),
leothedragon 0:8f0bb79ddd48 1129 (size_t)security->resource_value_string(M2MSecurity::M2MServerUri, m2m_id).size(),
leothedragon 0:8f0bb79ddd48 1130 CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1131 }
leothedragon 0:8f0bb79ddd48 1132
leothedragon 0:8f0bb79ddd48 1133 M2MDevice *device = M2MInterfaceFactory::create_device();
leothedragon 0:8f0bb79ddd48 1134 if (status == CCS_STATUS_SUCCESS && device) {
leothedragon 0:8f0bb79ddd48 1135 String temp = "";
leothedragon 0:8f0bb79ddd48 1136 uint32_t currenttime = (uint32_t)device->resource_value_int(M2MDevice::CurrentTime, 0);
leothedragon 0:8f0bb79ddd48 1137 uint8_t data[4];
leothedragon 0:8f0bb79ddd48 1138 memcpy(data, &currenttime, 4);
leothedragon 0:8f0bb79ddd48 1139 ccs_delete_item(g_fcc_current_time_parameter_name, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1140 ccs_set_item(g_fcc_current_time_parameter_name, data, 4, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1141
leothedragon 0:8f0bb79ddd48 1142 temp = device->resource_value_string(M2MDevice::Timezone, 0);
leothedragon 0:8f0bb79ddd48 1143 if (temp.size() > 0) {
leothedragon 0:8f0bb79ddd48 1144 ccs_delete_item(g_fcc_device_time_zone_parameter_name, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1145 ccs_set_item(g_fcc_device_time_zone_parameter_name, (const uint8_t*)temp.c_str(), temp.size(), CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1146 }
leothedragon 0:8f0bb79ddd48 1147
leothedragon 0:8f0bb79ddd48 1148 temp = device->resource_value_string(M2MDevice::UTCOffset, 0);
leothedragon 0:8f0bb79ddd48 1149 if (temp.size() > 0) {
leothedragon 0:8f0bb79ddd48 1150 ccs_delete_item(g_fcc_offset_from_utc_parameter_name, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1151 ccs_set_item(g_fcc_offset_from_utc_parameter_name, (const uint8_t*)temp.c_str(), temp.size(), CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1152 }
leothedragon 0:8f0bb79ddd48 1153
leothedragon 0:8f0bb79ddd48 1154 status = CCS_STATUS_SUCCESS;
leothedragon 0:8f0bb79ddd48 1155 }
leothedragon 0:8f0bb79ddd48 1156 else {
leothedragon 0:8f0bb79ddd48 1157 tr_debug("No device object to store!");
leothedragon 0:8f0bb79ddd48 1158 }
leothedragon 0:8f0bb79ddd48 1159
leothedragon 0:8f0bb79ddd48 1160 return status;
leothedragon 0:8f0bb79ddd48 1161 }
leothedragon 0:8f0bb79ddd48 1162
leothedragon 0:8f0bb79ddd48 1163 ccs_status_e ConnectorClient::set_bootstrap_credentials(M2MSecurity *security)
leothedragon 0:8f0bb79ddd48 1164 {
leothedragon 0:8f0bb79ddd48 1165 tr_debug("ConnectorClient::set_bootstrap_credentials");
leothedragon 0:8f0bb79ddd48 1166 ccs_status_e status = CCS_STATUS_ERROR;
leothedragon 0:8f0bb79ddd48 1167
leothedragon 0:8f0bb79ddd48 1168 size_t uri_size = MAX_CERTIFICATE_SIZE;
leothedragon 0:8f0bb79ddd48 1169 uint8_t bootstrap_uri[MAX_CERTIFICATE_SIZE];
leothedragon 0:8f0bb79ddd48 1170 uint8_t *bootstrap_uri_ptr = (uint8_t*)&bootstrap_uri;
leothedragon 0:8f0bb79ddd48 1171
leothedragon 0:8f0bb79ddd48 1172 int32_t bs_id = security->get_security_instance_id(M2MSecurity::Bootstrap);
leothedragon 0:8f0bb79ddd48 1173 if (bs_id == -1) {
leothedragon 0:8f0bb79ddd48 1174 return status;
leothedragon 0:8f0bb79ddd48 1175 }
leothedragon 0:8f0bb79ddd48 1176
leothedragon 0:8f0bb79ddd48 1177 String bs_uri = security->resource_value_string(M2MSecurity::M2MServerUri, bs_id);
leothedragon 0:8f0bb79ddd48 1178 if (bs_uri.size() <= 0) {
leothedragon 0:8f0bb79ddd48 1179 return status;
leothedragon 0:8f0bb79ddd48 1180 }
leothedragon 0:8f0bb79ddd48 1181
leothedragon 0:8f0bb79ddd48 1182 // Update BS uri only if it has changed.
leothedragon 0:8f0bb79ddd48 1183 // If uri is missing or some other error while reading the item --> return error.
leothedragon 0:8f0bb79ddd48 1184 if (ccs_get_string_item(g_fcc_bootstrap_server_uri_name, bootstrap_uri_ptr, uri_size, CCS_CONFIG_ITEM) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1185 if (strcmp((const char*)bootstrap_uri_ptr, bs_uri.c_str()) != 0) {
leothedragon 0:8f0bb79ddd48 1186 tr_info("ConnectorClient::set_bootstrap_credentials - update uri from: %s to: %s", (char*)bootstrap_uri_ptr, bs_uri.c_str());
leothedragon 0:8f0bb79ddd48 1187 ccs_delete_item(g_fcc_bootstrap_server_uri_name, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1188 status = ccs_set_item(g_fcc_bootstrap_server_uri_name,
leothedragon 0:8f0bb79ddd48 1189 (const uint8_t*)bs_uri.c_str(),
leothedragon 0:8f0bb79ddd48 1190 strlen(bs_uri.c_str()),
leothedragon 0:8f0bb79ddd48 1191 CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1192 } else {
leothedragon 0:8f0bb79ddd48 1193 status = CCS_STATUS_SUCCESS;
leothedragon 0:8f0bb79ddd48 1194 }
leothedragon 0:8f0bb79ddd48 1195 }
leothedragon 0:8f0bb79ddd48 1196
leothedragon 0:8f0bb79ddd48 1197 return status;
leothedragon 0:8f0bb79ddd48 1198 }
leothedragon 0:8f0bb79ddd48 1199
leothedragon 0:8f0bb79ddd48 1200 ccs_status_e ConnectorClient::clear_first_to_claim()
leothedragon 0:8f0bb79ddd48 1201 {
leothedragon 0:8f0bb79ddd48 1202 tr_debug("ConnectorClient::clear_first_to_claim");
leothedragon 0:8f0bb79ddd48 1203 return ccs_delete_item(KEY_FIRST_TO_CLAIM, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1204 }
leothedragon 0:8f0bb79ddd48 1205
leothedragon 0:8f0bb79ddd48 1206
leothedragon 0:8f0bb79ddd48 1207 const ConnectorClientEndpointInfo *ConnectorClient::endpoint_info() const
leothedragon 0:8f0bb79ddd48 1208 {
leothedragon 0:8f0bb79ddd48 1209 return &_endpoint_info;
leothedragon 0:8f0bb79ddd48 1210 }
leothedragon 0:8f0bb79ddd48 1211
leothedragon 0:8f0bb79ddd48 1212 bool ConnectorClient::bootstrap_credentials_stored_in_kcm()
leothedragon 0:8f0bb79ddd48 1213 {
leothedragon 0:8f0bb79ddd48 1214 size_t real_size = 0;
leothedragon 0:8f0bb79ddd48 1215 ccs_status_e success = ccs_item_size(g_fcc_bootstrap_server_uri_name, &real_size, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1216 // Return true if bootstrap uri exists in KCM
leothedragon 0:8f0bb79ddd48 1217 if ((success == CCS_STATUS_SUCCESS) && real_size > 0) {
leothedragon 0:8f0bb79ddd48 1218 return true;
leothedragon 0:8f0bb79ddd48 1219 } else {
leothedragon 0:8f0bb79ddd48 1220 return false;
leothedragon 0:8f0bb79ddd48 1221 }
leothedragon 0:8f0bb79ddd48 1222 }
leothedragon 0:8f0bb79ddd48 1223
leothedragon 0:8f0bb79ddd48 1224 bool ConnectorClient::is_first_to_claim()
leothedragon 0:8f0bb79ddd48 1225 {
leothedragon 0:8f0bb79ddd48 1226 size_t real_size = 0;
leothedragon 0:8f0bb79ddd48 1227 uint8_t data[CONFIG_BOOLEAN_ITEM_SIZE] = {0};
leothedragon 0:8f0bb79ddd48 1228 uint32_t value = 0;
leothedragon 0:8f0bb79ddd48 1229 ccs_status_e status = ccs_get_item(KEY_FIRST_TO_CLAIM, data, CONFIG_BOOLEAN_ITEM_SIZE, &real_size, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1230 if (status == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1231 memcpy(&value, data, CONFIG_BOOLEAN_ITEM_SIZE);
leothedragon 0:8f0bb79ddd48 1232 // Return true if first to claim is set
leothedragon 0:8f0bb79ddd48 1233 if (value == 1) {
leothedragon 0:8f0bb79ddd48 1234 return true;
leothedragon 0:8f0bb79ddd48 1235 }
leothedragon 0:8f0bb79ddd48 1236 }
leothedragon 0:8f0bb79ddd48 1237 return false;
leothedragon 0:8f0bb79ddd48 1238 }
leothedragon 0:8f0bb79ddd48 1239
leothedragon 0:8f0bb79ddd48 1240 void ConnectorClient::timer_expired(M2MTimerObserver::Type type)
leothedragon 0:8f0bb79ddd48 1241 {
leothedragon 0:8f0bb79ddd48 1242 if (type == M2MTimerObserver::BootstrapFlowTimer) {
leothedragon 0:8f0bb79ddd48 1243 start_bootstrap();
leothedragon 0:8f0bb79ddd48 1244 }
leothedragon 0:8f0bb79ddd48 1245 }
leothedragon 0:8f0bb79ddd48 1246
leothedragon 0:8f0bb79ddd48 1247 #ifndef MBED_CLIENT_DISABLE_EST_FEATURE
leothedragon 0:8f0bb79ddd48 1248 void ConnectorClient::est_enrollment_result(est_enrollment_result_e result,
leothedragon 0:8f0bb79ddd48 1249 cert_chain_context_s *cert_chain,
leothedragon 0:8f0bb79ddd48 1250 void *context)
leothedragon 0:8f0bb79ddd48 1251 {
leothedragon 0:8f0bb79ddd48 1252 tr_debug("ConnectorClient::est_enrollment_result - %s", result == EST_ENROLLMENT_SUCCESS ? "successful" : "failed");
leothedragon 0:8f0bb79ddd48 1253 if (result == EST_ENROLLMENT_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1254 tr_debug("ConnectorClient::est_enrollment_result - PublicKey size %d", cert_chain->chain_length);
leothedragon 0:8f0bb79ddd48 1255 }
leothedragon 0:8f0bb79ddd48 1256
leothedragon 0:8f0bb79ddd48 1257 ConnectorClient *cc = static_cast<ConnectorClient*>(context);
leothedragon 0:8f0bb79ddd48 1258 assert(cc);
leothedragon 0:8f0bb79ddd48 1259 assert(cc->_security != NULL);
leothedragon 0:8f0bb79ddd48 1260
leothedragon 0:8f0bb79ddd48 1261 int32_t m2m_id = cc->_security->get_security_instance_id(M2MSecurity::M2MServer);
leothedragon 0:8f0bb79ddd48 1262 StartupSubStateRegistration state = State_EST_Failure;
leothedragon 0:8f0bb79ddd48 1263
leothedragon 0:8f0bb79ddd48 1264 if (result == EST_ENROLLMENT_SUCCESS &&
leothedragon 0:8f0bb79ddd48 1265 m2m_id >= 0 &&
leothedragon 0:8f0bb79ddd48 1266 cert_chain != NULL &&
leothedragon 0:8f0bb79ddd48 1267 cert_chain->chain_length > 0)
leothedragon 0:8f0bb79ddd48 1268 {
leothedragon 0:8f0bb79ddd48 1269
leothedragon 0:8f0bb79ddd48 1270 kcm_cert_chain_handle chain_handle;
leothedragon 0:8f0bb79ddd48 1271 kcm_status_e status = kcm_cert_chain_create(&chain_handle,
leothedragon 0:8f0bb79ddd48 1272 (const uint8_t*)g_fcc_lwm2m_device_certificate_name,
leothedragon 0:8f0bb79ddd48 1273 strlen(g_fcc_lwm2m_device_certificate_name),
leothedragon 0:8f0bb79ddd48 1274 cert_chain->chain_length,
leothedragon 0:8f0bb79ddd48 1275 false);
leothedragon 0:8f0bb79ddd48 1276 tr_debug("Cert chain create %d", status);
leothedragon 0:8f0bb79ddd48 1277 if (status == KCM_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1278 cert_context_s *cert = cert_chain->certs;
leothedragon 0:8f0bb79ddd48 1279 while (cert != NULL) {
leothedragon 0:8f0bb79ddd48 1280
leothedragon 0:8f0bb79ddd48 1281 // Store certificate
leothedragon 0:8f0bb79ddd48 1282 status = kcm_cert_chain_add_next(chain_handle, cert->cert, cert->cert_length);
leothedragon 0:8f0bb79ddd48 1283 if (status != KCM_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1284 break;
leothedragon 0:8f0bb79ddd48 1285 }
leothedragon 0:8f0bb79ddd48 1286
leothedragon 0:8f0bb79ddd48 1287 cert = cert->next;
leothedragon 0:8f0bb79ddd48 1288 }
leothedragon 0:8f0bb79ddd48 1289
leothedragon 0:8f0bb79ddd48 1290 status = kcm_cert_chain_close(chain_handle);
leothedragon 0:8f0bb79ddd48 1291 if (status == KCM_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1292 tr_info("ConnectorClient::est_enrollment_result() - Certificates stored successfully");
leothedragon 0:8f0bb79ddd48 1293 tr_info("ConnectorClient::est_enrollment_result() - Storing lwm2m credentials");
leothedragon 0:8f0bb79ddd48 1294 if (cc->set_connector_credentials(cc->_security) == CCS_STATUS_SUCCESS) {
leothedragon 0:8f0bb79ddd48 1295 state = State_EST_Success;
leothedragon 0:8f0bb79ddd48 1296 }
leothedragon 0:8f0bb79ddd48 1297 }
leothedragon 0:8f0bb79ddd48 1298 else {
leothedragon 0:8f0bb79ddd48 1299 tr_error("ConnectorClient::est_enrollment_result - storing certificate chain failed!");
leothedragon 0:8f0bb79ddd48 1300 }
leothedragon 0:8f0bb79ddd48 1301 }
leothedragon 0:8f0bb79ddd48 1302 }
leothedragon 0:8f0bb79ddd48 1303
leothedragon 0:8f0bb79ddd48 1304 // Finally free the certificate chain context
leothedragon 0:8f0bb79ddd48 1305 EstClient::free_cert_chain_context(cert_chain);
leothedragon 0:8f0bb79ddd48 1306
leothedragon 0:8f0bb79ddd48 1307 cc->internal_event(state);
leothedragon 0:8f0bb79ddd48 1308 }
leothedragon 0:8f0bb79ddd48 1309 #endif /* !MBED_CLIENT_DISABLE_EST_FEATURE */
leothedragon 0:8f0bb79ddd48 1310
leothedragon 0:8f0bb79ddd48 1311
leothedragon 0:8f0bb79ddd48 1312 M2MInterface::BindingMode ConnectorClient::transport_mode()
leothedragon 0:8f0bb79ddd48 1313 {
leothedragon 0:8f0bb79ddd48 1314 #ifdef MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP
leothedragon 0:8f0bb79ddd48 1315 return M2MInterface::UDP;
leothedragon 0:8f0bb79ddd48 1316 #elif defined MBED_CLOUD_CLIENT_TRANSPORT_MODE_TCP
leothedragon 0:8f0bb79ddd48 1317 return M2MInterface::TCP;
leothedragon 0:8f0bb79ddd48 1318 #elif defined MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP_QUEUE
leothedragon 0:8f0bb79ddd48 1319 return M2MInterface::UDP_QUEUE;
leothedragon 0:8f0bb79ddd48 1320 #elif defined MBED_CLOUD_CLIENT_TRANSPORT_MODE_TCP_QUEUE
leothedragon 0:8f0bb79ddd48 1321 return M2MInterface::TCP_QUEUE;
leothedragon 0:8f0bb79ddd48 1322 #else
leothedragon 0:8f0bb79ddd48 1323 return M2MInterface::UDP;
leothedragon 0:8f0bb79ddd48 1324 #endif
leothedragon 0:8f0bb79ddd48 1325 }
leothedragon 0:8f0bb79ddd48 1326
leothedragon 0:8f0bb79ddd48 1327 void ConnectorClient::init_security_object()
leothedragon 0:8f0bb79ddd48 1328 {
leothedragon 0:8f0bb79ddd48 1329 if (_security) {
leothedragon 0:8f0bb79ddd48 1330 for (int i = 0; i <= M2MSecurity::Bootstrap; i++) {
leothedragon 0:8f0bb79ddd48 1331 // _security->create_object_instance() returns NULL if object already exists
leothedragon 0:8f0bb79ddd48 1332 if (_security->create_object_instance((M2MSecurity::ServerType)i)) {
leothedragon 0:8f0bb79ddd48 1333 M2MResource* res = _security->get_resource(M2MSecurity::ServerPublicKey, i);
leothedragon 0:8f0bb79ddd48 1334 if (res) {
leothedragon 0:8f0bb79ddd48 1335 res->set_resource_read_callback(read_security_object_data_from_kcm, this);
leothedragon 0:8f0bb79ddd48 1336 res->set_resource_write_callback(write_security_object_data_to_kcm, this);
leothedragon 0:8f0bb79ddd48 1337 }
leothedragon 0:8f0bb79ddd48 1338
leothedragon 0:8f0bb79ddd48 1339 res = _security->get_resource(M2MSecurity::PublicKey, i);
leothedragon 0:8f0bb79ddd48 1340 if (res) {
leothedragon 0:8f0bb79ddd48 1341 res->set_resource_read_callback(read_security_object_data_from_kcm, this);
leothedragon 0:8f0bb79ddd48 1342 res->set_resource_write_callback(write_security_object_data_to_kcm, this);
leothedragon 0:8f0bb79ddd48 1343 }
leothedragon 0:8f0bb79ddd48 1344
leothedragon 0:8f0bb79ddd48 1345 res = _security->get_resource(M2MSecurity::Secretkey, i);
leothedragon 0:8f0bb79ddd48 1346 if (res) {
leothedragon 0:8f0bb79ddd48 1347 res->set_resource_read_callback(read_security_object_data_from_kcm, this);
leothedragon 0:8f0bb79ddd48 1348 res->set_resource_write_callback(write_security_object_data_to_kcm, this);
leothedragon 0:8f0bb79ddd48 1349 }
leothedragon 0:8f0bb79ddd48 1350
leothedragon 0:8f0bb79ddd48 1351 res = _security->get_resource(M2MSecurity::OpenCertificateChain, i);
leothedragon 0:8f0bb79ddd48 1352 if (res) {
leothedragon 0:8f0bb79ddd48 1353 res->set_resource_read_callback(open_certificate_chain_callback, this);
leothedragon 0:8f0bb79ddd48 1354 }
leothedragon 0:8f0bb79ddd48 1355
leothedragon 0:8f0bb79ddd48 1356 res = _security->get_resource(M2MSecurity::ReadDeviceCertificateChain, i);
leothedragon 0:8f0bb79ddd48 1357 if (res) {
leothedragon 0:8f0bb79ddd48 1358 res->set_resource_read_callback(read_certificate_chain_callback, this);
leothedragon 0:8f0bb79ddd48 1359 }
leothedragon 0:8f0bb79ddd48 1360
leothedragon 0:8f0bb79ddd48 1361 res = _security->get_resource(M2MSecurity::CloseCertificateChain, i);
leothedragon 0:8f0bb79ddd48 1362 if (res) {
leothedragon 0:8f0bb79ddd48 1363 res->set_resource_read_callback(close_certificate_chain_callback, this);
leothedragon 0:8f0bb79ddd48 1364 }
leothedragon 0:8f0bb79ddd48 1365 }
leothedragon 0:8f0bb79ddd48 1366 }
leothedragon 0:8f0bb79ddd48 1367 }
leothedragon 0:8f0bb79ddd48 1368 }
leothedragon 0:8f0bb79ddd48 1369
leothedragon 0:8f0bb79ddd48 1370 void *ConnectorClient::certificate_chain_handle() const
leothedragon 0:8f0bb79ddd48 1371 {
leothedragon 0:8f0bb79ddd48 1372 return _certificate_chain_handle;
leothedragon 0:8f0bb79ddd48 1373 }
leothedragon 0:8f0bb79ddd48 1374
leothedragon 0:8f0bb79ddd48 1375 void ConnectorClient::set_certificate_chain_handle(void *cert_handle)
leothedragon 0:8f0bb79ddd48 1376 {
leothedragon 0:8f0bb79ddd48 1377 _certificate_chain_handle = cert_handle;
leothedragon 0:8f0bb79ddd48 1378 }
leothedragon 0:8f0bb79ddd48 1379
leothedragon 0:8f0bb79ddd48 1380 void ConnectorClient::bootstrap_again()
leothedragon 0:8f0bb79ddd48 1381 {
leothedragon 0:8f0bb79ddd48 1382 // delete the old connector credentials
leothedragon 0:8f0bb79ddd48 1383 ccs_delete_item(g_fcc_lwm2m_server_uri_name, CCS_CONFIG_ITEM);
leothedragon 0:8f0bb79ddd48 1384 ccs_delete_item(g_fcc_lwm2m_server_ca_certificate_name, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 1385 ccs_delete_item(g_fcc_lwm2m_device_certificate_name, CCS_CERTIFICATE_ITEM);
leothedragon 0:8f0bb79ddd48 1386 ccs_delete_item(g_fcc_lwm2m_device_private_key_name, CCS_PRIVATE_KEY_ITEM);
leothedragon 0:8f0bb79ddd48 1387
leothedragon 0:8f0bb79ddd48 1388 tr_error("ConnectorClient::bootstrap_again in %d seconds", _rebootstrap_time);
leothedragon 0:8f0bb79ddd48 1389
leothedragon 0:8f0bb79ddd48 1390 _rebootstrap_timer.start_timer(_rebootstrap_time * 1000, M2MTimerObserver::BootstrapFlowTimer, true);
leothedragon 0:8f0bb79ddd48 1391 _rebootstrap_time *= 2;
leothedragon 0:8f0bb79ddd48 1392 if (_rebootstrap_time > MAX_REBOOTSTRAP_TIMEOUT) {
leothedragon 0:8f0bb79ddd48 1393 _rebootstrap_time = MAX_REBOOTSTRAP_TIMEOUT;
leothedragon 0:8f0bb79ddd48 1394 }
leothedragon 0:8f0bb79ddd48 1395
leothedragon 0:8f0bb79ddd48 1396 _callback->connector_error(M2MInterface::SecureConnectionFailed, CONNECTOR_BOOTSTRAP_AGAIN);
leothedragon 0:8f0bb79ddd48 1397 }