Sample program showing how to connect GR-PEACH into Watson IoT through mbed Connector and Watson's Connector Bridge

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

Overview

This sample program shows how to connect GR-PEACH into Watson IoT through mbed Connector and Watson's Connector Bridge. Note that this program is derived from https://github.com/ARMmbed/mbed-ethernet-sample-techcon2016.

In this program, at first, the barcode data input from camera is decoded on GR-PEACH using ZXing which is an open-source, multi-format 1D/2D barcode image processing library. Then, the decoded string is sent to Watson IoT via mbed Device Connector and Watson's Connector Bridge. At last, the delivered string is confirmed via NodeRED flow.

Required hardware

Application setup

  1. Select the connection type. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Connection-type.
  2. Set the client credentials. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Client-credentials.
  3. Change Ethernet settings. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Ethernet-settings.
  4. Change Wifi settings. For details, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Wifi-settings.

Building this sample program

  1. Import this sample program onto mbed Compiler.
  2. Configure this sample program in accordance with Application setup.
  3. Compile the example on mbed Compiler and download the resultant binary file.
  4. Plug the Ethernet cable into GR-PEACH if you are using Ethernet mode. /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen7.png
  5. Plug the micro-USB cable into the OpenSDA port with lies on the next to the RESET button.
  6. Copy the binary previously downloaded to your PC to GR-PEACH to flash this sample program. When the copy is successfully completed, the board is ready to work.
  7. Press the RESET button on the board to run this sample program.
  8. For verification, please refer to the following wiki:
    https://developer.mbed.org/teams/Renesas/code/mbed-os_Watson-IoT_ZXing_sample/wiki/Monitoring-the-application.

Application resources

This sample program exposes two resources listed below:

  1. /311/0/5850 : Trigger to toggle LED on GR-PEACH (PUT). When "1" is sent to this resource by PUT method, LED should be turned off. Otherwise, LED should be turned on.
  2. /888/0/7700: Decode result of barcode data input from camera (GET)

