Doug Anson / mbedConnectorInterfaceWithDM

Fork of mbedConnectorInterfaceV3 by Doug Anson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ConnectorEndpoint.cpp Source File

ConnectorEndpoint.cpp

Go to the documentation of this file.
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 // Device Manager support
00033 #include "mbed-connector-interface/DeviceManager.h"
00034 
00035 // factory storage and configurator support (mbed Cloud R1.2+)
00036 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00037 // trace configuration
00038 #include "mbed-trace/mbed_trace.h"
00039 
00040 // updater support
00041 #include "update_ui_example.h"
00042 
00043 // factory flow support
00044 #include "factory_configurator_client.h"
00045 #endif
00046 
00047 // our endpoint instance
00048 static Connector::Endpoint *__endpoint = NULL;
00049 
00050 // LWIP Network interface instance
00051 NetworkInterface *__network_interface = NULL;
00052 
00053 // Connector namespace
00054 namespace Connector {
00055 
00056 // STATIC: Plumb the network
00057 void Endpoint::plumbNetwork(void *device_manager,bool canActAsRouterNode) {
00058     // create our endpoint instance...
00059     if (__endpoint == NULL) {
00060         // initialize our endpoint instance
00061         printf("Connector::Endpoint::plumbNetwork: initializing endpoint instance...\r\n");
00062         __endpoint = (Connector::Endpoint *)utils_init_endpoint(canActAsRouterNode);
00063     }
00064     
00065     // make sure we have an endpoint...
00066     if (__endpoint != NULL) {
00067         // set the device manager
00068         if (device_manager != NULL) {
00069             // device manager has been supplied
00070             printf("Connector::Endpoint::plumbNetwork: setting a device manager...\r\n");
00071             __endpoint->setDeviceManager(device_manager);
00072         }
00073     
00074         // configure the endpoint...
00075         printf("Connector::Endpoint::plumbNetwork: configuring endpoint...\r\n");
00076         utils_configure_endpoint((void *)__endpoint);
00077         
00078         // plumb the endpoint's network...
00079         printf("Connector::Endpoint::plumbNetwork: plumbing network...\r\n");
00080         net_plumb_network((void *)__endpoint);
00081     }
00082 }
00083 
00084 // STATIC: Finalize the endpoint's configuration and begin the endpoint's main even loop (static, not tied into Logger)
00085 void Endpoint::start()
00086 {
00087     if (__endpoint != NULL) {
00088         // build out the endpoint with its configuration...
00089         printf("Connector::Endpoint::start: building out endpoint...\r\n");
00090         utils_build_endpoint((void *)__endpoint);
00091         
00092         // make sure we have an endpoint interface before continuing... 
00093         if (__endpoint != NULL && __endpoint->getEndpointInterface() != NULL) {
00094             // finalize the endpoint and start its main loop
00095             printf("Endpoint::start: finalize and run the endpoint main loop..\r\n");
00096             net_finalize_and_run_endpoint_main_loop((void *)__endpoint);
00097         }
00098         else {
00099             // not starting the endpoint due to errors
00100             printf("Connector::Endpoint::start: Not starting endpoint due to errors (no endpoint interface)... exiting...\r\n");
00101             
00102             // end in error... 
00103             while(true) {
00104                 Thread::wait(1000);
00105             }
00106         }
00107     }
00108     else {
00109         // not starting the endpoint due to errors
00110         printf("Connector::Endpoint::start: Not starting endpoint due to errors (no endpoint)... exiting...\r\n");
00111         
00112         // end in error... 
00113         while(true) {
00114             Thread::wait(1000);
00115         }
00116     }
00117 }
00118 
00119 // STATIC: Set the ConnectionStatusInterface Implementation instance
00120 void Endpoint::setConnectionStatusInterface(ConnectionStatusInterface *csi) {
00121     if (__endpoint != NULL) {
00122         __endpoint->setConnectionStatusInterfaceImpl(csi);
00123     }
00124 }
00125 
00126 // Constructor
00127 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00128 Endpoint::Endpoint(const Logger *logger, const Options *options)  : MbedCloudClientCallback(), M2MInterfaceObserver() 
00129 #else
00130 Endpoint::Endpoint(const Logger *logger, const Options *options)  : M2MInterfaceObserver() 
00131 #endif
00132 {
00133     this->m_logger = (Logger *)logger;
00134     this->m_options = (Options *)options;
00135     this->m_device_manager = NULL;
00136     this->m_connected = false;
00137     this->m_registered = false;
00138     this->m_csi = NULL;
00139     this->m_oim = NULL;
00140     this->m_endpoint_security = NULL;
00141     this->m_endpoint_interface = NULL;
00142 }
00143 
00144 // Copy Constructor
00145 Endpoint::Endpoint(const Endpoint &ep)
00146 {
00147     this->m_logger = ep.m_logger;
00148     this->m_options = ep.m_options;
00149     this->m_endpoint_interface = ep.m_endpoint_interface;
00150     this->m_endpoint_security = ep.m_endpoint_security;
00151     this->m_endpoint_object_list = ep.m_endpoint_object_list;
00152     this->m_device_manager = ep.m_device_manager;
00153     this->m_connected = ep.m_connected;
00154     this->m_registered = ep.m_registered;
00155     this->m_csi = ep.m_csi;
00156     this->m_oim = ep.m_oim;
00157 }
00158 
00159 // Destructor
00160 Endpoint::~Endpoint() {
00161 #ifndef ENABLE_MBED_CLOUD_SUPPORT
00162     if (this->m_endpoint_interface != NULL)
00163         delete this->m_endpoint_interface;
00164         
00165     if (this->m_endpoint_security != NULL)
00166         delete this->m_endpoint_security;
00167 #endif
00168 }
00169 
00170 // set the device manager
00171 void Endpoint::setDeviceManager(void *device_manager) {
00172     this->m_device_manager = device_manager;
00173 }
00174 
00175 // get the device manager
00176 void *Endpoint::getDeviceManager(void) {
00177     return this->m_device_manager;
00178 }
00179 
00180 // router node behavior setting
00181 void Endpoint::asRouterNode(bool canActAsRouterNode) {
00182     this->m_canActAsRouterNode = canActAsRouterNode;
00183 }
00184 
00185 // set our Options
00186 void Endpoint::setOptions(Options *options) {
00187     this->m_options = options;
00188 }
00189 
00190 // get our Options
00191 Options *Endpoint::getOptions() {
00192     return this->m_options;
00193 }
00194 
00195 // get our endpoint security instance
00196 M2MSecurity *Endpoint::getSecurityInstance() {
00197     return this->m_endpoint_security;
00198 }
00199 
00200 // set our endpoint security instance
00201 void Endpoint::setSecurityInstance(M2MSecurity *security) {
00202     if (security != NULL) {
00203         this->m_endpoint_security = security;
00204     }
00205 }
00206 
00207 // get our ObjectList
00208 M2MObjectList Endpoint::getEndpointObjectList() {
00209     return this->m_endpoint_object_list;
00210 }
00211 
00212 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00213 // get our endpoint interface
00214 MbedCloudClient *Endpoint::getEndpointInterface() {
00215     return this->m_endpoint_interface;
00216 }
00217 #else
00218 // get our endpoint interface
00219 M2MInterface *Endpoint::getEndpointInterface() {
00220     return this->m_endpoint_interface;
00221 }
00222 #endif
00223 
00224 // Connector::Endpoint: create our interface
00225 void Endpoint::createEndpointInterface() {
00226 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00227     this->createCloudEndpointInterface();
00228 #else
00229     this->createConnectorEndpointInterface();
00230 #endif
00231 }
00232 
00233 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00234 // mbedCloudClient: initialize Storage
00235 bool Endpoint::initializeStorage() {
00236 #ifdef MBED_CLOUD_STORAGE_INIT
00237     // initialize mbed-trace
00238     mbed_trace_init();
00239     
00240     // now initialize the FCC interface
00241     fcc_status_e status = fcc_init();
00242     if(status != FCC_STATUS_SUCCESS) {
00243         this->logger()->log("initializeStorage: ERROR: mfcc_init failed with status=%d...", status);
00244         return false;
00245     }
00246     #ifdef MBED_RESET_STORAGE
00247     // Resets storage to an empty state.
00248     // Use this function when you want to clear SD card from all the factory-tool generated data and user data.
00249     // After this operation device must be injected again by using factory tool or developer certificate.
00250     this->logger()->log("initializeStorage: Resetting storage to an empty state...");
00251     fcc_status_e delete_status = fcc_storage_delete();
00252     if (delete_status != FCC_STATUS_SUCCESS) {
00253         this->logger()->log("initializeStorage: Failed to reset storage to an empty state. status=%d (OK)...", delete_status);
00254     }
00255     #endif
00256 #else
00257     // storage initialization not enabled
00258     this->logger()->log("initializeStorage: storage initialize disabled (OK)...");
00259 #endif
00260     return true;
00261 }
00262 
00263 // mbedCloudClient:: initialize factory flow
00264 bool Endpoint::initializeFactoryFlow() {
00265 #ifdef MBED_CLOUD_DEV_FLOW_INIT
00266 #ifdef MBED_CONF_APP_DEVELOPER_MODE
00267     this->logger()->log("initializeFactoryFlow: Start developer flow...");
00268     fcc_status_e status = fcc_developer_flow();
00269     if (status == FCC_STATUS_KCM_FILE_EXIST_ERROR) {
00270         this->logger()->log("initializeFactoryFlow: Developer credentials already exists (OK)...");
00271     } else if (status != FCC_STATUS_SUCCESS) {
00272         this->logger()->log("initializeFactoryFlow: ERROR: Failed to load developer credentials");
00273         return false;
00274     }
00275     status = fcc_verify_device_configured_4mbed_cloud();
00276     if (status != FCC_STATUS_SUCCESS) {
00277         this->logger()->log("initializeFactoryFlow: ERROR: Device not configured for mbed Cloud");
00278         return false;
00279     }
00280     return true;
00281 #else
00282     this->logger()->log("initializeFactoryFlow: non-developer factory flow chosen... continuing...");
00283     return true;
00284 #endif
00285 #else
00286     this->logger()->log("initializeFactoryFlow: developer flow init disabled (OK)...");
00287     return true;
00288 #endif
00289 }
00290 
00291 // mbedCloudClient: create our interface
00292 void Endpoint::createCloudEndpointInterface() {
00293     if (this->m_endpoint_interface == NULL) {
00294         bool storage_init = this->initializeStorage();
00295         bool factory_flow_init = this->initializeFactoryFlow();
00296         if (storage_init && factory_flow_init) {
00297             // create a new instance of mbedCloudClient
00298             this->logger()->log("createCloudEndpointInterface: creating mbed cloud client instance...");
00299             this->m_endpoint_interface = new MbedCloudClient();
00300             if (this->m_endpoint_interface == NULL) {
00301                 // unable to allocate the MbedCloudClient instance
00302                 this->logger()->log("createCloudEndpointInterface: ERROR: unable to allocate MbedCloudClient instance...");
00303             }
00304             else {
00305                 // enable hooks for Updater support (R1.2+) (if enabled)
00306 #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE     
00307                 // Establish the updater hook   
00308                 update_ui_set_cloud_client(this->m_endpoint_interface);
00309                 
00310                 // Update Authorize Handler (optional, disabled by default)
00311 #ifdef ENABLE_UPDATE_AUTHORIZE_HANDLER
00312                 this->m_endpoint_interface->set_update_authorize_handler(&Connector::Endpoint::update_authorize);
00313 #endif
00314                 
00315                 // Update Progress Handler (optional, disabled by default)
00316 #ifdef ENABLE_UPDATE_PROGRESS_HANDLER
00317                 this->m_endpoint_interface->set_update_progress_handler(&Connector::Endpoint::update_progress);
00318 #endif
00319 
00320 #endif
00321             }
00322         }
00323         else {
00324             if (storage_init) {
00325                 // unable to create mbed cloud client instance... (FAILED factory flow init)
00326                 this->logger()->log("createCloudEndpointInterface: ERROR: unable to initialize factory flow...");
00327             }
00328             else {
00329                 // unable to create mbed cloud client instance... (FAILED storage init)
00330                 this->logger()->log("createCloudEndpointInterface: ERROR: unable to initialize storage...");
00331             }
00332             this->m_endpoint_interface = NULL;
00333         }
00334     }
00335     
00336     // bind LWIP network interface pointer...                                          
00337     if (__network_interface != NULL && this->m_endpoint_interface != NULL) {
00338         this->logger()->log("Connector::Endpoint: binding LWIP network instance (Cloud)...");
00339         this->m_endpoint_interface->on_registered(&Connector::Endpoint::on_registered);
00340         this->m_endpoint_interface->on_unregistered(&Connector::Endpoint::on_unregistered);
00341         this->m_endpoint_interface->on_error(&Connector::Endpoint::on_error);
00342         this->m_endpoint_interface->set_update_callback(this);
00343     }
00344     else {
00345         // skipping LWIP bind...
00346         this->logger()->log("Connector::Endpoint: ERROR (Cloud) skipping LWIP network instance bind due to previous error...");
00347     }
00348 }
00349 #else
00350 // mbed-client: create our interface
00351 void Endpoint::createConnectorEndpointInterface() {
00352     // get the CoAP listening port
00353     uint16_t listening_port = (uint16_t)this->m_options->getConnectorPort();
00354     
00355     // randomize the port if we are using certificates...
00356     if (this->m_options->getServerCertificateSize() > 0) {
00357         // Randomizing listening port for Certificate mode connectivity
00358         srand(time(NULL));
00359         listening_port = rand() % 65535 + 12345;
00360     }
00361     
00362     // DEBUG
00363     //this->logger()->log("Connector::Endpoint: listening port: %d",listening_port);
00364     
00365     // Socket protocol type: TCP or UDP
00366     M2MInterface::BindingMode socket_protocol_type = M2MInterface::UDP;
00367     if (this->m_options->getCoAPConnectionType() == COAP_TCP)  socket_protocol_type = M2MInterface::TCP;
00368     
00369     // Socket address type: IPv4 or IPv6
00370     M2MInterface::NetworkStack socket_address_type = M2MInterface::LwIP_IPv4;
00371     if (this->m_options->getIPAddressType() == IP_ADDRESS_TYPE_IPV6) {
00372         // IPv6 mode for the socket addressing type... 
00373         socket_address_type = M2MInterface::LwIP_IPv6;
00374         
00375 #if defined (IPV4_OVERRIDE)
00376         // OVERRIDE (until patched...)
00377         this->logger()->log("Connector::Endpoint: Socket Address Type: IPv4 (IPv6 OVERRIDE)");
00378         socket_address_type = M2MInterface::LwIP_IPv4;
00379 #endif
00380     }
00381     
00382     // DEBUG
00383     if (socket_protocol_type == M2MInterface::TCP) this->logger()->log("Connector::Endpoint: Socket Protocol: TCP");
00384     if (socket_protocol_type == M2MInterface::UDP) this->logger()->log("Connector::Endpoint: Socket Protocol: UDP");
00385     if (socket_address_type == M2MInterface::LwIP_IPv4) this->logger()->log("Connector::Endpoint: Socket Address Type: IPv4");
00386     if (socket_address_type == M2MInterface::LwIP_IPv6) this->logger()->log("Connector::Endpoint: Socket Address Type: IPv6");
00387     
00388     // Create the endpoint M2MInterface instance
00389     this->m_endpoint_interface = M2MInterfaceFactory::create_interface(*this,
00390                                               (char *)this->m_options->getEndpointNodename().c_str(),   // endpoint name
00391                                               (char *)this->m_options->getEndpointType().c_str(),       // endpoint type
00392                                               (int32_t)this->m_options->getLifetime(),                  // registration lifetime (in seconds)
00393                                               listening_port,                                           // listening port (ephemeral...)
00394                                               (char *)this->m_options->getDomain().c_str(),             // endpoint domain
00395                                               socket_protocol_type,                                     // Socket protocol type: UDP or TCP...
00396                                               socket_address_type,                                      // Socket addressing type: IPv4 or IPv6 
00397                                               CONTEXT_ADDRESS_STRING                                    // context address string (mbedConnectorInterface.h)
00398                                               );                                    
00399     
00400     // bind LWIP network interface pointer...                                          
00401     if (__network_interface != NULL && this->m_endpoint_interface != NULL) {
00402         this->logger()->log("Connector::Endpoint: binding LWIP network instance (Connector)...");
00403         this->m_endpoint_interface->set_platform_network_handler((void *)__network_interface);
00404     }
00405 }
00406 #endif
00407 
00408 // mbed-client: createEndpointSecurityInstance()
00409 M2MSecurity *Endpoint::createEndpointSecurityInstance()  {
00410 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00411         // internalized... not used.
00412         return NULL;
00413 #else
00414         // Creates register server object with mbed device server address and other parameters
00415         M2MSecurity *server = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
00416         if (server != NULL)  {
00417             const String url = this->m_options->getConnectorURL();
00418             server->set_resource_value(M2MSecurity::M2MServerUri, url);
00419             server->set_resource_value(M2MSecurity::BootstrapServer, false);
00420             server->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate);
00421             server->set_resource_value(M2MSecurity::ServerPublicKey,this->m_options->getServerCertificate(),this->m_options->getServerCertificateSize());
00422             server->set_resource_value(M2MSecurity::PublicKey,this->m_options->getClientCertificate(),this->m_options->getClientCertificateSize());
00423             server->set_resource_value(M2MSecurity::Secretkey,this->m_options->getClientKey(),this->m_options->getClientKeySize());
00424         }
00425         return server;
00426 #endif
00427 }
00428 
00429 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00430 // mbed-cloud-client: Callback from mbed client stack if any error is encountered
00431 void Endpoint::on_error(int error_code) {
00432     char *error = (char *)"No Error";
00433     switch(error_code) {
00434         case MbedCloudClient::ConnectErrorNone:
00435             error = (char *)"MbedCloudClient::ConnectErrorNone";
00436             break;
00437         case MbedCloudClient::ConnectAlreadyExists:
00438             error = (char *)"MbedCloudClient::ConnectAlreadyExists";
00439             break;
00440         case MbedCloudClient::ConnectBootstrapFailed:
00441             error = (char *)"MbedCloudClient::ConnectBootstrapFailed";
00442             break;
00443         case MbedCloudClient::ConnectInvalidParameters:
00444             error = (char *)"MbedCloudClient::ConnectInvalidParameters";
00445             break;
00446         case MbedCloudClient::ConnectNotRegistered:
00447             error = (char *)"MbedCloudClient::ConnectNotRegistered";
00448             break;
00449         case MbedCloudClient::ConnectTimeout:
00450             error = (char *)"MbedCloudClient::ConnectTimeout";
00451             break;
00452         case MbedCloudClient::ConnectNetworkError:
00453             error = (char *)"MbedCloudClient::ConnectNetworkError";
00454             break;
00455         case MbedCloudClient::ConnectResponseParseFailed:
00456             error = (char *)"MbedCloudClient::ConnectResponseParseFailed";
00457             break;
00458         case MbedCloudClient::ConnectUnknownError:
00459             error = (char *)"MbedCloudClient::ConnectUnknownError";
00460             break;
00461         case MbedCloudClient::ConnectMemoryConnectFail:
00462             error = (char *)"MbedCloudClient::ConnectMemoryConnectFail";
00463             break;
00464         case MbedCloudClient::ConnectNotAllowed:
00465             error = (char *)"MbedCloudClient::ConnectNotAllowed";
00466             break;
00467         case MbedCloudClient::ConnectSecureConnectionFailed:
00468             error = (char *)"MbedCloudClient::ConnectSecureConnectionFailed";
00469             break;
00470         case MbedCloudClient::ConnectDnsResolvingFailed:
00471             error = (char *)"MbedCloudClient::ConnectDnsResolvingFailed";
00472             break;
00473 #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE
00474         case UpdateClient::WarningCertificateNotFound:
00475             error = (char *)"MbedCloudClient(Update): WarningCertificateNotFound";
00476             break;
00477         case UpdateClient::WarningIdentityNotFound:
00478             error = (char *)"MbedCloudClient(Update): WarningIdentityNotFound";
00479             break;
00480         case UpdateClient::WarningCertificateInvalid:
00481             error = (char *)"MbedCloudClient(Update): WarningCertificateInvalid";
00482             break;
00483         case UpdateClient::WarningSignatureInvalid:
00484             error = (char *)"MbedCloudClient(Update): WarningSignatureInvalid";
00485             break;
00486         case UpdateClient::WarningVendorMismatch:
00487             error = (char *)"MbedCloudClient(Update): WarningVendorMismatch";
00488             break;
00489         case UpdateClient::WarningClassMismatch:
00490             error = (char *)"MbedCloudClient(Update): WarningClassMismatch";
00491             break;
00492         case UpdateClient::WarningDeviceMismatch:
00493             error = (char *)"MbedCloudClient(Update): WarningDeviceMismatch";
00494             break;
00495         case UpdateClient::WarningURINotFound:
00496             error = (char *)"MbedCloudClient(Update): WarningURINotFound";
00497             break;
00498         case UpdateClient::WarningRollbackProtection:
00499             error = (char *)"MbedCloudClient(Update): WarningRollbackProtection. Manifest is older than currently running image.";
00500             break;
00501         case UpdateClient::WarningUnknown:
00502             error = (char *)"MbedCloudClient(Update): WarningUnknown";
00503             break;
00504         case UpdateClient::ErrorWriteToStorage:
00505             error = (char *)"MbedCloudClient(Update): ErrorWriteToStorage";
00506             break;
00507 #endif      
00508         default:
00509             error = (char *)"UNKNOWN";
00510     }
00511     printf("Connector::Endpoint(Cloud) Error(%x): %s\r\n",error_code,error);
00512 }
00513 
00514 // mbed-cloud-client: update_authorized
00515 void Endpoint::update_authorize(int32_t request) {
00516     // simple debug for now... this will NOT authorize the update request... 
00517     printf("Connector::Endpoint(Cloud) Update Authorize: request: %d\n",(int)request);
00518 }
00519     
00520 // mbed-cloud-client: update_progress
00521 void Endpoint::update_progress(uint32_t progress, uint32_t total) {
00522     // simple debug for now...
00523     printf("Connector::Endpoint(Cloud) Update Progress: (%d/%d)\n",(int)progress,(int)total);
00524 }
00525 #endif
00526 
00527 // mbed-client: Callback from mbed client stack if any error is encountered
00528 void Endpoint::error(M2MInterface::Error error) {
00529         switch(error){
00530             case M2MInterface::AlreadyExists:
00531                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::AlreadyExists");
00532                 break;
00533             case M2MInterface::BootstrapFailed:
00534                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::BootstrapFailed");
00535                 break;
00536             case M2MInterface::InvalidParameters:
00537                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::InvalidParameters");
00538                 break;
00539             case M2MInterface::NotRegistered:
00540                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::NotRegistered");
00541                 break;
00542             case M2MInterface::Timeout:
00543                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::Timeout");
00544                 break;
00545             case M2MInterface::NetworkError:
00546                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::NetworkError");
00547                 break;
00548             case M2MInterface::ResponseParseFailed:
00549                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::ResponseParseFailed");
00550                 break;
00551             case M2MInterface::UnknownError:
00552                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::UnknownError");
00553                 break;
00554             case M2MInterface::MemoryFail:
00555                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::MemoryFail");
00556                 break;
00557             case M2MInterface::NotAllowed:
00558                 this->logger()->log("Connector::Endpoint(ERROR): M2MInterface::NotAllowed");
00559                 break;
00560             default:
00561                 break;
00562         }
00563 }
00564 
00565 // re-register the endpoint
00566 void Endpoint::re_register_endpoint() {
00567     if (this->m_endpoint_interface != NULL)  {
00568 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00569         // DEBUG
00570         this->logger()->log("Connector::Endpoint(Cloud): re-register endpoint...");
00571 #else
00572         this->m_endpoint_interface->update_registration(this->m_endpoint_security,this->m_options->getLifetime());
00573 #endif
00574     }  
00575 }
00576 
00577 // de-register endpoint 
00578 void Endpoint::de_register_endpoint(void) {
00579     if (this->m_endpoint_interface != NULL) {
00580 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00581         // DEBUG
00582         this->logger()->log("Connector::Endpoint(Cloud): de-registering endpoint...");
00583         this->m_endpoint_interface->close();
00584 #else
00585         // de-register endpoint
00586         this->logger()->log("Connector::Endpoint: de-registering endpoint...");
00587         if (this->m_csi != NULL) {
00588             this->m_csi->begin_object_unregistering((void *)this);
00589         }
00590         else {
00591             this->m_endpoint_interface->unregister_object(NULL);
00592         }
00593 #endif      
00594     }
00595 }
00596 
00597 // register the endpoint
00598 void Endpoint::register_endpoint(M2MSecurity *endpoint_security, M2MObjectList endpoint_objects) {
00599 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00600     if (this->m_endpoint_interface != NULL) {
00601         this->logger()->log("Connector::Endpoint(Cloud): adding objects to endpoint...");
00602         this->m_endpoint_interface->add_objects(endpoint_objects);
00603         
00604         this->logger()->log("Connector::Endpoint(Cloud): registering endpoint...");
00605         this->m_endpoint_interface->setup(__network_interface);
00606     }
00607 #else
00608     if (this->m_endpoint_interface != NULL && endpoint_security != NULL && endpoint_objects.size() > 0)  {
00609         // register  endpoint
00610         this->logger()->log("Connector::Endpoint: registering endpoint...");
00611         this->m_endpoint_interface->register_object(endpoint_security, endpoint_objects);
00612     }
00613 #endif
00614 }
00615 
00616 #ifdef ENABLE_MBED_CLOUD_SUPPORT
00617 // object registered
00618 void Endpoint::on_registered()  {
00619     if (__endpoint != NULL) {
00620         printf("Connector::Endpoint(Cloud): on_registered()\r\n");
00621         __endpoint->object_registered();
00622     }
00623 }
00624 
00625 // registration updated
00626 void Endpoint::on_registration_updated()  {
00627     if (__endpoint != NULL) {
00628         printf("Connector::Endpoint(Cloud): on_registration_updated()\r\n");
00629         __endpoint->registration_updated();
00630     }
00631 }
00632 
00633 // object unregistered
00634 void Endpoint::on_unregistered()  {
00635     if (__endpoint != NULL) {
00636         printf("Connector::Endpoint(Cloud): on_unregistered()\r\n");
00637         __endpoint->object_unregistered(__endpoint->getSecurityInstance());
00638     }
00639 }
00640 #endif
00641 
00642 // object registered
00643 void Endpoint::object_registered(M2MSecurity *security, const M2MServer &server)  {                    
00644     this->object_registered((void *)security,(void *)&server);
00645 }
00646 
00647 // registration updated
00648 void Endpoint::registration_updated(M2MSecurity *security, const M2MServer &server)  {
00649     this->registration_updated((void *)security,(void *)&server);
00650 }
00651 
00652 // object unregistered
00653 void Endpoint::object_unregistered(M2MSecurity *security)  {
00654     // DEBUG
00655     this->logger()->log("Connector::Endpoint: endpoint de-registered.");
00656     
00657     // no longer connected/registered
00658     this->m_registered = false;
00659     this->m_connected = false;
00660     
00661     // stop all observers...
00662     this->stopObservations();
00663     
00664     // invoke ConnectionHandler if we have one...
00665     if (this->m_csi != NULL) {
00666         this->m_csi->object_unregistered((void *)this,(void *)security);
00667     }
00668     
00669     // halt the main event loop... we are done. 
00670     net_shutdown_endpoint();
00671 }
00672 
00673 // bootstrap done
00674 void Endpoint::bootstrap_done(M2MSecurity *security) {
00675     this->logger()->log("Connector::Endpoint: endpoint bootstrapped.");
00676     if (this->m_csi != NULL) {
00677         this->m_csi->bootstrapped((void *)this,(void *)security);
00678     }
00679 }
00680 
00681 // object registered
00682 void Endpoint::object_registered(void *security,void *server)  {                       
00683     this->logger()->log("Connector::Endpoint: endpoint registered.");
00684     this->m_connected = true;
00685     this->m_registered = true;
00686     if (this->m_csi != NULL) {
00687         this->m_csi->object_registered((void *)this,security,server);
00688     }
00689 }
00690 
00691 // registration updated
00692 void Endpoint::registration_updated(void *security,void *server)  {
00693     this->logger()->log("Connector::Endpoint: endpoint re-registered.");
00694     this->m_connected = true;
00695     this->m_registered = true;
00696     if (this->m_csi != NULL) {
00697         this->m_csi->registration_updated((void *)this,security,server);
00698     }
00699 }
00700 
00701 // resource value updated
00702 void Endpoint::value_updated(M2MBase *base, M2MBase::BaseType type) {
00703     // Lookup the resource and invoke process() on it...
00704     DynamicResource *target_res = this->lookupDynamicResource(base);
00705     if (target_res != NULL) {
00706         // DEBUG
00707         //this->logger()->log("Value Updated (Custom Resource)");
00708     
00709         // its a custom resource...
00710         target_res->process(base->operation(),type);
00711     }
00712     
00713 #ifndef ENABLE_MBED_CLOUD_SUPPORT
00714     else {
00715         // DEBUG
00716         //this->logger()->log("Value Updated (Device Manager)");
00717         
00718         // let DeviceManager handle it
00719         ((DeviceManager *)this->m_device_manager)->process(base,type);
00720     }
00721 #endif
00722 
00723     // CSI
00724     if (this->m_csi != NULL) {
00725         this->m_csi->value_updated((void *)this,(void *)base,(int)type);
00726     }
00727 }
00728 
00729 // lookup which DynamicResource cooresponds to a given M2MBase instance...
00730 DynamicResource *Endpoint::lookupDynamicResource(M2MBase *base) {
00731     const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
00732     for(int i=0; i<(int)dynamic_resources->size(); ++i) {
00733         M2MBase *t = (M2MBase *)dynamic_resources->at(i)->getResource();
00734         if (t == base) {
00735             return dynamic_resources->at(i);
00736         }
00737     }   
00738     return NULL;
00739 }
00740 
00741 // build out the endpoint
00742 void Endpoint::buildEndpoint()
00743 {   
00744     // initialize as an mbed-client
00745     this->createEndpointInterface();
00746     
00747     // make sure we have an endpoint interface...
00748     if (this->getEndpointInterface() != NULL) {
00749         // Create our server instance
00750         this->setSecurityInstance(this->createEndpointSecurityInstance());
00751         
00752         // We now have to bind our device resources
00753         if (this->m_device_manager != NULL) {
00754             // DEBUG
00755             this->logger()->log("Connector::Endpoint::build(): plumbing the device management objects and resources...");
00756                 
00757             // bind the device manager
00758             ((DeviceManager *)this->m_device_manager)->bind();
00759             
00760             // push back the Device Resources Object 
00761             if (this->m_options->getDeviceResourcesObject() != NULL) {
00762                 // DEBUG
00763                 this->logger()->log("Connector::Endpoint::build(): plumbing device resources object...");
00764                 
00765                 // push back the device resources object
00766                 this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getDeviceResourcesObject());
00767             }
00768             else {
00769                 // unable to plumb device manager
00770                 this->logger()->log("Connector::Endpoint::build(): Unable to plumb device resources. Not installing device resource object...");
00771             }
00772             
00773             // push back the Firmware Resources Object 
00774             if (this->m_options->getFirmwareResourcesObject() != NULL) {
00775                 // DEBUG
00776                 this->logger()->log("Connector::Endpoint::build(): plumbing firmware resources object...");
00777                 
00778                 // push back the firmware resources object
00779                 this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getFirmwareResourcesObject());
00780             }
00781             else {
00782                 // unable to plumb firmware manager
00783                 this->logger()->log("Connector::Endpoint::build(): Unable to plumb firmware resources. Not installing firmware resource object...");
00784             }
00785         }
00786         else {
00787             // no device manager installed
00788             this->logger()->log("Connector::Endpoint::build(): No device manager installed.");
00789         }
00790             
00791         // Loop through Static Resources and bind each of them...
00792         this->logger()->log("Connector::Endpoint::build(): adding static resources...");
00793         const StaticResourcesList *static_resources = this->m_options->getStaticResourceList();
00794         for(int i=0; i<(int)static_resources->size(); ++i) {
00795             this->logger()->log("Connector::Endpoint::build(): binding static resource: [%s]...",static_resources->at(i)->getFullName().c_str());
00796             static_resources->at(i)->bind(this);
00797         }
00798     
00799         // Loop through Dynamic Resources and bind each of them...
00800         this->logger()->log("Connector::Endpoint::build(): adding dynamic resources...");
00801         const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
00802         for(int i=0; i<(int)dynamic_resources->size(); ++i) {
00803             this->logger()->log("Connector::Endpoint::build(): binding dynamic resource: [%s]...",dynamic_resources->at(i)->getFullName().c_str());
00804             dynamic_resources->at(i)->bind(this);
00805         }
00806     
00807         // Get the ObjectList from the ObjectInstanceManager...
00808         NamedPointerList list = this->getObjectInstanceManager()->getObjectList();
00809         
00810         // DEBUG
00811         //this->logger()->log("Endpoint::build(): All Resources bound. Number of Objects in list: %d",list.size());
00812             
00813         // add all of the object instances we have created...
00814         for(int i=0;i<(int)list.size();++i) {
00815             // DEBUG
00816             //this->logger()->log("Endpoint::build(): adding Object Instance with ObjID: %s...",list.at(i).name().c_str());
00817             
00818             // push back the object instance...
00819             this->m_endpoint_object_list.push_back((M2MObject *)(list.at(i).ptr()));
00820         }
00821     }
00822     else {
00823         // no endpoint interface created
00824         this->logger()->log("Endpoint::build(): ERROR in creating the endpoint interface...");
00825     }
00826 }
00827 
00828 // stop underlying observation mechanisms
00829 void Endpoint::stopObservations() {
00830     const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
00831     for(int i=0; i<(int)dynamic_resources->size(); ++i) {
00832         if (dynamic_resources->at(i)->isObservable() == true) {
00833             ResourceObserver *observer = (ResourceObserver *)dynamic_resources->at(i)->getObserver();
00834             if (observer != NULL) {
00835                 this->logger()->log("Connector::Endpoint::stopObservations(): stopping resource observer for: [%s]...",dynamic_resources->at(i)->getFullName().c_str());
00836                 observer->halt();
00837             }
00838         }
00839     }
00840 }
00841 
00842 // underlying network is connected (SET)
00843 void Endpoint::isConnected(bool connected) {
00844     this->m_connected = connected;
00845 }
00846 
00847 // underlying network is connected (GET)
00848 bool Endpoint::isConnected() {
00849      return this->m_connected;
00850 }
00851 
00852 // Registered with mDC/mDS
00853 bool Endpoint::isRegistered() {
00854      return this->m_registered;
00855 }
00856 
00857 // Set the ConnectionStatusInterface
00858 void Endpoint::setConnectionStatusInterfaceImpl(ConnectionStatusInterface *csi) {
00859     this->m_csi = csi;
00860 }
00861 
00862 // Set our ObjectInstanceManager
00863 void Endpoint::setObjectInstanceManager(ObjectInstanceManager *oim) {
00864     this->m_oim = oim;
00865 }
00866 
00867 // Get our ObjectInstanceManager
00868 ObjectInstanceManager *Endpoint::getObjectInstanceManager() {
00869     return this->m_oim;
00870 }
00871 
00872 // our logger
00873 Logger *Endpoint::logger()
00874 {
00875     return this->m_logger;
00876 }
00877 
00878 } // namespace Connector