Had to fork with a different name, because of some incompatibility issues.
DeviceClient.cpp@18:ce12e2072cbb, 2019-10-20 (annotated)
- Committer:
- lamell
- Date:
- Sun Oct 20 23:21:52 2019 -0400
- Revision:
- 18:ce12e2072cbb
- Parent:
- 12:ac091f717e40
- Child:
- 19:85e9bc1a3a6a
CHanges in the TCPSocket configuration and use, because mbed 5.14 is mandatory to change it.
Also moved the NetworkInterface from private to public so the network connection can be used in other modules in the program,
like the connection to the server to connect to the update link.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sathipal | 0:f86732d81998 | 1 | /******************************************************************************* |
sathipal | 0:f86732d81998 | 2 | * Copyright (c) 2015 IBM Corp. |
sathipal | 0:f86732d81998 | 3 | * |
sathipal | 0:f86732d81998 | 4 | * All rights reserved. This program and the accompanying materials |
sathipal | 0:f86732d81998 | 5 | * are made available under the terms of the Eclipse Public License v1.0 |
sathipal | 0:f86732d81998 | 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. |
sathipal | 0:f86732d81998 | 7 | * |
sathipal | 0:f86732d81998 | 8 | * The Eclipse Public License is available at |
sathipal | 0:f86732d81998 | 9 | * http://www.eclipse.org/legal/epl-v10.html |
sathipal | 0:f86732d81998 | 10 | * and the Eclipse Distribution License is available at |
sathipal | 0:f86732d81998 | 11 | * http://www.eclipse.org/org/documents/edl-v10.php. |
sathipal | 0:f86732d81998 | 12 | * |
sathipal | 0:f86732d81998 | 13 | * Contributors: |
sathipal | 0:f86732d81998 | 14 | * Sathisumar Palaniappan - initial implementation |
sathipal | 3:3d91bf839b49 | 15 | * Sathisumar Palaniappan - added reconnect logic and isConnected() method |
lokeshhk | 5:ea9f483e0294 | 16 | * Lokesh K Haralakatta - Port to mbed OS 5 support |
lokeshhk | 5:ea9f483e0294 | 17 | * Lokesh K Haralakatta - Added SSL/TLS Support |
sathipal | 0:f86732d81998 | 18 | *******************************************************************************/ |
sathipal | 0:f86732d81998 | 19 | #include "MQTTClient.h" |
sathipal | 0:f86732d81998 | 20 | #include "DeviceClient.h" |
sathipal | 0:f86732d81998 | 21 | |
sathipal | 3:3d91bf839b49 | 22 | // need a wrapper since K64F and LPC1768 wont have the same name for mii read methods |
lamell | 12:ac091f717e40 | 23 | #if defined(TARGET_UBLOX_C027) || defined(TARGET_K64F) || defined(TARGET_DISCO_F746NG) |
sathipal | 3:3d91bf839b49 | 24 | |
sathipal | 3:3d91bf839b49 | 25 | static uint32_t linkStatus(void) |
sathipal | 3:3d91bf839b49 | 26 | { |
sathipal | 3:3d91bf839b49 | 27 | return (1); |
sathipal | 3:3d91bf839b49 | 28 | } |
sathipal | 3:3d91bf839b49 | 29 | #elif defined(TARGET_LPC1768) |
sathipal | 3:3d91bf839b49 | 30 | #include "lpc_phy.h" |
sathipal | 3:3d91bf839b49 | 31 | |
sathipal | 3:3d91bf839b49 | 32 | static uint32_t linkStatus(void) |
sathipal | 3:3d91bf839b49 | 33 | { |
sathipal | 3:3d91bf839b49 | 34 | return (lpc_mii_read_data() & 1); |
sathipal | 3:3d91bf839b49 | 35 | } |
sathipal | 3:3d91bf839b49 | 36 | #endif |
lamell | 12:ac091f717e40 | 37 | |
sathipal | 0:f86732d81998 | 38 | using namespace IoTF; |
sathipal | 0:f86732d81998 | 39 | |
sathipal | 0:f86732d81998 | 40 | CommandHandler handler = NULL; |
sathipal | 0:f86732d81998 | 41 | void msgArrived(MQTT::MessageData& md); |
sathipal | 0:f86732d81998 | 42 | |
sathipal | 0:f86732d81998 | 43 | /** |
sathipal | 0:f86732d81998 | 44 | * A client, used by device, that handles connections with the IBM Internet of Things Foundation. |
sathipal | 0:f86732d81998 | 45 | * This class allows device to publish events and receive commands to/from IBM IoT Foundation wtih simple function calls. |
sathipal | 0:f86732d81998 | 46 | */ |
sathipal | 2:199ddea804cd | 47 | DeviceClient::DeviceClient():org(NULL),deviceType(NULL),deviceId(NULL), |
lokeshhk | 5:ea9f483e0294 | 48 | authMethod(NULL),authToken(NULL),mqttNetwork(NULL),mqttClient(NULL),connected(false),port(0) |
sathipal | 2:199ddea804cd | 49 | { |
lokeshhk | 5:ea9f483e0294 | 50 | LOG("Constructor#1 called::\r\n"); |
sathipal | 0:f86732d81998 | 51 | } |
sathipal | 0:f86732d81998 | 52 | |
lokeshhk | 5:ea9f483e0294 | 53 | DeviceClient::DeviceClient(char *orgId, char *typeId, char *id, int port):org(orgId),deviceType(typeId), |
lokeshhk | 5:ea9f483e0294 | 54 | deviceId(id),authMethod(NULL),authToken(NULL),connected(false), port(port) |
sathipal | 2:199ddea804cd | 55 | { |
lokeshhk | 5:ea9f483e0294 | 56 | LOG("Constructor#2 called:: org=%s, type=%s, id=%s\r\n", (org==NULL)?"NULL":org, |
sathipal | 0:f86732d81998 | 57 | (deviceType==NULL)?"NULL":deviceType, (deviceId==NULL)?"NULL":deviceId); |
lokeshhk | 5:ea9f483e0294 | 58 | |
sathipal | 0:f86732d81998 | 59 | if(strcmp(this->org, QUICKSTART) != 0) { |
lokeshhk | 5:ea9f483e0294 | 60 | WARN("Registered flow must provide valid token\r\n"); |
sathipal | 0:f86732d81998 | 61 | } |
lokeshhk | 5:ea9f483e0294 | 62 | |
lokeshhk | 5:ea9f483e0294 | 63 | mqttNetwork = new MQTTNetwork(); |
lokeshhk | 5:ea9f483e0294 | 64 | mqttClient = new MQTT::Client<MQTTNetwork, Countdown>(*mqttNetwork); |
lokeshhk | 5:ea9f483e0294 | 65 | |
sathipal | 0:f86732d81998 | 66 | } |
sathipal | 0:f86732d81998 | 67 | |
lokeshhk | 5:ea9f483e0294 | 68 | DeviceClient::DeviceClient(char *orgId, char *typeId,char *id, char *method, char *token, int port):org(orgId), |
lokeshhk | 5:ea9f483e0294 | 69 | deviceType(typeId),deviceId(id),authMethod(method),authToken(token),connected(false), port(port) |
sathipal | 2:199ddea804cd | 70 | { |
sathipal | 0:f86732d81998 | 71 | // Don't print token for security reasons |
lokeshhk | 5:ea9f483e0294 | 72 | LOG("Constructor#3 called:: org=%s, type=%s, id=%s\r\n", (org==NULL)?"NULL":org, |
sathipal | 0:f86732d81998 | 73 | (deviceType==NULL)?"NULL":deviceType, (deviceId==NULL)?"NULL":deviceId); |
lokeshhk | 5:ea9f483e0294 | 74 | |
lokeshhk | 5:ea9f483e0294 | 75 | mqttNetwork = new MQTTNetwork(); |
lokeshhk | 5:ea9f483e0294 | 76 | mqttClient = new MQTT::Client<MQTTNetwork, Countdown>(*mqttNetwork); |
sathipal | 0:f86732d81998 | 77 | } |
sathipal | 0:f86732d81998 | 78 | |
sathipal | 0:f86732d81998 | 79 | /** |
sathipal | 0:f86732d81998 | 80 | * Connect to the IBM Internet of Things Foundation |
lokeshhk | 5:ea9f483e0294 | 81 | */ |
sathipal | 0:f86732d81998 | 82 | bool DeviceClient::connect() |
lokeshhk | 5:ea9f483e0294 | 83 | { |
sathipal | 0:f86732d81998 | 84 | char *organizationName, *typeId, *id; |
lokeshhk | 5:ea9f483e0294 | 85 | bool rc = false; |
sathipal | 0:f86732d81998 | 86 | // Check if any organization is set |
lokeshhk | 5:ea9f483e0294 | 87 | if(this->org == NULL || (strcmp("", this->org) == 0)) |
sathipal | 3:3d91bf839b49 | 88 | { |
lamell | 18:ce12e2072cbb | 89 | organizationName = (char*)QUICKSTART; |
sathipal | 0:f86732d81998 | 90 | } else { |
sathipal | 0:f86732d81998 | 91 | organizationName = this->org; |
sathipal | 0:f86732d81998 | 92 | } |
lokeshhk | 5:ea9f483e0294 | 93 | |
sathipal | 0:f86732d81998 | 94 | // Check if device type is already mentioned |
lokeshhk | 5:ea9f483e0294 | 95 | if(this->deviceType == NULL || (strcmp("", this->deviceType) == 0)) |
sathipal | 3:3d91bf839b49 | 96 | { |
lamell | 18:ce12e2072cbb | 97 | typeId = (char*)"iotsample-mbed"; |
sathipal | 0:f86732d81998 | 98 | } else { |
sathipal | 0:f86732d81998 | 99 | typeId = this->deviceType; |
sathipal | 0:f86732d81998 | 100 | } |
lokeshhk | 5:ea9f483e0294 | 101 | |
sathipal | 0:f86732d81998 | 102 | char hostname[strlen(organizationName) + strlen(IBM_IOT_MESSAGING) + 1]; |
sathipal | 0:f86732d81998 | 103 | sprintf(hostname, "%s%s", organizationName, IBM_IOT_MESSAGING); |
lokeshhk | 5:ea9f483e0294 | 104 | |
lamell | 18:ce12e2072cbb | 105 | //NetworkInterface* net = mqttNetwork->getEth(); |
lamell | 18:ce12e2072cbb | 106 | NetworkInterface* net = mqttNetwork->network; |
lamell | 18:ce12e2072cbb | 107 | |
lokeshhk | 5:ea9f483e0294 | 108 | const char* ip = net->get_ip_address(); |
sathipal | 0:f86732d81998 | 109 | |
sathipal | 0:f86732d81998 | 110 | // Get devices MAC address if deviceId is not set already |
lokeshhk | 5:ea9f483e0294 | 111 | if(this->deviceId == NULL || (strcmp("", this->deviceId) == 0)) |
sathipal | 3:3d91bf839b49 | 112 | { |
sathipal | 0:f86732d81998 | 113 | char tmpBuf[50]; |
sathipal | 0:f86732d81998 | 114 | id = getMac(tmpBuf, sizeof(tmpBuf)); |
sathipal | 0:f86732d81998 | 115 | } else { |
sathipal | 0:f86732d81998 | 116 | id = this->deviceId; |
sathipal | 0:f86732d81998 | 117 | } |
lokeshhk | 5:ea9f483e0294 | 118 | |
sathipal | 0:f86732d81998 | 119 | // Construct clientId - d:org:type:id |
sathipal | 0:f86732d81998 | 120 | char clientId[strlen(organizationName) + strlen(typeId) + strlen(id) + 5]; |
sathipal | 0:f86732d81998 | 121 | sprintf(clientId, "d:%s:%s:%s", organizationName, typeId, id); |
lokeshhk | 5:ea9f483e0294 | 122 | |
sathipal | 0:f86732d81998 | 123 | // Initialize MQTT Connect |
sathipal | 0:f86732d81998 | 124 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; |
sathipal | 0:f86732d81998 | 125 | data.MQTTVersion = 4; |
sathipal | 0:f86732d81998 | 126 | data.clientID.cstring = clientId; |
lokeshhk | 5:ea9f483e0294 | 127 | |
sathipal | 0:f86732d81998 | 128 | int quickstartMode = (strcmp(organizationName, QUICKSTART) == 0); |
lokeshhk | 5:ea9f483e0294 | 129 | |
lokeshhk | 5:ea9f483e0294 | 130 | if (!quickstartMode) |
lokeshhk | 5:ea9f483e0294 | 131 | { |
lamell | 18:ce12e2072cbb | 132 | data.username.cstring = (char*)"use-token-auth"; |
sathipal | 0:f86732d81998 | 133 | data.password.cstring = this->authToken; |
lokeshhk | 5:ea9f483e0294 | 134 | |
lokeshhk | 5:ea9f483e0294 | 135 | //Check and initialize appropriate port |
lokeshhk | 5:ea9f483e0294 | 136 | if(port == 1883) |
lokeshhk | 5:ea9f483e0294 | 137 | port = MQTT_TLS_PORT; |
sathipal | 0:f86732d81998 | 138 | } |
lokeshhk | 5:ea9f483e0294 | 139 | |
lokeshhk | 5:ea9f483e0294 | 140 | logData(net, hostname, clientId); |
lokeshhk | 5:ea9f483e0294 | 141 | |
lokeshhk | 5:ea9f483e0294 | 142 | if(ip){ |
lokeshhk | 5:ea9f483e0294 | 143 | rc = tryConnect(hostname, data); |
lokeshhk | 5:ea9f483e0294 | 144 | // By default subscribe to commands if we are in registered flow |
lokeshhk | 5:ea9f483e0294 | 145 | if(rc == true && !quickstartMode) |
lokeshhk | 5:ea9f483e0294 | 146 | { |
lokeshhk | 5:ea9f483e0294 | 147 | subscribeToCommands(); |
lokeshhk | 5:ea9f483e0294 | 148 | } |
lokeshhk | 5:ea9f483e0294 | 149 | if(rc == true) |
lokeshhk | 5:ea9f483e0294 | 150 | { |
lokeshhk | 5:ea9f483e0294 | 151 | connected = true; |
lokeshhk | 5:ea9f483e0294 | 152 | LOG("Device Client Connected to %s:%d\r\n",hostname,port); |
lokeshhk | 5:ea9f483e0294 | 153 | } |
sathipal | 3:3d91bf839b49 | 154 | } |
lokeshhk | 5:ea9f483e0294 | 155 | else |
lokeshhk | 5:ea9f483e0294 | 156 | LOG("No IP Assigned to Network Interface...\r\n"); |
lokeshhk | 5:ea9f483e0294 | 157 | |
sathipal | 0:f86732d81998 | 158 | return rc; |
sathipal | 0:f86732d81998 | 159 | } |
sathipal | 0:f86732d81998 | 160 | |
sathipal | 3:3d91bf839b49 | 161 | /** |
sathipal | 3:3d91bf839b49 | 162 | * Reconnect when the connection is lost. This method disconnects the active connection if any |
lokeshhk | 5:ea9f483e0294 | 163 | * and tries to initiate a fresh connection. |
sathipal | 3:3d91bf839b49 | 164 | * This method uses the Ethernet Link status wherever applicable while reconnecting. i.e, tries to |
sathipal | 3:3d91bf839b49 | 165 | * initiate the connection only when the Ethernet cable is plugged in. |
sathipal | 3:3d91bf839b49 | 166 | */ |
lokeshhk | 5:ea9f483e0294 | 167 | bool DeviceClient::reConnect() |
sathipal | 3:3d91bf839b49 | 168 | { |
lokeshhk | 5:ea9f483e0294 | 169 | LOG("DeviceClient::reConnect() entry and connected = %s\r\n",(connected == true)?"true":"false"); |
sathipal | 3:3d91bf839b49 | 170 | if(connected == true) |
sathipal | 3:3d91bf839b49 | 171 | { |
sathipal | 3:3d91bf839b49 | 172 | disconnect(); |
sathipal | 3:3d91bf839b49 | 173 | } |
sathipal | 3:3d91bf839b49 | 174 | |
sathipal | 3:3d91bf839b49 | 175 | if(linkStatus()) |
sathipal | 3:3d91bf839b49 | 176 | { |
lamell | 18:ce12e2072cbb | 177 | //NetworkInterface* net = mqttNetwork->getEth(); |
lamell | 18:ce12e2072cbb | 178 | NetworkInterface* net = mqttNetwork->network; |
lokeshhk | 5:ea9f483e0294 | 179 | if(net->connect() == 0) |
sathipal | 3:3d91bf839b49 | 180 | { |
sathipal | 3:3d91bf839b49 | 181 | bool status = connect(); |
lokeshhk | 5:ea9f483e0294 | 182 | if(status == false) |
sathipal | 3:3d91bf839b49 | 183 | { |
lokeshhk | 5:ea9f483e0294 | 184 | net->disconnect(); |
sathipal | 3:3d91bf839b49 | 185 | } |
sathipal | 3:3d91bf839b49 | 186 | return status; |
sathipal | 3:3d91bf839b49 | 187 | } |
sathipal | 3:3d91bf839b49 | 188 | } |
sathipal | 3:3d91bf839b49 | 189 | return false; |
sathipal | 3:3d91bf839b49 | 190 | } |
sathipal | 3:3d91bf839b49 | 191 | |
lokeshhk | 5:ea9f483e0294 | 192 | bool DeviceClient::tryConnect(char *hostname, MQTTPacket_connectData &data) |
sathipal | 2:199ddea804cd | 193 | { |
sathipal | 0:f86732d81998 | 194 | int rc = -1; |
sathipal | 0:f86732d81998 | 195 | int retryAttempt = 0; |
lokeshhk | 5:ea9f483e0294 | 196 | do { |
lokeshhk | 5:ea9f483e0294 | 197 | rc = mqttNetwork->connect(hostname, port); |
lokeshhk | 5:ea9f483e0294 | 198 | if (rc != 0) |
sathipal | 3:3d91bf839b49 | 199 | { |
lokeshhk | 5:ea9f483e0294 | 200 | WARN("mqttNetwork connect returned: %d\r\n", rc); |
sathipal | 0:f86732d81998 | 201 | } |
sathipal | 0:f86732d81998 | 202 | |
lokeshhk | 5:ea9f483e0294 | 203 | // MQTT connect |
lokeshhk | 5:ea9f483e0294 | 204 | if (rc == 0 && (rc = mqttClient->connect(data)) != 0) |
sathipal | 3:3d91bf839b49 | 205 | { |
lokeshhk | 5:ea9f483e0294 | 206 | WARN("MQTT connect returned %d\r\n", rc); |
sathipal | 0:f86732d81998 | 207 | if (rc == MQTT_NOT_AUTHORIZED || rc == MQTT_BAD_USERNAME_OR_PASSWORD) |
sathipal | 0:f86732d81998 | 208 | return false; // don't reattempt to connect if credentials are wrong |
sathipal | 0:f86732d81998 | 209 | } else if (rc == MQTT_CONNECTION_ACCEPTED) { |
sathipal | 0:f86732d81998 | 210 | return true; |
sathipal | 0:f86732d81998 | 211 | } |
lokeshhk | 5:ea9f483e0294 | 212 | |
sathipal | 0:f86732d81998 | 213 | int timeout = getConnTimeout(++retryAttempt); |
lokeshhk | 5:ea9f483e0294 | 214 | |
lokeshhk | 5:ea9f483e0294 | 215 | WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout); |
lokeshhk | 5:ea9f483e0294 | 216 | |
sathipal | 2:199ddea804cd | 217 | // enough retry is done - return to application |
lamell | 7:b14763b63562 | 218 | if (retryAttempt == 5){ |
lamell | 7:b14763b63562 | 219 | |
lamell | 7:b14763b63562 | 220 | //Here's my modification. If not connected, RESET the board. |
lamell | 7:b14763b63562 | 221 | NVIC_SystemReset(); |
sathipal | 2:199ddea804cd | 222 | return false; |
lamell | 7:b14763b63562 | 223 | } else { |
sathipal | 0:f86732d81998 | 224 | wait(timeout); |
lamell | 7:b14763b63562 | 225 | } |
sathipal | 0:f86732d81998 | 226 | } while(true); |
sathipal | 0:f86732d81998 | 227 | } |
sathipal | 0:f86732d81998 | 228 | |
lokeshhk | 5:ea9f483e0294 | 229 | void DeviceClient::logData(NetworkInterface* net, char *hostname, char *clientId) |
sathipal | 2:199ddea804cd | 230 | { |
lokeshhk | 5:ea9f483e0294 | 231 | // Network debug statements |
lokeshhk | 5:ea9f483e0294 | 232 | LOG("=====================================\r\n"); |
lokeshhk | 5:ea9f483e0294 | 233 | LOG("Connection Config Details:\r\n"); |
lokeshhk | 5:ea9f483e0294 | 234 | LOG("IP ADDRESS: %s\r\n", net->get_ip_address()); |
lokeshhk | 5:ea9f483e0294 | 235 | LOG("MAC ADDRESS: %s\r\n", net->get_mac_address()); |
lokeshhk | 5:ea9f483e0294 | 236 | LOG("Gateway: %s\r\n", net->get_gateway()); |
lokeshhk | 5:ea9f483e0294 | 237 | LOG("Network Mask: %s\r\n", net->get_netmask()); |
lokeshhk | 5:ea9f483e0294 | 238 | LOG("Server Hostname: %s\r\n", hostname); |
lokeshhk | 5:ea9f483e0294 | 239 | LOG("Server Port: %d\r\n", port); |
lokeshhk | 5:ea9f483e0294 | 240 | LOG("Client ID: %s\r\n", clientId); |
lokeshhk | 5:ea9f483e0294 | 241 | LOG("=====================================\r\n"); |
sathipal | 0:f86732d81998 | 242 | } |
sathipal | 0:f86732d81998 | 243 | |
sathipal | 0:f86732d81998 | 244 | int DeviceClient::getConnTimeout(int attemptNumber) |
sathipal | 0:f86732d81998 | 245 | { |
sathipal | 0:f86732d81998 | 246 | // Try to increase the timeout every time |
sathipal | 0:f86732d81998 | 247 | return (attemptNumber * attemptNumber * 5); |
sathipal | 0:f86732d81998 | 248 | } |
sathipal | 0:f86732d81998 | 249 | |
lamell | 8:cb2c98efdca8 | 250 | |
sathipal | 3:3d91bf839b49 | 251 | /** |
sathipal | 3:3d91bf839b49 | 252 | * Returns the connection status, connected or disconnected. |
sathipal | 3:3d91bf839b49 | 253 | */ |
sathipal | 3:3d91bf839b49 | 254 | bool DeviceClient::isConnected() { |
lokeshhk | 5:ea9f483e0294 | 255 | return mqttClient->isConnected(); |
sathipal | 3:3d91bf839b49 | 256 | } |
sathipal | 0:f86732d81998 | 257 | |
sathipal | 0:f86732d81998 | 258 | /** |
lokeshhk | 5:ea9f483e0294 | 259 | * Publish data to the IBM Internet of Things Foundation. Note that data is published |
lokeshhk | 5:ea9f483e0294 | 260 | * by default at Quality of Service (QoS) 0, which means that a successful send |
sathipal | 0:f86732d81998 | 261 | * does not guarantee receipt even if the publish has been successful. |
sathipal | 0:f86732d81998 | 262 | */ |
sathipal | 0:f86732d81998 | 263 | bool DeviceClient::publishEvent(char *eventName, char *data, MQTT::QoS qos) |
sathipal | 0:f86732d81998 | 264 | { |
lokeshhk | 5:ea9f483e0294 | 265 | if(!mqttClient->isConnected()) |
sathipal | 3:3d91bf839b49 | 266 | { |
lokeshhk | 5:ea9f483e0294 | 267 | WARN("Client is not connected \r\n"); |
sathipal | 0:f86732d81998 | 268 | return false; |
sathipal | 0:f86732d81998 | 269 | } |
lokeshhk | 5:ea9f483e0294 | 270 | |
sathipal | 0:f86732d81998 | 271 | MQTT::Message message; |
sathipal | 0:f86732d81998 | 272 | /* Topic format must be iot-2/evt/<eventName>/fmt/json (let us stick to json format for now) |
sathipal | 0:f86732d81998 | 273 | * |
sathipal | 0:f86732d81998 | 274 | * So length must be 10 + strlen(eventName) + 9 + 1 |
sathipal | 0:f86732d81998 | 275 | * iot-2/evt/ = 10 |
sathipal | 0:f86732d81998 | 276 | * /fmt/json = 9 |
sathipal | 0:f86732d81998 | 277 | * NULL char = 1 |
sathipal | 0:f86732d81998 | 278 | */ |
lokeshhk | 5:ea9f483e0294 | 279 | |
sathipal | 0:f86732d81998 | 280 | char topic[10 + strlen(eventName) + 9 + 1]; |
sathipal | 0:f86732d81998 | 281 | sprintf(topic, "%s%s%s", "iot-2/evt/", eventName, "/fmt/json"); |
lokeshhk | 5:ea9f483e0294 | 282 | |
sathipal | 0:f86732d81998 | 283 | message.qos = qos; |
sathipal | 0:f86732d81998 | 284 | message.retained = false; |
sathipal | 0:f86732d81998 | 285 | message.dup = false; |
sathipal | 0:f86732d81998 | 286 | message.payload = (void*)data; |
sathipal | 0:f86732d81998 | 287 | message.payloadlen = strlen(data); |
lokeshhk | 5:ea9f483e0294 | 288 | |
lokeshhk | 5:ea9f483e0294 | 289 | LOG("Publishing %s\r\n", data); |
lokeshhk | 5:ea9f483e0294 | 290 | int rc = mqttClient->publish(topic, message); |
sathipal | 0:f86732d81998 | 291 | return rc == 0; |
sathipal | 0:f86732d81998 | 292 | } |
sathipal | 0:f86732d81998 | 293 | |
lokeshhk | 5:ea9f483e0294 | 294 | void DeviceClient::setCommandCallback(CommandHandler callbackFunc) |
sathipal | 2:199ddea804cd | 295 | { |
sathipal | 0:f86732d81998 | 296 | handler = callbackFunc; |
sathipal | 0:f86732d81998 | 297 | } |
sathipal | 0:f86732d81998 | 298 | /** |
sathipal | 0:f86732d81998 | 299 | * Subscribe to commands from the application. This will be executed only for |
sathipal | 0:f86732d81998 | 300 | * registered flow (quickstart flow does not support command publish) |
sathipal | 0:f86732d81998 | 301 | */ |
lokeshhk | 5:ea9f483e0294 | 302 | int DeviceClient::subscribeToCommands() |
sathipal | 2:199ddea804cd | 303 | { |
sathipal | 0:f86732d81998 | 304 | int rc = 0; |
sathipal | 0:f86732d81998 | 305 | // iot-2/cmd/+/fmt/+ |
lokeshhk | 5:ea9f483e0294 | 306 | if ((rc = mqttClient->subscribe("iot-2/cmd/+/fmt/+", MQTT::QOS2, msgArrived)) != 0) |
lokeshhk | 5:ea9f483e0294 | 307 | WARN("rc from MQTT subscribe is %d\r\n", rc); |
sathipal | 0:f86732d81998 | 308 | return rc; |
sathipal | 0:f86732d81998 | 309 | } |
sathipal | 0:f86732d81998 | 310 | |
sathipal | 0:f86732d81998 | 311 | /** |
lokeshhk | 5:ea9f483e0294 | 312 | * Callback method to be registered with MQTT::Client. MQTT::Client calls whenever |
sathipal | 0:f86732d81998 | 313 | * any command is published to the topic subscribed earlier. |
sathipal | 0:f86732d81998 | 314 | */ |
sathipal | 0:f86732d81998 | 315 | void msgArrived(MQTT::MessageData& md) |
sathipal | 0:f86732d81998 | 316 | { |
sathipal | 0:f86732d81998 | 317 | // check whether callback is registered by the client code |
lokeshhk | 5:ea9f483e0294 | 318 | if(handler == NULL) |
sathipal | 3:3d91bf839b49 | 319 | { |
sathipal | 0:f86732d81998 | 320 | return; |
sathipal | 0:f86732d81998 | 321 | } |
lokeshhk | 5:ea9f483e0294 | 322 | |
sathipal | 0:f86732d81998 | 323 | MQTT::Message &message = md.message; |
sathipal | 0:f86732d81998 | 324 | char topic[md.topicName.lenstring.len + 1]; |
lokeshhk | 5:ea9f483e0294 | 325 | |
sathipal | 0:f86732d81998 | 326 | sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); |
lokeshhk | 5:ea9f483e0294 | 327 | |
lamell | 10:665cfb0da4c5 | 328 | LOG("Message arrived on topic %s: Length: %ul. Payload: %s\r\n", topic, message.payloadlen, message.payload); |
lokeshhk | 5:ea9f483e0294 | 329 | |
sathipal | 0:f86732d81998 | 330 | // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/ |
sathipal | 0:f86732d81998 | 331 | char* start = strstr(topic, "/cmd/") + 5; |
sathipal | 0:f86732d81998 | 332 | int len = strstr(topic, "/fmt/") - start; |
sathipal | 0:f86732d81998 | 333 | |
sathipal | 0:f86732d81998 | 334 | char name[len + 1]; |
lokeshhk | 5:ea9f483e0294 | 335 | |
sathipal | 0:f86732d81998 | 336 | memcpy(name, start, len); |
sathipal | 0:f86732d81998 | 337 | name[len] = NULL; |
lokeshhk | 5:ea9f483e0294 | 338 | |
sathipal | 0:f86732d81998 | 339 | start = strstr(topic, "/fmt/") + 5; |
lokeshhk | 5:ea9f483e0294 | 340 | |
sathipal | 0:f86732d81998 | 341 | char format[20]; // ToDO: need to find the length of the format |
sathipal | 0:f86732d81998 | 342 | strcpy(format, start); |
lokeshhk | 5:ea9f483e0294 | 343 | |
sathipal | 0:f86732d81998 | 344 | char payload[message.payloadlen + 1]; |
sathipal | 0:f86732d81998 | 345 | sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload); |
lokeshhk | 5:ea9f483e0294 | 346 | |
sathipal | 0:f86732d81998 | 347 | IoTF::Command cmd(name, format, payload); |
sathipal | 0:f86732d81998 | 348 | (*handler)(cmd); |
sathipal | 0:f86732d81998 | 349 | } |
sathipal | 0:f86732d81998 | 350 | |
sathipal | 3:3d91bf839b49 | 351 | /** |
sathipal | 3:3d91bf839b49 | 352 | * Disconnects the connection in order. |
sathipal | 3:3d91bf839b49 | 353 | */ |
lokeshhk | 5:ea9f483e0294 | 354 | bool DeviceClient::disconnect() |
sathipal | 2:199ddea804cd | 355 | { |
sathipal | 3:3d91bf839b49 | 356 | int rc = 0; |
lokeshhk | 5:ea9f483e0294 | 357 | if(mqttClient->isConnected()) |
sathipal | 3:3d91bf839b49 | 358 | { |
lokeshhk | 5:ea9f483e0294 | 359 | rc = mqttClient->disconnect(); |
sathipal | 0:f86732d81998 | 360 | } |
lokeshhk | 5:ea9f483e0294 | 361 | |
lamell | 18:ce12e2072cbb | 362 | //NetworkInterface* net = mqttNetwork->getEth(); |
lamell | 18:ce12e2072cbb | 363 | NetworkInterface* net = mqttNetwork->network; |
lokeshhk | 5:ea9f483e0294 | 364 | mqttNetwork->disconnect(); |
lokeshhk | 5:ea9f483e0294 | 365 | net->disconnect(); |
sathipal | 3:3d91bf839b49 | 366 | connected = false; |
sathipal | 3:3d91bf839b49 | 367 | return rc == 0; |
sathipal | 0:f86732d81998 | 368 | } |
sathipal | 0:f86732d81998 | 369 | |
sathipal | 0:f86732d81998 | 370 | // Yield to allow MQTT client to process the command |
lokeshhk | 5:ea9f483e0294 | 371 | void DeviceClient::yield(int ms) |
sathipal | 2:199ddea804cd | 372 | { |
lokeshhk | 5:ea9f483e0294 | 373 | if(mqttClient->isConnected()) |
sathipal | 3:3d91bf839b49 | 374 | { |
lokeshhk | 5:ea9f483e0294 | 375 | mqttClient->yield(ms); |
sathipal | 0:f86732d81998 | 376 | } |
sathipal | 0:f86732d81998 | 377 | } |
sathipal | 0:f86732d81998 | 378 | |
sathipal | 2:199ddea804cd | 379 | // Obtain DeviceId address |
lokeshhk | 5:ea9f483e0294 | 380 | char* DeviceClient::getDeviceId(char* buf, int buflen) |
lokeshhk | 5:ea9f483e0294 | 381 | { |
lokeshhk | 5:ea9f483e0294 | 382 | if(this->deviceId == NULL || (strcmp("", this->deviceId) == 0)) |
sathipal | 3:3d91bf839b49 | 383 | { |
sathipal | 2:199ddea804cd | 384 | return getMac(buf, buflen); |
sathipal | 2:199ddea804cd | 385 | } else { |
sathipal | 2:199ddea804cd | 386 | return strncpy(buf, this->deviceId, buflen); |
sathipal | 2:199ddea804cd | 387 | } |
sathipal | 2:199ddea804cd | 388 | } |
sathipal | 0:f86732d81998 | 389 | // Obtain MAC address |
lokeshhk | 5:ea9f483e0294 | 390 | char* DeviceClient::getMac(char* buf, int buflen) |
lokeshhk | 5:ea9f483e0294 | 391 | { |
lamell | 18:ce12e2072cbb | 392 | //NetworkInterface* net = mqttNetwork->getEth(); |
lamell | 18:ce12e2072cbb | 393 | NetworkInterface* net = mqttNetwork->network; |
lokeshhk | 5:ea9f483e0294 | 394 | strncpy(buf, net->get_mac_address(), buflen); |
sathipal | 0:f86732d81998 | 395 | |
sathipal | 0:f86732d81998 | 396 | char* pos; // Remove colons from mac address |
sathipal | 0:f86732d81998 | 397 | while ((pos = strchr(buf, ':')) != NULL) |
sathipal | 0:f86732d81998 | 398 | memmove(pos, pos + 1, strlen(pos) + 1); |
sathipal | 0:f86732d81998 | 399 | return buf; |
lokeshhk | 5:ea9f483e0294 | 400 | } |
lamell | 8:cb2c98efdca8 | 401 | |
lamell | 8:cb2c98efdca8 | 402 | char* DeviceClient::ipaddress() { |
lamell | 8:cb2c98efdca8 | 403 | //char iplocal[25]; |
lamell | 8:cb2c98efdca8 | 404 | |
lamell | 18:ce12e2072cbb | 405 | //NetworkInterface* net = mqttNetwork->getEth(); |
lamell | 18:ce12e2072cbb | 406 | NetworkInterface* net = mqttNetwork->network; |
lamell | 8:cb2c98efdca8 | 407 | //const char* ip = net->get_ip_address(); |
lamell | 8:cb2c98efdca8 | 408 | |
lamell | 8:cb2c98efdca8 | 409 | //strcpy(iplocal,ip); |
lamell | 8:cb2c98efdca8 | 410 | //return iplocal; |
lamell | 8:cb2c98efdca8 | 411 | return (char*)net->get_ip_address(); |
lamell | 8:cb2c98efdca8 | 412 | } |
lamell | 10:665cfb0da4c5 | 413 | |
lamell | 10:665cfb0da4c5 | 414 | //NetworkInterface* DeviceClient::eth() { |
lamell | 10:665cfb0da4c5 | 415 | // NetworkInterface* net = mqttNetwork->getEth(); |
lamell | 10:665cfb0da4c5 | 416 | // return (NetworkInterface*)net; |
lamell | 10:665cfb0da4c5 | 417 | //} |