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.
ConnectorEndpoint.cpp
00001 /** 00002 * @file ConnectorEndpoint.cpp 00003 * @brief mbed CoAP Endpoint base class 00004 * @author Doug Anson/Chris Paola 00005 * @version 1.0 00006 * @see 00007 * 00008 * Copyright (c) 2014 00009 * 00010 * Licensed under the Apache License, Version 2.0 (the "License"); 00011 * you may not use this file except in compliance with the License. 00012 * You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, software 00017 * distributed under the License is distributed on an "AS IS" BASIS, 00018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 * See the License for the specific language governing permissions and 00020 * limitations under the License. 00021 */ 00022 00023 // Lower level Network 00024 #include "mbed-connector-interface/mbedEndpointNetwork.h" 00025 00026 // ConnectorEndpoint 00027 #include "mbed-connector-interface/ConnectorEndpoint.h" 00028 00029 // Utils support 00030 #include "mbed-connector-interface/Utils.h" 00031 00032 // DEBUG 00033 #ifndef NDEBUG 00034 #define DEBUG_OUT(...) { printf(__VA_ARGS__); } 00035 #else 00036 #define DEBUG_OUT(...) /* nothing */ 00037 #endif 00038 00039 // our endpoint instance 00040 static Connector::Endpoint *__endpoint = NULL; 00041 00042 // Connector namespace 00043 namespace Connector { 00044 00045 // STATIC: Plumb the network 00046 void Endpoint::plumbNetwork(void *device_manager,bool canActAsRouterNode) { 00047 if (__endpoint == NULL) { 00048 // initialize our endpoint instance 00049 DEBUG_OUT("Endpoint::plumbNetwork: initializing endpoint instance...\r\n"); 00050 __endpoint = (Connector::Endpoint *)utils_init_endpoint(canActAsRouterNode); 00051 } 00052 00053 // set the device manager 00054 if (device_manager != NULL) { 00055 // device manager has been supplied 00056 DEBUG_OUT("Endpoint::plumbNetwork: setting a device manager...\r\n"); 00057 __endpoint->setDeviceManager(device_manager); 00058 } 00059 else { 00060 // no device manager supplied 00061 DEBUG_OUT("Endpoint::plumbNetwork: no device manager supplied (OK)\r\n"); 00062 } 00063 00064 // configure the endpoint now... 00065 DEBUG_OUT("Endpoint::plumbNetwork: configuring endpoint...\r\n"); 00066 utils_configure_endpoint((void *)__endpoint); 00067 00068 // plumb network 00069 DEBUG_OUT("Endpoint::plumbNetwork: plumbing network...\r\n"); 00070 net_plumb_network((void *)__endpoint); 00071 } 00072 00073 // STATIC: Finalize the endpoint's configuration and begin the endpoint's main even loop (static, not tied into Logger) 00074 void Endpoint::start() 00075 { 00076 // complete setup of our endpoint... 00077 DEBUG_OUT("Endpoint::start: building out endpoint...\r\n"); 00078 utils_build_endpoint((void *)__endpoint); 00079 00080 // register the endpoint 00081 DEBUG_OUT("Endpoint::start: completing endpoint build out..\r\n"); 00082 net_perform_endpoint_registration(__endpoint); 00083 } 00084 00085 // Constructor 00086 Endpoint::Endpoint(const Logger *logger, const Options *options) : M2MInterfaceObserver() 00087 { 00088 this->m_logger = (Logger *)logger; 00089 this->m_options = (Options *)options; 00090 this->m_device_manager = NULL; 00091 this->m_connected = false; 00092 this->m_registered = false; 00093 } 00094 00095 // Copy Constructor 00096 Endpoint::Endpoint(const Endpoint &ep) 00097 { 00098 this->m_logger = ep.m_logger; 00099 this->m_options = ep.m_options; 00100 this->m_interface = ep.m_interface; 00101 this->m_server_instance = ep.m_server_instance; 00102 this->m_object_list = ep.m_object_list; 00103 this->m_device_object = ep.m_device_object; 00104 this->m_device_manager = ep.m_device_manager; 00105 this->m_connected = ep.m_connected; 00106 this->m_registered = ep.m_registered; 00107 } 00108 00109 // Destructor 00110 Endpoint::~Endpoint() { 00111 if (this->m_interface != NULL) 00112 delete this->m_interface; 00113 if (this->m_server_instance != NULL) 00114 delete this->m_server_instance; 00115 } 00116 00117 // set the device manager 00118 void Endpoint::setDeviceManager(void *device_manager) { 00119 this->m_device_manager = device_manager; 00120 } 00121 00122 // get the device manager 00123 void *Endpoint::getDeviceManager(void) { 00124 return this->m_device_manager; 00125 } 00126 00127 // router node behavior setting 00128 void Endpoint::asRouterNode(bool canActAsRouterNode) { 00129 this->m_canActAsRouterNode = canActAsRouterNode; 00130 } 00131 00132 // set our Options 00133 void Endpoint::setOptions(Options *options) { 00134 this->m_options = options; 00135 } 00136 00137 // get our Options 00138 Options *Endpoint::getOptions() { 00139 return this->m_options; 00140 } 00141 00142 // get our Server 00143 M2MSecurity *Endpoint::getServer() { 00144 return this->m_server_instance; 00145 } 00146 00147 // get our ObjectList 00148 M2MObjectList Endpoint::getObjectList() { 00149 return this->m_object_list; 00150 } 00151 00152 // mbed-client: create our interface 00153 void Endpoint::create_interface() { 00154 // get the CoAP listening port 00155 uint16_t listening_port = (uint16_t)this->m_options->getConnectorPort(); 00156 00157 // randomize the port if we are using certificates... 00158 if (this->m_options->getServerCertificateSize() > 0) { 00159 // Randomizing listening port for Certificate mode connectivity 00160 srand(time(NULL)); 00161 listening_port = rand() % 65535 + 12345; 00162 } 00163 00164 // Binding Mode - TCP or UDP 00165 M2MInterface::BindingMode network_protocol = M2MInterface::UDP; 00166 if (this->m_options->getCoAPConnectionType() == COAP_TCP) network_protocol = M2MInterface::TCP; 00167 00168 // Network Type IPv4 or IPv6 00169 M2MInterface::NetworkStack ip_address_type = M2MInterface::LwIP_IPv4; 00170 if (this->m_options->getIPAddressType() == IP_ADDRESS_TYPE_IPV6) ip_address_type = M2MInterface::LwIP_IPv6; 00171 00172 // DEBUG 00173 if (network_protocol == M2MInterface::TCP) this->logger()->log("Endpoint: Underlying Protocol: TCP"); 00174 if (network_protocol == M2MInterface::UDP) this->logger()->log("Endpoint: Underlying Protocol: UDP"); 00175 if (ip_address_type == M2MInterface::LwIP_IPv4) this->logger()->log("Endpoint: IP Address Type: IPv4"); 00176 if (ip_address_type == M2MInterface::LwIP_IPv6) this->logger()->log("Endpoint: IP Address Type: IPv6"); 00177 00178 // Create the M2M Interface instance 00179 this->m_interface = M2MInterfaceFactory::create_interface(*this, 00180 (char *)this->m_options->getEndpointNodename().c_str(), 00181 (char *)this->m_options->getEndpointType().c_str(), 00182 (int32_t)this->m_options->getLifetime(), 00183 listening_port, // listening port 00184 (char *)this->m_options->getDomain().c_str(), 00185 network_protocol, // CoAP over UDP or TCP... 00186 ip_address_type); // IPv4 addressing or IPv6 addressing 00187 } 00188 00189 // mbed-client: create_server_instance() 00190 M2MSecurity *Endpoint::create_server_instance() { 00191 // Creates register server object with mbed device server address and other parameters 00192 M2MSecurity *server = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer); 00193 if (server != NULL) { 00194 const String url = this->m_options->getConnectorURL(); 00195 server->set_resource_value(M2MSecurity::M2MServerUri, url); 00196 server->set_resource_value(M2MSecurity::BootstrapServer, NULL); 00197 server->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate); 00198 server->set_resource_value(M2MSecurity::ServerPublicKey,this->m_options->getServerCertificate(),this->m_options->getServerCertificateSize()); 00199 server->set_resource_value(M2MSecurity::PublicKey,this->m_options->getClientCertificate(),this->m_options->getClientCertificateSize()); 00200 server->set_resource_value(M2MSecurity::Secretkey,this->m_options->getClientKey(),this->m_options->getClientKeySize()); 00201 } 00202 return server; 00203 } 00204 00205 // mbed-client: Callback from mbed client stack if any error is encountered 00206 void Endpoint::error(M2MInterface::Error error) { 00207 switch(error){ 00208 case M2MInterface::AlreadyExists: 00209 DEBUG_OUT("[ERROR:] M2MInterface::AlreadyExists"); 00210 break; 00211 case M2MInterface::BootstrapFailed: 00212 DEBUG_OUT("[ERROR:] M2MInterface::BootstrapFailed"); 00213 break; 00214 case M2MInterface::InvalidParameters: 00215 DEBUG_OUT("[ERROR:] M2MInterface::InvalidParameters"); 00216 break; 00217 case M2MInterface::NotRegistered: 00218 DEBUG_OUT("[ERROR:] M2MInterface::NotRegistered"); 00219 break; 00220 case M2MInterface::Timeout: 00221 DEBUG_OUT("[ERROR:] M2MInterface::Timeout"); 00222 break; 00223 case M2MInterface::NetworkError: 00224 DEBUG_OUT("[ERROR:] M2MInterface::NetworkError"); 00225 break; 00226 case M2MInterface::ResponseParseFailed: 00227 DEBUG_OUT("[ERROR:] M2MInterface::ResponseParseFailed"); 00228 break; 00229 case M2MInterface::UnknownError: 00230 DEBUG_OUT("[ERROR:] M2MInterface::UnknownError"); 00231 break; 00232 case M2MInterface::MemoryFail: 00233 DEBUG_OUT("[ERROR:] M2MInterface::MemoryFail"); 00234 break; 00235 case M2MInterface::NotAllowed: 00236 DEBUG_OUT("[ERROR:] M2MInterface::NotAllowed"); 00237 break; 00238 default: 00239 break; 00240 } 00241 } 00242 00243 // register the endpoint 00244 void Endpoint::register_endpoint(M2MSecurity *server_instance, M2MObjectList resources) { 00245 if (this->m_interface != NULL && server_instance != NULL && resources.size() > 0) { 00246 // register endpoint 00247 this->logger()->log("Registering endpoint..."); 00248 this->m_interface->register_object(server_instance, resources); 00249 } 00250 } 00251 00252 // re-register the endpoint 00253 void Endpoint::re_register_endpoint() { 00254 if (this->m_interface != NULL) { 00255 this->m_interface->update_registration(this->m_server_instance, this->m_options->getLifetime()); 00256 } 00257 } 00258 00259 // de-register endpoint 00260 void Endpoint::de_register_endpoint(void) { 00261 if (this->m_interface != NULL) { 00262 // de-register endpoint 00263 this->logger()->log("De-registering endpoint..."); 00264 this->m_interface->unregister_object(NULL); 00265 } 00266 } 00267 00268 // object registered 00269 void Endpoint::object_registered(M2MSecurity */*security_object */, const M2MServer &/*server_object*/) { 00270 this->logger()->log("Endpoint registered"); 00271 this->m_connected = true; 00272 this->m_registered = true; 00273 } 00274 00275 // registration updated 00276 void Endpoint::registration_updated(M2MSecurity */*security_object*/, const M2MServer &/*server_object*/) { 00277 this->logger()->log("Endpoint re-registered."); 00278 this->m_connected = true; 00279 this->m_registered = true; 00280 } 00281 00282 // object unregistered 00283 void Endpoint::object_unregistered(M2MSecurity */*server_object*/) { 00284 // ready to exit 00285 this->logger()->log("Endpoint de-registered... Ready to exit..."); 00286 this->m_registered = false; 00287 } 00288 00289 // bootstrap done 00290 void Endpoint::bootstrap_done(M2MSecurity * /*server_object */) { 00291 this->logger()->log("Bootstrapped"); 00292 } 00293 00294 // resource value updated 00295 void Endpoint::value_updated(M2MBase *base, M2MBase::BaseType type) { 00296 this->logger()->log("Value Updated"); 00297 DynamicResource *target_res = this->lookupDynamicResource(base); 00298 target_res->process(base->operation(),type); 00299 } 00300 00301 // lookup which DynamicResource cooresponds to a given M2MBase instance... 00302 DynamicResource *Endpoint::lookupDynamicResource(M2MBase *base) { 00303 DynamicResource *res = NULL; 00304 bool found = false; 00305 const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList(); 00306 for(int i=0; i<(int)dynamic_resources->size() && found == false; ++i) { 00307 M2MBase *t = dynamic_resources->at(i)->getResource(); 00308 if (t == base) { 00309 res = dynamic_resources->at(i); 00310 found = true; 00311 } 00312 } 00313 00314 return res; 00315 } 00316 00317 // build out the endpoint 00318 void Endpoint::build_endpoint() 00319 { 00320 // initialize as an mbed-client 00321 this->create_interface(); 00322 00323 // Create our server instance 00324 this->m_server_instance = this->create_server_instance(); 00325 00326 // Loop through Static Resources and bind each of them... 00327 this->logger()->log("Endpoint::build(): adding device resources..."); 00328 const DeviceResourcesList *device_resources = this->m_options->getDeviceResourceList(); 00329 for(int i=0; i<(int)device_resources->size(); ++i) { 00330 this->logger()->log("Endpoint::build(): binding device resource: [%s]...",device_resources->at(i)->getFullName().c_str()); 00331 this->m_object_list.push_back(device_resources->at(i)->bind(this)); 00332 } 00333 00334 // Loop through Static Resources and bind each of them... 00335 this->logger()->log("Endpoint::build(): adding static resources..."); 00336 const StaticResourcesList *static_resources = this->m_options->getStaticResourceList(); 00337 for(int i=0; i<(int)static_resources->size(); ++i) { 00338 this->logger()->log("Endpoint::build(): binding static resource: [%s]...",static_resources->at(i)->getFullName().c_str()); 00339 this->m_object_list.push_back(static_resources->at(i)->bind(this)); 00340 } 00341 00342 // Loop through Dynamic Resources and bind each of them... 00343 this->logger()->log("Endpoint::build(): adding dynamic resources..."); 00344 const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList(); 00345 for(int i=0; i<(int)dynamic_resources->size(); ++i) { 00346 this->logger()->log("Endpoint::build(): binding dynamic resource: [%s]...",dynamic_resources->at(i)->getFullName().c_str()); 00347 this->m_object_list.push_back(dynamic_resources->at(i)->bind(this)); 00348 } 00349 } 00350 00351 // underlying network is connected (SET) 00352 void Endpoint::isConnected(bool connected) { 00353 this->m_connected = connected; 00354 } 00355 00356 // underlying network is connected (GET) 00357 bool Endpoint::isConnected() { 00358 return this->m_connected; 00359 } 00360 00361 // Registered with mDC/mDS 00362 bool Endpoint::isRegistered() { 00363 return this->m_registered; 00364 } 00365 00366 // our logger 00367 Logger *Endpoint::logger() 00368 { 00369 return this->m_logger; 00370 } 00371 00372 } // namespace Connector
Generated on Wed Jul 13 2022 21:59:32 by
1.7.2