Local copy
Dependencies: C12832_lcd ConfigFile EthernetInterface LM75B MMA7660 MQTTPacket mbed-rtos mbed
Fork of IBMIoTClientExampleForLPC1768 by
src/QuickstartClient.cpp@5:1b54a0b7b39d, 2014-06-24 (annotated)
- Committer:
- samdanbury
- Date:
- Tue Jun 24 10:47:12 2014 +0000
- Revision:
- 5:1b54a0b7b39d
- Parent:
- 3:ca5b84eb8f3b
- Child:
- 6:a022f983f94b
set password if not in quickstart mode
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
samdanbury | 0:6276e9f72327 | 1 | /******************************************************************************* |
samdanbury | 0:6276e9f72327 | 2 | * Copyright (c) 2014 IBM Corporation and other Contributors. |
samdanbury | 0:6276e9f72327 | 3 | * |
samdanbury | 0:6276e9f72327 | 4 | * All rights reserved. This program and the accompanying materials |
samdanbury | 0:6276e9f72327 | 5 | * are made available under the terms of the Eclipse Public License v1.0 |
samdanbury | 0:6276e9f72327 | 6 | * which accompanies this distribution, and is available at |
samdanbury | 0:6276e9f72327 | 7 | * http://www.eclipse.org/legal/epl-v10.html |
samdanbury | 0:6276e9f72327 | 8 | * |
samdanbury | 0:6276e9f72327 | 9 | * Contributors: Sam Danbury |
samdanbury | 0:6276e9f72327 | 10 | * IBM - Initial Contribution |
samdanbury | 0:6276e9f72327 | 11 | *******************************************************************************/ |
samdanbury | 0:6276e9f72327 | 12 | |
samdanbury | 0:6276e9f72327 | 13 | #include "QuickstartClient.h" |
samdanbury | 0:6276e9f72327 | 14 | |
samdanbury | 0:6276e9f72327 | 15 | QuickstartClient::QuickstartClient(string mac) { |
samdanbury | 2:25ddff75a8c7 | 16 | quickstartMode = true; |
samdanbury | 0:6276e9f72327 | 17 | connected = false; |
samdanbury | 0:6276e9f72327 | 18 | macAddress = mac; |
samdanbury | 0:6276e9f72327 | 19 | |
samdanbury | 2:25ddff75a8c7 | 20 | //Generate topic string |
samdanbury | 3:ca5b84eb8f3b | 21 | memcpy(topic, "iot-2/evt/status/fmt/json", 25); |
samdanbury | 3:ca5b84eb8f3b | 22 | topic[25] = '\0'; |
samdanbury | 2:25ddff75a8c7 | 23 | |
samdanbury | 2:25ddff75a8c7 | 24 | loadConfig(); |
samdanbury | 0:6276e9f72327 | 25 | |
samdanbury | 0:6276e9f72327 | 26 | tryMqttConnect(); |
samdanbury | 0:6276e9f72327 | 27 | } |
samdanbury | 0:6276e9f72327 | 28 | |
samdanbury | 2:25ddff75a8c7 | 29 | void QuickstartClient::loadConfig() { |
samdanbury | 2:25ddff75a8c7 | 30 | |
samdanbury | 2:25ddff75a8c7 | 31 | ConfigFile cfg; |
samdanbury | 2:25ddff75a8c7 | 32 | |
samdanbury | 3:ca5b84eb8f3b | 33 | char value[30]; |
samdanbury | 3:ca5b84eb8f3b | 34 | char value1[30]; |
samdanbury | 3:ca5b84eb8f3b | 35 | char value2[30]; |
samdanbury | 3:ca5b84eb8f3b | 36 | char value3[30]; |
samdanbury | 2:25ddff75a8c7 | 37 | |
samdanbury | 2:25ddff75a8c7 | 38 | if (cfg.read("/local/device.cfg")) { |
samdanbury | 2:25ddff75a8c7 | 39 | quickstartMode = false; |
samdanbury | 2:25ddff75a8c7 | 40 | |
samdanbury | 3:ca5b84eb8f3b | 41 | if (cfg.getValue("org", value, sizeof(value))) { |
samdanbury | 2:25ddff75a8c7 | 42 | stringstream ss(value); |
samdanbury | 2:25ddff75a8c7 | 43 | ss >> org; |
samdanbury | 2:25ddff75a8c7 | 44 | } else { |
samdanbury | 2:25ddff75a8c7 | 45 | lcd.printf("No org defined in config\n"); |
samdanbury | 2:25ddff75a8c7 | 46 | } |
samdanbury | 2:25ddff75a8c7 | 47 | |
samdanbury | 3:ca5b84eb8f3b | 48 | if (cfg.getValue("type", value1, sizeof(value1))) { |
samdanbury | 3:ca5b84eb8f3b | 49 | stringstream ss(value1); |
samdanbury | 2:25ddff75a8c7 | 50 | ss >> type; |
samdanbury | 2:25ddff75a8c7 | 51 | } else { |
samdanbury | 2:25ddff75a8c7 | 52 | lcd.printf("No type defined in config\n"); |
samdanbury | 2:25ddff75a8c7 | 53 | } |
samdanbury | 2:25ddff75a8c7 | 54 | |
samdanbury | 3:ca5b84eb8f3b | 55 | if (cfg.getValue("id", value2, sizeof(value2))) { |
samdanbury | 3:ca5b84eb8f3b | 56 | stringstream ss(value2); |
samdanbury | 2:25ddff75a8c7 | 57 | ss >> id; |
samdanbury | 2:25ddff75a8c7 | 58 | } else { |
samdanbury | 2:25ddff75a8c7 | 59 | lcd.printf("No id defined in config\n"); |
samdanbury | 2:25ddff75a8c7 | 60 | } |
samdanbury | 2:25ddff75a8c7 | 61 | |
samdanbury | 3:ca5b84eb8f3b | 62 | if (cfg.getValue("token", value3, sizeof(value3))) { |
samdanbury | 3:ca5b84eb8f3b | 63 | stringstream ss(value3); |
samdanbury | 2:25ddff75a8c7 | 64 | ss >> token; |
samdanbury | 2:25ddff75a8c7 | 65 | } else { |
samdanbury | 2:25ddff75a8c7 | 66 | lcd.printf("No token defined in config\n"); |
samdanbury | 2:25ddff75a8c7 | 67 | } |
samdanbury | 3:ca5b84eb8f3b | 68 | |
samdanbury | 2:25ddff75a8c7 | 69 | } else { |
samdanbury | 2:25ddff75a8c7 | 70 | org = "quickstart"; |
samdanbury | 2:25ddff75a8c7 | 71 | type = "iotsample-mbed-lpc1768"; |
samdanbury | 2:25ddff75a8c7 | 72 | id = macAddress; |
samdanbury | 2:25ddff75a8c7 | 73 | } |
samdanbury | 2:25ddff75a8c7 | 74 | |
samdanbury | 2:25ddff75a8c7 | 75 | } |
samdanbury | 2:25ddff75a8c7 | 76 | |
samdanbury | 0:6276e9f72327 | 77 | int QuickstartClient::reconnectDelay(int i) { |
samdanbury | 0:6276e9f72327 | 78 | if (i < 10) { |
samdanbury | 0:6276e9f72327 | 79 | return 3; //First 10 attempts try within 3 seconds |
samdanbury | 0:6276e9f72327 | 80 | } else if (i < 20) { |
samdanbury | 0:6276e9f72327 | 81 | return 60; //Next 10 attempts retry after every 1 minute |
samdanbury | 0:6276e9f72327 | 82 | } else { |
samdanbury | 0:6276e9f72327 | 83 | return 600; //After 20 attempts, retry every 10 minutes |
samdanbury | 0:6276e9f72327 | 84 | } |
samdanbury | 0:6276e9f72327 | 85 | } |
samdanbury | 0:6276e9f72327 | 86 | |
samdanbury | 0:6276e9f72327 | 87 | void QuickstartClient::tryMqttConnect() { |
samdanbury | 0:6276e9f72327 | 88 | int retryAttempt = 0; |
samdanbury | 0:6276e9f72327 | 89 | |
samdanbury | 0:6276e9f72327 | 90 | //Reinstantiate TCP socket connection object |
samdanbury | 0:6276e9f72327 | 91 | mysock = TCPSocketConnection(); |
samdanbury | 0:6276e9f72327 | 92 | |
samdanbury | 0:6276e9f72327 | 93 | while (connected == false) { |
samdanbury | 0:6276e9f72327 | 94 | lcd.cls(); |
samdanbury | 0:6276e9f72327 | 95 | lcd.locate(0,0); |
samdanbury | 0:6276e9f72327 | 96 | lcd.printf("Trying to connect..."); |
samdanbury | 0:6276e9f72327 | 97 | |
samdanbury | 0:6276e9f72327 | 98 | //Based on number of connection attempts, determine timeout |
samdanbury | 0:6276e9f72327 | 99 | int connDelayTimeout = reconnectDelay(++retryAttempt); |
samdanbury | 0:6276e9f72327 | 100 | |
samdanbury | 0:6276e9f72327 | 101 | //Attempt to reconnect |
samdanbury | 0:6276e9f72327 | 102 | connect(); |
samdanbury | 0:6276e9f72327 | 103 | |
samdanbury | 0:6276e9f72327 | 104 | //If connection was not established, continue retry |
samdanbury | 0:6276e9f72327 | 105 | if (connected == false) { |
samdanbury | 0:6276e9f72327 | 106 | wait(connDelayTimeout); |
samdanbury | 0:6276e9f72327 | 107 | } else { |
samdanbury | 0:6276e9f72327 | 108 | break; |
samdanbury | 0:6276e9f72327 | 109 | } |
samdanbury | 0:6276e9f72327 | 110 | } |
samdanbury | 0:6276e9f72327 | 111 | } |
samdanbury | 0:6276e9f72327 | 112 | |
samdanbury | 0:6276e9f72327 | 113 | void QuickstartClient::connect() { |
samdanbury | 0:6276e9f72327 | 114 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; |
samdanbury | 0:6276e9f72327 | 115 | int rc = 0; |
samdanbury | 0:6276e9f72327 | 116 | int len = 0; |
samdanbury | 0:6276e9f72327 | 117 | char buf[200]; |
samdanbury | 0:6276e9f72327 | 118 | int buflen = sizeof(buf); |
samdanbury | 0:6276e9f72327 | 119 | |
samdanbury | 0:6276e9f72327 | 120 | //Connect to TCP socket |
samdanbury | 0:6276e9f72327 | 121 | mysock.connect(IBM_IOT_BROKER, IBM_IOT_PORT); |
samdanbury | 0:6276e9f72327 | 122 | |
samdanbury | 2:25ddff75a8c7 | 123 | //Construct client ID |
samdanbury | 2:25ddff75a8c7 | 124 | string str = string("d:") + org + ":" + type + ":" + id; |
samdanbury | 3:ca5b84eb8f3b | 125 | char clientId[str.size()]; |
samdanbury | 3:ca5b84eb8f3b | 126 | memcpy(clientId, str.c_str(), str.size() + 1); |
samdanbury | 0:6276e9f72327 | 127 | |
samdanbury | 0:6276e9f72327 | 128 | //Set MQTT connect options |
samdanbury | 0:6276e9f72327 | 129 | data.clientID.cstring = clientId; |
samdanbury | 0:6276e9f72327 | 130 | data.keepAliveInterval = 20; |
samdanbury | 0:6276e9f72327 | 131 | data.cleansession = 1; |
samdanbury | 0:6276e9f72327 | 132 | data.MQTTVersion = 3; |
samdanbury | 5:1b54a0b7b39d | 133 | if (!quickstartMode) { |
samdanbury | 5:1b54a0b7b39d | 134 | //TODO: set mqtt password to the token in the config file it it is NOT in quickstart mode |
samdanbury | 5:1b54a0b7b39d | 135 | //data.password.cstring = token; |
samdanbury | 5:1b54a0b7b39d | 136 | } |
samdanbury | 0:6276e9f72327 | 137 | |
samdanbury | 0:6276e9f72327 | 138 | //Attempt MQTT connect |
samdanbury | 0:6276e9f72327 | 139 | len = MQTTSerialize_connect(buf, buflen, &data); |
samdanbury | 0:6276e9f72327 | 140 | rc = 0; |
samdanbury | 0:6276e9f72327 | 141 | while (rc < len) { |
samdanbury | 0:6276e9f72327 | 142 | int rc1 = mysock.send(buf, len); |
samdanbury | 0:6276e9f72327 | 143 | if (rc1 == -1) { |
samdanbury | 0:6276e9f72327 | 144 | connected = false; |
samdanbury | 0:6276e9f72327 | 145 | break; |
samdanbury | 0:6276e9f72327 | 146 | } else { |
samdanbury | 0:6276e9f72327 | 147 | rc += rc1; |
samdanbury | 0:6276e9f72327 | 148 | } |
samdanbury | 0:6276e9f72327 | 149 | } |
samdanbury | 0:6276e9f72327 | 150 | if (rc == len) { |
samdanbury | 0:6276e9f72327 | 151 | connected = true; |
samdanbury | 0:6276e9f72327 | 152 | } |
samdanbury | 0:6276e9f72327 | 153 | } |
samdanbury | 0:6276e9f72327 | 154 | |
samdanbury | 0:6276e9f72327 | 155 | void QuickstartClient::publish(string thePayload) { |
samdanbury | 0:6276e9f72327 | 156 | int rc = 0; |
samdanbury | 0:6276e9f72327 | 157 | int len = 0; |
samdanbury | 0:6276e9f72327 | 158 | char buf[250]; |
samdanbury | 0:6276e9f72327 | 159 | int buflen = sizeof(buf); |
samdanbury | 0:6276e9f72327 | 160 | |
samdanbury | 0:6276e9f72327 | 161 | MQTTString topicString = MQTTString_initializer; |
samdanbury | 0:6276e9f72327 | 162 | |
samdanbury | 0:6276e9f72327 | 163 | topicString.cstring = topic; |
samdanbury | 0:6276e9f72327 | 164 | |
samdanbury | 0:6276e9f72327 | 165 | //Convert payload from string to char array |
samdanbury | 0:6276e9f72327 | 166 | char* payload = new char [thePayload.length()+1]; |
samdanbury | 0:6276e9f72327 | 167 | std::strcpy (payload, thePayload.c_str()); |
samdanbury | 0:6276e9f72327 | 168 | int payloadlen = strlen(payload); |
samdanbury | 0:6276e9f72327 | 169 | |
samdanbury | 0:6276e9f72327 | 170 | //Attempt MQTT publish |
samdanbury | 0:6276e9f72327 | 171 | len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, payload, payloadlen); |
samdanbury | 0:6276e9f72327 | 172 | rc = 0; |
samdanbury | 0:6276e9f72327 | 173 | while (rc < len) { |
samdanbury | 0:6276e9f72327 | 174 | int rc1 = mysock.send(buf, len); |
samdanbury | 0:6276e9f72327 | 175 | if (rc1 == -1) { |
samdanbury | 0:6276e9f72327 | 176 | //If return code from MQTT publish is -1, attempt reconnect |
samdanbury | 0:6276e9f72327 | 177 | connected = false; |
samdanbury | 0:6276e9f72327 | 178 | tryMqttConnect(); |
samdanbury | 0:6276e9f72327 | 179 | break; |
samdanbury | 0:6276e9f72327 | 180 | } else { |
samdanbury | 0:6276e9f72327 | 181 | rc += rc1; |
samdanbury | 0:6276e9f72327 | 182 | } |
samdanbury | 0:6276e9f72327 | 183 | } |
samdanbury | 0:6276e9f72327 | 184 | wait(0.2); |
samdanbury | 0:6276e9f72327 | 185 | |
samdanbury | 0:6276e9f72327 | 186 | if (payload) { |
samdanbury | 0:6276e9f72327 | 187 | delete payload; |
samdanbury | 0:6276e9f72327 | 188 | } |
samdanbury | 0:6276e9f72327 | 189 | } |