Setup of Watson IoT

  1. You should create Watson IoT Instance by the following procedure:
    • Login IBM Bluemix from https://console.ng.bluemix.net/ and login it.
    • Select Services as follows: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen6.png
    • Select Internet of Things" as follows: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen7_1.png
    • Press Get Started as follows: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen8.png
    • Configure Watson IoT Instance
      • Leave unbound /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen9.png
      • Select the Free plan, then click Create /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen10.png

  2. You should create Watson IoT Application Credentials Once you successfully create Watson IoT Instance, you should see the following Watson IoT dashboard: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen11.png
    • On dashboard, launch the Connect your devices dashboard /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen12.png
    • Click APPS /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen13.png
    • Click Generate API Key /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen14_1.png
    • Record the API Key and Authenticatoin Token. Then click Generate after adding a comment /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen15.png Note that these two values will be needed in the later step.
  3. Watson IoT NodeRED Application should be created in accordance with the following procedure:
    • Go back to your Bluemix Dashboard: https://console.ng.bluemix.net
    • Click Create Application /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen16.png
    • Select Node-RED Starter /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen17.png
    • Enter a unique App name and Click Create /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen18.png
    • Application will Stage after a few minutes
    • Application will report app is running when the staging has completed
  4. Watson NodeRED Application should be binded to Watson IoT instance
    • You can now see the dashboard below: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen19.png
    • Click Connections. Then, press Connect Existing /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen20.png
    • Click on Watson IoT Instance badge. Then, press Connect /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen21.png
    • NodeRED application will restage. This will take a while. Please wait for Your app is running state /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen22.png /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen23.png
  5. You should acquire mbed Device Connector DOMAIN value
    • Go to the mbed Device Connector Dashboard: https://connector.mbed.com and log in /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen41.png
    • Select Access Key in order to create a new token /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen42.png
    • Click CREATE NEW ACCESS KEY and enter a unique name. Then, push ADD bution /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen43.png
    • an API token is generated. Need to save the generated string for later steps /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen44.png
  1. You should configure Watson IoT ARM mbed Connector Bridge
    • Go back to the Watson IoT Dashboard and select Extensions /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen24.png
    • Press Add Extension /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen25.png
    • Add ARM mbed Connector /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen26_1.png
    • Setup the bridge /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen27.png
    • Enter your Connector API Token to Access Key and MBED_DOMAIN to Domain Id, respectively. Then, click Check Connection /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen28.png
    • If the connection is successfully established, you can see Connection Established. Then, press Done /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen29.png
  2. NodeRED Flow Example should be imported
    • Open NODEFLOW_GR-PEACH.txt
    • Navigate to the URL that you recorded earlier for your Watson IoT NodeRED Application (i.e. http://<app name>.mybluemix.net) and Select Go to your NodeRED flow editor /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen30.png
    • Select menu, Import and Clipboard /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen31.png
    • Paste the entire contents of JSON code described in NODEFLOW_GR-PEACH.txt and click Import /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen32.png
  3. Watson IoT Application Node Flow should be configured
    • Double-click input node and link them to your Watson IoT instance. /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen33.png
    • Click on the edit button /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen34.png
    • First enter arbitrary name. Then, Watson API Key and Watson Auth Token previously acquired. Finally, press Add to save /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen35.png
    • Enter MBED_ENDPOINT_NAME in security.h as Device ID. Then, press Done to save /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen36.png
    • Double-click output node /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen37.png
    • Edit API Key and Device Id in the same manner as that for input node
    • Click LED OFF and LED ON node and replace MBED_ENDPOINT_NAME_GOES_HERE with MBED_ENDPOINT_NAME as shown below: /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen38.png
    • Click Deproy to deploy NodeRED application /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen39.png
  4. Invoke sample program
    • Press the reset button on GR-PEACH
    • The decode result of barcode data should be shown in debug window /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen40_1.png
    • Also, you can toggle LED by clicking Turn LED OFF and Turn LED ON injection node /media/uploads/HinoNaka/mbed-os_watson-iot_zxing_sample_screen40_2.png

mbedConnectorInterface/source/ConnectorEndpoint.cpp

Committer:
Osamu Nakamura
Date:
2016-11-24
Revision:
0:ad834d403a8c

File content as of revision 0:ad834d403a8c:

/**
 * @file    ConnectorEndpoint.cpp
 * @brief   mbed CoAP Endpoint base class
 * @author  Doug Anson/Chris Paola
 * @version 1.0
 * @see
 *
 * Copyright (c) 2014
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
 // Lower level Network
#include "mbed-connector-interface/mbedEndpointNetwork.h"

// ConnectorEndpoint
#include "mbed-connector-interface/ConnectorEndpoint.h"

// Utils support
#include "mbed-connector-interface/Utils.h"

// Device Manager support
#include "mbed-connector-interface/DeviceManager.h"

// our endpoint instance
static Connector::Endpoint *__endpoint = NULL;

// LWIP Network interface instance
NetworkInterface *__network_interface = NULL;

// Connector namespace
namespace Connector {

// STATIC: Plumb the network
void Endpoint::plumbNetwork(void *device_manager,bool canActAsRouterNode) {
	// create our endpoint instance...
	if (__endpoint == NULL) {
		// initialize our endpoint instance
		printf("Connector::Endpoint::plumbNetwork: initializing endpoint instance...\r\n");
		__endpoint = (Connector::Endpoint *)utils_init_endpoint(canActAsRouterNode);
	}
	
	// set the device manager
	if (device_manager != NULL) {
		// device manager has been supplied
		printf("Connector::Endpoint::plumbNetwork: setting a device manager...\r\n");
		__endpoint->setDeviceManager(device_manager);
	}
	else {
		// no device manager supplied
		printf("Connector::Endpoint::plumbNetwork: no device manager supplied (OK)\r\n");
	}

    // configure the endpoint...
    printf("Connector::Endpoint::plumbNetwork: configuring endpoint...\r\n");
    utils_configure_endpoint((void *)__endpoint);
    
    // plumb the endpoint's network...
	printf("Connector::Endpoint::plumbNetwork: plumbing network...\r\n");
	net_plumb_network((void *)__endpoint);
}

// STATIC: Finalize the endpoint's configuration and begin the endpoint's main even loop (static, not tied into Logger)
void Endpoint::start()
{
    // build out the endpoint with its configuration...
    printf("Connector::Endpoint::start: building out endpoint...\r\n");
    utils_build_endpoint((void *)__endpoint);
    
    // finalize the endpoint and start its main loop
    printf("Endpoint::start: finalize and run the endpoint main loop..\r\n");
	net_finalize_and_run_endpoint_main_loop((void *)__endpoint);
}

// STATIC: Set the ConnectionStatusInterface Implementation instance
void Endpoint::setConnectionStatusInterface(ConnectionStatusInterface *csi) {
	if (__endpoint != NULL) {
		__endpoint->setConnectionStatusInterfaceImpl(csi);
	}
}

// Constructor
Endpoint::Endpoint(const Logger *logger, const Options *options)  : M2MInterfaceObserver() 
{
    this->m_logger = (Logger *)logger;
    this->m_options = (Options *)options;
    this->m_device_manager = NULL;
    this->m_connected = false;
    this->m_registered = false;
    this->m_csi = NULL;
    this->m_oim = NULL;
}

// Copy Constructor
Endpoint::Endpoint(const Endpoint &ep)
{
    this->m_logger = ep.m_logger;
    this->m_options = ep.m_options;
    this->m_endpoint_interface = ep.m_endpoint_interface;
    this->m_endpoint_security = ep.m_endpoint_security;
    this->m_endpoint_object_list = ep.m_endpoint_object_list;
    this->m_device_manager = ep.m_device_manager;
    this->m_connected = ep.m_connected;
    this->m_registered = ep.m_registered;
    this->m_csi = ep.m_csi;
    this->m_oim = ep.m_oim;
}

// Destructor
Endpoint::~Endpoint() {
	if (this->m_endpoint_interface != NULL)
		delete this->m_endpoint_interface;
	if (this->m_endpoint_security != NULL)
		delete this->m_endpoint_security;
}

// set the device manager
void Endpoint::setDeviceManager(void *device_manager) {
	this->m_device_manager = device_manager;
}

// get the device manager
void *Endpoint::getDeviceManager(void) {
	return this->m_device_manager;
}

// router node behavior setting
void Endpoint::asRouterNode(bool canActAsRouterNode) {
	this->m_canActAsRouterNode = canActAsRouterNode;
}

// set our Options
void Endpoint::setOptions(Options *options) {
	this->m_options = options;
}

// get our Options
Options *Endpoint::getOptions() {
	return this->m_options;
}

// get our Server
M2MSecurity *Endpoint::getEndpointSecurity() {
	return this->m_endpoint_security;
}

// get our ObjectList
M2MObjectList Endpoint::getEndpointObjectList() {
	return this->m_endpoint_object_list;
}

// get our endpoint interface
M2MInterface *Endpoint::getEndpointInterface() {
	return this->m_endpoint_interface;
}

// mbed-client: create our interface
void Endpoint::createEndpointInterface() {
	// get the CoAP listening port
    uint16_t listening_port = (uint16_t)this->m_options->getConnectorPort();
    
    // randomize the port if we are using certificates...
	if (this->m_options->getServerCertificateSize() > 0) {
		// Randomizing listening port for Certificate mode connectivity
		srand(time(NULL));
		listening_port = rand() % 65535 + 12345;
	}
	
	// DEBUG
	//this->logger()->logging("Connector::Endpoint: listening port: %d",listening_port);
	
	// Socket protocol type: TCP or UDP
	M2MInterface::BindingMode socket_protocol_type = M2MInterface::UDP;
	if (this->m_options->getCoAPConnectionType() == COAP_TCP)  socket_protocol_type = M2MInterface::TCP;
	
	// Socket address type: IPv4 or IPv6
	M2MInterface::NetworkStack socket_address_type = M2MInterface::LwIP_IPv4;
	if (this->m_options->getIPAddressType() == IP_ADDRESS_TYPE_IPV6) {
		// IPv6 mode for the socket addressing type... 
		socket_address_type = M2MInterface::LwIP_IPv6;
		
#if defined (IPV4_OVERRIDE)
		// OVERRIDE (until patched...)
		this->logger()->logging("Connector::Endpoint: Socket Address Type: IPv4 (IPv6 OVERRIDE)");
		socket_address_type = M2MInterface::LwIP_IPv4;
#endif
	}
	
	// DEBUG
	if (socket_protocol_type == M2MInterface::TCP) this->logger()->logging("Connector::Endpoint: Socket Protocol: TCP");
	if (socket_protocol_type == M2MInterface::UDP) this->logger()->logging("Connector::Endpoint: Socket Protocol: UDP");
	if (socket_address_type == M2MInterface::LwIP_IPv4) this->logger()->logging("Connector::Endpoint: Socket Address Type: IPv4");
	if (socket_address_type == M2MInterface::LwIP_IPv6) this->logger()->logging("Connector::Endpoint: Socket Address Type: IPv6");
	
	// Create the endpoint M2MInterface instance
    this->m_endpoint_interface = M2MInterfaceFactory::create_interface(*this,
                                              (char *)this->m_options->getEndpointNodename().c_str(),	// endpoint name
                                              (char *)this->m_options->getEndpointType().c_str(),		// endpoint type
                                              (int32_t)this->m_options->getLifetime(),					// registration lifetime (in seconds)
                                              listening_port,											// listening port (ephemeral...)
                                              (char *)this->m_options->getDomain().c_str(),				// endpoint domain
                                              socket_protocol_type,										// Socket protocol type: UDP or TCP...
                                              socket_address_type,										// Socket addressing type: IPv4 or IPv6 
                                              CONTEXT_ADDRESS_STRING									// context address string (mbedConnectorInterface.h)
                                              );									
    
    // bind LWIP network interface pointer...                                          
	if (__network_interface != NULL && this->m_endpoint_interface != NULL) {
		this->logger()->logging("Connector::Endpoint: binding LWIP network instance...");
		this->m_endpoint_interface->set_platform_network_handler((void *)__network_interface);
	}
}

// mbed-client: createEndpointInstance()
M2MSecurity *Endpoint::createEndpointInstance()  {
        // Creates register server object with mbed device server address and other parameters
        M2MSecurity *server = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
        if (server != NULL)  {
        	const String url = this->m_options->getConnectorURL();
            server->set_resource_value(M2MSecurity::M2MServerUri, url);
            server->set_resource_value(M2MSecurity::BootstrapServer, false);
            server->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate);
            server->set_resource_value(M2MSecurity::ServerPublicKey,this->m_options->getServerCertificate(),this->m_options->getServerCertificateSize());
            server->set_resource_value(M2MSecurity::PublicKey,this->m_options->getClientCertificate(),this->m_options->getClientCertificateSize());
            server->set_resource_value(M2MSecurity::Secretkey,this->m_options->getClientKey(),this->m_options->getClientKeySize());
        }
        return server;
}

// mbed-client: Callback from mbed client stack if any error is encountered
void Endpoint::error(M2MInterface::Error error) {
        switch(error){
            case M2MInterface::AlreadyExists:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::AlreadyExists");
                break;
            case M2MInterface::BootstrapFailed:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::BootstrapFailed");
                break;
            case M2MInterface::InvalidParameters:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::InvalidParameters");
                break;
            case M2MInterface::NotRegistered:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::NotRegistered");
                break;
            case M2MInterface::Timeout:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::Timeout");
                break;
            case M2MInterface::NetworkError:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::NetworkError");
                break;
            case M2MInterface::ResponseParseFailed:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::ResponseParseFailed");
                break;
            case M2MInterface::UnknownError:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::UnknownError");
                break;
            case M2MInterface::MemoryFail:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::MemoryFail");
                break;
            case M2MInterface::NotAllowed:
                this->logger()->logging("Connector::Endpoint(ERROR): M2MInterface::NotAllowed");
                break;
            default:
                break;
        }
}

// register the endpoint
void Endpoint::register_endpoint(M2MSecurity *endpoint_security, M2MObjectList endpoint_objects) {
    if (this->m_endpoint_interface != NULL && endpoint_security != NULL && endpoint_objects.size() > 0)  {
    	// register  endpoint
    	this->logger()->logging("Connector::Endpoint: registering endpoint...");
        this->m_endpoint_interface->register_object(endpoint_security, endpoint_objects);
    }
}

// re-register the endpoint
void Endpoint::re_register_endpoint() {
	if (this->m_endpoint_interface != NULL)  {
		this->m_endpoint_interface->update_registration(this->m_endpoint_security,this->m_options->getLifetime());
  	}  
}

// de-register endpoint 
void Endpoint::de_register_endpoint(void) {
	if (this->m_endpoint_interface != NULL) {
		// de-register endpoint
		this->logger()->logging("Connector::Endpoint: de-registering endpoint...");
		this->m_endpoint_interface->unregister_object(NULL);
		if (this->m_csi != NULL) {
			this->m_csi->begin_object_unregistering((void *)this);
		}		
	}
}

// object registered
void Endpoint::object_registered(M2MSecurity *security, const M2MServer &server)  {	    	           
	this->logger()->logging("Connector::Endpoint: endpoint registered.");
	this->m_connected = true;
	this->m_registered = true;
	if (this->m_csi != NULL) {
		this->m_csi->object_registered((void *)this,(void *)security,(void *)&server);
	}
}

// registration updated
void Endpoint::registration_updated(M2MSecurity *security, const M2MServer &server)  {
	this->logger()->logging("Connector::Endpoint: endpoint re-registered.");
	this->m_connected = true;
	this->m_registered = true;
	if (this->m_csi != NULL) {
		this->m_csi->registration_updated((void *)this,(void *)security,(void *)&server);
	}
}

// object unregistered
void Endpoint::object_unregistered(M2MSecurity *server)  {
	// DEBUG
	this->logger()->logging("Connector::Endpoint: endpoint de-registered.");
	
	// no longer connected/registered
	this->m_registered = false;
	this->m_connected = false;
	
	// stop all observers...
	this->stopObservations();
	
	// invoke ConnectionHandler if we have one...
	if (this->m_csi != NULL) {
		this->m_csi->object_unregistered((void *)this,(void *)server);
	}
	
	// halt the main event loop... we are done. 
	net_shutdown_endpoint();
}

// bootstrap done
void Endpoint::bootstrap_done(M2MSecurity *server) {
	this->logger()->logging("Connector::Endpoint: endpoint bootstrapped.");
	if (this->m_csi != NULL) {
		this->m_csi->bootstrapped((void *)this,(void *)server);
	}
}

// resource value updated
void Endpoint::value_updated(M2MBase *base, M2MBase::BaseType type) {
	// Lookup the resource and invoke process() on it...
	DynamicResource *target_res = this->lookupDynamicResource(base);
	if (target_res != NULL) {
		// DEBUG
		//this->logger()->logging("Value Updated (Custom Resource)");
	
		// its a custom resource...
		target_res->process(base->operation(),type);
	}
	else {
		// DEBUG
		//this->logger()->logging("Value Updated (Device Manager)");
		
		// let DeviceManager handle it
		((DeviceManager *)this->m_device_manager)->process(base,type);
	}
	
	// CSI
	if (this->m_csi != NULL) {
		this->m_csi->value_updated((void *)this,(void *)base,(int)type);
	}
}

// lookup which DynamicResource cooresponds to a given M2MBase instance...
DynamicResource *Endpoint::lookupDynamicResource(M2MBase *base) {
	const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
    for(int i=0; i<(int)dynamic_resources->size(); ++i) {
    	M2MBase *t = (M2MBase *)dynamic_resources->at(i)->getResource();
        if (t == base) {
        	return dynamic_resources->at(i);
        }
    }	
	return NULL;
}

// build out the endpoint
void Endpoint::buildEndpoint()
{	
    // initialize as an mbed-client
    this->createEndpointInterface();
   
    // Create our server instance
    this->m_endpoint_security = this->createEndpointInstance();
    
    // We now have to bind our device resources
    if (this->m_device_manager != NULL) {
    	// DEBUG
	    this->logger()->logging("Connector::Endpoint::build(): plumbing the device management objects and resources...");
	    	
    	// bind the device manager
	    ((DeviceManager *)this->m_device_manager)->bind();
	    
	    // push back the Device Resources Object 
	    if (this->m_options->getDeviceResourcesObject() != NULL) {
	    	// DEBUG
	    	this->logger()->logging("Connector::Endpoint::build(): plumbing device resources object...");
	    	
	    	// push back the device resources object
	    	this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getDeviceResourcesObject());
	    }
	    else {
	    	// unable to plumb device manager
	    	this->logger()->logging("Connector::Endpoint::build(): Unable to plumb device resources. Not installing device resource object...");
	    }
	    
	    // push back the Firmware Resources Object 
	    if (this->m_options->getFirmwareResourcesObject() != NULL) {
	    	// DEBUG
	    	this->logger()->logging("Connector::Endpoint::build(): plumbing firmware resources object...");
	    	
	    	// push back the firmware resources object
	    	this->m_endpoint_object_list.push_back((M2MObject *)this->m_options->getFirmwareResourcesObject());
	    }
	    else {
	    	// unable to plumb firmware manager
	    	this->logger()->logging("Connector::Endpoint::build(): Unable to plumb firmware resources. Not installing firmware resource object...");
	    }
    }
    else {
    	// no device manager installed
	    this->logger()->logging("Connector::Endpoint::build(): No device manager installed.");
    }
        
    // Loop through Static Resources and bind each of them...
    this->logger()->logging("Connector::Endpoint::build(): adding static resources...");
    const StaticResourcesList *static_resources = this->m_options->getStaticResourceList();
    for(int i=0; i<(int)static_resources->size(); ++i) {
        this->logger()->logging("Connector::Endpoint::build(): binding static resource: [%s]...",static_resources->at(i)->getFullName().c_str());
        static_resources->at(i)->bind(this);
    }

    // Loop through Dynamic Resources and bind each of them...
    this->logger()->logging("Connector::Endpoint::build(): adding dynamic resources...");
    const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
    for(int i=0; i<(int)dynamic_resources->size(); ++i) {
        this->logger()->logging("Connector::Endpoint::build(): binding dynamic resource: [%s]...",dynamic_resources->at(i)->getFullName().c_str());
        dynamic_resources->at(i)->bind(this);
    }

    // Get the ObjectList from the ObjectInstanceManager...
    NamedPointerList list = this->getObjectInstanceManager()->getObjectList();
    
    // DEBUG
    //this->logger()->logging("Endpoint::build(): All Resources bound. Number of Objects in list: %d",list.size());
        
    // add all of the object instances we have created...
    for(int i=0;i<(int)list.size();++i) {
    	// DEBUG
    	//this->logger()->logging("Endpoint::build(): adding Object Instance with ObjID: %s...",list.at(i).name().c_str());
    	
    	// push back the object instance...
    	this->m_endpoint_object_list.push_back((M2MObject *)(list.at(i).ptr()));
    }
}

// stop underlying observation mechanisms
void Endpoint::stopObservations() {
	const DynamicResourcesList *dynamic_resources = this->m_options->getDynamicResourceList();
    for(int i=0; i<(int)dynamic_resources->size(); ++i) {
        if (dynamic_resources->at(i)->isObservable() == true) {
        	ResourceObserver *observer = (ResourceObserver *)dynamic_resources->at(i)->getObserver();
        	if (observer != NULL) {
        		this->logger()->logging("Connector::Endpoint::stopObservations(): stopping resource observer for: [%s]...",dynamic_resources->at(i)->getFullName().c_str());
        		observer->halt();
        	}
        }
    }
}

// underlying network is connected (SET)
void Endpoint::isConnected(bool connected) {
	this->m_connected = connected;
}

// underlying network is connected (GET)
bool Endpoint::isConnected() {
     return this->m_connected;
}

// Registered with mDC/mDS
bool Endpoint::isRegistered() {
     return this->m_registered;
}

// Set the ConnectionStatusInterface
void Endpoint::setConnectionStatusInterfaceImpl(ConnectionStatusInterface *csi) {
	this->m_csi = csi;
}

// Set our ObjectInstanceManager
void Endpoint::setObjectInstanceManager(ObjectInstanceManager *oim) {
	this->m_oim = oim;
}

// Get our ObjectInstanceManager
ObjectInstanceManager *Endpoint::getObjectInstanceManager() {
	return this->m_oim;
}

// our logger
Logger *Endpoint::logger()
{
    return this->m_logger;
}

} // namespace Connector