Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedConnectorInterfaceV3 by
source/ConnectorEndpoint.cpp@110:0af085ececd2, 2017-04-26 (annotated)
- Committer:
- ansond
- Date:
- Wed Apr 26 04:23:14 2017 +0000
- Revision:
- 110:0af085ececd2
- Parent:
- 109:e3fc9140cbbf
- Child:
- 111:9407038559f7
updates for R1.2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ansond | 0:1f1f55e73248 | 1 | /** |
ansond | 0:1f1f55e73248 | 2 | * @file ConnectorEndpoint.cpp |
ansond | 0:1f1f55e73248 | 3 | * @brief mbed CoAP Endpoint base class |
ansond | 0:1f1f55e73248 | 4 | * @author Doug Anson/Chris Paola |
ansond | 0:1f1f55e73248 | 5 | * @version 1.0 |
ansond | 0:1f1f55e73248 | 6 | * @see |
ansond | 0:1f1f55e73248 | 7 | * |
ansond | 0:1f1f55e73248 | 8 | * Copyright (c) 2014 |
ansond | 0:1f1f55e73248 | 9 | * |
ansond | 0:1f1f55e73248 | 10 | * Licensed under the Apache License, Version 2.0 (the "License"); |
ansond | 0:1f1f55e73248 | 11 | * you may not use this file except in compliance with the License. |
ansond | 0:1f1f55e73248 | 12 | * You may obtain a copy of the License at |
ansond | 0:1f1f55e73248 | 13 | * |
ansond | 0:1f1f55e73248 | 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
ansond | 0:1f1f55e73248 | 15 | * |
ansond | 0:1f1f55e73248 | 16 | * Unless required by applicable law or agreed to in writing, software |
ansond | 0:1f1f55e73248 | 17 | * distributed under the License is distributed on an "AS IS" BASIS, |
ansond | 0:1f1f55e73248 | 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ansond | 0:1f1f55e73248 | 19 | * See the License for the specific language governing permissions and |
ansond | 0:1f1f55e73248 | 20 | * limitations under the License. |
ansond | 0:1f1f55e73248 | 21 | */ |
ansond | 0:1f1f55e73248 | 22 | |
ansond | 0:1f1f55e73248 | 23 | // Lower level Network |
ansond | 0:1f1f55e73248 | 24 | #include "mbed-connector-interface/mbedEndpointNetwork.h" |
ansond | 0:1f1f55e73248 | 25 | |
ansond | 0:1f1f55e73248 | 26 | // ConnectorEndpoint |
ansond | 0:1f1f55e73248 | 27 | #include "mbed-connector-interface/ConnectorEndpoint.h" |
ansond | 0:1f1f55e73248 | 28 | |
ansond | 0:1f1f55e73248 | 29 | // Utils support |
ansond | 0:1f1f55e73248 | 30 | #include "mbed-connector-interface/Utils.h" |
ansond | 0:1f1f55e73248 | 31 | |
ansond | 27:b8aaf7dc7023 | 32 | // Device Manager support |
ansond | 27:b8aaf7dc7023 | 33 | #include "mbed-connector-interface/DeviceManager.h" |
ansond | 27:b8aaf7dc7023 | 34 | |
ansond | 96:73a85768f235 | 35 | // factory storage and configurator support (mbed Cloud R1.2+) |
ansond | 96:73a85768f235 | 36 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 99:7f563f0a6c3c | 37 | // trace configuration |
ansond | 97:b141b6b8b37f | 38 | #include "mbed-trace/mbed_trace.h" |
ansond | 99:7f563f0a6c3c | 39 | |
ansond | 99:7f563f0a6c3c | 40 | // updater support |
ansond | 99:7f563f0a6c3c | 41 | #include "update_ui_example.h" |
ansond | 99:7f563f0a6c3c | 42 | |
ansond | 99:7f563f0a6c3c | 43 | // factory flow support |
ansond | 96:73a85768f235 | 44 | #include "mbed_factory_configurator_client.h" |
ansond | 96:73a85768f235 | 45 | #endif |
ansond | 96:73a85768f235 | 46 | |
ansond | 1:16f0fb5b8d97 | 47 | // our endpoint instance |
ansond | 1:16f0fb5b8d97 | 48 | static Connector::Endpoint *__endpoint = NULL; |
ansond | 0:1f1f55e73248 | 49 | |
ansond | 54:dfee8691c83a | 50 | // LWIP Network interface instance |
ansond | 60:0d9e607dd678 | 51 | NetworkInterface *__network_interface = NULL; |
ansond | 27:b8aaf7dc7023 | 52 | |
ansond | 0:1f1f55e73248 | 53 | // Connector namespace |
ansond | 0:1f1f55e73248 | 54 | namespace Connector { |
ansond | 0:1f1f55e73248 | 55 | |
ansond | 0:1f1f55e73248 | 56 | // STATIC: Plumb the network |
ansond | 13:9edad7677211 | 57 | void Endpoint::plumbNetwork(void *device_manager,bool canActAsRouterNode) { |
ansond | 54:dfee8691c83a | 58 | // create our endpoint instance... |
ansond | 1:16f0fb5b8d97 | 59 | if (__endpoint == NULL) { |
ansond | 1:16f0fb5b8d97 | 60 | // initialize our endpoint instance |
ansond | 54:dfee8691c83a | 61 | printf("Connector::Endpoint::plumbNetwork: initializing endpoint instance...\r\n"); |
ansond | 1:16f0fb5b8d97 | 62 | __endpoint = (Connector::Endpoint *)utils_init_endpoint(canActAsRouterNode); |
ansond | 1:16f0fb5b8d97 | 63 | } |
ansond | 13:9edad7677211 | 64 | |
ansond | 110:0af085ececd2 | 65 | // make sure we have an endpoint... |
ansond | 110:0af085ececd2 | 66 | if (__endpoint != NULL) { |
ansond | 110:0af085ececd2 | 67 | // set the device manager |
ansond | 110:0af085ececd2 | 68 | if (device_manager != NULL) { |
ansond | 110:0af085ececd2 | 69 | // device manager has been supplied |
ansond | 110:0af085ececd2 | 70 | printf("Connector::Endpoint::plumbNetwork: setting a device manager...\r\n"); |
ansond | 110:0af085ececd2 | 71 | __endpoint->setDeviceManager(device_manager); |
ansond | 110:0af085ececd2 | 72 | } |
ansond | 110:0af085ececd2 | 73 | |
ansond | 110:0af085ececd2 | 74 | // configure the endpoint... |
ansond | 110:0af085ececd2 | 75 | printf("Connector::Endpoint::plumbNetwork: configuring endpoint...\r\n"); |
ansond | 110:0af085ececd2 | 76 | utils_configure_endpoint((void *)__endpoint); |
ansond | 110:0af085ececd2 | 77 | |
ansond | 110:0af085ececd2 | 78 | // plumb the endpoint's network... |
ansond | 110:0af085ececd2 | 79 | printf("Connector::Endpoint::plumbNetwork: plumbing network...\r\n"); |
ansond | 110:0af085ececd2 | 80 | net_plumb_network((void *)__endpoint); |
ansond | 13:9edad7677211 | 81 | } |
ansond | 0:1f1f55e73248 | 82 | } |
ansond | 0:1f1f55e73248 | 83 | |
ansond | 0:1f1f55e73248 | 84 | // STATIC: Finalize the endpoint's configuration and begin the endpoint's main even loop (static, not tied into Logger) |
ansond | 8:f950fb1b78c0 | 85 | void Endpoint::start() |
ansond | 8:f950fb1b78c0 | 86 | { |
ansond | 110:0af085ececd2 | 87 | if (__endpoint != NULL) { |
ansond | 110:0af085ececd2 | 88 | // build out the endpoint with its configuration... |
ansond | 110:0af085ececd2 | 89 | printf("Connector::Endpoint::start: building out endpoint...\r\n"); |
ansond | 110:0af085ececd2 | 90 | utils_build_endpoint((void *)__endpoint); |
ansond | 110:0af085ececd2 | 91 | |
ansond | 110:0af085ececd2 | 92 | // finalize the endpoint and start its main loop |
ansond | 110:0af085ececd2 | 93 | printf("Endpoint::start: finalize and run the endpoint main loop..\r\n"); |
ansond | 110:0af085ececd2 | 94 | net_finalize_and_run_endpoint_main_loop((void *)__endpoint); |
ansond | 110:0af085ececd2 | 95 | } |
ansond | 110:0af085ececd2 | 96 | else { |
ansond | 110:0af085ececd2 | 97 | // not starting the endpoint due to errors |
ansond | 110:0af085ececd2 | 98 | printf("Connector::Endpoint::start: Not starting endpoint due to errors... exiting...\r\n"); |
ansond | 110:0af085ececd2 | 99 | |
ansond | 110:0af085ececd2 | 100 | // end in error... |
ansond | 110:0af085ececd2 | 101 | while(true) { |
ansond | 110:0af085ececd2 | 102 | Thread::wait(1000); |
ansond | 110:0af085ececd2 | 103 | } |
ansond | 110:0af085ececd2 | 104 | } |
ansond | 0:1f1f55e73248 | 105 | } |
ansond | 0:1f1f55e73248 | 106 | |
ansond | 43:3fb57c4fba34 | 107 | // STATIC: Set the ConnectionStatusInterface Implementation instance |
ansond | 43:3fb57c4fba34 | 108 | void Endpoint::setConnectionStatusInterface(ConnectionStatusInterface *csi) { |
ansond | 43:3fb57c4fba34 | 109 | if (__endpoint != NULL) { |
ansond | 44:7c73baf9f4c1 | 110 | __endpoint->setConnectionStatusInterfaceImpl(csi); |
ansond | 43:3fb57c4fba34 | 111 | } |
ansond | 43:3fb57c4fba34 | 112 | } |
ansond | 43:3fb57c4fba34 | 113 | |
ansond | 0:1f1f55e73248 | 114 | // Constructor |
ansond | 87:00b3837986c7 | 115 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 87:00b3837986c7 | 116 | Endpoint::Endpoint(const Logger *logger, const Options *options) : MbedCloudClientCallback(), M2MInterfaceObserver() |
ansond | 87:00b3837986c7 | 117 | #else |
ansond | 0:1f1f55e73248 | 118 | Endpoint::Endpoint(const Logger *logger, const Options *options) : M2MInterfaceObserver() |
ansond | 87:00b3837986c7 | 119 | #endif |
ansond | 0:1f1f55e73248 | 120 | { |
ansond | 0:1f1f55e73248 | 121 | this->m_logger = (Logger *)logger; |
ansond | 0:1f1f55e73248 | 122 | this->m_options = (Options *)options; |
ansond | 13:9edad7677211 | 123 | this->m_device_manager = NULL; |
ansond | 13:9edad7677211 | 124 | this->m_connected = false; |
ansond | 15:c11dbe4d354c | 125 | this->m_registered = false; |
ansond | 27:b8aaf7dc7023 | 126 | this->m_csi = NULL; |
ansond | 27:b8aaf7dc7023 | 127 | this->m_oim = NULL; |
ansond | 81:a2441163a06e | 128 | this->m_endpoint_security = NULL; |
ansond | 74:6abfb2a03020 | 129 | this->m_endpoint_interface = NULL; |
ansond | 0:1f1f55e73248 | 130 | } |
ansond | 0:1f1f55e73248 | 131 | |
ansond | 0:1f1f55e73248 | 132 | // Copy Constructor |
ansond | 0:1f1f55e73248 | 133 | Endpoint::Endpoint(const Endpoint &ep) |
ansond | 0:1f1f55e73248 | 134 | { |
ansond | 0:1f1f55e73248 | 135 | this->m_logger = ep.m_logger; |
ansond | 0:1f1f55e73248 | 136 | this->m_options = ep.m_options; |
ansond | 46:62da4ce20276 | 137 | this->m_endpoint_interface = ep.m_endpoint_interface; |
ansond | 46:62da4ce20276 | 138 | this->m_endpoint_security = ep.m_endpoint_security; |
ansond | 46:62da4ce20276 | 139 | this->m_endpoint_object_list = ep.m_endpoint_object_list; |
ansond | 13:9edad7677211 | 140 | this->m_device_manager = ep.m_device_manager; |
ansond | 13:9edad7677211 | 141 | this->m_connected = ep.m_connected; |
ansond | 15:c11dbe4d354c | 142 | this->m_registered = ep.m_registered; |
ansond | 27:b8aaf7dc7023 | 143 | this->m_csi = ep.m_csi; |
ansond | 27:b8aaf7dc7023 | 144 | this->m_oim = ep.m_oim; |
ansond | 0:1f1f55e73248 | 145 | } |
ansond | 0:1f1f55e73248 | 146 | |
ansond | 0:1f1f55e73248 | 147 | // Destructor |
ansond | 0:1f1f55e73248 | 148 | Endpoint::~Endpoint() { |
ansond | 75:9152ea6b4c59 | 149 | #ifndef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 46:62da4ce20276 | 150 | if (this->m_endpoint_interface != NULL) |
ansond | 46:62da4ce20276 | 151 | delete this->m_endpoint_interface; |
ansond | 73:f12a767bc300 | 152 | |
ansond | 46:62da4ce20276 | 153 | if (this->m_endpoint_security != NULL) |
ansond | 46:62da4ce20276 | 154 | delete this->m_endpoint_security; |
ansond | 73:f12a767bc300 | 155 | #endif |
ansond | 0:1f1f55e73248 | 156 | } |
ansond | 0:1f1f55e73248 | 157 | |
ansond | 13:9edad7677211 | 158 | // set the device manager |
ansond | 13:9edad7677211 | 159 | void Endpoint::setDeviceManager(void *device_manager) { |
ansond | 13:9edad7677211 | 160 | this->m_device_manager = device_manager; |
ansond | 13:9edad7677211 | 161 | } |
ansond | 13:9edad7677211 | 162 | |
ansond | 13:9edad7677211 | 163 | // get the device manager |
ansond | 13:9edad7677211 | 164 | void *Endpoint::getDeviceManager(void) { |
ansond | 13:9edad7677211 | 165 | return this->m_device_manager; |
ansond | 13:9edad7677211 | 166 | } |
ansond | 13:9edad7677211 | 167 | |
ansond | 1:16f0fb5b8d97 | 168 | // router node behavior setting |
ansond | 1:16f0fb5b8d97 | 169 | void Endpoint::asRouterNode(bool canActAsRouterNode) { |
ansond | 1:16f0fb5b8d97 | 170 | this->m_canActAsRouterNode = canActAsRouterNode; |
ansond | 1:16f0fb5b8d97 | 171 | } |
ansond | 1:16f0fb5b8d97 | 172 | |
ansond | 1:16f0fb5b8d97 | 173 | // set our Options |
ansond | 1:16f0fb5b8d97 | 174 | void Endpoint::setOptions(Options *options) { |
ansond | 1:16f0fb5b8d97 | 175 | this->m_options = options; |
ansond | 1:16f0fb5b8d97 | 176 | } |
ansond | 1:16f0fb5b8d97 | 177 | |
ansond | 0:1f1f55e73248 | 178 | // get our Options |
ansond | 0:1f1f55e73248 | 179 | Options *Endpoint::getOptions() { |
ansond | 0:1f1f55e73248 | 180 | return this->m_options; |
ansond | 0:1f1f55e73248 | 181 | } |
ansond | 0:1f1f55e73248 | 182 | |
ansond | 81:a2441163a06e | 183 | // get our endpoint security instance |
ansond | 81:a2441163a06e | 184 | M2MSecurity *Endpoint::getSecurityInstance() { |
ansond | 46:62da4ce20276 | 185 | return this->m_endpoint_security; |
ansond | 0:1f1f55e73248 | 186 | } |
ansond | 81:a2441163a06e | 187 | |
ansond | 81:a2441163a06e | 188 | // set our endpoint security instance |
ansond | 81:a2441163a06e | 189 | void Endpoint::setSecurityInstance(M2MSecurity *security) { |
ansond | 81:a2441163a06e | 190 | if (security != NULL) { |
ansond | 81:a2441163a06e | 191 | this->m_endpoint_security = security; |
ansond | 81:a2441163a06e | 192 | } |
ansond | 81:a2441163a06e | 193 | } |
ansond | 0:1f1f55e73248 | 194 | |
ansond | 0:1f1f55e73248 | 195 | // get our ObjectList |
ansond | 46:62da4ce20276 | 196 | M2MObjectList Endpoint::getEndpointObjectList() { |
ansond | 46:62da4ce20276 | 197 | return this->m_endpoint_object_list; |
ansond | 46:62da4ce20276 | 198 | } |
ansond | 46:62da4ce20276 | 199 | |
ansond | 73:f12a767bc300 | 200 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 73:f12a767bc300 | 201 | // get our endpoint interface |
ansond | 73:f12a767bc300 | 202 | MbedCloudClient *Endpoint::getEndpointInterface() { |
ansond | 73:f12a767bc300 | 203 | return this->m_endpoint_interface; |
ansond | 73:f12a767bc300 | 204 | } |
ansond | 73:f12a767bc300 | 205 | #else |
ansond | 46:62da4ce20276 | 206 | // get our endpoint interface |
ansond | 46:62da4ce20276 | 207 | M2MInterface *Endpoint::getEndpointInterface() { |
ansond | 46:62da4ce20276 | 208 | return this->m_endpoint_interface; |
ansond | 0:1f1f55e73248 | 209 | } |
ansond | 73:f12a767bc300 | 210 | #endif |
ansond | 0:1f1f55e73248 | 211 | |
ansond | 71:5069a202e892 | 212 | // Connector::Endpoint: create our interface |
ansond | 71:5069a202e892 | 213 | void Endpoint::createEndpointInterface() { |
ansond | 71:5069a202e892 | 214 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 98:56e429670fdb | 215 | this->createCloudEndpointInterface(); |
ansond | 71:5069a202e892 | 216 | #else |
ansond | 72:6b1d37b5420a | 217 | this->createConnectorEndpointInterface(); |
ansond | 71:5069a202e892 | 218 | #endif |
ansond | 71:5069a202e892 | 219 | } |
ansond | 71:5069a202e892 | 220 | |
ansond | 71:5069a202e892 | 221 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 96:73a85768f235 | 222 | // mbedCloudClient: initialize Storage |
ansond | 96:73a85768f235 | 223 | bool Endpoint::initializeStorage() { |
ansond | 106:8c504a89c1dc | 224 | #ifdef MBED_CLOUD_STORAGE_INIT |
ansond | 96:73a85768f235 | 225 | // initialize mbed-trace |
ansond | 96:73a85768f235 | 226 | mbed_trace_init(); |
ansond | 96:73a85768f235 | 227 | |
ansond | 96:73a85768f235 | 228 | // Resets storage to an empty state. |
ansond | 96:73a85768f235 | 229 | // Use this function when you want to clear SD card from all the factory-tool generated data and user data. |
ansond | 96:73a85768f235 | 230 | // After this operation device must be injected again by using factory tool or developer certificate. |
ansond | 110:0af085ececd2 | 231 | #ifdef MBED_RESET_STORAGE |
ansond | 96:73a85768f235 | 232 | this->logger()->log("initializeStorage: Resetting storage to an empty state..."); |
ansond | 96:73a85768f235 | 233 | mfcc_status_e delete_status = mfcc_storage_delete(); |
ansond | 96:73a85768f235 | 234 | if (delete_status != MFCC_STATUS_SUCCESS) { |
ansond | 96:73a85768f235 | 235 | this->logger()->log("initializeStorage: Failed to reset storage to an empty state. status=%d (OK)...", delete_status); |
ansond | 96:73a85768f235 | 236 | } |
ansond | 96:73a85768f235 | 237 | #endif |
ansond | 96:73a85768f235 | 238 | mfcc_status_e status = mfcc_init(); |
ansond | 96:73a85768f235 | 239 | if(status != MFCC_STATUS_SUCCESS) { |
ansond | 96:73a85768f235 | 240 | this->logger()->log("initializeStorage: ERROR: mfcc_init failed with status=%d...", status); |
ansond | 96:73a85768f235 | 241 | return false; |
ansond | 96:73a85768f235 | 242 | } |
ansond | 106:8c504a89c1dc | 243 | #else |
ansond | 106:8c504a89c1dc | 244 | // not enabled |
ansond | 106:8c504a89c1dc | 245 | this->logger()->log("initializeStorage: storage initialize disabled (OK)..."); |
ansond | 106:8c504a89c1dc | 246 | #endif |
ansond | 96:73a85768f235 | 247 | return true; |
ansond | 96:73a85768f235 | 248 | } |
ansond | 96:73a85768f235 | 249 | |
ansond | 96:73a85768f235 | 250 | // mbedCloudClient:: initialize factory flow |
ansond | 96:73a85768f235 | 251 | bool Endpoint::initializeFactoryFlow() { |
ansond | 106:8c504a89c1dc | 252 | #ifdef MBED_CLOUD_DEV_FLOW_INIT |
ansond | 96:73a85768f235 | 253 | #ifdef MBED_CONF_APP_DEVELOPER_MODE |
ansond | 96:73a85768f235 | 254 | this->logger()->log("initializeFactoryFlow: Start developer flow..."); |
ansond | 97:b141b6b8b37f | 255 | mfcc_status_e status = mfcc_developer_flow(); |
ansond | 96:73a85768f235 | 256 | if (status == MFCC_STATUS_KCM_FILE_EXIST_ERROR) { |
ansond | 96:73a85768f235 | 257 | this->logger()->log("initializeFactoryFlow: Developer credentials already exists (OK)..."); |
ansond | 96:73a85768f235 | 258 | } else if (status != MFCC_STATUS_SUCCESS) { |
ansond | 96:73a85768f235 | 259 | this->logger()->log("initializeFactoryFlow: ERROR: Failed to load developer credentials"); |
ansond | 96:73a85768f235 | 260 | return false; |
ansond | 96:73a85768f235 | 261 | } |
ansond | 96:73a85768f235 | 262 | status = mfcc_verify_device_configured_4mbed_cloud(); |
ansond | 96:73a85768f235 | 263 | if (status != MFCC_STATUS_SUCCESS) { |
ansond | 96:73a85768f235 | 264 | this->logger()->log("initializeFactoryFlow: ERROR: Device not configured for mbed Cloud"); |
ansond | 96:73a85768f235 | 265 | return false; |
ansond | 96:73a85768f235 | 266 | } |
ansond | 96:73a85768f235 | 267 | return true; |
ansond | 96:73a85768f235 | 268 | #else |
ansond | 96:73a85768f235 | 269 | this->logger()->log("initializeFactoryFlow: non-developer factory flow chosen... continuing..."); |
ansond | 96:73a85768f235 | 270 | return true; |
ansond | 96:73a85768f235 | 271 | #endif |
ansond | 106:8c504a89c1dc | 272 | #else |
ansond | 106:8c504a89c1dc | 273 | this->logger()->log("initializeFactoryFlow: developer flow init disabled (OK)..."); |
ansond | 106:8c504a89c1dc | 274 | return true; |
ansond | 106:8c504a89c1dc | 275 | #endif |
ansond | 96:73a85768f235 | 276 | } |
ansond | 96:73a85768f235 | 277 | |
ansond | 71:5069a202e892 | 278 | // mbedCloudClient: create our interface |
ansond | 71:5069a202e892 | 279 | void Endpoint::createCloudEndpointInterface() { |
ansond | 74:6abfb2a03020 | 280 | if (this->m_endpoint_interface == NULL) { |
ansond | 109:e3fc9140cbbf | 281 | bool storage_init = this->initializeStorage(); |
ansond | 109:e3fc9140cbbf | 282 | bool factory_flow_init = this->initializeFactoryFlow(); |
ansond | 109:e3fc9140cbbf | 283 | if (storage_init && factory_flow_init) { |
ansond | 105:aeaaee8fbb1d | 284 | // create a new instance of mbedCloudClient |
ansond | 109:e3fc9140cbbf | 285 | this->logger()->log("createCloudEndpointInterface: creating mbed cloud client instance..."); |
ansond | 105:aeaaee8fbb1d | 286 | this->m_endpoint_interface = new MbedCloudClient(); |
ansond | 105:aeaaee8fbb1d | 287 | if (this->m_endpoint_interface == NULL) { |
ansond | 105:aeaaee8fbb1d | 288 | // unable to allocate the MbedCloudClient instance |
ansond | 105:aeaaee8fbb1d | 289 | this->logger()->log("createCloudEndpointInterface: ERROR: unable to allocate MbedCloudClient instance..."); |
ansond | 105:aeaaee8fbb1d | 290 | } |
ansond | 105:aeaaee8fbb1d | 291 | else { |
ansond | 105:aeaaee8fbb1d | 292 | // enable hooks for Updater support (R1.2+) (if enabled) |
ansond | 105:aeaaee8fbb1d | 293 | #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE |
ansond | 105:aeaaee8fbb1d | 294 | update_ui_set_cloud_client(this->m_endpoint_interface); |
ansond | 105:aeaaee8fbb1d | 295 | this->m_endpoint_interface->set_update_authorize_handler(&Connector::Endpoint::update_authorize); |
ansond | 105:aeaaee8fbb1d | 296 | this->m_endpoint_interface->set_update_progress_handler(&Connector::Endpoint::update_progress); |
ansond | 105:aeaaee8fbb1d | 297 | #endif |
ansond | 105:aeaaee8fbb1d | 298 | } |
ansond | 98:56e429670fdb | 299 | } |
ansond | 109:e3fc9140cbbf | 300 | else { |
ansond | 109:e3fc9140cbbf | 301 | if (storage_init) { |
ansond | 109:e3fc9140cbbf | 302 | // unable to create mbed cloud client instance... (FAILED factory flow init) |
ansond | 109:e3fc9140cbbf | 303 | this->logger()->log("createCloudEndpointInterface: ERROR: unable to initialize factory flow..."); |
ansond | 109:e3fc9140cbbf | 304 | } |
ansond | 109:e3fc9140cbbf | 305 | else { |
ansond | 109:e3fc9140cbbf | 306 | // unable to create mbed cloud client instance... (FAILED storage init) |
ansond | 109:e3fc9140cbbf | 307 | this->logger()->log("createCloudEndpointInterface: ERROR: unable to initialize storage..."); |
ansond | 109:e3fc9140cbbf | 308 | } |
ansond | 109:e3fc9140cbbf | 309 | this->m_endpoint_interface = NULL; |
ansond | 109:e3fc9140cbbf | 310 | } |
ansond | 74:6abfb2a03020 | 311 | } |
ansond | 74:6abfb2a03020 | 312 | |
ansond | 71:5069a202e892 | 313 | // bind LWIP network interface pointer... |
ansond | 71:5069a202e892 | 314 | if (__network_interface != NULL && this->m_endpoint_interface != NULL) { |
ansond | 71:5069a202e892 | 315 | this->logger()->log("Connector::Endpoint: binding LWIP network instance (Cloud)..."); |
ansond | 81:a2441163a06e | 316 | this->m_endpoint_interface->on_registered(&Connector::Endpoint::on_registered); |
ansond | 81:a2441163a06e | 317 | this->m_endpoint_interface->on_unregistered(&Connector::Endpoint::on_unregistered); |
ansond | 81:a2441163a06e | 318 | this->m_endpoint_interface->on_error(&Connector::Endpoint::on_error); |
ansond | 81:a2441163a06e | 319 | this->m_endpoint_interface->set_update_callback(this); |
ansond | 71:5069a202e892 | 320 | } |
ansond | 109:e3fc9140cbbf | 321 | else { |
ansond | 109:e3fc9140cbbf | 322 | // skipping LWIP bind... |
ansond | 109:e3fc9140cbbf | 323 | this->logger()->log("Connector::Endpoint: ERROR (Cloud) skipping LWIP network instance bind due to previous error..."); |
ansond | 109:e3fc9140cbbf | 324 | } |
ansond | 71:5069a202e892 | 325 | } |
ansond | 81:a2441163a06e | 326 | #else |
ansond | 0:1f1f55e73248 | 327 | // mbed-client: create our interface |
ansond | 71:5069a202e892 | 328 | void Endpoint::createConnectorEndpointInterface() { |
ansond | 10:3f79b5e67c22 | 329 | // get the CoAP listening port |
ansond | 10:3f79b5e67c22 | 330 | uint16_t listening_port = (uint16_t)this->m_options->getConnectorPort(); |
ansond | 10:3f79b5e67c22 | 331 | |
ansond | 10:3f79b5e67c22 | 332 | // randomize the port if we are using certificates... |
ansond | 10:3f79b5e67c22 | 333 | if (this->m_options->getServerCertificateSize() > 0) { |
ansond | 0:1f1f55e73248 | 334 | // Randomizing listening port for Certificate mode connectivity |
ansond | 0:1f1f55e73248 | 335 | srand(time(NULL)); |
ansond | 10:3f79b5e67c22 | 336 | listening_port = rand() % 65535 + 12345; |
ansond | 10:3f79b5e67c22 | 337 | } |
ansond | 10:3f79b5e67c22 | 338 | |
ansond | 60:0d9e607dd678 | 339 | // DEBUG |
ansond | 61:d02cd5e2bb26 | 340 | //this->logger()->log("Connector::Endpoint: listening port: %d",listening_port); |
ansond | 60:0d9e607dd678 | 341 | |
ansond | 61:d02cd5e2bb26 | 342 | // Socket protocol type: TCP or UDP |
ansond | 61:d02cd5e2bb26 | 343 | M2MInterface::BindingMode socket_protocol_type = M2MInterface::UDP; |
ansond | 61:d02cd5e2bb26 | 344 | if (this->m_options->getCoAPConnectionType() == COAP_TCP) socket_protocol_type = M2MInterface::TCP; |
ansond | 10:3f79b5e67c22 | 345 | |
ansond | 61:d02cd5e2bb26 | 346 | // Socket address type: IPv4 or IPv6 |
ansond | 61:d02cd5e2bb26 | 347 | M2MInterface::NetworkStack socket_address_type = M2MInterface::LwIP_IPv4; |
ansond | 62:e5882bd28210 | 348 | if (this->m_options->getIPAddressType() == IP_ADDRESS_TYPE_IPV6) { |
ansond | 61:d02cd5e2bb26 | 349 | // IPv6 mode for the socket addressing type... |
ansond | 61:d02cd5e2bb26 | 350 | socket_address_type = M2MInterface::LwIP_IPv6; |
ansond | 59:dd395412bd19 | 351 | |
ansond | 59:dd395412bd19 | 352 | #if defined (IPV4_OVERRIDE) |
ansond | 61:d02cd5e2bb26 | 353 | // OVERRIDE (until patched...) |
ansond | 61:d02cd5e2bb26 | 354 | this->logger()->log("Connector::Endpoint: Socket Address Type: IPv4 (IPv6 OVERRIDE)"); |
ansond | 61:d02cd5e2bb26 | 355 | socket_address_type = M2MInterface::LwIP_IPv4; |
ansond | 59:dd395412bd19 | 356 | #endif |
ansond | 59:dd395412bd19 | 357 | } |
ansond | 10:3f79b5e67c22 | 358 | |
ansond | 10:3f79b5e67c22 | 359 | // DEBUG |
ansond | 61:d02cd5e2bb26 | 360 | if (socket_protocol_type == M2MInterface::TCP) this->logger()->log("Connector::Endpoint: Socket Protocol: TCP"); |
ansond | 61:d02cd5e2bb26 | 361 | if (socket_protocol_type == M2MInterface::UDP) this->logger()->log("Connector::Endpoint: Socket Protocol: UDP"); |
ansond | 61:d02cd5e2bb26 | 362 | if (socket_address_type == M2MInterface::LwIP_IPv4) this->logger()->log("Connector::Endpoint: Socket Address Type: IPv4"); |
ansond | 61:d02cd5e2bb26 | 363 | if (socket_address_type == M2MInterface::LwIP_IPv6) this->logger()->log("Connector::Endpoint: Socket Address Type: IPv6"); |
ansond | 10:3f79b5e67c22 | 364 | |
ansond | 61:d02cd5e2bb26 | 365 | // Create the endpoint M2MInterface instance |
ansond | 46:62da4ce20276 | 366 | this->m_endpoint_interface = M2MInterfaceFactory::create_interface(*this, |
ansond | 61:d02cd5e2bb26 | 367 | (char *)this->m_options->getEndpointNodename().c_str(), // endpoint name |
ansond | 61:d02cd5e2bb26 | 368 | (char *)this->m_options->getEndpointType().c_str(), // endpoint type |
ansond | 61:d02cd5e2bb26 | 369 | (int32_t)this->m_options->getLifetime(), // registration lifetime (in seconds) |
ansond | 61:d02cd5e2bb26 | 370 | listening_port, // listening port (ephemeral...) |
ansond | 61:d02cd5e2bb26 | 371 | (char *)this->m_options->getDomain().c_str(), // endpoint domain |
ansond | 61:d02cd5e2bb26 | 372 | socket_protocol_type, // Socket protocol type: UDP or TCP... |
ansond | 61:d02cd5e2bb26 | 373 | socket_address_type, // Socket addressing type: IPv4 or IPv6 |
ansond | 61:d02cd5e2bb26 | 374 | CONTEXT_ADDRESS_STRING // context address string (mbedConnectorInterface.h) |
ansond | 60:0d9e607dd678 | 375 | ); |
ansond | 61:d02cd5e2bb26 | 376 | |
ansond | 61:d02cd5e2bb26 | 377 | // bind LWIP network interface pointer... |
ansond | 46:62da4ce20276 | 378 | if (__network_interface != NULL && this->m_endpoint_interface != NULL) { |
ansond | 71:5069a202e892 | 379 | this->logger()->log("Connector::Endpoint: binding LWIP network instance (Connector)..."); |
ansond | 60:0d9e607dd678 | 380 | this->m_endpoint_interface->set_platform_network_handler((void *)__network_interface); |
ansond | 27:b8aaf7dc7023 | 381 | } |
ansond | 0:1f1f55e73248 | 382 | } |
ansond | 81:a2441163a06e | 383 | #endif |
ansond | 0:1f1f55e73248 | 384 | |
ansond | 81:a2441163a06e | 385 | // mbed-client: createEndpointSecurityInstance() |
ansond | 81:a2441163a06e | 386 | M2MSecurity *Endpoint::createEndpointSecurityInstance() { |
ansond | 81:a2441163a06e | 387 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 81:a2441163a06e | 388 | // internalized... not used. |
ansond | 81:a2441163a06e | 389 | return NULL; |
ansond | 81:a2441163a06e | 390 | #else |
ansond | 0:1f1f55e73248 | 391 | // Creates register server object with mbed device server address and other parameters |
ansond | 0:1f1f55e73248 | 392 | M2MSecurity *server = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer); |
ansond | 0:1f1f55e73248 | 393 | if (server != NULL) { |
ansond | 0:1f1f55e73248 | 394 | const String url = this->m_options->getConnectorURL(); |
ansond | 0:1f1f55e73248 | 395 | server->set_resource_value(M2MSecurity::M2MServerUri, url); |
ansond | 38:bb6d2be4d54c | 396 | server->set_resource_value(M2MSecurity::BootstrapServer, false); |
ansond | 0:1f1f55e73248 | 397 | server->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate); |
ansond | 0:1f1f55e73248 | 398 | server->set_resource_value(M2MSecurity::ServerPublicKey,this->m_options->getServerCertificate(),this->m_options->getServerCertificateSize()); |
ansond | 0:1f1f55e73248 | 399 | server->set_resource_value(M2MSecurity::PublicKey,this->m_options->getClientCertificate(),this->m_options->getClientCertificateSize()); |
ansond | 0:1f1f55e73248 | 400 | server->set_resource_value(M2MSecurity::Secretkey,this->m_options->getClientKey(),this->m_options->getClientKeySize()); |
ansond | 0:1f1f55e73248 | 401 | } |
ansond | 0:1f1f55e73248 | 402 | return server; |
ansond | 81:a2441163a06e | 403 | #endif |
ansond | 0:1f1f55e73248 | 404 | } |
ansond | 0:1f1f55e73248 | 405 | |
ansond | 81:a2441163a06e | 406 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 81:a2441163a06e | 407 | // mbed-cloud-client: Callback from mbed client stack if any error is encountered |
ansond | 82:e085176f6719 | 408 | void Endpoint::on_error(int error_code) { |
ansond | 85:ad357f0a48d2 | 409 | char *error = (char *)"No Error"; |
ansond | 81:a2441163a06e | 410 | switch(error_code) { |
ansond | 81:a2441163a06e | 411 | case 0x01: |
ansond | 84:e5f53e7492cb | 412 | error = (char *)"MbedCloudClient::IdentityError"; |
ansond | 81:a2441163a06e | 413 | break; |
ansond | 81:a2441163a06e | 414 | case 0x02: |
ansond | 84:e5f53e7492cb | 415 | error = (char *)"MbedCloudClient::IdentityInvalidParameter"; |
ansond | 81:a2441163a06e | 416 | break; |
ansond | 81:a2441163a06e | 417 | case 0x03: |
ansond | 84:e5f53e7492cb | 418 | error = (char *)"MbedCloudClient::IdentityOutofMemory"; |
ansond | 81:a2441163a06e | 419 | break; |
ansond | 81:a2441163a06e | 420 | case 0x04: |
ansond | 84:e5f53e7492cb | 421 | error = (char *)"MbedCloudClient::IdentityProvisioningError"; |
ansond | 81:a2441163a06e | 422 | break; |
ansond | 81:a2441163a06e | 423 | case 0x05: |
ansond | 84:e5f53e7492cb | 424 | error = (char *)"MbedCloudClient::IdentityInvalidSessionID"; |
ansond | 81:a2441163a06e | 425 | break; |
ansond | 81:a2441163a06e | 426 | case 0x06: |
ansond | 84:e5f53e7492cb | 427 | error = (char *)"MbedCloudClient::IdentityNetworkError"; |
ansond | 81:a2441163a06e | 428 | break; |
ansond | 81:a2441163a06e | 429 | case 0x07: |
ansond | 84:e5f53e7492cb | 430 | error = (char *)"MbedCloudClient::IdentityInvalidMessageType"; |
ansond | 81:a2441163a06e | 431 | break; |
ansond | 81:a2441163a06e | 432 | case 0x08: |
ansond | 84:e5f53e7492cb | 433 | error = (char *)"MbedCloudClient::IdentityInvalidMessageSize"; |
ansond | 81:a2441163a06e | 434 | break; |
ansond | 81:a2441163a06e | 435 | case 0x09: |
ansond | 84:e5f53e7492cb | 436 | error = (char *)"MbedCloudClient::IdentityCertOrKeyNotFound"; |
ansond | 81:a2441163a06e | 437 | break; |
ansond | 81:a2441163a06e | 438 | case 0x0A: |
ansond | 84:e5f53e7492cb | 439 | error = (char *)"MbedCloudClient::IdentityRetransmissionError"; |
ansond | 81:a2441163a06e | 440 | break; |
ansond | 81:a2441163a06e | 441 | case 0x30: |
ansond | 84:e5f53e7492cb | 442 | error = (char *)"MbedCloudClient::ConnectErrorNone"; |
ansond | 81:a2441163a06e | 443 | break; |
ansond | 81:a2441163a06e | 444 | case 0x31: |
ansond | 84:e5f53e7492cb | 445 | error = (char *)"MbedCloudClient::ConnectAlreadyExists"; |
ansond | 81:a2441163a06e | 446 | break; |
ansond | 81:a2441163a06e | 447 | case 0x32: |
ansond | 84:e5f53e7492cb | 448 | error = (char *)"MbedCloudClient::ConnectBootstrapFailed"; |
ansond | 81:a2441163a06e | 449 | break; |
ansond | 81:a2441163a06e | 450 | case 0x33: |
ansond | 84:e5f53e7492cb | 451 | error = (char *)"MbedCloudClient::ConnectInvalidParameters"; |
ansond | 81:a2441163a06e | 452 | break; |
ansond | 81:a2441163a06e | 453 | case 0x34: |
ansond | 84:e5f53e7492cb | 454 | error = (char *)"MbedCloudClient::ConnectNotRegistered"; |
ansond | 81:a2441163a06e | 455 | break; |
ansond | 81:a2441163a06e | 456 | case 0x35: |
ansond | 84:e5f53e7492cb | 457 | error = (char *)"MbedCloudClient::ConnectTimeout"; |
ansond | 81:a2441163a06e | 458 | break; |
ansond | 81:a2441163a06e | 459 | case 0x36: |
ansond | 84:e5f53e7492cb | 460 | error = (char *)"MbedCloudClient::ConnectNetworkError"; |
ansond | 81:a2441163a06e | 461 | break; |
ansond | 81:a2441163a06e | 462 | case 0x37: |
ansond | 84:e5f53e7492cb | 463 | error = (char *)"MbedCloudClient::ConnectResponseParseFailed"; |
ansond | 81:a2441163a06e | 464 | break; |
ansond | 81:a2441163a06e | 465 | case 0x38: |
ansond | 84:e5f53e7492cb | 466 | error = (char *)"MbedCloudClient::ConnectUnknownError"; |
ansond | 81:a2441163a06e | 467 | break; |
ansond | 81:a2441163a06e | 468 | case 0x39: |
ansond | 84:e5f53e7492cb | 469 | error = (char *)"MbedCloudClient::ConnectMemoryFail"; |
ansond | 81:a2441163a06e | 470 | break; |
ansond | 81:a2441163a06e | 471 | case 0x3A: |
ansond | 84:e5f53e7492cb | 472 | error = (char *)"MbedCloudClient::ConnectNotAllowed"; |
ansond | 81:a2441163a06e | 473 | break; |
ansond | 81:a2441163a06e | 474 | case 0x3B: |
ansond | 84:e5f53e7492cb | 475 | error = (char *)"MbedCloudClient::ConnectSecureConnectionFailed"; |
ansond | 81:a2441163a06e | 476 | break; |
ansond | 81:a2441163a06e | 477 | case 0x3C: |
ansond | 84:e5f53e7492cb | 478 | error = (char *)"MbedCloudClient::ConnectDnsResolvingFailed"; |
ansond | 81:a2441163a06e | 479 | break; |
ansond | 81:a2441163a06e | 480 | default: |
ansond | 84:e5f53e7492cb | 481 | error = (char *)"UNKNOWN"; |
ansond | 81:a2441163a06e | 482 | } |
ansond | 85:ad357f0a48d2 | 483 | printf("Connector::Endpoint(Cloud) Error(%x): %s\r\n",error_code,error); |
ansond | 81:a2441163a06e | 484 | } |
ansond | 98:56e429670fdb | 485 | |
ansond | 98:56e429670fdb | 486 | // mbed-cloud-client: update_authorized |
ansond | 98:56e429670fdb | 487 | void Endpoint::update_authorize(int32_t request) { |
ansond | 98:56e429670fdb | 488 | // simple debug for now... |
ansond | 101:305cc6527e20 | 489 | printf("Connector::Endpoint(Cloud) Update Authorize: request: %d\n",(int)request); |
ansond | 98:56e429670fdb | 490 | } |
ansond | 98:56e429670fdb | 491 | |
ansond | 98:56e429670fdb | 492 | // mbed-cloud-client: update_progress |
ansond | 98:56e429670fdb | 493 | void Endpoint::update_progress(uint32_t progress, uint32_t total) { |
ansond | 98:56e429670fdb | 494 | // simple debug for now... |
ansond | 101:305cc6527e20 | 495 | printf("Connector::Endpoint(Cloud) Update Progress: (%d/%d)\n",(int)progress,(int)total); |
ansond | 98:56e429670fdb | 496 | } |
ansond | 89:ccd22d25f431 | 497 | #endif |
ansond | 89:ccd22d25f431 | 498 | |
ansond | 0:1f1f55e73248 | 499 | // mbed-client: Callback from mbed client stack if any error is encountered |
ansond | 0:1f1f55e73248 | 500 | void Endpoint::error(M2MInterface::Error error) { |
ansond | 0:1f1f55e73248 | 501 | switch(error){ |
ansond | 0:1f1f55e73248 | 502 | case M2MInterface::AlreadyExists: |
ansond | 54:dfee8691c83a | 503 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::AlreadyExists"); |
ansond | 0:1f1f55e73248 | 504 | break; |
ansond | 0:1f1f55e73248 | 505 | case M2MInterface::BootstrapFailed: |
ansond | 54:dfee8691c83a | 506 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::BootstrapFailed"); |
ansond | 0:1f1f55e73248 | 507 | break; |
ansond | 0:1f1f55e73248 | 508 | case M2MInterface::InvalidParameters: |
ansond | 54:dfee8691c83a | 509 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::InvalidParameters"); |
ansond | 0:1f1f55e73248 | 510 | break; |
ansond | 0:1f1f55e73248 | 511 | case M2MInterface::NotRegistered: |
ansond | 54:dfee8691c83a | 512 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::NotRegistered"); |
ansond | 0:1f1f55e73248 | 513 | break; |
ansond | 0:1f1f55e73248 | 514 | case M2MInterface::Timeout: |
ansond | 54:dfee8691c83a | 515 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::Timeout"); |
ansond | 0:1f1f55e73248 | 516 | break; |
ansond | 0:1f1f55e73248 | 517 | case M2MInterface::NetworkError: |
ansond | 54:dfee8691c83a | 518 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::NetworkError"); |
ansond | 0:1f1f55e73248 | 519 | break; |
ansond | 0:1f1f55e73248 | 520 | case M2MInterface::ResponseParseFailed: |
ansond | 54:dfee8691c83a | 521 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::ResponseParseFailed"); |
ansond | 0:1f1f55e73248 | 522 | break; |
ansond | 0:1f1f55e73248 | 523 | case M2MInterface::UnknownError: |
ansond | 54:dfee8691c83a | 524 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::UnknownError"); |
ansond | 0:1f1f55e73248 | 525 | break; |
ansond | 0:1f1f55e73248 | 526 | case M2MInterface::MemoryFail: |
ansond | 54:dfee8691c83a | 527 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::MemoryFail"); |
ansond | 0:1f1f55e73248 | 528 | break; |
ansond | 0:1f1f55e73248 | 529 | case M2MInterface::NotAllowed: |
ansond | 54:dfee8691c83a | 530 | this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::NotAllowed"); |
ansond | 0:1f1f55e73248 | 531 | break; |
ansond | 0:1f1f55e73248 | 532 | default: |
ansond | 0:1f1f55e73248 | 533 | break; |
ansond | 0:1f1f55e73248 | 534 | } |
ansond | 0:1f1f55e73248 | 535 | } |
ansond | 81:a2441163a06e | 536 | |
ansond | 76:7f55e1c0635d | 537 | // re-register the endpoint |
ansond | 76:7f55e1c0635d | 538 | void Endpoint::re_register_endpoint() { |
ansond | 76:7f55e1c0635d | 539 | if (this->m_endpoint_interface != NULL) { |
ansond | 76:7f55e1c0635d | 540 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 81:a2441163a06e | 541 | // DEBUG |
ansond | 81:a2441163a06e | 542 | this->logger()->log("Connector::Endpoint(Cloud): re-register endpoint..."); |
ansond | 76:7f55e1c0635d | 543 | #else |
ansond | 76:7f55e1c0635d | 544 | this->m_endpoint_interface->update_registration(this->m_endpoint_security,this->m_options->getLifetime()); |
ansond | 76:7f55e1c0635d | 545 | #endif |
ansond | 76:7f55e1c0635d | 546 | } |
ansond | 76:7f55e1c0635d | 547 | } |
ansond | 76:7f55e1c0635d | 548 | |
ansond | 76:7f55e1c0635d | 549 | // de-register endpoint |
ansond | 76:7f55e1c0635d | 550 | void Endpoint::de_register_endpoint(void) { |
ansond | 76:7f55e1c0635d | 551 | if (this->m_endpoint_interface != NULL) { |
ansond | 76:7f55e1c0635d | 552 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 81:a2441163a06e | 553 | // DEBUG |
ansond | 81:a2441163a06e | 554 | this->logger()->log("Connector::Endpoint(Cloud): de-registering endpoint..."); |
ansond | 76:7f55e1c0635d | 555 | this->m_endpoint_interface->close(); |
ansond | 76:7f55e1c0635d | 556 | #else |
ansond | 76:7f55e1c0635d | 557 | // de-register endpoint |
ansond | 76:7f55e1c0635d | 558 | this->logger()->log("Connector::Endpoint: de-registering endpoint..."); |
ansond | 76:7f55e1c0635d | 559 | if (this->m_csi != NULL) { |
ansond | 76:7f55e1c0635d | 560 | this->m_csi->begin_object_unregistering((void *)this); |
ansond | 76:7f55e1c0635d | 561 | } |
ansond | 76:7f55e1c0635d | 562 | else { |
ansond | 76:7f55e1c0635d | 563 | this->m_endpoint_interface->unregister_object(NULL); |
ansond | 76:7f55e1c0635d | 564 | } |
ansond | 76:7f55e1c0635d | 565 | #endif |
ansond | 76:7f55e1c0635d | 566 | } |
ansond | 76:7f55e1c0635d | 567 | } |
ansond | 76:7f55e1c0635d | 568 | |
ansond | 77:cee832ba6dd0 | 569 | // register the endpoint |
ansond | 77:cee832ba6dd0 | 570 | void Endpoint::register_endpoint(M2MSecurity *endpoint_security, M2MObjectList endpoint_objects) { |
ansond | 76:7f55e1c0635d | 571 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 76:7f55e1c0635d | 572 | if (this->m_endpoint_interface != NULL) { |
ansond | 90:cff3317ad4b0 | 573 | this->logger()->log("Connector::Endpoint(Cloud): adding objects to endpoint..."); |
ansond | 90:cff3317ad4b0 | 574 | this->m_endpoint_interface->add_objects(endpoint_objects); |
ansond | 90:cff3317ad4b0 | 575 | |
ansond | 81:a2441163a06e | 576 | this->logger()->log("Connector::Endpoint(Cloud): registering endpoint..."); |
ansond | 90:cff3317ad4b0 | 577 | this->m_endpoint_interface->setup(__network_interface); |
ansond | 76:7f55e1c0635d | 578 | } |
ansond | 76:7f55e1c0635d | 579 | #else |
ansond | 46:62da4ce20276 | 580 | if (this->m_endpoint_interface != NULL && endpoint_security != NULL && endpoint_objects.size() > 0) { |
ansond | 23:5852c0884714 | 581 | // register endpoint |
ansond | 54:dfee8691c83a | 582 | this->logger()->log("Connector::Endpoint: registering endpoint..."); |
ansond | 46:62da4ce20276 | 583 | this->m_endpoint_interface->register_object(endpoint_security, endpoint_objects); |
ansond | 23:5852c0884714 | 584 | } |
ansond | 77:cee832ba6dd0 | 585 | #endif |
ansond | 0:1f1f55e73248 | 586 | } |
ansond | 0:1f1f55e73248 | 587 | |
ansond | 81:a2441163a06e | 588 | #ifdef ENABLE_MBED_CLOUD_SUPPORT |
ansond | 81:a2441163a06e | 589 | // object registered |
ansond | 83:8d856fa24fda | 590 | void Endpoint::on_registered() { |
ansond | 83:8d856fa24fda | 591 | if (__endpoint != NULL) { |
ansond | 87:00b3837986c7 | 592 | printf("Connector::Endpoint(Cloud): on_registered()\r\n"); |
ansond | 87:00b3837986c7 | 593 | __endpoint->object_registered(); |
ansond | 81:a2441163a06e | 594 | } |
ansond | 81:a2441163a06e | 595 | } |
ansond | 81:a2441163a06e | 596 | |
ansond | 81:a2441163a06e | 597 | // registration updated |
ansond | 82:e085176f6719 | 598 | void Endpoint::on_registration_updated() { |
ansond | 83:8d856fa24fda | 599 | if (__endpoint != NULL) { |
ansond | 87:00b3837986c7 | 600 | printf("Connector::Endpoint(Cloud): on_registration_updated()\r\n"); |
ansond | 87:00b3837986c7 | 601 | __endpoint->registration_updated(); |
ansond | 81:a2441163a06e | 602 | } |
ansond | 81:a2441163a06e | 603 | } |
ansond | 81:a2441163a06e | 604 | |
ansond | 81:a2441163a06e | 605 | // object unregistered |
ansond | 82:e085176f6719 | 606 | void Endpoint::on_unregistered() { |
ansond | 83:8d856fa24fda | 607 | if (__endpoint != NULL) { |
ansond | 87:00b3837986c7 | 608 | printf("Connector::Endpoint(Cloud): on_unregistered()\r\n"); |
ansond | 88:e78093f6334f | 609 | __endpoint->object_unregistered(__endpoint->getSecurityInstance()); |
ansond | 81:a2441163a06e | 610 | } |
ansond | 81:a2441163a06e | 611 | } |
ansond | 82:e085176f6719 | 612 | #endif |
ansond | 81:a2441163a06e | 613 | |
ansond | 8:f950fb1b78c0 | 614 | // object registered |
ansond | 87:00b3837986c7 | 615 | void Endpoint::object_registered(M2MSecurity *security, const M2MServer &server) { |
ansond | 88:e78093f6334f | 616 | this->object_registered((void *)security,(void *)&server); |
ansond | 8:f950fb1b78c0 | 617 | } |
ansond | 8:f950fb1b78c0 | 618 | |
ansond | 8:f950fb1b78c0 | 619 | // registration updated |
ansond | 87:00b3837986c7 | 620 | void Endpoint::registration_updated(M2MSecurity *security, const M2MServer &server) { |
ansond | 88:e78093f6334f | 621 | this->registration_updated((void *)security,(void *)&server); |
ansond | 8:f950fb1b78c0 | 622 | } |
ansond | 8:f950fb1b78c0 | 623 | |
ansond | 8:f950fb1b78c0 | 624 | // object unregistered |
ansond | 87:00b3837986c7 | 625 | void Endpoint::object_unregistered(M2MSecurity *security) { |
ansond | 54:dfee8691c83a | 626 | // DEBUG |
ansond | 54:dfee8691c83a | 627 | this->logger()->log("Connector::Endpoint: endpoint de-registered."); |
ansond | 54:dfee8691c83a | 628 | |
ansond | 54:dfee8691c83a | 629 | // no longer connected/registered |
ansond | 15:c11dbe4d354c | 630 | this->m_registered = false; |
ansond | 54:dfee8691c83a | 631 | this->m_connected = false; |
ansond | 54:dfee8691c83a | 632 | |
ansond | 54:dfee8691c83a | 633 | // stop all observers... |
ansond | 54:dfee8691c83a | 634 | this->stopObservations(); |
ansond | 54:dfee8691c83a | 635 | |
ansond | 54:dfee8691c83a | 636 | // invoke ConnectionHandler if we have one... |
ansond | 27:b8aaf7dc7023 | 637 | if (this->m_csi != NULL) { |
ansond | 87:00b3837986c7 | 638 | this->m_csi->object_unregistered((void *)this,(void *)security); |
ansond | 27:b8aaf7dc7023 | 639 | } |
ansond | 54:dfee8691c83a | 640 | |
ansond | 54:dfee8691c83a | 641 | // halt the main event loop... we are done. |
ansond | 54:dfee8691c83a | 642 | net_shutdown_endpoint(); |
ansond | 0:1f1f55e73248 | 643 | } |
ansond | 0:1f1f55e73248 | 644 | |
ansond | 0:1f1f55e73248 | 645 | // bootstrap done |
ansond | 87:00b3837986c7 | 646 | void Endpoint::bootstrap_done(M2MSecurity *security) { |
ansond | 54:dfee8691c83a | 647 | this->logger()->log("Connector::Endpoint: endpoint bootstrapped."); |
ansond | 27:b8aaf7dc7023 | 648 | if (this->m_csi != NULL) { |
ansond | 87:00b3837986c7 | 649 | this->m_csi->bootstrapped((void *)this,(void *)security); |
ansond | 87:00b3837986c7 | 650 | } |
ansond | 87:00b3837986c7 | 651 | } |
ansond | 87:00b3837986c7 | 652 | |
ansond | 87:00b3837986c7 | 653 | // object registered |
ansond | 87:00b3837986c7 | 654 | void Endpoint::object_registered(void *security,void *server) { |
ansond | 87:00b3837986c7 | 655 | this->logger()->log("Connector::Endpoint: endpoint registered."); |
ansond | 87:00b3837986c7 | 656 | this->m_connected = true; |
ansond | 87:00b3837986c7 | 657 | this->m_registered = true; |
ansond | 87:00b3837986c7 | 658 | if (this->m_csi != NULL) { |
ansond | 87:00b3837986c7 | 659 | this->m_csi->object_registered((void *)this,security,server); |
ansond | 87:00b3837986c7 | 660 | } |
ansond | 87:00b3837986c7 | 661 | } |
ansond | 87:00b3837986c7 | 662 | |
ansond | 87:00b3837986c7 | 663 | // registration updated |
ansond | 87:00b3837986c7 | 664 | void Endpoint::registration_updated(void *security,void *server) { |
ansond | 87:00b3837986c7 | 665 | this->logger()->log("Connector::Endpoint: endpoint re-registered."); |
ansond | 87:00b3837986c7 | 666 | this->m_connected = true; |
ansond | 87:00b3837986c7 | 667 | this->m_registered = true; |
ansond | 87:00b3837986c7 | 668 | if (this->m_csi != NULL) { |
ansond | 87:00b3837986c7 | 669 | this->m_csi->registration_updated((void *)this,security,server); |
ansond | 27:b8aaf7dc7023 | 670 | } |
ansond | 0:1f1f55e73248 | 671 | } |
ansond | 0:1f1f55e73248 | 672 | |
ansond | 0:1f1f55e73248 | 673 | // resource value updated |
ansond | 0:1f1f55e73248 | 674 | void Endpoint::value_updated(M2MBase *base, M2MBase::BaseType type) { |
ansond | 29:be035befb437 | 675 | // Lookup the resource and invoke process() on it... |
ansond | 0:1f1f55e73248 | 676 | DynamicResource *target_res = this->lookupDynamicResource(base); |
ansond | 29:be035befb437 | 677 | if (target_res != NULL) { |
ansond | 29:be035befb437 | 678 | // DEBUG |
ansond | 43:3fb57c4fba34 | 679 | //this->logger()->log("Value Updated (Custom Resource)"); |
ansond | 29:be035befb437 | 680 | |
ansond | 29:be035befb437 | 681 | // its a custom resource... |
ansond | 29:be035befb437 | 682 | target_res->process(base->operation(),type); |
ansond | 29:be035befb437 | 683 | } |
ansond | 29:be035befb437 | 684 | else { |
ansond | 29:be035befb437 | 685 | // DEBUG |
ansond | 43:3fb57c4fba34 | 686 | //this->logger()->log("Value Updated (Device Manager)"); |
ansond | 29:be035befb437 | 687 | |
ansond | 29:be035befb437 | 688 | // let DeviceManager handle it |
ansond | 29:be035befb437 | 689 | ((DeviceManager *)this->m_device_manager)->process(base,type); |
ansond | 29:be035befb437 | 690 | } |
ansond | 29:be035befb437 | 691 | |
ansond | 29:be035befb437 | 692 | // CSI |
ansond | 27:b8aaf7dc7023 | 693 | if (this->m_csi != NULL) { |
ansond | 27:b8aaf7dc7023 | 694 | this->m_csi->value_updated((void *)this,(void *)base,(int)type); |
ansond | 27:b8aaf7dc7023 | 695 | } |
ansond | 0:1f1f55e73248 | 696 | } |
ansond | 0:1f1f55e73248 | 697 | |
ansond | 0:1f1f55e73248 | 698 | // lookup which DynamicResource cooresponds to a given M2MBase instance... |
ansond | 0:1f1f55e73248 | 699 | DynamicResource *Endpoint::lookupDynamicResource(M2MBase *base) { |
ansond | 0:1f1f55e73248 | 700 | const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList(); |
ansond | 29:be035befb437 | 701 | for(int i=0; i<(int)dynamic_resources->size(); ++i) { |
ansond | 29:be035befb437 | 702 | M2MBase *t = (M2MBase *)dynamic_resources->at(i)->getResource(); |
ansond | 0:1f1f55e73248 | 703 | if (t == base) { |
ansond | 29:be035befb437 | 704 | return dynamic_resources->at(i); |
ansond | 0:1f1f55e73248 | 705 | } |
ansond | 0:1f1f55e73248 | 706 | } |
ansond | 29:be035befb437 | 707 | return NULL; |
ansond | 0:1f1f55e73248 | 708 | } |
ansond | 0:1f1f55e73248 | 709 | |
ansond | 8:f950fb1b78c0 | 710 | // build out the endpoint |
ansond | 46:62da4ce20276 | 711 | void Endpoint::buildEndpoint() |
ansond | 0:1f1f55e73248 | 712 | { |
ansond | 27:b8aaf7dc7023 | 713 | // initialize as an mbed-client |
ansond | 46:62da4ce20276 | 714 | this->createEndpointInterface(); |
ansond | 81:a2441163a06e | 715 | |
ansond | 27:b8aaf7dc7023 | 716 | // Create our server instance |
ansond | 81:a2441163a06e | 717 | this->setSecurityInstance(this->createEndpointSecurityInstance()); |
ansond | 27:b8aaf7dc7023 | 718 | |
ansond | 27:b8aaf7dc7023 | 719 | // We now have to bind our device resources |
ansond | 27:b8aaf7dc7023 | 720 | if (this->m_device_manager != NULL) { |
ansond | 40:5c039dcbd7b2 | 721 | // DEBUG |
ansond | 54:dfee8691c83a | 722 | this->logger()->log("Connector::Endpoint::build(): plumbing the device management objects and resources..."); |
ansond | 40:5c039dcbd7b2 | 723 | |
ansond | 27:b8aaf7dc7023 | 724 | // bind the device manager |
ansond | 27:b8aaf7dc7023 | 725 | ((DeviceManager *)this->m_device_manager)->bind(); |
ansond | 27:b8aaf7dc7023 | 726 | |
ansond | 27:b8aaf7dc7023 | 727 | // push back the Device Resources Object |
ansond | 27:b8aaf7dc7023 | 728 | if (this->m_options->getDeviceResourcesObject() != NULL) { |
ansond | 27:b8aaf7dc7023 | 729 | // DEBUG |
ansond | 54:dfee8691c83a | 730 | this->logger()->log("Connector::Endpoint::build(): plumbing device resources object..."); |
ansond | 27:b8aaf7dc7023 | 731 | |
ansond | 27:b8aaf7dc7023 | 732 | // push back the device resources object |
ansond | 46:62da4ce20276 | 733 | this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getDeviceResourcesObject()); |
ansond | 27:b8aaf7dc7023 | 734 | } |
ansond | 27:b8aaf7dc7023 | 735 | else { |
ansond | 27:b8aaf7dc7023 | 736 | // unable to plumb device manager |
ansond | 54:dfee8691c83a | 737 | this->logger()->log("Connector::Endpoint::build(): Unable to plumb device resources. Not installing device resource object..."); |
ansond | 27:b8aaf7dc7023 | 738 | } |
ansond | 27:b8aaf7dc7023 | 739 | |
ansond | 27:b8aaf7dc7023 | 740 | // push back the Firmware Resources Object |
ansond | 27:b8aaf7dc7023 | 741 | if (this->m_options->getFirmwareResourcesObject() != NULL) { |
ansond | 27:b8aaf7dc7023 | 742 | // DEBUG |
ansond | 54:dfee8691c83a | 743 | this->logger()->log("Connector::Endpoint::build(): plumbing firmware resources object..."); |
ansond | 27:b8aaf7dc7023 | 744 | |
ansond | 27:b8aaf7dc7023 | 745 | // push back the firmware resources object |
ansond | 46:62da4ce20276 | 746 | this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getFirmwareResourcesObject()); |
ansond | 27:b8aaf7dc7023 | 747 | } |
ansond | 27:b8aaf7dc7023 | 748 | else { |
ansond | 27:b8aaf7dc7023 | 749 | // unable to plumb firmware manager |
ansond | 54:dfee8691c83a | 750 | this->logger()->log("Connector::Endpoint::build(): Unable to plumb firmware resources. Not installing firmware resource object..."); |
ansond | 27:b8aaf7dc7023 | 751 | } |
ansond | 27:b8aaf7dc7023 | 752 | } |
ansond | 27:b8aaf7dc7023 | 753 | else { |
ansond | 27:b8aaf7dc7023 | 754 | // no device manager installed |
ansond | 54:dfee8691c83a | 755 | this->logger()->log("Connector::Endpoint::build(): No device manager installed."); |
ansond | 0:1f1f55e73248 | 756 | } |
ansond | 0:1f1f55e73248 | 757 | |
ansond | 0:1f1f55e73248 | 758 | // Loop through Static Resources and bind each of them... |
ansond | 54:dfee8691c83a | 759 | this->logger()->log("Connector::Endpoint::build(): adding static resources..."); |
ansond | 0:1f1f55e73248 | 760 | const StaticResourcesList *static_resources = this->m_options->getStaticResourceList(); |
ansond | 0:1f1f55e73248 | 761 | for(int i=0; i<(int)static_resources->size(); ++i) { |
ansond | 54:dfee8691c83a | 762 | this->logger()->log("Connector::Endpoint::build(): binding static resource: [%s]...",static_resources->at(i)->getFullName().c_str()); |
ansond | 27:b8aaf7dc7023 | 763 | static_resources->at(i)->bind(this); |
ansond | 0:1f1f55e73248 | 764 | } |
ansond | 0:1f1f55e73248 | 765 | |
ansond | 0:1f1f55e73248 | 766 | // Loop through Dynamic Resources and bind each of them... |
ansond | 54:dfee8691c83a | 767 | this->logger()->log("Connector::Endpoint::build(): adding dynamic resources..."); |
ansond | 0:1f1f55e73248 | 768 | const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList(); |
ansond | 0:1f1f55e73248 | 769 | for(int i=0; i<(int)dynamic_resources->size(); ++i) { |
ansond | 54:dfee8691c83a | 770 | this->logger()->log("Connector::Endpoint::build(): binding dynamic resource: [%s]...",dynamic_resources->at(i)->getFullName().c_str()); |
ansond | 27:b8aaf7dc7023 | 771 | dynamic_resources->at(i)->bind(this); |
ansond | 27:b8aaf7dc7023 | 772 | } |
ansond | 27:b8aaf7dc7023 | 773 | |
ansond | 27:b8aaf7dc7023 | 774 | // Get the ObjectList from the ObjectInstanceManager... |
ansond | 27:b8aaf7dc7023 | 775 | NamedPointerList list = this->getObjectInstanceManager()->getObjectList(); |
ansond | 27:b8aaf7dc7023 | 776 | |
ansond | 27:b8aaf7dc7023 | 777 | // DEBUG |
ansond | 45:db754b994deb | 778 | //this->logger()->log("Endpoint::build(): All Resources bound. Number of Objects in list: %d",list.size()); |
ansond | 27:b8aaf7dc7023 | 779 | |
ansond | 27:b8aaf7dc7023 | 780 | // add all of the object instances we have created... |
ansond | 38:bb6d2be4d54c | 781 | for(int i=0;i<(int)list.size();++i) { |
ansond | 27:b8aaf7dc7023 | 782 | // DEBUG |
ansond | 45:db754b994deb | 783 | //this->logger()->log("Endpoint::build(): adding Object Instance with ObjID: %s...",list.at(i).name().c_str()); |
ansond | 27:b8aaf7dc7023 | 784 | |
ansond | 27:b8aaf7dc7023 | 785 | // push back the object instance... |
ansond | 46:62da4ce20276 | 786 | this->m_endpoint_object_list.push_back((M2MObject *)(list.at(i).ptr())); |
ansond | 0:1f1f55e73248 | 787 | } |
ansond | 0:1f1f55e73248 | 788 | } |
ansond | 0:1f1f55e73248 | 789 | |
ansond | 54:dfee8691c83a | 790 | // stop underlying observation mechanisms |
ansond | 54:dfee8691c83a | 791 | void Endpoint::stopObservations() { |
ansond | 54:dfee8691c83a | 792 | const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList(); |
ansond | 54:dfee8691c83a | 793 | for(int i=0; i<(int)dynamic_resources->size(); ++i) { |
ansond | 54:dfee8691c83a | 794 | if (dynamic_resources->at(i)->isObservable() == true) { |
ansond | 54:dfee8691c83a | 795 | ResourceObserver *observer = (ResourceObserver *)dynamic_resources->at(i)->getObserver(); |
ansond | 54:dfee8691c83a | 796 | if (observer != NULL) { |
ansond | 54:dfee8691c83a | 797 | this->logger()->log("Connector::Endpoint::stopObservations(): stopping resource observer for: [%s]...",dynamic_resources->at(i)->getFullName().c_str()); |
ansond | 54:dfee8691c83a | 798 | observer->halt(); |
ansond | 54:dfee8691c83a | 799 | } |
ansond | 54:dfee8691c83a | 800 | } |
ansond | 54:dfee8691c83a | 801 | } |
ansond | 54:dfee8691c83a | 802 | } |
ansond | 54:dfee8691c83a | 803 | |
ansond | 13:9edad7677211 | 804 | // underlying network is connected (SET) |
ansond | 13:9edad7677211 | 805 | void Endpoint::isConnected(bool connected) { |
ansond | 13:9edad7677211 | 806 | this->m_connected = connected; |
ansond | 13:9edad7677211 | 807 | } |
ansond | 13:9edad7677211 | 808 | |
ansond | 13:9edad7677211 | 809 | // underlying network is connected (GET) |
ansond | 13:9edad7677211 | 810 | bool Endpoint::isConnected() { |
ansond | 13:9edad7677211 | 811 | return this->m_connected; |
ansond | 13:9edad7677211 | 812 | } |
ansond | 13:9edad7677211 | 813 | |
ansond | 15:c11dbe4d354c | 814 | // Registered with mDC/mDS |
ansond | 15:c11dbe4d354c | 815 | bool Endpoint::isRegistered() { |
ansond | 15:c11dbe4d354c | 816 | return this->m_registered; |
ansond | 15:c11dbe4d354c | 817 | } |
ansond | 15:c11dbe4d354c | 818 | |
ansond | 43:3fb57c4fba34 | 819 | // Set the ConnectionStatusInterface |
ansond | 27:b8aaf7dc7023 | 820 | void Endpoint::setConnectionStatusInterfaceImpl(ConnectionStatusInterface *csi) { |
ansond | 43:3fb57c4fba34 | 821 | this->m_csi = csi; |
ansond | 27:b8aaf7dc7023 | 822 | } |
ansond | 27:b8aaf7dc7023 | 823 | |
ansond | 27:b8aaf7dc7023 | 824 | // Set our ObjectInstanceManager |
ansond | 27:b8aaf7dc7023 | 825 | void Endpoint::setObjectInstanceManager(ObjectInstanceManager *oim) { |
ansond | 27:b8aaf7dc7023 | 826 | this->m_oim = oim; |
ansond | 27:b8aaf7dc7023 | 827 | } |
ansond | 27:b8aaf7dc7023 | 828 | |
ansond | 27:b8aaf7dc7023 | 829 | // Get our ObjectInstanceManager |
ansond | 27:b8aaf7dc7023 | 830 | ObjectInstanceManager *Endpoint::getObjectInstanceManager() { |
ansond | 27:b8aaf7dc7023 | 831 | return this->m_oim; |
ansond | 27:b8aaf7dc7023 | 832 | } |
ansond | 27:b8aaf7dc7023 | 833 | |
ansond | 0:1f1f55e73248 | 834 | // our logger |
ansond | 0:1f1f55e73248 | 835 | Logger *Endpoint::logger() |
ansond | 0:1f1f55e73248 | 836 | { |
ansond | 0:1f1f55e73248 | 837 | return this->m_logger; |
ansond | 0:1f1f55e73248 | 838 | } |
ansond | 0:1f1f55e73248 | 839 | |
ansond | 0:1f1f55e73248 | 840 | } // namespace Connector |