This is the sample program that can see the decode result of barcode data on Watson IoT.

Dependencies:   AsciiFont DisplayApp GR-PEACH_video LCD_shield_config LWIPBP3595Interface_STA_for_mbed-os USBDevice

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 // our endpoint instance
00036 static Connector::Endpoint *__endpoint = NULL;
00037 
00038 // LWIP Network interface instance
00039 NetworkInterface *__network_interface = NULL;
00040 
00041 // Connector namespace
00042 namespace Connector {
00043 
00044 // STATIC: Plumb the network
00045 void Endpoint::plumbNetwork(void *device_manager,bool canActAsRouterNode) {
00046     // create our endpoint instance...
00047     if (__endpoint == NULL) {
00048         // initialize our endpoint instance
00049         printf("Connector::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         printf("Connector::Endpoint::plumbNetwork: setting a device manager...\r\n");
00057         __endpoint->setDeviceManager(device_manager);
00058     }
00059     else {
00060         // no device manager supplied
00061         printf("Connector::Endpoint::plumbNetwork: no device manager supplied (OK)\r\n");
00062     }
00063 
00064     // configure the endpoint...
00065     printf("Connector::Endpoint::plumbNetwork: configuring endpoint...\r\n");
00066     utils_configure_endpoint((void *)__endpoint);
00067     
00068     // plumb the endpoint's network...
00069     printf("Connector::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     // build out the endpoint with its configuration...
00077     printf("Connector::Endpoint::start: building out endpoint...\r\n");
00078     utils_build_endpoint((void *)__endpoint);
00079     
00080     // finalize the endpoint and start its main loop
00081     printf("Endpoint::start: finalize and run the endpoint main loop..\r\n");
00082     net_finalize_and_run_endpoint_main_loop((void *)__endpoint);
00083 }
00084 
00085 // STATIC: Set the ConnectionStatusInterface Implementation instance
00086 void Endpoint::setConnectionStatusInterface(ConnectionStatusInterface *csi) {
00087     if (__endpoint != NULL) {
00088         __endpoint->setConnectionStatusInterfaceImpl(csi);
00089     }
00090 }
00091 
00092 // Constructor
00093 Endpoint::Endpoint(const Logger *logger, const Options *options)  : M2MInterfaceObserver() 
00094 {
00095     this->m_logger = (Logger *)logger;
00096     this->m_options = (Options *)options;
00097     this->m_device_manager = NULL;
00098     this->m_connected = false;
00099     this->m_registered = false;
00100     this->m_csi = NULL;
00101     this->m_oim = NULL;
00102 }
00103 
00104 // Copy Constructor
00105 Endpoint::Endpoint(const Endpoint &ep)
00106 {
00107     this->m_logger = ep.m_logger;
00108     this->m_options = ep.m_options;
00109     this->m_endpoint_interface = ep.m_endpoint_interface;
00110     this->m_endpoint_security = ep.m_endpoint_security;
00111     this->m_endpoint_object_list = ep.m_endpoint_object_list;
00112     this->m_device_manager = ep.m_device_manager;
00113     this->m_connected = ep.m_connected;
00114     this->m_registered = ep.m_registered;
00115     this->m_csi = ep.m_csi;
00116     this->m_oim = ep.m_oim;
00117 }
00118 
00119 // Destructor
00120 Endpoint::~Endpoint() {
00121     if (this->m_endpoint_interface != NULL)
00122         delete this->m_endpoint_interface;
00123     if (this->m_endpoint_security != NULL)
00124         delete this->m_endpoint_security;
00125 }
00126 
00127 // set the device manager
00128 void Endpoint::setDeviceManager(void *device_manager) {
00129     this->m_device_manager = device_manager;
00130 }
00131 
00132 // get the device manager
00133 void *Endpoint::getDeviceManager(void) {
00134     return this->m_device_manager;
00135 }
00136 
00137 // router node behavior setting
00138 void Endpoint::asRouterNode(bool canActAsRouterNode) {
00139     this->m_canActAsRouterNode = canActAsRouterNode;
00140 }
00141 
00142 // set our Options
00143 void Endpoint::setOptions(Options *options) {
00144     this->m_options = options;
00145 }
00146 
00147 // get our Options
00148 Options *Endpoint::getOptions() {
00149     return this->m_options;
00150 }
00151 
00152 // get our Server
00153 M2MSecurity *Endpoint::getEndpointSecurity() {
00154     return this->m_endpoint_security;
00155 }
00156 
00157 // get our ObjectList
00158 M2MObjectList Endpoint::getEndpointObjectList() {
00159     return this->m_endpoint_object_list;
00160 }
00161 
00162 // get our endpoint interface
00163 M2MInterface *Endpoint::getEndpointInterface() {
00164     return this->m_endpoint_interface;
00165 }
00166 
00167 // mbed-client: create our interface
00168 void Endpoint::createEndpointInterface() {
00169     // get the CoAP listening port
00170     uint16_t listening_port = (uint16_t)this->m_options->getConnectorPort();
00171     
00172     // randomize the port if we are using certificates...
00173     if (this->m_options->getServerCertificateSize() > 0) {
00174         // Randomizing listening port for Certificate mode connectivity
00175         srand(time(NULL));
00176         listening_port = rand() % 65535 + 12345;
00177     }
00178     
00179     // DEBUG
00180     //this->logger()->logging("Connector::Endpoint: listening port: %d",listening_port);
00181     
00182     // Socket protocol type: TCP or UDP
00183     M2MInterface::BindingMode socket_protocol_type = M2MInterface::UDP;
00184     if (this->m_options->getCoAPConnectionType() == COAP_TCP)  socket_protocol_type = M2MInterface::TCP;
00185     
00186     // Socket address type: IPv4 or IPv6
00187     M2MInterface::NetworkStack socket_address_type = M2MInterface::LwIP_IPv4;
00188     if (this->m_options->getIPAddressType() == IP_ADDRESS_TYPE_IPV6) {
00189         // IPv6 mode for the socket addressing type... 
00190         socket_address_type = M2MInterface::LwIP_IPv6;
00191         
00192 #if defined (IPV4_OVERRIDE)
00193         // OVERRIDE (until patched...)
00194         this->logger()->logging("Connector::Endpoint: Socket Address Type: IPv4 (IPv6 OVERRIDE)");
00195         socket_address_type = M2MInterface::LwIP_IPv4;
00196 #endif
00197     }
00198     
00199     // DEBUG
00200     if (socket_protocol_type == M2MInterface::TCP) this->logger()->logging("Connector::Endpoint: Socket Protocol: TCP");
00201     if (socket_protocol_type == M2MInterface::UDP) this->logger()->logging("Connector::Endpoint: Socket Protocol: UDP");
00202     if (socket_address_type == M2MInterface::LwIP_IPv4) this->logger()->logging("Connector::Endpoint: Socket Address Type: IPv4");
00203     if (socket_address_type == M2MInterface::LwIP_IPv6) this->logger()->logging("Connector::Endpoint: Socket Address Type: IPv6");
00204     
00205     // Create the endpoint M2MInterface instance
00206     this->m_endpoint_interface = M2MInterfaceFactory::create_interface(*this,
00207                                               (char *)this->m_options->getEndpointNodename().c_str(),   // endpoint name
00208                                               (char *)this->m_options->getEndpointType().c_str(),       // endpoint type
00209                                               (int32_t)this->m_options->getLifetime(),                  // registration lifetime (in seconds)
00210                                               listening_port,                                           // listening port (ephemeral...)
00211                                               (char *)this->m_options->getDomain().c_str(),             // endpoint domain
00212                                               socket_protocol_type,                                     // Socket protocol type: UDP or TCP...
00213                                               socket_address_type,                                      // Socket addressing type: IPv4 or IPv6 
00214                                               CONTEXT_ADDRESS_STRING                                    // context address string (mbedConnectorInterface.h)
00215                                               );                                    
00216     
00217     // bind LWIP network interface pointer...                                          
00218     if (__network_interface != NULL && this->m_endpoint_interface != NULL) {
00219         this->logger()->logging("Connector::Endpoint: binding LWIP network instance...");
00220         this->m_endpoint_interface->set_platform_network_handler((void *)__network_interface);
00221     }
00222 }
00223 
00224 // mbed-client: createEndpointInstance()
00225 M2MSecurity *Endpoint::createEndpointInstance()  {
00226         // Creates register server object with mbed device server address and other parameters
00227         M2MSecurity *server = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
00228         if (server != NULL)  {
00229             const String url = this->m_options->getConnectorURL();
00230             server->set_resource_value(M2MSecurity::M2MServerUri, url);
00231             server->set_resource_value(M2MSecurity::BootstrapServer, false);
00232             server->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate);
00233             server->set_resource_value(M2MSecurity::ServerPublicKey,this->m_options->getServerCertificate(),this->m_options->getServerCertificateSize());
00234             server->set_resource_value(M2MSecurity::PublicKey,this->m_options->getClientCertificate(),this->m_options->getClientCertificateSize());
00235             server->set_resource_value(M2MSecurity::Secretkey,this->m_options->getClientKey(),this->m_options->getClientKeySize());
00236         }
00237         return server;
00238 }
00239 
00240 // mbed-client: Callback from mbed client stack if any error is encountered
00241 void Endpoint::error(M2MInterface::Error error) {
00242         switch(error){
00243             case M2MInterface::AlreadyExists:
00244                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::AlreadyExists");
00245                 break;
00246             case M2MInterface::BootstrapFailed:
00247                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::BootstrapFailed");
00248                 break;
00249             case M2MInterface::InvalidParameters:
00250                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::InvalidParameters");
00251                 break;
00252             case M2MInterface::NotRegistered:
00253                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::NotRegistered");
00254                 break;
00255             case M2MInterface::Timeout:
00256                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::Timeout");
00257                 break;
00258             case M2MInterface::NetworkError:
00259                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::NetworkError");
00260                 break;
00261             case M2MInterface::ResponseParseFailed:
00262                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::ResponseParseFailed");
00263                 break;
00264             case M2MInterface::UnknownError:
00265                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::UnknownError");
00266                 break;
00267             case M2MInterface::MemoryFail:
00268                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::MemoryFail");
00269                 break;
00270             case M2MInterface::NotAllowed:
00271                 this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::NotAllowed");
00272                 break;
00273             default:
00274                 break;
00275         }
00276 }
00277 
00278 // register the endpoint
00279 void Endpoint::register_endpoint(M2MSecurity *endpoint_security, M2MObjectList endpoint_objects) {
00280     if (this->m_endpoint_interface != NULL && endpoint_security != NULL && endpoint_objects.size() > 0)  {
00281         // register  endpoint
00282         this->logger()->logging("Connector::Endpoint: registering endpoint...");
00283         this->m_endpoint_interface->register_object(endpoint_security, endpoint_objects);
00284     }
00285 }
00286 
00287 // re-register the endpoint
00288 void Endpoint::re_register_endpoint() {
00289     if (this->m_endpoint_interface != NULL)  {
00290         this->m_endpoint_interface->update_registration(this->m_endpoint_security,this->m_options->getLifetime());
00291     }  
00292 }
00293 
00294 // de-register endpoint 
00295 void Endpoint::de_register_endpoint(void) {
00296     if (this->m_endpoint_interface != NULL) {
00297         // de-register endpoint
00298         this->logger()->logging("Connector::Endpoint: de-registering endpoint...");
00299         this->m_endpoint_interface->unregister_object(NULL);
00300         if (this->m_csi != NULL) {
00301             this->m_csi->begin_object_unregistering((void *)this);
00302         }       
00303     }
00304 }
00305 
00306 // object registered
00307 void Endpoint::object_registered(M2MSecurity *security, const M2MServer &server)  {                    
00308     this->logger()->logging("Connector::Endpoint: endpoint registered.");
00309     this->m_connected = true;
00310     this->m_registered = true;
00311     if (this->m_csi != NULL) {
00312         this->m_csi->object_registered((void *)this,(void *)security,(void *)&server);
00313     }
00314 }
00315 
00316 // registration updated
00317 void Endpoint::registration_updated(M2MSecurity *security, const M2MServer &server)  {
00318     this->logger()->logging("Connector::Endpoint: endpoint re-registered.");
00319     this->m_connected = true;
00320     this->m_registered = true;
00321     if (this->m_csi != NULL) {
00322         this->m_csi->registration_updated((void *)this,(void *)security,(void *)&server);
00323     }
00324 }
00325 
00326 // object unregistered
00327 void Endpoint::object_unregistered(M2MSecurity *server)  {
00328     // DEBUG
00329     this->logger()->logging("Connector::Endpoint: endpoint de-registered.");
00330     
00331     // no longer connected/registered
00332     this->m_registered = false;
00333     this->m_connected = false;
00334     
00335     // stop all observers...
00336     this->stopObservations();
00337     
00338     // invoke ConnectionHandler if we have one...
00339     if (this->m_csi != NULL) {
00340         this->m_csi->object_unregistered((void *)this,(void *)server);
00341     }
00342     
00343     // halt the main event loop... we are done. 
00344     net_shutdown_endpoint();
00345 }
00346 
00347 // bootstrap done
00348 void Endpoint::bootstrap_done(M2MSecurity *server) {
00349     this->logger()->logging("Connector::Endpoint: endpoint bootstrapped.");
00350     if (this->m_csi != NULL) {
00351         this->m_csi->bootstrapped((void *)this,(void *)server);
00352     }
00353 }
00354 
00355 // resource value updated
00356 void Endpoint::value_updated(M2MBase *base, M2MBase::BaseType type) {
00357     // Lookup the resource and invoke process() on it...
00358     DynamicResource *target_res = this->lookupDynamicResource(base);
00359     if (target_res != NULL) {
00360         // DEBUG
00361         //this->logger()->logging("Value Updated (Custom Resource)");
00362     
00363         // its a custom resource...
00364         target_res->process(base->operation(),type);
00365     }
00366     else {
00367         // DEBUG
00368         //this->logger()->logging("Value Updated (Device Manager)");
00369         
00370         // let DeviceManager handle it
00371         ((DeviceManager *)this->m_device_manager)->process(base,type);
00372     }
00373     
00374     // CSI
00375     if (this->m_csi != NULL) {
00376         this->m_csi->value_updated((void *)this,(void *)base,(int)type);
00377     }
00378 }
00379 
00380 // lookup which DynamicResource cooresponds to a given M2MBase instance...
00381 DynamicResource *Endpoint::lookupDynamicResource(M2MBase *base) {
00382     const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
00383     for(int i=0; i<(int)dynamic_resources->size(); ++i) {
00384         M2MBase *t = (M2MBase *)dynamic_resources->at(i)->getResource();
00385         if (t == base) {
00386             return dynamic_resources->at(i);
00387         }
00388     }   
00389     return NULL;
00390 }
00391 
00392 // build out the endpoint
00393 void Endpoint::buildEndpoint()
00394 {   
00395     // initialize as an mbed-client
00396     this->createEndpointInterface();
00397    
00398     // Create our server instance
00399     this->m_endpoint_security = this->createEndpointInstance();
00400     
00401     // We now have to bind our device resources
00402     if (this->m_device_manager != NULL) {
00403         // DEBUG
00404         this->logger()->logging("Connector::Endpoint::build(): plumbing the device management objects and resources...");
00405             
00406         // bind the device manager
00407         ((DeviceManager *)this->m_device_manager)->bind();
00408         
00409         // push back the Device Resources Object 
00410         if (this->m_options->getDeviceResourcesObject() != NULL) {
00411             // DEBUG
00412             this->logger()->logging("Connector::Endpoint::build(): plumbing device resources object...");
00413             
00414             // push back the device resources object
00415             this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getDeviceResourcesObject());
00416         }
00417         else {
00418             // unable to plumb device manager
00419             this->logger()->logging("Connector::Endpoint::build(): Unable to plumb device resources. Not installing device resource object...");
00420         }
00421         
00422         // push back the Firmware Resources Object 
00423         if (this->m_options->getFirmwareResourcesObject() != NULL) {
00424             // DEBUG
00425             this->logger()->logging("Connector::Endpoint::build(): plumbing firmware resources object...");
00426             
00427             // push back the firmware resources object
00428             this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getFirmwareResourcesObject());
00429         }
00430         else {
00431             // unable to plumb firmware manager
00432             this->logger()->logging("Connector::Endpoint::build(): Unable to plumb firmware resources. Not installing firmware resource object...");
00433         }
00434     }
00435     else {
00436         // no device manager installed
00437         this->logger()->logging("Connector::Endpoint::build(): No device manager installed.");
00438     }
00439         
00440     // Loop through Static Resources and bind each of them...
00441     this->logger()->logging("Connector::Endpoint::build(): adding static resources...");
00442     const StaticResourcesList *static_resources = this->m_options->getStaticResourceList();
00443     for(int i=0; i<(int)static_resources->size(); ++i) {
00444         this->logger()->logging("Connector::Endpoint::build(): binding static resource: [%s]...",static_resources->at(i)->getFullName().c_str());
00445         static_resources->at(i)->bind(this);
00446     }
00447 
00448     // Loop through Dynamic Resources and bind each of them...
00449     this->logger()->logging("Connector::Endpoint::build(): adding dynamic resources...");
00450     const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
00451     for(int i=0; i<(int)dynamic_resources->size(); ++i) {
00452         this->logger()->logging("Connector::Endpoint::build(): binding dynamic resource: [%s]...",dynamic_resources->at(i)->getFullName().c_str());
00453         dynamic_resources->at(i)->bind(this);
00454     }
00455 
00456     // Get the ObjectList from the ObjectInstanceManager...
00457     NamedPointerList list = this->getObjectInstanceManager()->getObjectList();
00458     
00459     // DEBUG
00460     //this->logger()->logging("Endpoint::build(): All Resources bound. Number of Objects in list: %d",list.size());
00461         
00462     // add all of the object instances we have created...
00463     for(int i=0;i<(int)list.size();++i) {
00464         // DEBUG
00465         //this->logger()->logging("Endpoint::build(): adding Object Instance with ObjID: %s...",list.at(i).name().c_str());
00466         
00467         // push back the object instance...
00468         this->m_endpoint_object_list.push_back((M2MObject *)(list.at(i).ptr()));
00469     }
00470 }
00471 
00472 // stop underlying observation mechanisms
00473 void Endpoint::stopObservations() {
00474     const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
00475     for(int i=0; i<(int)dynamic_resources->size(); ++i) {
00476         if (dynamic_resources->at(i)->isObservable() == true) {
00477             ResourceObserver *observer = (ResourceObserver *)dynamic_resources->at(i)->getObserver();
00478             if (observer != NULL) {
00479                 this->logger()->logging("Connector::Endpoint::stopObservations(): stopping resource observer for: [%s]...",dynamic_resources->at(i)->getFullName().c_str());
00480                 observer->halt();
00481             }
00482         }
00483     }
00484 }
00485 
00486 // underlying network is connected (SET)
00487 void Endpoint::isConnected(bool connected) {
00488     this->m_connected = connected;
00489 }
00490 
00491 // underlying network is connected (GET)
00492 bool Endpoint::isConnected() {
00493      return this->m_connected;
00494 }
00495 
00496 // Registered with mDC/mDS
00497 bool Endpoint::isRegistered() {
00498      return this->m_registered;
00499 }
00500 
00501 // Set the ConnectionStatusInterface
00502 void Endpoint::setConnectionStatusInterfaceImpl(ConnectionStatusInterface *csi) {
00503     this->m_csi = csi;
00504 }
00505 
00506 // Set our ObjectInstanceManager
00507 void Endpoint::setObjectInstanceManager(ObjectInstanceManager *oim) {
00508     this->m_oim = oim;
00509 }
00510 
00511 // Get our ObjectInstanceManager
00512 ObjectInstanceManager *Endpoint::getObjectInstanceManager() {
00513     return this->m_oim;
00514 }
00515 
00516 // our logger
00517 Logger *Endpoint::logger()
00518 {
00519     return this->m_logger;
00520 }
00521 
00522 } // namespace Connector