mqtt specific components for the impact mbed endpoint library

Dependents:   mbed_mqtt_endpoint_ublox_ethernet mbed_mqtt_endpoint_ublox_cellular mbed_mqtt_endpoint_nxp

Committer:
ansond
Date:
Thu Mar 27 17:48:38 2014 +0000
Revision:
5:1ba6e68bf50e
Parent:
0:a3fc1c6ef150
Child:
6:2db2c7e75ad9
updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:a3fc1c6ef150 1 /* Copyright C2013 Doug Anson, MIT License
ansond 0:a3fc1c6ef150 2 *
ansond 0:a3fc1c6ef150 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
ansond 0:a3fc1c6ef150 4 * and associated documentation files the "Software", to deal in the Software without restriction,
ansond 0:a3fc1c6ef150 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
ansond 0:a3fc1c6ef150 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
ansond 0:a3fc1c6ef150 7 * furnished to do so, subject to the following conditions:
ansond 0:a3fc1c6ef150 8 *
ansond 0:a3fc1c6ef150 9 * The above copyright notice and this permission notice shall be included in all copies or
ansond 0:a3fc1c6ef150 10 * substantial portions of the Software.
ansond 0:a3fc1c6ef150 11 *
ansond 0:a3fc1c6ef150 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
ansond 0:a3fc1c6ef150 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ansond 0:a3fc1c6ef150 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
ansond 0:a3fc1c6ef150 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ansond 0:a3fc1c6ef150 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ansond 0:a3fc1c6ef150 17 */
ansond 0:a3fc1c6ef150 18
ansond 0:a3fc1c6ef150 19 #include "MQTTTransport.h"
ansond 0:a3fc1c6ef150 20 #include "MBEDEndpoint.h"
ansond 0:a3fc1c6ef150 21
ansond 0:a3fc1c6ef150 22 // MBED Light support
ansond 0:a3fc1c6ef150 23 #include "MBEDLight.h"
ansond 0:a3fc1c6ef150 24
ansond 5:1ba6e68bf50e 25 // Light Personality: Emulated Light Resource Factory
ansond 5:1ba6e68bf50e 26 #include "EmulatedLightResourceFactory.h"
ansond 0:a3fc1c6ef150 27
ansond 5:1ba6e68bf50e 28 // Light Personality: Emulated Actions we can act on with the Light personalikty
ansond 0:a3fc1c6ef150 29 #include "EmulatedLightDimmerAction.h"
ansond 0:a3fc1c6ef150 30 #include "EmulatedLightSwitchAction.h"
ansond 0:a3fc1c6ef150 31
ansond 0:a3fc1c6ef150 32 // string support
ansond 0:a3fc1c6ef150 33 #include <stdlib.h>
ansond 0:a3fc1c6ef150 34 #include <string.h>
ansond 0:a3fc1c6ef150 35
ansond 0:a3fc1c6ef150 36 // shutdown endpoint reference
ansond 0:a3fc1c6ef150 37 extern void closedown(int code);
ansond 0:a3fc1c6ef150 38
ansond 0:a3fc1c6ef150 39 // default constructor
ansond 0:a3fc1c6ef150 40 MBEDEndpoint::MBEDEndpoint(ErrorHandler *error_handler,EthernetInterface *ethernet) {
ansond 0:a3fc1c6ef150 41 bool success = true;
ansond 0:a3fc1c6ef150 42 this->m_instance_id = 0;
ansond 0:a3fc1c6ef150 43 this->m_preferences = NULL;
ansond 0:a3fc1c6ef150 44 memset(this->m_lcd_status,0,TEMP_BUFFER_LEN+1);
ansond 0:a3fc1c6ef150 45 memset(this->m_gw_address,0,PREFERENCE_VALUE_LEN+1);
ansond 0:a3fc1c6ef150 46 for(int i=0;i<NUM_TRANSPORTS;++i) this->m_transports[i] = NULL;
ansond 0:a3fc1c6ef150 47 this->m_error_handler = error_handler;
ansond 0:a3fc1c6ef150 48 this->m_error_handler->setEndpoint((void *)this);
ansond 0:a3fc1c6ef150 49 if (success) this->initPreferences();
ansond 0:a3fc1c6ef150 50 if (success) this->initEndpointName();
ansond 0:a3fc1c6ef150 51 if (success) this->logger()->turnLEDBlue();
ansond 0:a3fc1c6ef150 52 #ifdef MAC_ADDRESS
ansond 0:a3fc1c6ef150 53 extern char fmt_mac[RESOURCE_VALUE_LEN+1];
ansond 0:a3fc1c6ef150 54 if (success)this->logger()->log("%s (MAC: %s)",ENDPOINT_VERSION_ANNOUNCE,fmt_mac);
ansond 0:a3fc1c6ef150 55 #else
ansond 0:a3fc1c6ef150 56 if (success)this->logger()->log(ENDPOINT_VERSION_ANNOUNCE);
ansond 0:a3fc1c6ef150 57 #endif
ansond 0:a3fc1c6ef150 58 if (success) this->initGWAddress();
ansond 0:a3fc1c6ef150 59 if (success) this->logger()->log("IOC GW IP: %s",GW_IPADDRESS);
ansond 0:a3fc1c6ef150 60 if (PL_ENABLE && success) this->logger()->log("Philips Light ID: %d Philips Gateway IP: %s",PL_LIGHT_ID,PL_GW_ADDRESS);
ansond 0:a3fc1c6ef150 61 if (success) success = this->initializeEthernet(ethernet);
ansond 0:a3fc1c6ef150 62 if (success) this->logger()->turnLEDYellow();
ansond 0:a3fc1c6ef150 63 if (success)this->m_map = new MBEDToIOCResourceMap(error_handler);
ansond 0:a3fc1c6ef150 64 if (success) success = this->initializeTransports();
ansond 5:1ba6e68bf50e 65 if (success) success = this->initializePersonality();
ansond 0:a3fc1c6ef150 66 if (success) this->logger()->turnLEDOrange();
ansond 0:a3fc1c6ef150 67 this->logger()->lcdStatusOnly(true);
ansond 0:a3fc1c6ef150 68 if (!success) closedown(2);
ansond 0:a3fc1c6ef150 69 }
ansond 0:a3fc1c6ef150 70
ansond 0:a3fc1c6ef150 71 // default destructor
ansond 0:a3fc1c6ef150 72 MBEDEndpoint::~MBEDEndpoint() {
ansond 0:a3fc1c6ef150 73 bool success = true;
ansond 0:a3fc1c6ef150 74 if (success) this->logger()->turnLEDYellow();
ansond 5:1ba6e68bf50e 75 if (success) success = this->closePersonality();
ansond 0:a3fc1c6ef150 76 if (success) success = this->closeTransports();
ansond 0:a3fc1c6ef150 77 if (success) success = this->closeEthernet();
ansond 0:a3fc1c6ef150 78 if (success) this->logger()->turnLEDBlue();
ansond 0:a3fc1c6ef150 79 if (this->m_map != NULL) delete this->m_map;
ansond 0:a3fc1c6ef150 80 }
ansond 0:a3fc1c6ef150 81
ansond 0:a3fc1c6ef150 82 // get the IOC <--> MBED resource map
ansond 0:a3fc1c6ef150 83 MBEDToIOCResourceMap *MBEDEndpoint::getMap() { return this->m_map; }
ansond 0:a3fc1c6ef150 84
ansond 0:a3fc1c6ef150 85 // initialize our preferences
ansond 0:a3fc1c6ef150 86 void MBEDEndpoint::initPreferences() { if (this->m_preferences == NULL) this->m_preferences = new Preferences(this->logger()); if (this->m_preferences != NULL) this->m_preferences->fixCoordsForIOC(); }
ansond 0:a3fc1c6ef150 87
ansond 0:a3fc1c6ef150 88 // get our preferences
ansond 0:a3fc1c6ef150 89 Preferences *MBEDEndpoint::preferences() { return this->m_preferences; }
ansond 0:a3fc1c6ef150 90
ansond 0:a3fc1c6ef150 91 // initialize the GW address from the configuration
ansond 0:a3fc1c6ef150 92 void MBEDEndpoint::initGWAddress() {
ansond 0:a3fc1c6ef150 93 memset(this->m_gw_address,0,PREFERENCE_VALUE_LEN+1);
ansond 0:a3fc1c6ef150 94 this->preferences()->getPreference("gw_address",this->m_gw_address,PREFERENCE_VALUE_LEN,GW_IPADDRESS);
ansond 0:a3fc1c6ef150 95 this->logger()->log("GW IP: %s",this->getGWAddress());
ansond 0:a3fc1c6ef150 96 }
ansond 0:a3fc1c6ef150 97
ansond 0:a3fc1c6ef150 98 // get our GW address
ansond 0:a3fc1c6ef150 99 char *MBEDEndpoint::getGWAddress() { return this->m_gw_address; }
ansond 0:a3fc1c6ef150 100
ansond 0:a3fc1c6ef150 101 // get our LCD status
ansond 0:a3fc1c6ef150 102 char *MBEDEndpoint::getLCDStatus() {
ansond 0:a3fc1c6ef150 103 memset(this->m_lcd_status,0,TEMP_BUFFER_LEN+1);
ansond 0:a3fc1c6ef150 104
ansond 0:a3fc1c6ef150 105 // look at Light#0 to determine the IOC linkage ID...
ansond 0:a3fc1c6ef150 106 char *ioc = this->m_lights[0]->getResourceFactory()->getResourceValue(IOC_LINKAGE_RESOURCE);
ansond 0:a3fc1c6ef150 107
ansond 0:a3fc1c6ef150 108 // color our LED depending on whether we have IOC linkage or not...
ansond 0:a3fc1c6ef150 109 if (ioc == NULL || strcmp(ioc,IOC_LINKAGE_UNSET) == 0) this->logger()->turnLEDOrange();
ansond 0:a3fc1c6ef150 110 else this->logger()->turnLEDGreen();
ansond 0:a3fc1c6ef150 111
ansond 0:a3fc1c6ef150 112 sprintf(this->m_lcd_status,"Node: %s\nGW IP: %s\nIOC Link: %s",this->getEndpointName(),this->getGWAddress(),ioc);
ansond 0:a3fc1c6ef150 113 return this->m_lcd_status;
ansond 0:a3fc1c6ef150 114 }
ansond 0:a3fc1c6ef150 115
ansond 5:1ba6e68bf50e 116 // initialize our personality
ansond 5:1ba6e68bf50e 117 bool MBEDEndpoint::initializeEndpointPersonality() {
ansond 5:1ba6e68bf50e 118 #ifdef LIGHT_PERSONALITY
ansond 5:1ba6e68bf50e 119 return this->initializeLights();
ansond 5:1ba6e68bf50e 120 #else
ansond 5:1ba6e68bf50e 121 return NULL;
ansond 5:1ba6e68bf50e 122 #endif
ansond 5:1ba6e68bf50e 123 }
ansond 5:1ba6e68bf50e 124
ansond 0:a3fc1c6ef150 125 // initialize the Lights
ansond 0:a3fc1c6ef150 126 bool MBEDEndpoint::initializeLights() {
ansond 0:a3fc1c6ef150 127 int index = this->preferences()->getIntPreference("endpoint_id",LIGHT_NAME_INDEX);
ansond 0:a3fc1c6ef150 128 this->logger()->log("Initializing Lights...");
ansond 0:a3fc1c6ef150 129 for(int i=0;i<NUM_LIGHTS;++i) {
ansond 0:a3fc1c6ef150 130 this->m_lights[i] = new MBEDLight(this->logger(),this->m_transports,i+index,this);
ansond 0:a3fc1c6ef150 131 this->m_lights[i]->setDimmerAction(new EmulatedLightDimmerAction(this->logger(),this->m_lights[i]));
ansond 0:a3fc1c6ef150 132 this->m_lights[i]->setSwitchAction(new EmulatedLightSwitchAction(this->logger(),this->m_lights[i]));
ansond 0:a3fc1c6ef150 133 }
ansond 0:a3fc1c6ef150 134 return true;
ansond 0:a3fc1c6ef150 135 }
ansond 0:a3fc1c6ef150 136
ansond 0:a3fc1c6ef150 137 // does the input name match any of our light resources?
ansond 0:a3fc1c6ef150 138 int MBEDEndpoint::indexOfLight(char *name) {
ansond 0:a3fc1c6ef150 139 bool found = false;
ansond 0:a3fc1c6ef150 140 int index = -1;
ansond 0:a3fc1c6ef150 141
ansond 0:a3fc1c6ef150 142 for(int i=0;i<NUM_LIGHTS && !found;++i) {
ansond 0:a3fc1c6ef150 143 if (strcmp(this->m_lights[i]->getName(),name) == 0) {
ansond 0:a3fc1c6ef150 144 found = true;
ansond 0:a3fc1c6ef150 145 index = i;
ansond 0:a3fc1c6ef150 146 }
ansond 0:a3fc1c6ef150 147 }
ansond 0:a3fc1c6ef150 148
ansond 0:a3fc1c6ef150 149 return index;
ansond 0:a3fc1c6ef150 150 }
ansond 0:a3fc1c6ef150 151
ansond 0:a3fc1c6ef150 152 // get a specific resources
ansond 0:a3fc1c6ef150 153 ResourceFactory *MBEDEndpoint::getResources(int index) {
ansond 0:a3fc1c6ef150 154 if (index >= 0 && index < NUM_LIGHTS) return this->m_lights[index]->resources();
ansond 0:a3fc1c6ef150 155 return NULL;
ansond 0:a3fc1c6ef150 156 }
ansond 0:a3fc1c6ef150 157
ansond 5:1ba6e68bf50e 158 // initialize the ResourceFactory to fit our personality
ansond 5:1ba6e68bf50e 159 ResourceFactory *MBEDEndpoint::initResourceFactory() {
ansond 5:1ba6e68bf50e 160 #ifdef LIGHT_PERSONALITY
ansond 5:1ba6e68bf50e 161 return this->initLightResourceFactory();
ansond 5:1ba6e68bf50e 162 #else
ansond 5:1ba6e68bf50e 163 return NULL;
ansond 5:1ba6e68bf50e 164 #endif
ansond 5:1ba6e68bf50e 165 }
ansond 5:1ba6e68bf50e 166
ansond 5:1ba6e68bf50e 167 // initialize a Light Resource Factory
ansond 5:1ba6e68bf50e 168 ResourceFactory *MBEDEndpoint::initLightResourceFactory() { return new EmulatedLightResourceFactory(this->logger(),(void *)this); }
ansond 0:a3fc1c6ef150 169
ansond 0:a3fc1c6ef150 170 // Initialize the Endpoint Name - will be the first Light resource name (and there must be one...)
ansond 0:a3fc1c6ef150 171 void MBEDEndpoint::initEndpointName() {
ansond 0:a3fc1c6ef150 172 this->m_instance_id = this->preferences()->getIntPreference("endpoint_id",LIGHT_NAME_INDEX);
ansond 0:a3fc1c6ef150 173 memset(this->m_endpoint_name,0,LIGHT_NAME_LEN+1);
ansond 0:a3fc1c6ef150 174 sprintf(this->m_endpoint_name,LIGHT_NAME,this->m_instance_id);
ansond 0:a3fc1c6ef150 175 }
ansond 0:a3fc1c6ef150 176
ansond 0:a3fc1c6ef150 177 // get our endpoint name
ansond 0:a3fc1c6ef150 178 char *MBEDEndpoint::getEndpointName() { return this->m_endpoint_name; }
ansond 0:a3fc1c6ef150 179
ansond 0:a3fc1c6ef150 180 // get our instance id
ansond 0:a3fc1c6ef150 181 int MBEDEndpoint::getInstanceID() { return this->m_instance_id; }
ansond 0:a3fc1c6ef150 182
ansond 0:a3fc1c6ef150 183 // initialize a specific transport
ansond 0:a3fc1c6ef150 184 bool MBEDEndpoint::initializeTransport(int index,char *key,Transport *transport) {
ansond 0:a3fc1c6ef150 185 bool success = false;
ansond 0:a3fc1c6ef150 186 if (this->m_transports[index] == NULL) {
ansond 0:a3fc1c6ef150 187 this->logger()->log("Initializing %s Transport...", key);
ansond 0:a3fc1c6ef150 188 this->m_transports[index] = transport;
ansond 0:a3fc1c6ef150 189 if (this->m_transports[index] != NULL) success = this->m_transports[index]->connect();
ansond 0:a3fc1c6ef150 190 if (success) this->logger()->log("Transport %s initialized and connected",key);
ansond 0:a3fc1c6ef150 191 }
ansond 0:a3fc1c6ef150 192 else {
ansond 0:a3fc1c6ef150 193 this->logger()->log("%s already connected (OK)...", key);
ansond 0:a3fc1c6ef150 194 success = true;
ansond 0:a3fc1c6ef150 195 }
ansond 0:a3fc1c6ef150 196 return success;
ansond 0:a3fc1c6ef150 197 }
ansond 0:a3fc1c6ef150 198
ansond 0:a3fc1c6ef150 199 // initialize our transports
ansond 0:a3fc1c6ef150 200 bool MBEDEndpoint::initializeTransports() {
ansond 0:a3fc1c6ef150 201 bool success = true;
ansond 0:a3fc1c6ef150 202
ansond 0:a3fc1c6ef150 203 if (success == true) {
ansond 0:a3fc1c6ef150 204 // MQTT Initialization
ansond 0:a3fc1c6ef150 205 success = this->initializeTransport(MQTT_TRANSPORT,"MQTT",new MQTTTransport(this->m_error_handler,this,this->getMap()));
ansond 0:a3fc1c6ef150 206 }
ansond 0:a3fc1c6ef150 207
ansond 0:a3fc1c6ef150 208 if (success == true) {
ansond 0:a3fc1c6ef150 209 // HTTP Initialization
ansond 0:a3fc1c6ef150 210 success = this->initializeTransport(HTTP_TRANSPORT,"HTTP",new IOCHTTPTransport(this->m_error_handler,this));
ansond 0:a3fc1c6ef150 211 }
ansond 0:a3fc1c6ef150 212 return success;
ansond 0:a3fc1c6ef150 213 }
ansond 0:a3fc1c6ef150 214
ansond 0:a3fc1c6ef150 215 // initialize our Ethernet
ansond 0:a3fc1c6ef150 216 bool MBEDEndpoint::initializeEthernet(EthernetInterface *ethernet) {
ansond 0:a3fc1c6ef150 217 bool success = false;
ansond 0:a3fc1c6ef150 218 this->m_ethernet = ethernet;
ansond 0:a3fc1c6ef150 219 if (this->m_ethernet != NULL) {
ansond 0:a3fc1c6ef150 220 this->logger()->log("Initializing Ethernet...");
ansond 0:a3fc1c6ef150 221
ansond 0:a3fc1c6ef150 222 // connect up ethernet
ansond 0:a3fc1c6ef150 223 this->m_ethernet->init();
ansond 0:a3fc1c6ef150 224 this->m_ethernet->connect();
ansond 0:a3fc1c6ef150 225
ansond 0:a3fc1c6ef150 226 // display our IP address
ansond 0:a3fc1c6ef150 227 char *ipaddr = this->m_ethernet->getIPAddress();
ansond 0:a3fc1c6ef150 228 if (ipaddr != NULL && strlen(ipaddr) > 0) {
ansond 0:a3fc1c6ef150 229 this->logger()->log("IPAddress: %s",this->m_ethernet->getIPAddress());
ansond 0:a3fc1c6ef150 230 success = true;
ansond 0:a3fc1c6ef150 231 }
ansond 0:a3fc1c6ef150 232 else {
ansond 0:a3fc1c6ef150 233 this->logger()->log("Ethernet Not Connected...");
ansond 0:a3fc1c6ef150 234 success = false;
ansond 0:a3fc1c6ef150 235 }
ansond 0:a3fc1c6ef150 236 }
ansond 0:a3fc1c6ef150 237 else {
ansond 0:a3fc1c6ef150 238 this->logger()->log("No Ethernet instance found");
ansond 0:a3fc1c6ef150 239 success = false;
ansond 0:a3fc1c6ef150 240 }
ansond 0:a3fc1c6ef150 241 return success;
ansond 0:a3fc1c6ef150 242 }
ansond 0:a3fc1c6ef150 243
ansond 0:a3fc1c6ef150 244 // load up all endpoints into the IOC
ansond 0:a3fc1c6ef150 245 bool MBEDEndpoint::loadEndpoints() {
ansond 0:a3fc1c6ef150 246 bool success = true;
ansond 0:a3fc1c6ef150 247 this->logger()->log("Loading All Endpoints to IOC...");
ansond 0:a3fc1c6ef150 248 for(int i=0;i<NUM_LIGHTS && success;++i) success = this->loadEndpoint(this->m_lights[i]);
ansond 0:a3fc1c6ef150 249 return success;
ansond 0:a3fc1c6ef150 250 }
ansond 0:a3fc1c6ef150 251
ansond 0:a3fc1c6ef150 252 // load up our endpoint to the IOC
ansond 0:a3fc1c6ef150 253 bool MBEDEndpoint::loadEndpoint(Light *light) {
ansond 0:a3fc1c6ef150 254 bool success = false;
ansond 0:a3fc1c6ef150 255 char result[IOC_RESULT_LEN+1];
ansond 0:a3fc1c6ef150 256 char payload[IOC_PAYLOAD_LEN+1];
ansond 0:a3fc1c6ef150 257
ansond 0:a3fc1c6ef150 258 // initialize
ansond 0:a3fc1c6ef150 259 memset(result,0,IOC_RESULT_LEN+1);
ansond 0:a3fc1c6ef150 260 memset(payload,0,IOC_PAYLOAD_LEN+1);
ansond 0:a3fc1c6ef150 261
ansond 0:a3fc1c6ef150 262 // DEBUG
ansond 0:a3fc1c6ef150 263 this->logger()->log("Building Payload for Light: %s...",light->getName());
ansond 0:a3fc1c6ef150 264
ansond 0:a3fc1c6ef150 265 // build the payload
ansond 0:a3fc1c6ef150 266 char *data = this->buildIOCPayload(payload,IOC_PAYLOAD_LEN,light);
ansond 0:a3fc1c6ef150 267
ansond 0:a3fc1c6ef150 268 // issue the request
ansond 0:a3fc1c6ef150 269 if (data != NULL && strlen(data) > 0) {
ansond 0:a3fc1c6ef150 270 // DEBUG
ansond 0:a3fc1c6ef150 271 this->logger()->log("Sending Light: %s to the IOC...",light->getName());
ansond 0:a3fc1c6ef150 272
ansond 0:a3fc1c6ef150 273 // load
ansond 0:a3fc1c6ef150 274 success = this->m_transports[LOAD_TRANSPORT]->loadEndpoint((char *)payload,strlen(payload),(char *)result,IOC_RESULT_LEN);
ansond 0:a3fc1c6ef150 275 }
ansond 0:a3fc1c6ef150 276
ansond 0:a3fc1c6ef150 277 // DEBUG
ansond 0:a3fc1c6ef150 278 //if (success) this->logger()->log("Saving IOC ID for Light: %s...",light->getName());
ansond 0:a3fc1c6ef150 279
ansond 0:a3fc1c6ef150 280 // update the IOC ID if found
ansond 0:a3fc1c6ef150 281 if (success) this->saveIOCID(light,result);
ansond 0:a3fc1c6ef150 282
ansond 0:a3fc1c6ef150 283 // DEBUG
ansond 0:a3fc1c6ef150 284 if (success) this->logger()->log("Light: %s IOC ID=%d sent successfully",light->getName(),light->getIOCID());
ansond 0:a3fc1c6ef150 285
ansond 0:a3fc1c6ef150 286 // DEBUG
ansond 0:a3fc1c6ef150 287 if (!success) {
ansond 0:a3fc1c6ef150 288 if (light != NULL) this->logger()->log("Light: %s send FAILED",light->getName());
ansond 0:a3fc1c6ef150 289 else this->logger()->log("Light: send FAILED (NULL LIGHT)");
ansond 0:a3fc1c6ef150 290 }
ansond 0:a3fc1c6ef150 291
ansond 0:a3fc1c6ef150 292 // return our status
ansond 0:a3fc1c6ef150 293 return success;
ansond 0:a3fc1c6ef150 294 }
ansond 0:a3fc1c6ef150 295
ansond 0:a3fc1c6ef150 296 // update all endpoints to the IOC
ansond 0:a3fc1c6ef150 297 bool MBEDEndpoint::updateEndpoints() {
ansond 0:a3fc1c6ef150 298 bool success = true;
ansond 0:a3fc1c6ef150 299 for(int i=0;i<NUM_LIGHTS && success;++i) success = this->updateEndpoints(i);
ansond 0:a3fc1c6ef150 300 return success;
ansond 0:a3fc1c6ef150 301 }
ansond 0:a3fc1c6ef150 302
ansond 0:a3fc1c6ef150 303 // update all endpoints to the IOC
ansond 0:a3fc1c6ef150 304 bool MBEDEndpoint::updateEndpoints(int index) {
ansond 0:a3fc1c6ef150 305 if (index >= 0 && index < NUM_LIGHTS) return this->updateEndpoint(this->m_lights[index]);
ansond 0:a3fc1c6ef150 306 return false;
ansond 0:a3fc1c6ef150 307 }
ansond 0:a3fc1c6ef150 308
ansond 0:a3fc1c6ef150 309 // update our endpoint with the IOC
ansond 0:a3fc1c6ef150 310 bool MBEDEndpoint::updateEndpoint(Light *light) {
ansond 0:a3fc1c6ef150 311 bool success = false;
ansond 0:a3fc1c6ef150 312 char result[IOC_RESULT_LEN+1];
ansond 0:a3fc1c6ef150 313 char payload[IOC_PAYLOAD_LEN+1];
ansond 0:a3fc1c6ef150 314
ansond 0:a3fc1c6ef150 315 // initialize
ansond 0:a3fc1c6ef150 316 memset(result,0,IOC_RESULT_LEN+1);
ansond 0:a3fc1c6ef150 317 memset(payload,0,IOC_PAYLOAD_LEN+1);
ansond 0:a3fc1c6ef150 318
ansond 0:a3fc1c6ef150 319 // build the payload
ansond 0:a3fc1c6ef150 320 char *data = this->buildIOCPayload(payload,IOC_PAYLOAD_LEN,light);
ansond 0:a3fc1c6ef150 321
ansond 0:a3fc1c6ef150 322 // issue the request
ansond 0:a3fc1c6ef150 323 if (data != NULL && strlen(data) > 0) {
ansond 0:a3fc1c6ef150 324 // DEBUG
ansond 0:a3fc1c6ef150 325 this->logger()->log("Updating Light: %s at the IOC...",light->getName());
ansond 0:a3fc1c6ef150 326
ansond 0:a3fc1c6ef150 327 // update
ansond 0:a3fc1c6ef150 328 success = this->m_transports[LOAD_TRANSPORT]->updateEndpoint(light->getIOCID(),(char *)payload,strlen(payload),(char *)result,IOC_RESULT_LEN);
ansond 0:a3fc1c6ef150 329 }
ansond 0:a3fc1c6ef150 330
ansond 0:a3fc1c6ef150 331 // DEBUG
ansond 0:a3fc1c6ef150 332 if (success) this->logger()->log("Update of Endpoint to IOC successful");
ansond 0:a3fc1c6ef150 333 else this->logger()->log("Update of Endpoint to IOC FAILED");
ansond 0:a3fc1c6ef150 334
ansond 0:a3fc1c6ef150 335 // return our status
ansond 0:a3fc1c6ef150 336 return success;
ansond 0:a3fc1c6ef150 337 }
ansond 0:a3fc1c6ef150 338
ansond 0:a3fc1c6ef150 339 // build out the Payload
ansond 0:a3fc1c6ef150 340 char *MBEDEndpoint::buildIOCPayload(char *data,int data_length,Light *light) {
ansond 0:a3fc1c6ef150 341 char tmp[TEMP_BUFFER_LEN+1];
ansond 0:a3fc1c6ef150 342
ansond 0:a3fc1c6ef150 343 // construct the payload for Load/Updates
ansond 0:a3fc1c6ef150 344 ResourceFactory *factory = light->getResourceFactory();
ansond 0:a3fc1c6ef150 345
ansond 0:a3fc1c6ef150 346 // start the buffer
ansond 0:a3fc1c6ef150 347 strcat(data,"{");
ansond 0:a3fc1c6ef150 348
ansond 0:a3fc1c6ef150 349 // loop through the resources and build a JSON representation for the payload
ansond 0:a3fc1c6ef150 350 for(int i=0;i<factory->numResources();++i) {
ansond 0:a3fc1c6ef150 351 // get the ith resource
ansond 0:a3fc1c6ef150 352 Resource *resource = factory->getResource(i);
ansond 0:a3fc1c6ef150 353 if (resource != NULL) {
ansond 0:a3fc1c6ef150 354 // add to the JSON payload
ansond 0:a3fc1c6ef150 355 char *name = this->getMap()->endpointNameToIOCName(resource->getName());
ansond 0:a3fc1c6ef150 356 char *value = resource->getValue();
ansond 0:a3fc1c6ef150 357
ansond 0:a3fc1c6ef150 358 // make sure that we have a positive IOC resource match for the NSP resource
ansond 0:a3fc1c6ef150 359 if (name != NULL && strlen(name) > 0) {
ansond 0:a3fc1c6ef150 360 // Handle LOCATION a special way
ansond 0:a3fc1c6ef150 361 if (strcmp(name,"LOCATION") != 0) {
ansond 0:a3fc1c6ef150 362 // standard name,value for IOC
ansond 0:a3fc1c6ef150 363 sprintf(tmp, "\"%s\":\"%s\",",name,value);
ansond 0:a3fc1c6ef150 364 }
ansond 0:a3fc1c6ef150 365 else {
ansond 0:a3fc1c6ef150 366 // IOC expects "Point(X,Y)" for LOCATION
ansond 0:a3fc1c6ef150 367 sprintf(tmp, "\"%s\":\"Point(%s)\",",name,value);
ansond 0:a3fc1c6ef150 368 }
ansond 0:a3fc1c6ef150 369 strcat(data,tmp);
ansond 0:a3fc1c6ef150 370
ansond 0:a3fc1c6ef150 371 // Handle /dev/addldata
ansond 0:a3fc1c6ef150 372 char *dev_addldata = this->getMap()->endpointNameToIOCName("/dev/addldata");
ansond 0:a3fc1c6ef150 373 if (dev_addldata != NULL && strcmp(name,dev_addldata) == 0 && light != NULL && light->getIOCID() > 0) {
ansond 0:a3fc1c6ef150 374 char buf[IOC_IOC_ID_LEN+1]; memset(buf,0,IOC_IOC_ID_LEN+1); sprintf(buf,"%d",light->getIOCID());
ansond 0:a3fc1c6ef150 375 sprintf(tmp,"\"%s\":\"id:%s\",",name,buf);
ansond 0:a3fc1c6ef150 376 strcat(data,tmp);
ansond 0:a3fc1c6ef150 377 }
ansond 0:a3fc1c6ef150 378 }
ansond 0:a3fc1c6ef150 379 }
ansond 0:a3fc1c6ef150 380 }
ansond 0:a3fc1c6ef150 381
ansond 0:a3fc1c6ef150 382 // Special Case: STARTDATETIME
ansond 0:a3fc1c6ef150 383 strcat(data,ENDPOINT_STARTTIME);
ansond 0:a3fc1c6ef150 384
ansond 0:a3fc1c6ef150 385 // Special Case: ENDDATETIME
ansond 0:a3fc1c6ef150 386 strcat(data,ENDPOINT_STOPTIME);
ansond 0:a3fc1c6ef150 387
ansond 0:a3fc1c6ef150 388 // Special Case: NAME
ansond 0:a3fc1c6ef150 389 sprintf(tmp,"\"NAME\":\"%s\",",light->getName());
ansond 0:a3fc1c6ef150 390 strcat(data,tmp);
ansond 0:a3fc1c6ef150 391
ansond 0:a3fc1c6ef150 392 // Special Case: TIMEZONEOFFSET
ansond 0:a3fc1c6ef150 393 strcat(data,ENDPOINT_TIMEZONE);
ansond 0:a3fc1c6ef150 394
ansond 0:a3fc1c6ef150 395 // close
ansond 0:a3fc1c6ef150 396 strcat(data,"}");
ansond 0:a3fc1c6ef150 397
ansond 0:a3fc1c6ef150 398 // DEBUG
ansond 0:a3fc1c6ef150 399 //this->logger()->log("Loading Payload: %s",data);
ansond 0:a3fc1c6ef150 400
ansond 0:a3fc1c6ef150 401 // return the payload
ansond 0:a3fc1c6ef150 402 return data;
ansond 0:a3fc1c6ef150 403 }
ansond 0:a3fc1c6ef150 404
ansond 0:a3fc1c6ef150 405 // save the IOC ID
ansond 0:a3fc1c6ef150 406 void MBEDEndpoint::saveIOCID(Light *light,char *json) {
ansond 0:a3fc1c6ef150 407 if (json != NULL) {
ansond 0:a3fc1c6ef150 408 //this->logger()->log("RESULT: %s",json);
ansond 0:a3fc1c6ef150 409
ansond 0:a3fc1c6ef150 410 // look for "id":
ansond 0:a3fc1c6ef150 411 char *check = "\"id\":";
ansond 0:a3fc1c6ef150 412 char *pos1 = strstr(json,check);
ansond 0:a3fc1c6ef150 413 if (pos1 != NULL) {
ansond 0:a3fc1c6ef150 414 char *pos2 = strstr(pos1,",");
ansond 0:a3fc1c6ef150 415 if (pos1 != NULL && pos2 != NULL && pos2 > pos1) {
ansond 0:a3fc1c6ef150 416 pos1 += strlen(check);
ansond 0:a3fc1c6ef150 417 int length = pos2 - pos1;
ansond 0:a3fc1c6ef150 418 char str_ioc_id[IOC_IOC_ID_LEN+1];
ansond 0:a3fc1c6ef150 419 memset(str_ioc_id,0,IOC_IOC_ID_LEN+1);
ansond 0:a3fc1c6ef150 420 strncpy(str_ioc_id,pos1,length);
ansond 0:a3fc1c6ef150 421
ansond 0:a3fc1c6ef150 422 // DEBUG
ansond 0:a3fc1c6ef150 423 //this->logger()->log("IOC ID found: %s",str_ioc_id);
ansond 0:a3fc1c6ef150 424
ansond 0:a3fc1c6ef150 425 // parse into int
ansond 0:a3fc1c6ef150 426 int ioc_id = 0;
ansond 0:a3fc1c6ef150 427 sscanf(str_ioc_id,"%d",&ioc_id);
ansond 0:a3fc1c6ef150 428
ansond 0:a3fc1c6ef150 429 // save the IOC ID
ansond 0:a3fc1c6ef150 430 if (ioc_id > 0) light->setIOCID(ioc_id);
ansond 0:a3fc1c6ef150 431 }
ansond 0:a3fc1c6ef150 432 else {
ansond 0:a3fc1c6ef150 433 // cannot find the ID tag in the result JSON
ansond 0:a3fc1c6ef150 434 this->logger()->log("Cannot find the IOC ID in the JSON result");
ansond 0:a3fc1c6ef150 435 this->logger()->log("JSON: %s",json);
ansond 0:a3fc1c6ef150 436 }
ansond 0:a3fc1c6ef150 437 }
ansond 0:a3fc1c6ef150 438 else {
ansond 0:a3fc1c6ef150 439 // cannot find the ID tag in the result JSON
ansond 0:a3fc1c6ef150 440 this->logger()->log("Cannot find the IOC ID in the JSON result");
ansond 0:a3fc1c6ef150 441 this->logger()->log("JSON: %s",json);
ansond 0:a3fc1c6ef150 442 }
ansond 0:a3fc1c6ef150 443 }
ansond 0:a3fc1c6ef150 444 }
ansond 0:a3fc1c6ef150 445
ansond 5:1ba6e68bf50e 446 // close down our endpoint personality
ansond 5:1ba6e68bf50e 447 bool MBEDEndpoint::closeEndpointPersonality() {
ansond 5:1ba6e68bf50e 448 #ifdef LIGHT_PERSONALITY
ansond 5:1ba6e68bf50e 449 return this->closeLights();
ansond 5:1ba6e68bf50e 450 #else
ansond 5:1ba6e68bf50e 451 return NULL;
ansond 5:1ba6e68bf50e 452 #endif
ansond 5:1ba6e68bf50e 453 }
ansond 5:1ba6e68bf50e 454
ansond 0:a3fc1c6ef150 455 // close down the Lights
ansond 0:a3fc1c6ef150 456 bool MBEDEndpoint::closeLights() {
ansond 0:a3fc1c6ef150 457 bool success = true;
ansond 0:a3fc1c6ef150 458 this->logger()->log("Closing down Lights...");
ansond 0:a3fc1c6ef150 459 for(int i=0;i<NUM_LIGHTS;++i)
ansond 0:a3fc1c6ef150 460 if (this->m_lights[i] != NULL) delete this->m_lights[i];
ansond 0:a3fc1c6ef150 461 return success;
ansond 0:a3fc1c6ef150 462 }
ansond 0:a3fc1c6ef150 463
ansond 0:a3fc1c6ef150 464 // close a given transport
ansond 0:a3fc1c6ef150 465 bool MBEDEndpoint::closeTransport(int index,char *key) {
ansond 0:a3fc1c6ef150 466 this->logger()->log("Closing down %s Transport...", key);
ansond 0:a3fc1c6ef150 467 if (this->m_transports[index] != NULL) delete this->m_transports[index];
ansond 0:a3fc1c6ef150 468 return true;
ansond 0:a3fc1c6ef150 469 }
ansond 0:a3fc1c6ef150 470
ansond 0:a3fc1c6ef150 471 // close down our transports
ansond 0:a3fc1c6ef150 472 bool MBEDEndpoint::closeTransports() {
ansond 0:a3fc1c6ef150 473 bool success = true;
ansond 0:a3fc1c6ef150 474
ansond 0:a3fc1c6ef150 475 if (success) {
ansond 0:a3fc1c6ef150 476 // close MQTT
ansond 0:a3fc1c6ef150 477 success = this->closeTransport(MQTT_TRANSPORT,"MQTT");
ansond 0:a3fc1c6ef150 478 }
ansond 0:a3fc1c6ef150 479
ansond 0:a3fc1c6ef150 480 if (success) {
ansond 0:a3fc1c6ef150 481 // close HTTP
ansond 0:a3fc1c6ef150 482 success = this->closeTransport(HTTP_TRANSPORT,"HTTP");
ansond 0:a3fc1c6ef150 483 }
ansond 0:a3fc1c6ef150 484
ansond 0:a3fc1c6ef150 485 return success;
ansond 0:a3fc1c6ef150 486 }
ansond 0:a3fc1c6ef150 487
ansond 0:a3fc1c6ef150 488 // close down our Ethernet
ansond 0:a3fc1c6ef150 489 bool MBEDEndpoint::closeEthernet() {
ansond 0:a3fc1c6ef150 490 this->logger()->log("Closing down Ethernet...");
ansond 0:a3fc1c6ef150 491 if (this->m_ethernet != NULL) this->m_ethernet->disconnect();
ansond 0:a3fc1c6ef150 492 return true;
ansond 0:a3fc1c6ef150 493 }
ansond 0:a3fc1c6ef150 494
ansond 0:a3fc1c6ef150 495 // min function
ansond 0:a3fc1c6ef150 496 int MBEDEndpoint::min(int value1,int value2) {
ansond 0:a3fc1c6ef150 497 if (value1 < value2) return value1;
ansond 0:a3fc1c6ef150 498 return value2;
ansond 0:a3fc1c6ef150 499 }
ansond 0:a3fc1c6ef150 500
ansond 0:a3fc1c6ef150 501 // get our error handler
ansond 0:a3fc1c6ef150 502 ErrorHandler *MBEDEndpoint::logger() { return this->m_error_handler; }
ansond 0:a3fc1c6ef150 503
ansond 0:a3fc1c6ef150 504 // main running loop
ansond 0:a3fc1c6ef150 505 void MBEDEndpoint::run() {
ansond 0:a3fc1c6ef150 506 this->logger()->log("Endpoint Main Loop");
ansond 0:a3fc1c6ef150 507 while(true) {
ansond 0:a3fc1c6ef150 508 // sleep a bit
ansond 0:a3fc1c6ef150 509 //this->logger()->log("Sleeping for a bit...");
ansond 0:a3fc1c6ef150 510 wait_ms(MAIN_LOOP_SLEEP);
ansond 0:a3fc1c6ef150 511
ansond 0:a3fc1c6ef150 512 // check for events
ansond 0:a3fc1c6ef150 513 //this->logger()->log("Processing Events...");
ansond 0:a3fc1c6ef150 514 for(int i=0;i<NUM_TRANSPORTS;++i) this->m_transports[i]->checkAndProcess();
ansond 0:a3fc1c6ef150 515
ansond 0:a3fc1c6ef150 516 // check for exit
ansond 0:a3fc1c6ef150 517 //this->logger()->log("Checking for exit...");
ansond 0:a3fc1c6ef150 518 this->logger()->checkForExit();
ansond 0:a3fc1c6ef150 519 }
ansond 0:a3fc1c6ef150 520 }
ansond 0:a3fc1c6ef150 521