MBED_DEMOS / Mbed 2 deprecated mbed_mqtt_endpoint_ublox_ethernet

Dependencies:   C027 C12832 EthernetInterface StatusReporter LM75B MQTT-ansond endpoint_core endpoint_mqtt mbed-rtos mbed

Committer:
ansond
Date:
Tue Feb 25 16:56:31 2014 +0000
Revision:
0:ae2a45502448
Child:
2:90a84a216c58
initial checkin

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:ae2a45502448 1 /* Copyright C2013 Doug Anson, MIT License
ansond 0:ae2a45502448 2 *
ansond 0:ae2a45502448 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
ansond 0:ae2a45502448 4 * and associated documentation files the "Software", to deal in the Software without restriction,
ansond 0:ae2a45502448 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
ansond 0:ae2a45502448 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
ansond 0:ae2a45502448 7 * furnished to do so, subject to the following conditions:
ansond 0:ae2a45502448 8 *
ansond 0:ae2a45502448 9 * The above copyright notice and this permission notice shall be included in all copies or
ansond 0:ae2a45502448 10 * substantial portions of the Software.
ansond 0:ae2a45502448 11 *
ansond 0:ae2a45502448 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
ansond 0:ae2a45502448 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ansond 0:ae2a45502448 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
ansond 0:ae2a45502448 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ansond 0:ae2a45502448 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ansond 0:ae2a45502448 17 */
ansond 0:ae2a45502448 18
ansond 0:ae2a45502448 19 #include "MQTTTransport.h"
ansond 0:ae2a45502448 20
ansond 0:ae2a45502448 21 #include "MBEDEndpoint.h"
ansond 0:ae2a45502448 22
ansond 0:ae2a45502448 23 // String splitting support
ansond 0:ae2a45502448 24 #include "splitstring.h"
ansond 0:ae2a45502448 25
ansond 0:ae2a45502448 26 // our transmitt instance
ansond 0:ae2a45502448 27 MQTTTransport *instance = NULL;
ansond 0:ae2a45502448 28
ansond 0:ae2a45502448 29 // MQTT callback to handle received messages
ansond 0:ae2a45502448 30 void _mqtt_message_handler(char *topic,char *payload,unsigned int length) {
ansond 0:ae2a45502448 31 if (instance != NULL) instance->processMessage((char *)payload,length);
ansond 0:ae2a45502448 32 }
ansond 0:ae2a45502448 33
ansond 0:ae2a45502448 34 // our MQTT client endpoint
ansond 0:ae2a45502448 35 PubSubClient _mqtt(MQTT_HOSTNAME,MQTT_HOSTPORT,_mqtt_message_handler);
ansond 0:ae2a45502448 36
ansond 0:ae2a45502448 37 // default constructor
ansond 0:ae2a45502448 38 MQTTTransport::MQTTTransport(ErrorHandler *error_handler) : Transport(error_handler) {
ansond 0:ae2a45502448 39 this->m_mqtt = NULL;
ansond 0:ae2a45502448 40 instance = this;
ansond 0:ae2a45502448 41 this->m_map = new MBEDToIOCResourceMap();
ansond 0:ae2a45502448 42 }
ansond 0:ae2a45502448 43
ansond 0:ae2a45502448 44 // default destructor
ansond 0:ae2a45502448 45 MQTTTransport::~MQTTTransport() {
ansond 0:ae2a45502448 46 this->disconnect();
ansond 0:ae2a45502448 47 if (this->m_mqtt != NULL) delete this->m_mqtt;
ansond 0:ae2a45502448 48 }
ansond 0:ae2a45502448 49
ansond 0:ae2a45502448 50 // process a MQTT Message
ansond 0:ae2a45502448 51 void MQTTTransport::processMessage(char *payload, unsigned int len) {
ansond 0:ae2a45502448 52 string message_type;
ansond 0:ae2a45502448 53 string message_name;
ansond 0:ae2a45502448 54 string message_verb;
ansond 0:ae2a45502448 55 string message_value;
ansond 0:ae2a45502448 56 string message_opt;
ansond 0:ae2a45502448 57 MBEDEndpoint *endpoint = (MBEDEndpoint *)this->getEndpoint();
ansond 0:ae2a45502448 58
ansond 0:ae2a45502448 59 // DEBUG
ansond 0:ae2a45502448 60 this->logger()->log("MQTT Message: %s length=%d",payload,len);
ansond 0:ae2a45502448 61
ansond 0:ae2a45502448 62 // split the string by the delimiter
ansond 0:ae2a45502448 63 splitstring str_payload(payload);
ansond 0:ae2a45502448 64 vector<string> data = str_payload.split(':');
ansond 0:ae2a45502448 65
ansond 0:ae2a45502448 66 // format of the MQTT message: message_type:name:verb|Parameter_X:value|keyword:optional_data
ansond 0:ae2a45502448 67 if (data.size() > 0) message_type = data[0];
ansond 0:ae2a45502448 68 if (data.size() > 1) message_name = data[1];
ansond 0:ae2a45502448 69 if (data.size() > 2) message_verb = data[2];
ansond 0:ae2a45502448 70 if (data.size() > 3) message_value = data[3];
ansond 0:ae2a45502448 71 if (data.size() > 4) message_opt = data[4];
ansond 0:ae2a45502448 72
ansond 0:ae2a45502448 73 // load endpoints
ansond 0:ae2a45502448 74 if (strcmp(message_type.c_str(),"endpoint") == 0) {
ansond 0:ae2a45502448 75 if (strcmp(message_name.c_str(),"all") == 0) {
ansond 0:ae2a45502448 76 if (strcmp(message_verb.c_str(),"load") == 0) {
ansond 0:ae2a45502448 77 // load up our endpoint
ansond 0:ae2a45502448 78 endpoint->loadEndpoint();
ansond 0:ae2a45502448 79 }
ansond 0:ae2a45502448 80 if (strcmp(message_verb.c_str(),"update") == 0) {
ansond 0:ae2a45502448 81 // update our endpoint
ansond 0:ae2a45502448 82 endpoint->updateEndpoint();
ansond 0:ae2a45502448 83 }
ansond 0:ae2a45502448 84 }
ansond 0:ae2a45502448 85 else {
ansond 0:ae2a45502448 86 // destined for our lights?
ansond 0:ae2a45502448 87 int index = endpoint->indexOfLight((char *)message_name.c_str());
ansond 0:ae2a45502448 88 if (index >= 0) {
ansond 0:ae2a45502448 89 if (strcmp(message_verb.c_str(),"update") == 0) {
ansond 0:ae2a45502448 90 // update our endpoint
ansond 0:ae2a45502448 91 endpoint->updateEndpoint();
ansond 0:ae2a45502448 92 }
ansond 0:ae2a45502448 93 }
ansond 0:ae2a45502448 94 }
ansond 0:ae2a45502448 95 }
ansond 0:ae2a45502448 96
ansond 0:ae2a45502448 97 // change a resource value
ansond 0:ae2a45502448 98 if (strcmp(message_type.c_str(),"change") == 0) {
ansond 0:ae2a45502448 99 // destined for our lights?
ansond 0:ae2a45502448 100 int index = endpoint->indexOfLight((char *)message_name.c_str());
ansond 0:ae2a45502448 101 if (index >= 0) {
ansond 0:ae2a45502448 102 // map the parameter to one of ours
ansond 0:ae2a45502448 103 char *mapped_resource = this->mapEndpointResourceToIOCResource((char *)message_verb.c_str());
ansond 0:ae2a45502448 104 if (mapped_resource != NULL) {
ansond 0:ae2a45502448 105 ResourceFactory *factory = endpoint->getResources(index);
ansond 0:ae2a45502448 106 factory->setResourceValue((char *)message_name.c_str(),(char *)message_value.c_str());
ansond 0:ae2a45502448 107 }
ansond 0:ae2a45502448 108 }
ansond 0:ae2a45502448 109 }
ansond 0:ae2a45502448 110
ansond 0:ae2a45502448 111 // get a resource value
ansond 0:ae2a45502448 112 if (strcmp(message_type.c_str(),"get") == 0) {
ansond 0:ae2a45502448 113 // destined for our lights?
ansond 0:ae2a45502448 114 int index = endpoint->indexOfLight((char *)message_name.c_str());
ansond 0:ae2a45502448 115 if (index >= 0) {
ansond 0:ae2a45502448 116 // map the parameter to one of ours
ansond 0:ae2a45502448 117 char *mapped_resource = this->mapEndpointResourceToIOCResource((char *)message_verb.c_str());
ansond 0:ae2a45502448 118 if (mapped_resource != NULL) {
ansond 0:ae2a45502448 119 ResourceFactory *factory = endpoint->getResources(index);
ansond 0:ae2a45502448 120 char *resource_value = factory->getResourceValue((char *)message_name.c_str());
ansond 0:ae2a45502448 121
ansond 0:ae2a45502448 122 // end the resource value back over MQTT
ansond 0:ae2a45502448 123 this->sendResourceValue((char *)message_name.c_str(),(char *)message_verb.c_str(),resource_value);
ansond 0:ae2a45502448 124 }
ansond 0:ae2a45502448 125 }
ansond 0:ae2a45502448 126 }
ansond 0:ae2a45502448 127 }
ansond 0:ae2a45502448 128
ansond 0:ae2a45502448 129 void MQTTTransport::sendResourceValue(char *endpoint_name,char *parameter_name,char *value) {
ansond 0:ae2a45502448 130 }
ansond 0:ae2a45502448 131
ansond 0:ae2a45502448 132 char *MQTTTransport::mapEndpointResourceToIOCResource(char *ioc_name) {
ansond 0:ae2a45502448 133 return this->m_map->getMBEDMappedName(ioc_name);
ansond 0:ae2a45502448 134 }
ansond 0:ae2a45502448 135
ansond 0:ae2a45502448 136 char *MQTTTransport::makeID(char *id_template,char *buffer) {
ansond 0:ae2a45502448 137 srand(time(0));
ansond 0:ae2a45502448 138 srand(rand());
ansond 0:ae2a45502448 139 sprintf(buffer,id_template,rand()%MQTT_MAXID_VALUE);
ansond 0:ae2a45502448 140 return buffer;
ansond 0:ae2a45502448 141 }
ansond 0:ae2a45502448 142
ansond 0:ae2a45502448 143 // connect up MQTT
ansond 0:ae2a45502448 144 bool MQTTTransport::connect() {
ansond 0:ae2a45502448 145 char mqtt_id[MQTT_ENDPOINT_IDLEN+1];
ansond 0:ae2a45502448 146 memset(mqtt_id,0,(MQTT_ENDPOINT_IDLEN+1));
ansond 0:ae2a45502448 147 if (this->m_connected == false) {
ansond 0:ae2a45502448 148 this->logger()->log("MQTT Init: %s:%d...",MQTT_HOSTNAME,MQTT_HOSTPORT);
ansond 0:ae2a45502448 149 this->m_mqtt = &_mqtt;
ansond 0:ae2a45502448 150 if (this->m_mqtt != NULL) {
ansond 0:ae2a45502448 151 char *id = this->makeID(MQTT_ENDPOINT_ID,mqtt_id);
ansond 0:ae2a45502448 152 this->logger()->log("MQTT Connect: ID: %s...",id);
ansond 0:ae2a45502448 153 if (this->m_mqtt->connect(id)) {
ansond 0:ae2a45502448 154 this->logger()->log("MQTT Subscribe: Topic: %s...",MQTT_IOC_TOPIC);
ansond 0:ae2a45502448 155 if (this->m_mqtt->subscribe(MQTT_IOC_TOPIC)) {
ansond 0:ae2a45502448 156 this->logger()->log("MQTT CONNECTED.");
ansond 0:ae2a45502448 157 this->m_connected = true;
ansond 0:ae2a45502448 158 }
ansond 0:ae2a45502448 159 else {
ansond 0:ae2a45502448 160 this->logger()->log("MQTT Subscribe: Topic: %s FAILED",MQTT_IOC_TOPIC);
ansond 0:ae2a45502448 161 this->logger()->turnLEDRed();
ansond 0:ae2a45502448 162 }
ansond 0:ae2a45502448 163 }
ansond 0:ae2a45502448 164 else {
ansond 0:ae2a45502448 165 this->logger()->log("MQTT Connect: ID: %s FAILED",id);
ansond 0:ae2a45502448 166 this->logger()->turnLEDRed();
ansond 0:ae2a45502448 167 }
ansond 0:ae2a45502448 168 }
ansond 0:ae2a45502448 169 else {
ansond 0:ae2a45502448 170 this->logger()->log("MQTT Unable to allocate new instance");
ansond 0:ae2a45502448 171 this->logger()->turnLEDRed();
ansond 0:ae2a45502448 172 }
ansond 0:ae2a45502448 173 }
ansond 0:ae2a45502448 174 else {
ansond 0:ae2a45502448 175 this->logger()->log("MQTT already connected (OK)");
ansond 0:ae2a45502448 176 }
ansond 0:ae2a45502448 177 return this->m_connected;
ansond 0:ae2a45502448 178 }
ansond 0:ae2a45502448 179
ansond 0:ae2a45502448 180 // disconnect from MQTT
ansond 0:ae2a45502448 181 bool MQTTTransport::disconnect() {
ansond 0:ae2a45502448 182 if (this->m_mqtt != NULL) {
ansond 0:ae2a45502448 183 this->logger()->log("MQTT Unsubscribing from: %s...",MQTT_IOC_TOPIC);
ansond 0:ae2a45502448 184 this->m_mqtt->unsubscribe(MQTT_IOC_TOPIC);
ansond 0:ae2a45502448 185 this->logger()->log("MQTT Disconnecting...");
ansond 0:ae2a45502448 186 this->m_mqtt->disconnect();
ansond 0:ae2a45502448 187 }
ansond 0:ae2a45502448 188 else {
ansond 0:ae2a45502448 189 this->logger()->log("MQTT already disconnected (OK)");
ansond 0:ae2a45502448 190 }
ansond 0:ae2a45502448 191 this->m_connected = false;
ansond 0:ae2a45502448 192 return true;
ansond 0:ae2a45502448 193 }
ansond 0:ae2a45502448 194
ansond 0:ae2a45502448 195 // check transport and process stuff
ansond 0:ae2a45502448 196 void MQTTTransport::checkAndProcess() {
ansond 0:ae2a45502448 197 if (this->m_mqtt != NULL && this->m_connected == true) {
ansond 0:ae2a45502448 198 this->m_mqtt->loop();
ansond 0:ae2a45502448 199 this->logger()->blinkMQTTTransportRxLED();
ansond 0:ae2a45502448 200 }
ansond 0:ae2a45502448 201 }