mbed based IoT Gateway More details http://blog.thiseldo.co.uk/wp-filez/IoTGateway.pdf

Dependencies:   NetServices FatFileSystem csv_parser mbed MQTTClient RF12B DNSResolver SDFileSystem

Committer:
SomeRandomBloke
Date:
Thu Apr 05 08:03:07 2012 +0000
Revision:
2:27714c8c9c0a
Parent:
0:a29a0225f203
Child:
3:f19f9c62c00b
Updates to complete mqtt output

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 0:a29a0225f203 1 /** IoT Gateway main code
SomeRandomBloke 0:a29a0225f203 2 *
SomeRandomBloke 0:a29a0225f203 3 * @author Andrew Lindsay
SomeRandomBloke 0:a29a0225f203 4 *
SomeRandomBloke 0:a29a0225f203 5 * @section LICENSE
SomeRandomBloke 0:a29a0225f203 6 *
SomeRandomBloke 0:a29a0225f203 7 * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk)
SomeRandomBloke 0:a29a0225f203 8 *
SomeRandomBloke 0:a29a0225f203 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
SomeRandomBloke 0:a29a0225f203 10 * of this software and associated documentation files (the "Software"), to deal
SomeRandomBloke 0:a29a0225f203 11 * in the Software without restriction, including without limitation the rights
SomeRandomBloke 0:a29a0225f203 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
SomeRandomBloke 0:a29a0225f203 13 * copies of the Software, and to permit persons to whom the Software is
SomeRandomBloke 0:a29a0225f203 14 * furnished to do so, subject to the following conditions:
SomeRandomBloke 0:a29a0225f203 15
SomeRandomBloke 0:a29a0225f203 16 * The above copyright notice and this permission notice shall be included in
SomeRandomBloke 0:a29a0225f203 17 * all copies or substantial portions of the Software.
SomeRandomBloke 0:a29a0225f203 18 *
SomeRandomBloke 0:a29a0225f203 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
SomeRandomBloke 0:a29a0225f203 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
SomeRandomBloke 0:a29a0225f203 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
SomeRandomBloke 0:a29a0225f203 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
SomeRandomBloke 0:a29a0225f203 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
SomeRandomBloke 0:a29a0225f203 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
SomeRandomBloke 0:a29a0225f203 25 * THE SOFTWARE.
SomeRandomBloke 0:a29a0225f203 26 *
SomeRandomBloke 0:a29a0225f203 27 * @section DESCRIPTION
SomeRandomBloke 0:a29a0225f203 28 *
SomeRandomBloke 0:a29a0225f203 29 * Code is to be classed as beta. There is a lot of debug code still includes
SomeRandomBloke 0:a29a0225f203 30 * to dump heap sizes and other values. It is still a work in progress and
SomeRandomBloke 0:a29a0225f203 31 * should be treated as such.
SomeRandomBloke 2:27714c8c9c0a 32 *
SomeRandomBloke 2:27714c8c9c0a 33 * Further documentation available from
SomeRandomBloke 2:27714c8c9c0a 34 * http://blog.thiseldo.co.uk/wp-filez/IoTGateway.pdf
SomeRandomBloke 0:a29a0225f203 35 *
SomeRandomBloke 0:a29a0225f203 36 * Sample configuration file IOTSETUP.TXT
SomeRandomBloke 0:a29a0225f203 37 *
SomeRandomBloke 0:a29a0225f203 38 * @code
SomeRandomBloke 0:a29a0225f203 39 * pachube.key=***your pachube api key***
SomeRandomBloke 0:a29a0225f203 40 * ip.mode=fixed
SomeRandomBloke 0:a29a0225f203 41 * ip.address=192.168.1.99
SomeRandomBloke 0:a29a0225f203 42 * ip.netmask=255.255.255.0
SomeRandomBloke 0:a29a0225f203 43 * ip.gateway=192.168.1.1
SomeRandomBloke 0:a29a0225f203 44 * ip.dns=192.168.1.1
SomeRandomBloke 0:a29a0225f203 45 * rfm12b.band=868
SomeRandomBloke 0:a29a0225f203 46 * rfm12b.id=30
SomeRandomBloke 0:a29a0225f203 47 * rfm12b.group=212
SomeRandomBloke 0:a29a0225f203 48 * time.timezone=GMT
SomeRandomBloke 0:a29a0225f203 49 * time.dst=yes
SomeRandomBloke 0:a29a0225f203 50 * mqtt.host=
SomeRandomBloke 2:27714c8c9c0a 51 * mqtt.port=1883
SomeRandomBloke 2:27714c8c9c0a 52 * mqtt.username=
SomeRandomBloke 2:27714c8c9c0a 53 * mqtt.password=
SomeRandomBloke 0:a29a0225f203 54 * @endcode
SomeRandomBloke 0:a29a0225f203 55 *
SomeRandomBloke 0:a29a0225f203 56 * Some values are not yet used
SomeRandomBloke 0:a29a0225f203 57 *
SomeRandomBloke 0:a29a0225f203 58 */
SomeRandomBloke 0:a29a0225f203 59
SomeRandomBloke 0:a29a0225f203 60
SomeRandomBloke 0:a29a0225f203 61 #include "mbed.h"
SomeRandomBloke 0:a29a0225f203 62 #include "SDFileSystem.h"
SomeRandomBloke 0:a29a0225f203 63 #include "EthernetNetIf.h"
SomeRandomBloke 0:a29a0225f203 64 #include "NTPClient.h"
SomeRandomBloke 2:27714c8c9c0a 65 #include "dnsresolve.h"
SomeRandomBloke 0:a29a0225f203 66 #include "RF12B.h"
SomeRandomBloke 0:a29a0225f203 67 #include "IoTRouting.h"
SomeRandomBloke 0:a29a0225f203 68
SomeRandomBloke 0:a29a0225f203 69
SomeRandomBloke 0:a29a0225f203 70 using std::string;
SomeRandomBloke 0:a29a0225f203 71
SomeRandomBloke 2:27714c8c9c0a 72 #define VERSION_INFO "IoT Gateway Basic - Version 0.5-BETA "
SomeRandomBloke 0:a29a0225f203 73
SomeRandomBloke 0:a29a0225f203 74 DigitalOut heartbeatLED(LED1, "heartbeatLED");
SomeRandomBloke 0:a29a0225f203 75 DigitalOut led2(LED2, "led2");
SomeRandomBloke 0:a29a0225f203 76 DigitalOut led3(LED3, "led3");
SomeRandomBloke 0:a29a0225f203 77 //DigitalOut led4(LED4, "led4");
SomeRandomBloke 0:a29a0225f203 78 DigitalOut linkLED(p30, "linkLED");
SomeRandomBloke 0:a29a0225f203 79 DigitalOut statusLED(p25, "statusLED");
SomeRandomBloke 0:a29a0225f203 80
SomeRandomBloke 2:27714c8c9c0a 81 // Put as much as we can into RAM bank AHBSRAM0 which is reserved for USB that we are not using
SomeRandomBloke 2:27714c8c9c0a 82
SomeRandomBloke 2:27714c8c9c0a 83 // Setup which filesystem to use, Local or uSD card, both use same name
SomeRandomBloke 0:a29a0225f203 84 __attribute((section("AHBSRAM0"))) LocalFileSystem fs("iotfs");
SomeRandomBloke 0:a29a0225f203 85 //__attribute((section("AHBSRAM0"))) SDFileSystem sd(p5, p6, p7, p8, "iotfs");
SomeRandomBloke 0:a29a0225f203 86
SomeRandomBloke 0:a29a0225f203 87 __attribute((section("AHBSRAM0"))) EthernetNetIf *eth;
SomeRandomBloke 0:a29a0225f203 88 __attribute((section("AHBSRAM0"))) NTPClient ntp;
SomeRandomBloke 0:a29a0225f203 89 __attribute((section("AHBSRAM0"))) Ethernet ethernet;
SomeRandomBloke 2:27714c8c9c0a 90 __attribute((section("AHBSRAM0"))) DNSResolver resolver;
SomeRandomBloke 0:a29a0225f203 91
SomeRandomBloke 0:a29a0225f203 92 // Configuration values loaded from file iotsetup.dat
SomeRandomBloke 0:a29a0225f203 93 __attribute((section("AHBSRAM0"))) IpAddr ipAddress(0, 0, 0, 0);
SomeRandomBloke 0:a29a0225f203 94 __attribute((section("AHBSRAM0"))) IpAddr netMask(255, 255, 255, 0);
SomeRandomBloke 0:a29a0225f203 95 __attribute((section("AHBSRAM0"))) IpAddr gwAddress(0, 0, 0, 0);
SomeRandomBloke 0:a29a0225f203 96 __attribute((section("AHBSRAM0"))) IpAddr dnsAddress(0, 0, 0, 0);
SomeRandomBloke 0:a29a0225f203 97 __attribute((section("AHBSRAM0"))) bool useDHCP = false;
SomeRandomBloke 0:a29a0225f203 98
SomeRandomBloke 0:a29a0225f203 99 // Static buffers
SomeRandomBloke 0:a29a0225f203 100 #define MAX_LINE_LENGTH 128
SomeRandomBloke 2:27714c8c9c0a 101 __attribute((section("AHBSRAM0"))) static char lineBuf[MAX_LINE_LENGTH];
SomeRandomBloke 2:27714c8c9c0a 102 __attribute((section("AHBSRAM0"))) static OutputPachube outPachube;
SomeRandomBloke 2:27714c8c9c0a 103 __attribute((section("AHBSRAM0"))) static IoTRouting rtr;
SomeRandomBloke 0:a29a0225f203 104
SomeRandomBloke 0:a29a0225f203 105 // Pachube config
SomeRandomBloke 2:27714c8c9c0a 106 __attribute((section("AHBSRAM0"))) static char pachubeApiKey[65];
SomeRandomBloke 0:a29a0225f203 107
SomeRandomBloke 0:a29a0225f203 108 // MQTT config
SomeRandomBloke 2:27714c8c9c0a 109 __attribute((section("AHBSRAM0"))) static IpAddr mqttHostAddress( 0, 0, 0, 0);
SomeRandomBloke 2:27714c8c9c0a 110 __attribute((section("AHBSRAM0"))) short mqttPort;
SomeRandomBloke 2:27714c8c9c0a 111 __attribute((section("AHBSRAM0"))) static char mqttUsername[MAX_LINE_LENGTH];
SomeRandomBloke 2:27714c8c9c0a 112 __attribute((section("AHBSRAM0"))) static char mqttPassword[MAX_LINE_LENGTH];
SomeRandomBloke 2:27714c8c9c0a 113 __attribute((section("AHBSRAM0"))) bool useMQTT = false;
SomeRandomBloke 2:27714c8c9c0a 114
SomeRandomBloke 0:a29a0225f203 115 //char mqttHostName[65];
SomeRandomBloke 0:a29a0225f203 116
SomeRandomBloke 0:a29a0225f203 117
SomeRandomBloke 0:a29a0225f203 118 // RFM12B config
SomeRandomBloke 0:a29a0225f203 119 __attribute((section("AHBSRAM0"))) static string rfm12bBands[4] = {"xxx", "433", "868", "915" };
SomeRandomBloke 2:27714c8c9c0a 120 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bId;
SomeRandomBloke 2:27714c8c9c0a 121 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bBand;
SomeRandomBloke 2:27714c8c9c0a 122 __attribute((section("AHBSRAM0"))) static uint8_t rfm12bGroup;
SomeRandomBloke 0:a29a0225f203 123
SomeRandomBloke 0:a29a0225f203 124 #define iotConfigFile "/iotfs/IOTSETUP.TXT"
SomeRandomBloke 2:27714c8c9c0a 125
SomeRandomBloke 0:a29a0225f203 126
SomeRandomBloke 0:a29a0225f203 127 __attribute((section("AHBSRAM0"))) RF12B rfm12b(p11, p12, p13, p14, p18);
SomeRandomBloke 0:a29a0225f203 128 __attribute((section("AHBSRAM0"))) Serial pc(USBTX, USBRX); // tx, rx
SomeRandomBloke 0:a29a0225f203 129
SomeRandomBloke 0:a29a0225f203 130 // Utility functions
SomeRandomBloke 0:a29a0225f203 131
SomeRandomBloke 0:a29a0225f203 132 /** convert string to IP address
SomeRandomBloke 0:a29a0225f203 133 *
SomeRandomBloke 0:a29a0225f203 134 * @param ipAddrInt IP address as single 32bit integer
SomeRandomBloke 0:a29a0225f203 135 * @param value The IP address as a string
SomeRandomBloke 0:a29a0225f203 136 */
SomeRandomBloke 0:a29a0225f203 137 void setIpAddress( int *ipAddrInt, char *value ) {
SomeRandomBloke 0:a29a0225f203 138 sscanf(value, "%d.%d.%d.%d", &ipAddrInt[0],&ipAddrInt[1],&ipAddrInt[2],&ipAddrInt[3]);
SomeRandomBloke 0:a29a0225f203 139 }
SomeRandomBloke 0:a29a0225f203 140
SomeRandomBloke 0:a29a0225f203 141 /** Get the value from a name=value pair
SomeRandomBloke 0:a29a0225f203 142 *
SomeRandomBloke 0:a29a0225f203 143 * @param buf The name/value pair character buffer
SomeRandomBloke 0:a29a0225f203 144 * @returns pointer to value
SomeRandomBloke 0:a29a0225f203 145 */
SomeRandomBloke 0:a29a0225f203 146 char *getConfigValue( char *buf ) {
SomeRandomBloke 0:a29a0225f203 147 char *ptr = strchr(buf, '=');
SomeRandomBloke 0:a29a0225f203 148 if ( ptr == NULL )
SomeRandomBloke 0:a29a0225f203 149 return NULL;
SomeRandomBloke 0:a29a0225f203 150 ptr++;
SomeRandomBloke 0:a29a0225f203 151 return ptr;
SomeRandomBloke 0:a29a0225f203 152 }
SomeRandomBloke 0:a29a0225f203 153
SomeRandomBloke 0:a29a0225f203 154 /** Copy zero or CR/LF terminated string to new zero terminated string
SomeRandomBloke 0:a29a0225f203 155 * Used when reading config values from files to remove CR/LF endings
SomeRandomBloke 0:a29a0225f203 156 *
SomeRandomBloke 0:a29a0225f203 157 * @param to Char pointer to destination
SomeRandomBloke 0:a29a0225f203 158 * @param from Char pointer to source
SomeRandomBloke 0:a29a0225f203 159 */
SomeRandomBloke 0:a29a0225f203 160 void strcpynull(char *to, char *from ) {
SomeRandomBloke 0:a29a0225f203 161 while ( *from != '\n' && *from != '\r' && *from != '\0' ) {
SomeRandomBloke 0:a29a0225f203 162 *to++ = *from++;
SomeRandomBloke 0:a29a0225f203 163 }
SomeRandomBloke 0:a29a0225f203 164 *to = '\0';
SomeRandomBloke 0:a29a0225f203 165 }
SomeRandomBloke 0:a29a0225f203 166
SomeRandomBloke 0:a29a0225f203 167
SomeRandomBloke 0:a29a0225f203 168 /** Read IoT gateway configuration file
SomeRandomBloke 0:a29a0225f203 169 * File is of format name=value
SomeRandomBloke 0:a29a0225f203 170 *
SomeRandomBloke 0:a29a0225f203 171 */
SomeRandomBloke 0:a29a0225f203 172 bool readConfig() {
SomeRandomBloke 0:a29a0225f203 173
SomeRandomBloke 0:a29a0225f203 174 FILE *fp = fopen(iotConfigFile, "r");
SomeRandomBloke 0:a29a0225f203 175 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 176 printf("Could not open file %s for read\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 177 return false;
SomeRandomBloke 0:a29a0225f203 178 }
SomeRandomBloke 0:a29a0225f203 179 // read file
SomeRandomBloke 0:a29a0225f203 180 while (!feof( fp )) {
SomeRandomBloke 0:a29a0225f203 181 fgets(lineBuf,MAX_LINE_LENGTH,fp);
SomeRandomBloke 0:a29a0225f203 182 //printf("%s",lineBuf);
SomeRandomBloke 0:a29a0225f203 183 // Need to read each entry and update config
SomeRandomBloke 0:a29a0225f203 184 char *nameStr;
SomeRandomBloke 0:a29a0225f203 185 char *valueStr;
SomeRandomBloke 0:a29a0225f203 186 nameStr = lineBuf;
SomeRandomBloke 0:a29a0225f203 187 valueStr = strchr( lineBuf, '=' );
SomeRandomBloke 0:a29a0225f203 188 if ( valueStr != NULL ) {
SomeRandomBloke 0:a29a0225f203 189 *valueStr++ = '\0';
SomeRandomBloke 0:a29a0225f203 190 int tmpAddress[4] = {0,0,0,0};
SomeRandomBloke 0:a29a0225f203 191 if ( strcmp( nameStr, "ip.address" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 192 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 193 ipAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 194
SomeRandomBloke 2:27714c8c9c0a 195 } else if ( strcmp( nameStr, "ip.netmask" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 196 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 197 netMask = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 198
SomeRandomBloke 2:27714c8c9c0a 199 } else if ( strcmp( nameStr, "ip.gateway" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 200 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 201 gwAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 202
SomeRandomBloke 2:27714c8c9c0a 203 } else if ( strcmp( nameStr, "ip.dns" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 204 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 0:a29a0225f203 205 dnsAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 206
SomeRandomBloke 2:27714c8c9c0a 207 } else if ( strcmp( nameStr, "ip.mode" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 208 useDHCP = (strncmp( valueStr, "dhcp", 4) == 0 ? true : false);
SomeRandomBloke 2:27714c8c9c0a 209
SomeRandomBloke 0:a29a0225f203 210 } else if ( strcmp( nameStr, "pachube.key" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 211 strcpynull(pachubeApiKey, valueStr );
SomeRandomBloke 2:27714c8c9c0a 212
SomeRandomBloke 2:27714c8c9c0a 213 } else if ( strcmp( nameStr, "mqtt.host" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 214 setIpAddress( &tmpAddress[0], valueStr );
SomeRandomBloke 2:27714c8c9c0a 215 mqttHostAddress = IpAddr( tmpAddress[0],tmpAddress[1],tmpAddress[2],tmpAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 216
SomeRandomBloke 2:27714c8c9c0a 217 } else if ( strcmp( nameStr, "mqtt.port" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 218 mqttPort = atoi( valueStr );
SomeRandomBloke 2:27714c8c9c0a 219
SomeRandomBloke 2:27714c8c9c0a 220 } else if ( strcmp( nameStr, "mqtt.username" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 221 strcpynull(mqttUsername, valueStr );
SomeRandomBloke 2:27714c8c9c0a 222
SomeRandomBloke 2:27714c8c9c0a 223 } else if ( strcmp( nameStr, "mqtt.password" ) == 0 ) {
SomeRandomBloke 2:27714c8c9c0a 224 strcpynull(mqttPassword, valueStr );
SomeRandomBloke 2:27714c8c9c0a 225
SomeRandomBloke 0:a29a0225f203 226 } else if ( strcmp( nameStr, "rfm12b.band" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 227 if ( strncmp( valueStr, "433", 3 ) == 0 )
SomeRandomBloke 0:a29a0225f203 228 rfm12bBand = RF12_433MHZ;
SomeRandomBloke 0:a29a0225f203 229 else if ( strncmp( valueStr, "868", 3 ) == 0 )
SomeRandomBloke 0:a29a0225f203 230 rfm12bBand = RF12_868MHZ;
SomeRandomBloke 0:a29a0225f203 231 else if ( strncmp( valueStr, "915", 3 ) == 0 )
SomeRandomBloke 0:a29a0225f203 232 rfm12bBand = RF12_915MHZ;
SomeRandomBloke 2:27714c8c9c0a 233
SomeRandomBloke 0:a29a0225f203 234 } else if ( strcmp( nameStr, "rfm12b.id" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 235 rfm12bId = atoi( valueStr );
SomeRandomBloke 0:a29a0225f203 236 } else if ( strcmp( nameStr, "rfm12b.group" ) == 0 ) {
SomeRandomBloke 0:a29a0225f203 237 rfm12bGroup = atoi( valueStr );
SomeRandomBloke 0:a29a0225f203 238 }
SomeRandomBloke 0:a29a0225f203 239 }
SomeRandomBloke 0:a29a0225f203 240 }
SomeRandomBloke 0:a29a0225f203 241 fclose(fp);
SomeRandomBloke 0:a29a0225f203 242
SomeRandomBloke 0:a29a0225f203 243 return true;
SomeRandomBloke 0:a29a0225f203 244 }
SomeRandomBloke 0:a29a0225f203 245
SomeRandomBloke 0:a29a0225f203 246 /** Write the current config to file
SomeRandomBloke 0:a29a0225f203 247 */
SomeRandomBloke 0:a29a0225f203 248 bool writeConfig() {
SomeRandomBloke 0:a29a0225f203 249
SomeRandomBloke 0:a29a0225f203 250 // Doesnt work?
SomeRandomBloke 0:a29a0225f203 251 // Rename original file
SomeRandomBloke 0:a29a0225f203 252 // if( rename ( iotConfigFile.c_str(), iotConfigFileBak.c_str() ) != 0 ) {
SomeRandomBloke 0:a29a0225f203 253 // printf("Could not rename file %s\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 254 // return false;
SomeRandomBloke 0:a29a0225f203 255 // }
SomeRandomBloke 0:a29a0225f203 256
SomeRandomBloke 0:a29a0225f203 257 FILE *fp = fopen(iotConfigFile, "w");
SomeRandomBloke 0:a29a0225f203 258 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 259 printf("Could not open file %s for write\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 260 return false;
SomeRandomBloke 0:a29a0225f203 261 }
SomeRandomBloke 0:a29a0225f203 262
SomeRandomBloke 0:a29a0225f203 263 time_t ctTime;
SomeRandomBloke 0:a29a0225f203 264 ctTime = time(NULL);
SomeRandomBloke 0:a29a0225f203 265
SomeRandomBloke 0:a29a0225f203 266 fprintf(fp, "# iotsetup created (UTC) %s\n", ctime(&ctTime));
SomeRandomBloke 0:a29a0225f203 267 fprintf(fp, "ip.mode=%s\n", (useDHCP ? "dhcp" : "fixed") );
SomeRandomBloke 0:a29a0225f203 268 // Add msg to say net config being ignored
SomeRandomBloke 0:a29a0225f203 269 if ( useDHCP )
SomeRandomBloke 0:a29a0225f203 270 fprintf(fp, "# Following ip.* parameters not used in DHCP mode\n");
SomeRandomBloke 0:a29a0225f203 271
SomeRandomBloke 0:a29a0225f203 272 fprintf(fp, "ip.address=%hhu.%hhu.%hhu.%hhu\n", ipAddress[0], ipAddress[1],ipAddress[2],ipAddress[3]);
SomeRandomBloke 0:a29a0225f203 273 fprintf(fp, "ip.netmask=%hhu.%hhu.%hhu.%hhu\n",netMask[0], netMask[1], netMask[2], netMask[3]);
SomeRandomBloke 0:a29a0225f203 274 fprintf(fp, "ip.gateway=%hhu.%hhu.%hhu.%hhu\n",gwAddress[0],gwAddress[1],gwAddress[2],gwAddress[3]);
SomeRandomBloke 0:a29a0225f203 275 fprintf(fp, "ip.dns=%hhu.%hhu.%hhu.%hhu\n",dnsAddress[0],dnsAddress[1],dnsAddress[2],dnsAddress[3]);
SomeRandomBloke 0:a29a0225f203 276
SomeRandomBloke 0:a29a0225f203 277 fprintf(fp, "rfm12b.band=%s\n",rfm12bBands[rfm12bBand].c_str());
SomeRandomBloke 0:a29a0225f203 278 fprintf(fp, "rfm12b.id=%d\n",rfm12bId);
SomeRandomBloke 0:a29a0225f203 279 fprintf(fp, "rfm12b.group=%d\n",rfm12bGroup);
SomeRandomBloke 0:a29a0225f203 280
SomeRandomBloke 0:a29a0225f203 281 fprintf(fp, "time.timezone=GMT\n");
SomeRandomBloke 0:a29a0225f203 282 fprintf(fp, "time.dst=yes\n");
SomeRandomBloke 2:27714c8c9c0a 283
SomeRandomBloke 2:27714c8c9c0a 284 fprintf(fp, "pachube.key=%s\n", pachubeApiKey );
SomeRandomBloke 2:27714c8c9c0a 285
SomeRandomBloke 2:27714c8c9c0a 286 fprintf(fp, "mqtt.host=%hhu.%hhu.%hhu.%hhu\n",mqttHostAddress[0],mqttHostAddress[1],mqttHostAddress[2],mqttHostAddress[3]);
SomeRandomBloke 2:27714c8c9c0a 287 fprintf(fp, "mqtt.port=%d\n",mqttPort);
SomeRandomBloke 2:27714c8c9c0a 288 fprintf(fp, "mqtt.username=%s\n", mqttUsername );
SomeRandomBloke 2:27714c8c9c0a 289 fprintf(fp, "mqtt.password=%s\n", mqttPassword );
SomeRandomBloke 2:27714c8c9c0a 290
SomeRandomBloke 0:a29a0225f203 291 fclose(fp);
SomeRandomBloke 0:a29a0225f203 292
SomeRandomBloke 0:a29a0225f203 293 return true;
SomeRandomBloke 0:a29a0225f203 294 }
SomeRandomBloke 0:a29a0225f203 295
SomeRandomBloke 0:a29a0225f203 296
SomeRandomBloke 0:a29a0225f203 297 // These external symbols are maintained by the linker to indicate the
SomeRandomBloke 0:a29a0225f203 298 // location of various regions in the device's memory. They will be used by
SomeRandomBloke 0:a29a0225f203 299 // DisplayRAMBanks() to dump the size of each RAM bank to stdout.
SomeRandomBloke 0:a29a0225f203 300 extern unsigned int Image$$RW_IRAM1$$Base;
SomeRandomBloke 0:a29a0225f203 301 extern unsigned int Image$$RW_IRAM1$$ZI$$Limit;
SomeRandomBloke 0:a29a0225f203 302 extern unsigned int Image$$RW_IRAM2$$Base;
SomeRandomBloke 0:a29a0225f203 303 extern unsigned int Image$$RW_IRAM2$$ZI$$Limit;
SomeRandomBloke 0:a29a0225f203 304 extern unsigned int Image$$RW_IRAM3$$Base;
SomeRandomBloke 0:a29a0225f203 305 extern unsigned int Image$$RW_IRAM3$$ZI$$Limit;
SomeRandomBloke 0:a29a0225f203 306
SomeRandomBloke 0:a29a0225f203 307 // Displays the size of static allocations for each RAM bank as indicated by
SomeRandomBloke 0:a29a0225f203 308 // ARM linker to stdout.
SomeRandomBloke 0:a29a0225f203 309 static void DisplayRAMBanks(void) {
SomeRandomBloke 0:a29a0225f203 310 printf("Static RAM bank allocations\r\n");
SomeRandomBloke 0:a29a0225f203 311 printf(" Main RAM = %u\r\n", (unsigned int)&Image$$RW_IRAM1$$ZI$$Limit -
SomeRandomBloke 0:a29a0225f203 312 (unsigned int)&Image$$RW_IRAM1$$Base);
SomeRandomBloke 0:a29a0225f203 313 printf(" RAM0 = %u\r\n", (unsigned int)&Image$$RW_IRAM2$$ZI$$Limit -
SomeRandomBloke 0:a29a0225f203 314 (unsigned int)&Image$$RW_IRAM2$$Base);
SomeRandomBloke 0:a29a0225f203 315 printf(" RAM1 = %u\r\n", (unsigned int)&Image$$RW_IRAM3$$ZI$$Limit -
SomeRandomBloke 0:a29a0225f203 316 (unsigned int)&Image$$RW_IRAM3$$Base);
SomeRandomBloke 0:a29a0225f203 317 }
SomeRandomBloke 0:a29a0225f203 318
SomeRandomBloke 0:a29a0225f203 319 /** Main function, where all the magic starts
SomeRandomBloke 0:a29a0225f203 320 */
SomeRandomBloke 0:a29a0225f203 321 int main() {
SomeRandomBloke 0:a29a0225f203 322 linkLED = 1;
SomeRandomBloke 0:a29a0225f203 323 statusLED = 0;
SomeRandomBloke 0:a29a0225f203 324 pc.baud(115200);
SomeRandomBloke 0:a29a0225f203 325
SomeRandomBloke 0:a29a0225f203 326 printf(VERSION_INFO);
SomeRandomBloke 0:a29a0225f203 327 printf("\n");
SomeRandomBloke 0:a29a0225f203 328
SomeRandomBloke 0:a29a0225f203 329 DisplayRAMBanks();
SomeRandomBloke 0:a29a0225f203 330
SomeRandomBloke 0:a29a0225f203 331 printf("Setting up...\n");
SomeRandomBloke 0:a29a0225f203 332 printf("\nHEAP STATS\n");
SomeRandomBloke 0:a29a0225f203 333 __heapstats((__heapprt)fprintf,stderr);
SomeRandomBloke 0:a29a0225f203 334
SomeRandomBloke 0:a29a0225f203 335 if ( !readConfig() ) {
SomeRandomBloke 0:a29a0225f203 336 error("Setup failed");
SomeRandomBloke 0:a29a0225f203 337 }
SomeRandomBloke 0:a29a0225f203 338
SomeRandomBloke 0:a29a0225f203 339 if (useDHCP) {
SomeRandomBloke 0:a29a0225f203 340 printf("Using DHCP\n");
SomeRandomBloke 0:a29a0225f203 341 eth = new EthernetNetIf( "IoTGateway" );
SomeRandomBloke 0:a29a0225f203 342 } else {
SomeRandomBloke 0:a29a0225f203 343 // printf("Using Fixed addressing\n");
SomeRandomBloke 0:a29a0225f203 344 eth = new EthernetNetIf( ipAddress, netMask, gwAddress, dnsAddress );
SomeRandomBloke 0:a29a0225f203 345 }
SomeRandomBloke 0:a29a0225f203 346 EthernetErr ethErr = eth->setup();
SomeRandomBloke 0:a29a0225f203 347 if (ethErr) {
SomeRandomBloke 0:a29a0225f203 348 printf("Error %d in setup.\n", ethErr);
SomeRandomBloke 0:a29a0225f203 349 return -1;
SomeRandomBloke 0:a29a0225f203 350 }
SomeRandomBloke 0:a29a0225f203 351
SomeRandomBloke 0:a29a0225f203 352 linkLED = !ethernet.link();
SomeRandomBloke 0:a29a0225f203 353
SomeRandomBloke 0:a29a0225f203 354 if (useDHCP) {
SomeRandomBloke 0:a29a0225f203 355 // We are using dhcp so get IP Address
SomeRandomBloke 0:a29a0225f203 356 ipAddress = eth->getIp();
SomeRandomBloke 0:a29a0225f203 357 }
SomeRandomBloke 0:a29a0225f203 358
SomeRandomBloke 0:a29a0225f203 359
SomeRandomBloke 0:a29a0225f203 360 // Get Current time
SomeRandomBloke 0:a29a0225f203 361 Host server(IpAddr(), 123, "0.uk.pool.ntp.org");
SomeRandomBloke 0:a29a0225f203 362 ntp.setTime(server);
SomeRandomBloke 0:a29a0225f203 363
SomeRandomBloke 0:a29a0225f203 364 time_t ctTime = time(NULL);
SomeRandomBloke 0:a29a0225f203 365 printf("\nTime is now (UTC): %s\n", ctime(&ctTime));
SomeRandomBloke 0:a29a0225f203 366
SomeRandomBloke 0:a29a0225f203 367 outPachube = OutputPachube();
SomeRandomBloke 0:a29a0225f203 368 outPachube.setApiKey( pachubeApiKey );
SomeRandomBloke 2:27714c8c9c0a 369 // printf("MAIN: outPachube = %ld\n",(int)&outPachube);
SomeRandomBloke 2:27714c8c9c0a 370 rtr.addOutput( (OutputDef*)&outPachube , OUTPUT_TYPE_PACHUBE);
SomeRandomBloke 2:27714c8c9c0a 371
SomeRandomBloke 0:a29a0225f203 372
SomeRandomBloke 2:27714c8c9c0a 373 //mqttHostAddress = IpAddr(192,168,1,77);
SomeRandomBloke 2:27714c8c9c0a 374 OutputMqtt outMqtt = OutputMqtt();
SomeRandomBloke 2:27714c8c9c0a 375 // mqttHostAddress = resolver.resolveName("api.pachube.com");
SomeRandomBloke 2:27714c8c9c0a 376 // Only use MQTT is we have a host IP address
SomeRandomBloke 2:27714c8c9c0a 377 if( mqttHostAddress[0] > 0 && mqttHostAddress[3] > 0 ) {
SomeRandomBloke 2:27714c8c9c0a 378 outMqtt.initConnection( &mqttHostAddress, mqttPort, mqttUsername, mqttPassword );
SomeRandomBloke 2:27714c8c9c0a 379 //( &serverIpAddr );
SomeRandomBloke 2:27714c8c9c0a 380 useMQTT = outMqtt.init();
SomeRandomBloke 0:a29a0225f203 381
SomeRandomBloke 2:27714c8c9c0a 382 if( useMQTT )
SomeRandomBloke 2:27714c8c9c0a 383 rtr.addOutput( (OutputDef*)&outMqtt , OUTPUT_TYPE_MQTT);
SomeRandomBloke 2:27714c8c9c0a 384 }
SomeRandomBloke 2:27714c8c9c0a 385
SomeRandomBloke 0:a29a0225f203 386 rtr.initRouting();
SomeRandomBloke 0:a29a0225f203 387
SomeRandomBloke 0:a29a0225f203 388 printf("Setup OK\n");
SomeRandomBloke 0:a29a0225f203 389
SomeRandomBloke 0:a29a0225f203 390 printf( "Setting RFM12B ID %d, Band %d Group %d\n",rfm12bId, rfm12bBand, rfm12bGroup);
SomeRandomBloke 0:a29a0225f203 391 rfm12b.init(rfm12bId, rfm12bBand, rfm12bGroup ); //id = 2, band 866, group 5
SomeRandomBloke 0:a29a0225f203 392
SomeRandomBloke 0:a29a0225f203 393 printf("Listening...\n");
SomeRandomBloke 0:a29a0225f203 394
SomeRandomBloke 0:a29a0225f203 395 Timer tm;
SomeRandomBloke 0:a29a0225f203 396 tm.start();
SomeRandomBloke 0:a29a0225f203 397
SomeRandomBloke 0:a29a0225f203 398 printf("\nHEAP STATS\n");
SomeRandomBloke 0:a29a0225f203 399 __heapstats((__heapprt)fprintf,stderr);
SomeRandomBloke 0:a29a0225f203 400
SomeRandomBloke 0:a29a0225f203 401 short dataLen = 0;
SomeRandomBloke 0:a29a0225f203 402 uint8_t *rf12Buf;
SomeRandomBloke 0:a29a0225f203 403
SomeRandomBloke 0:a29a0225f203 404 // Start receiving data
SomeRandomBloke 0:a29a0225f203 405 rfm12b.rf12_recvStart();
SomeRandomBloke 0:a29a0225f203 406 while (true) {
SomeRandomBloke 0:a29a0225f203 407 Net::poll();
SomeRandomBloke 0:a29a0225f203 408
SomeRandomBloke 0:a29a0225f203 409 // This is RFM12B specific
SomeRandomBloke 0:a29a0225f203 410 if ( rfm12b.available() > 0 ) {
SomeRandomBloke 0:a29a0225f203 411 statusLED = 1;
SomeRandomBloke 0:a29a0225f203 412 rf12Buf = rfm12b.get_data();
SomeRandomBloke 0:a29a0225f203 413 dataLen = rfm12b.length();
SomeRandomBloke 0:a29a0225f203 414
SomeRandomBloke 0:a29a0225f203 415 if ( rtr.routePayload( rf12Buf, dataLen + 3 ) ) {
SomeRandomBloke 0:a29a0225f203 416 // Successfully dealt with a packet
SomeRandomBloke 0:a29a0225f203 417
SomeRandomBloke 0:a29a0225f203 418 // Do something different if routed
SomeRandomBloke 0:a29a0225f203 419
SomeRandomBloke 0:a29a0225f203 420 }
SomeRandomBloke 0:a29a0225f203 421
SomeRandomBloke 0:a29a0225f203 422 // For now, acknowledge everything
SomeRandomBloke 0:a29a0225f203 423
SomeRandomBloke 0:a29a0225f203 424 // Send an ack if required
SomeRandomBloke 0:a29a0225f203 425 if ((rf12Buf[1] & ~RF12_HDR_MASK) == RF12_HDR_ACK // &&
SomeRandomBloke 0:a29a0225f203 426 //(config.nodeId & 0x20) == 0
SomeRandomBloke 0:a29a0225f203 427 ) {
SomeRandomBloke 0:a29a0225f203 428
SomeRandomBloke 0:a29a0225f203 429 printf("RFM12B -> ack\n");
SomeRandomBloke 0:a29a0225f203 430
SomeRandomBloke 0:a29a0225f203 431 byte addr = rf12Buf[1] & RF12_HDR_MASK;
SomeRandomBloke 0:a29a0225f203 432 rfm12b.rf12_sendStart(RF12_HDR_CTL | RF12_HDR_DST | addr, 0, 1);
SomeRandomBloke 0:a29a0225f203 433 }
SomeRandomBloke 0:a29a0225f203 434
SomeRandomBloke 0:a29a0225f203 435 statusLED = 0;
SomeRandomBloke 0:a29a0225f203 436 }
SomeRandomBloke 0:a29a0225f203 437
SomeRandomBloke 0:a29a0225f203 438 if (tm.read()>.5) {
SomeRandomBloke 0:a29a0225f203 439 heartbeatLED=!heartbeatLED; //Show that we are alive
SomeRandomBloke 0:a29a0225f203 440 tm.start();
SomeRandomBloke 0:a29a0225f203 441 }
SomeRandomBloke 0:a29a0225f203 442
SomeRandomBloke 2:27714c8c9c0a 443 // If using mqtt then send heartbeat
SomeRandomBloke 2:27714c8c9c0a 444 if(useMQTT) {
SomeRandomBloke 2:27714c8c9c0a 445 outMqtt.send(); // Used for heartbeat/keepalive packet
SomeRandomBloke 2:27714c8c9c0a 446 }
SomeRandomBloke 2:27714c8c9c0a 447
SomeRandomBloke 0:a29a0225f203 448 linkLED = !ethernet.link();
SomeRandomBloke 0:a29a0225f203 449
SomeRandomBloke 0:a29a0225f203 450 }
SomeRandomBloke 0:a29a0225f203 451
SomeRandomBloke 0:a29a0225f203 452 }
SomeRandomBloke 0:a29a0225f203 453
SomeRandomBloke 0:a29a0225f203 454 // The End!