mbed Connector Interface simplification API on top of mbed-client

Fork of mbedConnectorInterfaceV3 by Doug Anson

NOTE:

This repo has been replaced with https://github.com/ARMmbed/mbedConnectorInterface. No further updates will occur with this repo. Please use the github repo instead. Thanks!

Committer:
ansond
Date:
Sun Feb 21 15:44:34 2016 +0000
Revision:
2:1a7a292555d1
Parent:
1:16f0fb5b8d97
Child:
3:ce348020b691
updated

Who changed what in which revision?

UserRevisionLine numberNew 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 0:1f1f55e73248 32 // DEBUG
ansond 0:1f1f55e73248 33 #ifndef NDEBUG
ansond 0:1f1f55e73248 34 #define DEBUG_OUT(...) { printf(__VA_ARGS__); }
ansond 0:1f1f55e73248 35 #else
ansond 0:1f1f55e73248 36 #define DEBUG_OUT(...) /* nothing */
ansond 0:1f1f55e73248 37 #endif
ansond 0:1f1f55e73248 38
ansond 1:16f0fb5b8d97 39 // our endpoint instance
ansond 1:16f0fb5b8d97 40 static Connector::Endpoint *__endpoint = NULL;
ansond 0:1f1f55e73248 41
ansond 0:1f1f55e73248 42 // Connector namespace
ansond 0:1f1f55e73248 43 namespace Connector {
ansond 0:1f1f55e73248 44
ansond 0:1f1f55e73248 45 // STATIC: Plumb the network
ansond 0:1f1f55e73248 46 void Endpoint::plumbNetwork(bool canActAsRouterNode) {
ansond 1:16f0fb5b8d97 47 if (__endpoint == NULL) {
ansond 1:16f0fb5b8d97 48 // initialize our endpoint instance
ansond 1:16f0fb5b8d97 49 DEBUG_OUT("Endpoint::plumbNetwork: initializing endpoint instance...\r\n");
ansond 1:16f0fb5b8d97 50 __endpoint = (Connector::Endpoint *)utils_init_endpoint(canActAsRouterNode);
ansond 1:16f0fb5b8d97 51 }
ansond 1:16f0fb5b8d97 52
ansond 0:1f1f55e73248 53 // configure the endpoint now...
ansond 0:1f1f55e73248 54 DEBUG_OUT("Endpoint::plumbNetwork: configuring endpoint...\r\n");
ansond 1:16f0fb5b8d97 55 utils_configure_endpoint((void *)__endpoint);
ansond 2:1a7a292555d1 56
ansond 2:1a7a292555d1 57 // plumb network
ansond 2:1a7a292555d1 58 DEBUG_OUT("Endpoint::plumbNetwork: plumbing network...\r\n");
ansond 2:1a7a292555d1 59 net_stubs_plumb_network((void *)__endpoint);
ansond 0:1f1f55e73248 60 }
ansond 0:1f1f55e73248 61
ansond 0:1f1f55e73248 62 // STATIC: Finalize the endpoint's configuration and begin the endpoint's main even loop (static, not tied into Logger)
ansond 1:16f0fb5b8d97 63 void Endpoint::start() {
ansond 1:16f0fb5b8d97 64 // complete our registration setup...
ansond 1:16f0fb5b8d97 65 DEBUG_OUT("Endpoint::start: registering endpoint with Connector...\r\n");
ansond 1:16f0fb5b8d97 66 utils_register_endpoint((void *)__endpoint);
ansond 0:1f1f55e73248 67
ansond 1:16f0fb5b8d97 68 // Initialize our main loop...
ansond 1:16f0fb5b8d97 69 DEBUG_OUT("Endpoint::start: initializing main loop for endpoint...\r\n");
ansond 1:16f0fb5b8d97 70 net_stubs_create_main_loop(__endpoint);
ansond 0:1f1f55e73248 71
ansond 0:1f1f55e73248 72 // Begin the main loop
ansond 0:1f1f55e73248 73 DEBUG_OUT("Endpoint::start: entering main loop in endpoint...\r\n");
ansond 1:16f0fb5b8d97 74 net_stubs_begin_main_loop(__endpoint);
ansond 0:1f1f55e73248 75 }
ansond 0:1f1f55e73248 76
ansond 0:1f1f55e73248 77 // Constructor
ansond 0:1f1f55e73248 78 Endpoint::Endpoint(const Logger *logger, const Options *options) : M2MInterfaceObserver()
ansond 0:1f1f55e73248 79 {
ansond 0:1f1f55e73248 80 this->m_logger = (Logger *)logger;
ansond 0:1f1f55e73248 81 this->m_options = (Options *)options;
ansond 0:1f1f55e73248 82 }
ansond 0:1f1f55e73248 83
ansond 0:1f1f55e73248 84 // Copy Constructor
ansond 0:1f1f55e73248 85 Endpoint::Endpoint(const Endpoint &ep)
ansond 0:1f1f55e73248 86 {
ansond 0:1f1f55e73248 87 this->m_logger = ep.m_logger;
ansond 0:1f1f55e73248 88 this->m_options = ep.m_options;
ansond 0:1f1f55e73248 89 this->m_interface = ep.m_interface;
ansond 0:1f1f55e73248 90 this->m_server_instance = ep.m_server_instance;
ansond 0:1f1f55e73248 91 this->m_object_list = ep.m_object_list;
ansond 0:1f1f55e73248 92 this->m_device_object = ep.m_device_object;
ansond 0:1f1f55e73248 93 }
ansond 0:1f1f55e73248 94
ansond 0:1f1f55e73248 95 // Destructor
ansond 0:1f1f55e73248 96 Endpoint::~Endpoint() {
ansond 0:1f1f55e73248 97 if (this->m_interface != NULL)
ansond 0:1f1f55e73248 98 delete this->m_interface;
ansond 0:1f1f55e73248 99 if (this->m_server_instance != NULL)
ansond 0:1f1f55e73248 100 delete this->m_server_instance;
ansond 0:1f1f55e73248 101 }
ansond 0:1f1f55e73248 102
ansond 1:16f0fb5b8d97 103 // router node behavior setting
ansond 1:16f0fb5b8d97 104 void Endpoint::asRouterNode(bool canActAsRouterNode) {
ansond 1:16f0fb5b8d97 105 this->m_canActAsRouterNode = canActAsRouterNode;
ansond 1:16f0fb5b8d97 106 }
ansond 1:16f0fb5b8d97 107
ansond 1:16f0fb5b8d97 108 // set our Options
ansond 1:16f0fb5b8d97 109 void Endpoint::setOptions(Options *options) {
ansond 1:16f0fb5b8d97 110 this->m_options = options;
ansond 1:16f0fb5b8d97 111 }
ansond 1:16f0fb5b8d97 112
ansond 0:1f1f55e73248 113 // get our Options
ansond 0:1f1f55e73248 114 Options *Endpoint::getOptions() {
ansond 0:1f1f55e73248 115 return this->m_options;
ansond 0:1f1f55e73248 116 }
ansond 0:1f1f55e73248 117
ansond 0:1f1f55e73248 118 // get our Server
ansond 0:1f1f55e73248 119 M2MSecurity *Endpoint::getServer() {
ansond 0:1f1f55e73248 120 return this->m_server_instance;
ansond 0:1f1f55e73248 121 }
ansond 0:1f1f55e73248 122
ansond 0:1f1f55e73248 123 // get our ObjectList
ansond 0:1f1f55e73248 124 M2MObjectList Endpoint::getObjectList() {
ansond 0:1f1f55e73248 125 return this->m_object_list;
ansond 0:1f1f55e73248 126 }
ansond 0:1f1f55e73248 127
ansond 0:1f1f55e73248 128 // mbed-client: create our interface
ansond 0:1f1f55e73248 129 void Endpoint::create_interface() {
ansond 0:1f1f55e73248 130 // Randomizing listening port for Certificate mode connectivity
ansond 0:1f1f55e73248 131 srand(time(NULL));
ansond 0:1f1f55e73248 132 uint16_t port = rand() % 65535 + 12345;
ansond 0:1f1f55e73248 133 this->m_interface = M2MInterfaceFactory::create_interface(*this,
ansond 0:1f1f55e73248 134 (char *)this->m_options->getEndpointNodename().c_str(),
ansond 0:1f1f55e73248 135 (char *)this->m_options->getEndpointType().c_str(),
ansond 0:1f1f55e73248 136 (int32_t)this->m_options->getLifetime(),
ansond 0:1f1f55e73248 137 port,
ansond 0:1f1f55e73248 138 (char *)this->m_options->getDomain().c_str(),
ansond 0:1f1f55e73248 139 M2MInterface::UDP,
ansond 0:1f1f55e73248 140 M2MInterface::LwIP_IPv4);
ansond 0:1f1f55e73248 141 }
ansond 0:1f1f55e73248 142
ansond 0:1f1f55e73248 143 // mbed-client: create_server_instance()
ansond 0:1f1f55e73248 144 M2MSecurity *Endpoint::create_server_instance() {
ansond 0:1f1f55e73248 145 // Creates register server object with mbed device server address and other parameters
ansond 0:1f1f55e73248 146 M2MSecurity *server = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
ansond 0:1f1f55e73248 147 if (server != NULL) {
ansond 0:1f1f55e73248 148 const String url = this->m_options->getConnectorURL();
ansond 0:1f1f55e73248 149 server->set_resource_value(M2MSecurity::M2MServerUri, url);
ansond 0:1f1f55e73248 150 server->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate);
ansond 0:1f1f55e73248 151 server->set_resource_value(M2MSecurity::ServerPublicKey,this->m_options->getServerCertificate(),this->m_options->getServerCertificateSize());
ansond 0:1f1f55e73248 152 server->set_resource_value(M2MSecurity::PublicKey,this->m_options->getClientCertificate(),this->m_options->getClientCertificateSize());
ansond 0:1f1f55e73248 153 server->set_resource_value(M2MSecurity::Secretkey,this->m_options->getClientKey(),this->m_options->getClientKeySize());
ansond 0:1f1f55e73248 154 }
ansond 0:1f1f55e73248 155 return server;
ansond 0:1f1f55e73248 156 }
ansond 0:1f1f55e73248 157
ansond 0:1f1f55e73248 158 // mbed-client: Callback from mbed client stack if any error is encountered
ansond 0:1f1f55e73248 159 void Endpoint::error(M2MInterface::Error error) {
ansond 0:1f1f55e73248 160 switch(error){
ansond 0:1f1f55e73248 161 case M2MInterface::AlreadyExists:
ansond 0:1f1f55e73248 162 DEBUG_OUT("[ERROR:] M2MInterface::AlreadyExists");
ansond 0:1f1f55e73248 163 break;
ansond 0:1f1f55e73248 164 case M2MInterface::BootstrapFailed:
ansond 0:1f1f55e73248 165 DEBUG_OUT("[ERROR:] M2MInterface::BootstrapFailed");
ansond 0:1f1f55e73248 166 break;
ansond 0:1f1f55e73248 167 case M2MInterface::InvalidParameters:
ansond 0:1f1f55e73248 168 DEBUG_OUT("[ERROR:] M2MInterface::InvalidParameters");
ansond 0:1f1f55e73248 169 break;
ansond 0:1f1f55e73248 170 case M2MInterface::NotRegistered:
ansond 0:1f1f55e73248 171 DEBUG_OUT("[ERROR:] M2MInterface::NotRegistered");
ansond 0:1f1f55e73248 172 break;
ansond 0:1f1f55e73248 173 case M2MInterface::Timeout:
ansond 0:1f1f55e73248 174 DEBUG_OUT("[ERROR:] M2MInterface::Timeout");
ansond 0:1f1f55e73248 175 break;
ansond 0:1f1f55e73248 176 case M2MInterface::NetworkError:
ansond 0:1f1f55e73248 177 DEBUG_OUT("[ERROR:] M2MInterface::NetworkError");
ansond 0:1f1f55e73248 178 break;
ansond 0:1f1f55e73248 179 case M2MInterface::ResponseParseFailed:
ansond 0:1f1f55e73248 180 DEBUG_OUT("[ERROR:] M2MInterface::ResponseParseFailed");
ansond 0:1f1f55e73248 181 break;
ansond 0:1f1f55e73248 182 case M2MInterface::UnknownError:
ansond 0:1f1f55e73248 183 DEBUG_OUT("[ERROR:] M2MInterface::UnknownError");
ansond 0:1f1f55e73248 184 break;
ansond 0:1f1f55e73248 185 case M2MInterface::MemoryFail:
ansond 0:1f1f55e73248 186 DEBUG_OUT("[ERROR:] M2MInterface::MemoryFail");
ansond 0:1f1f55e73248 187 break;
ansond 0:1f1f55e73248 188 case M2MInterface::NotAllowed:
ansond 0:1f1f55e73248 189 DEBUG_OUT("[ERROR:] M2MInterface::NotAllowed");
ansond 0:1f1f55e73248 190 break;
ansond 0:1f1f55e73248 191 default:
ansond 0:1f1f55e73248 192 break;
ansond 0:1f1f55e73248 193 }
ansond 0:1f1f55e73248 194 }
ansond 0:1f1f55e73248 195
ansond 0:1f1f55e73248 196 // complete registration of the endpoint
ansond 0:1f1f55e73248 197 void Endpoint::complete_endpoint_registration(M2MSecurity *register_object, M2MObjectList object_list) {
ansond 0:1f1f55e73248 198 if (this->m_interface != NULL) {
ansond 0:1f1f55e73248 199 this->m_interface->register_object(register_object, object_list);
ansond 0:1f1f55e73248 200 }
ansond 0:1f1f55e73248 201 }
ansond 0:1f1f55e73248 202
ansond 0:1f1f55e73248 203 // deregister endpoint and stop scheduling
ansond 0:1f1f55e73248 204 void Endpoint::closedown_endpoint(void) {
ansond 0:1f1f55e73248 205 if (this->m_interface != NULL) {
ansond 0:1f1f55e73248 206 // de-register endpoint
ansond 0:1f1f55e73248 207 this->logger()->log("De-registering endpoint...");
ansond 0:1f1f55e73248 208 this->m_interface->unregister_object(NULL);
ansond 0:1f1f55e73248 209 }
ansond 0:1f1f55e73248 210 }
ansond 0:1f1f55e73248 211
ansond 0:1f1f55e73248 212 // re-register the endpoint
ansond 0:1f1f55e73248 213 void Endpoint::re_register_endpoint() {
ansond 0:1f1f55e73248 214 if (this->m_interface != NULL) {
ansond 0:1f1f55e73248 215 this->m_interface->update_registration(this->m_server_instance, this->m_options->getLifetime());
ansond 0:1f1f55e73248 216 }
ansond 0:1f1f55e73248 217 }
ansond 0:1f1f55e73248 218
ansond 0:1f1f55e73248 219 // bootstrap done
ansond 0:1f1f55e73248 220 void Endpoint::bootstrap_done(M2MSecurity * /*server_object */) {
ansond 0:1f1f55e73248 221 this->logger()->log("Bootstrapped");
ansond 0:1f1f55e73248 222 }
ansond 0:1f1f55e73248 223
ansond 0:1f1f55e73248 224 // object registered
ansond 0:1f1f55e73248 225 void Endpoint::object_registered(M2MSecurity */*security_object */, const M2MServer &/*server_object*/) {
ansond 0:1f1f55e73248 226 this->logger()->log("Registered");
ansond 0:1f1f55e73248 227 }
ansond 0:1f1f55e73248 228
ansond 0:1f1f55e73248 229 // object unregistered
ansond 0:1f1f55e73248 230 void Endpoint::object_unregistered(M2MSecurity */*server_object*/) {
ansond 0:1f1f55e73248 231 // ready to exit
ansond 0:1f1f55e73248 232 this->logger()->log("Endpoint has been deregistered.. Ready to exit...");
ansond 0:1f1f55e73248 233
ansond 0:1f1f55e73248 234 // stop
ansond 0:1f1f55e73248 235 //minar::Scheduler::stop();
ansond 0:1f1f55e73248 236 }
ansond 0:1f1f55e73248 237
ansond 0:1f1f55e73248 238 // registration updated
ansond 0:1f1f55e73248 239 void Endpoint::registration_updated(M2MSecurity */*security_object*/, const M2MServer &/*server_object*/) {
ansond 0:1f1f55e73248 240 this->logger()->log("Registration Updated");
ansond 0:1f1f55e73248 241 }
ansond 0:1f1f55e73248 242
ansond 0:1f1f55e73248 243 // resource value updated
ansond 0:1f1f55e73248 244 void Endpoint::value_updated(M2MBase *base, M2MBase::BaseType type) {
ansond 0:1f1f55e73248 245 this->logger()->log("Value Updated");
ansond 0:1f1f55e73248 246 DynamicResource *target_res = this->lookupDynamicResource(base);
ansond 0:1f1f55e73248 247 target_res->process(base->operation(),type);
ansond 0:1f1f55e73248 248 }
ansond 0:1f1f55e73248 249
ansond 0:1f1f55e73248 250 // lookup which DynamicResource cooresponds to a given M2MBase instance...
ansond 0:1f1f55e73248 251 DynamicResource *Endpoint::lookupDynamicResource(M2MBase *base) {
ansond 0:1f1f55e73248 252 DynamicResource *res = NULL;
ansond 0:1f1f55e73248 253 bool found = false;
ansond 0:1f1f55e73248 254 const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
ansond 0:1f1f55e73248 255 for(int i=0; i<(int)dynamic_resources->size() && found == false; ++i) {
ansond 0:1f1f55e73248 256 M2MBase *t = dynamic_resources->at(i)->getResource();
ansond 0:1f1f55e73248 257 if (t == base) {
ansond 0:1f1f55e73248 258 res = dynamic_resources->at(i);
ansond 0:1f1f55e73248 259 found = true;
ansond 0:1f1f55e73248 260 }
ansond 0:1f1f55e73248 261 }
ansond 0:1f1f55e73248 262
ansond 0:1f1f55e73248 263 return res;
ansond 0:1f1f55e73248 264 }
ansond 0:1f1f55e73248 265
ansond 0:1f1f55e73248 266 // register the endpoint
ansond 0:1f1f55e73248 267 void Endpoint::register_endpoint()
ansond 0:1f1f55e73248 268 {
ansond 0:1f1f55e73248 269 // initialize as an mbed-client
ansond 0:1f1f55e73248 270 this->create_interface();
ansond 0:1f1f55e73248 271
ansond 0:1f1f55e73248 272 // Create our server instance
ansond 0:1f1f55e73248 273 this->m_server_instance = this->create_server_instance();
ansond 0:1f1f55e73248 274
ansond 0:1f1f55e73248 275 // Loop through Static Resources and bind each of them...
ansond 0:1f1f55e73248 276 this->logger()->log("Endpoint::initialize(): adding device resources...");
ansond 0:1f1f55e73248 277 const DeviceResourcesList *device_resources = this->m_options->getDeviceResourceList();
ansond 0:1f1f55e73248 278 for(int i=0; i<(int)device_resources->size(); ++i) {
ansond 0:1f1f55e73248 279 this->logger()->log("Endpoint::initialize(): binding device resource: [%s]...",device_resources->at(i)->getFullName().c_str());
ansond 0:1f1f55e73248 280 this->m_object_list.push_back(device_resources->at(i)->bind(this));
ansond 0:1f1f55e73248 281 }
ansond 0:1f1f55e73248 282
ansond 0:1f1f55e73248 283 // Loop through Static Resources and bind each of them...
ansond 0:1f1f55e73248 284 this->logger()->log("Endpoint::initialize(): adding static resources...");
ansond 0:1f1f55e73248 285 const StaticResourcesList *static_resources = this->m_options->getStaticResourceList();
ansond 0:1f1f55e73248 286 for(int i=0; i<(int)static_resources->size(); ++i) {
ansond 0:1f1f55e73248 287 this->logger()->log("Endpoint::initialize(): binding static resource: [%s]...",static_resources->at(i)->getFullName().c_str());
ansond 0:1f1f55e73248 288 this->m_object_list.push_back(static_resources->at(i)->bind(this));
ansond 0:1f1f55e73248 289 }
ansond 0:1f1f55e73248 290
ansond 0:1f1f55e73248 291 // Loop through Dynamic Resources and bind each of them...
ansond 0:1f1f55e73248 292 this->logger()->log("Endpoint::initialize(): adding dynamic resources...");
ansond 0:1f1f55e73248 293 const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
ansond 0:1f1f55e73248 294 for(int i=0; i<(int)dynamic_resources->size(); ++i) {
ansond 0:1f1f55e73248 295 this->logger()->log("Endpoint::initialize(): binding dynamic resource: [%s]...",dynamic_resources->at(i)->getFullName().c_str());
ansond 0:1f1f55e73248 296 this->m_object_list.push_back(dynamic_resources->at(i)->bind(this));
ansond 0:1f1f55e73248 297 }
ansond 0:1f1f55e73248 298 }
ansond 0:1f1f55e73248 299
ansond 0:1f1f55e73248 300 // our logger
ansond 0:1f1f55e73248 301 Logger *Endpoint::logger()
ansond 0:1f1f55e73248 302 {
ansond 0:1f1f55e73248 303 return this->m_logger;
ansond 0:1f1f55e73248 304 }
ansond 0:1f1f55e73248 305
ansond 0:1f1f55e73248 306 } // namespace Connector
ansond 0:1f1f55e73248 307