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:
Mon Apr 02 22:05:20 2012 +0000
Revision:
0:a29a0225f203
Child:
2:27714c8c9c0a
Initial version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 0:a29a0225f203 1 /** IoT Gateway Routing for incoming messages
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 *
SomeRandomBloke 0:a29a0225f203 30 */
SomeRandomBloke 0:a29a0225f203 31
SomeRandomBloke 0:a29a0225f203 32 #include "mbed.h"
SomeRandomBloke 0:a29a0225f203 33 #include "RF12B.h"
SomeRandomBloke 0:a29a0225f203 34 #include "IoTRouting.h"
SomeRandomBloke 0:a29a0225f203 35 #include "csv_parser.h"
SomeRandomBloke 0:a29a0225f203 36 #include "PayloadV1.h"
SomeRandomBloke 0:a29a0225f203 37 #include "PayloadV2.h"
SomeRandomBloke 0:a29a0225f203 38 #include "PayloadSimple.h"
SomeRandomBloke 0:a29a0225f203 39 #include "OutputPachube.h"
SomeRandomBloke 0:a29a0225f203 40
SomeRandomBloke 0:a29a0225f203 41 //DigitalOut activityLED(p29, "activityLED");
SomeRandomBloke 0:a29a0225f203 42
SomeRandomBloke 0:a29a0225f203 43 #define iotRoutingFile "/iotfs/IOTRTG.TXT"
SomeRandomBloke 0:a29a0225f203 44 #define iotNodeDefFile "/iotfs/IOTNODE.TXT"
SomeRandomBloke 0:a29a0225f203 45
SomeRandomBloke 0:a29a0225f203 46
SomeRandomBloke 0:a29a0225f203 47 // Default Constructor
SomeRandomBloke 0:a29a0225f203 48 IoTRouting::IoTRouting() {}
SomeRandomBloke 0:a29a0225f203 49
SomeRandomBloke 0:a29a0225f203 50
SomeRandomBloke 0:a29a0225f203 51 void IoTRouting::addNodeToList(uint8_t groupId, uint8_t nodeId, uint8_t length, uint8_t type ) {
SomeRandomBloke 0:a29a0225f203 52 IoTNodeDef *pr = new IoTNodeDef();
SomeRandomBloke 0:a29a0225f203 53 pr->groupId = groupId;
SomeRandomBloke 0:a29a0225f203 54 pr->nodeId = nodeId;
SomeRandomBloke 0:a29a0225f203 55 pr->length = length;
SomeRandomBloke 0:a29a0225f203 56 pr->type = type;
SomeRandomBloke 0:a29a0225f203 57
SomeRandomBloke 0:a29a0225f203 58 _nodeDefList.push_back(pr);
SomeRandomBloke 0:a29a0225f203 59 }
SomeRandomBloke 0:a29a0225f203 60
SomeRandomBloke 0:a29a0225f203 61 void IoTRouting::addRoutingToList( short nodeId, short sensorId, float factor, byte outType,
SomeRandomBloke 0:a29a0225f203 62 char *param1, char *param2, char *param3, char *param4 ) {
SomeRandomBloke 0:a29a0225f203 63
SomeRandomBloke 0:a29a0225f203 64 PayloadRouting* pr = new PayloadRouting();
SomeRandomBloke 0:a29a0225f203 65 pr->nodeId = nodeId;
SomeRandomBloke 0:a29a0225f203 66 pr->sensorId = sensorId;
SomeRandomBloke 0:a29a0225f203 67
SomeRandomBloke 0:a29a0225f203 68 pr->factor = factor;
SomeRandomBloke 0:a29a0225f203 69 pr->outType = outType;
SomeRandomBloke 0:a29a0225f203 70
SomeRandomBloke 0:a29a0225f203 71 switch ( pr->outType ) {
SomeRandomBloke 0:a29a0225f203 72 case OUTPUT_TYPE_PACHUBE:
SomeRandomBloke 0:a29a0225f203 73 pr->output = pachubeOutput;
SomeRandomBloke 0:a29a0225f203 74 break;
SomeRandomBloke 0:a29a0225f203 75 case OUTPUT_TYPE_MQTT:
SomeRandomBloke 0:a29a0225f203 76 pr->output = mqttOutput;
SomeRandomBloke 0:a29a0225f203 77 break;
SomeRandomBloke 0:a29a0225f203 78 default:
SomeRandomBloke 0:a29a0225f203 79 pr->output = NULL;
SomeRandomBloke 0:a29a0225f203 80 break;
SomeRandomBloke 0:a29a0225f203 81 }
SomeRandomBloke 0:a29a0225f203 82
SomeRandomBloke 0:a29a0225f203 83 pr->param1 = new char[strlen(param1)+1];
SomeRandomBloke 0:a29a0225f203 84 strcpy(pr->param1, param1);
SomeRandomBloke 0:a29a0225f203 85 pr->param2 = new char[strlen(param2)+1];
SomeRandomBloke 0:a29a0225f203 86 strcpy(pr->param2, param2);
SomeRandomBloke 0:a29a0225f203 87 pr->param3 = new char[strlen(param3)+1];
SomeRandomBloke 0:a29a0225f203 88 strcpy(pr->param3, param3);
SomeRandomBloke 0:a29a0225f203 89 pr->param4 = new char[strlen(param4)+1];
SomeRandomBloke 0:a29a0225f203 90 strcpy(pr->param4, param4);
SomeRandomBloke 0:a29a0225f203 91 // printf("%d,%d,%f,%d,%s,%s,%s,%s\n",pr->nodeId, pr->sensorId, pr->factor, pr->outType, pr->param1, pr->param2, pr->param3, pr->param4);
SomeRandomBloke 0:a29a0225f203 92 _routing.push_back(pr);
SomeRandomBloke 0:a29a0225f203 93 }
SomeRandomBloke 0:a29a0225f203 94
SomeRandomBloke 0:a29a0225f203 95
SomeRandomBloke 0:a29a0225f203 96 void IoTRouting::initRouting() {
SomeRandomBloke 0:a29a0225f203 97 sendCount = 0;
SomeRandomBloke 0:a29a0225f203 98
SomeRandomBloke 0:a29a0225f203 99 FILE *fp = fopen(iotNodeDefFile, "r");
SomeRandomBloke 0:a29a0225f203 100 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 101 printf("Could not open file %s for read\n", iotNodeDefFile);
SomeRandomBloke 0:a29a0225f203 102 return;
SomeRandomBloke 0:a29a0225f203 103 }
SomeRandomBloke 0:a29a0225f203 104
SomeRandomBloke 0:a29a0225f203 105 // read file
SomeRandomBloke 0:a29a0225f203 106
SomeRandomBloke 0:a29a0225f203 107 const char field_terminator = ',';
SomeRandomBloke 0:a29a0225f203 108 const char line_terminator = '\n';
SomeRandomBloke 0:a29a0225f203 109 const char enclosure_char = '"';
SomeRandomBloke 0:a29a0225f203 110
SomeRandomBloke 0:a29a0225f203 111 csv_parser file_parser;
SomeRandomBloke 0:a29a0225f203 112
SomeRandomBloke 0:a29a0225f203 113 /* Define how many records we're gonna skip. This could be used to skip the column definitions. */
SomeRandomBloke 0:a29a0225f203 114 file_parser.set_skip_lines(0);
SomeRandomBloke 0:a29a0225f203 115
SomeRandomBloke 0:a29a0225f203 116 /* Specify the file to parse */
SomeRandomBloke 0:a29a0225f203 117 file_parser.init(fp);
SomeRandomBloke 0:a29a0225f203 118
SomeRandomBloke 0:a29a0225f203 119 /* Here we tell the parser how to parse the file */
SomeRandomBloke 0:a29a0225f203 120 file_parser.set_enclosed_char(enclosure_char, ENCLOSURE_OPTIONAL);
SomeRandomBloke 0:a29a0225f203 121 file_parser.set_field_term_char(field_terminator);
SomeRandomBloke 0:a29a0225f203 122 file_parser.set_line_term_char(line_terminator);
SomeRandomBloke 0:a29a0225f203 123
SomeRandomBloke 0:a29a0225f203 124 /* Check to see if there are more records, then grab each row one at a time */
SomeRandomBloke 0:a29a0225f203 125
SomeRandomBloke 0:a29a0225f203 126 while (file_parser.has_more_rows()) {
SomeRandomBloke 0:a29a0225f203 127 csv_row row = file_parser.get_row();
SomeRandomBloke 0:a29a0225f203 128 if (row.size()<4) {
SomeRandomBloke 0:a29a0225f203 129 printf("row too short %d\n", row.size());
SomeRandomBloke 0:a29a0225f203 130 continue;
SomeRandomBloke 0:a29a0225f203 131 }
SomeRandomBloke 0:a29a0225f203 132 addNodeToList((uint8_t)atoi(row[0].c_str()), (uint8_t)atoi(row[1].c_str()),
SomeRandomBloke 0:a29a0225f203 133 (uint8_t)atoi(row[2].c_str()), (uint8_t)atoi(row[3].c_str()));
SomeRandomBloke 0:a29a0225f203 134 }
SomeRandomBloke 0:a29a0225f203 135
SomeRandomBloke 0:a29a0225f203 136 fclose(fp);
SomeRandomBloke 0:a29a0225f203 137
SomeRandomBloke 0:a29a0225f203 138 // printf("Finished loading routing data\n");
SomeRandomBloke 0:a29a0225f203 139
SomeRandomBloke 0:a29a0225f203 140 fp = fopen(iotRoutingFile, "r");
SomeRandomBloke 0:a29a0225f203 141 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 142 printf("Could not open file %s for read\n", iotRoutingFile);
SomeRandomBloke 0:a29a0225f203 143 return;
SomeRandomBloke 0:a29a0225f203 144 }
SomeRandomBloke 0:a29a0225f203 145 // _routing=new list<PayloadRouting*>();
SomeRandomBloke 0:a29a0225f203 146
SomeRandomBloke 0:a29a0225f203 147 /* Define how many records we're gonna skip. This could be used to skip the column definitions. */
SomeRandomBloke 0:a29a0225f203 148 file_parser.set_skip_lines(0);
SomeRandomBloke 0:a29a0225f203 149
SomeRandomBloke 0:a29a0225f203 150 /* Specify the file to parse */
SomeRandomBloke 0:a29a0225f203 151 file_parser.init(fp);
SomeRandomBloke 0:a29a0225f203 152
SomeRandomBloke 0:a29a0225f203 153 /* Here we tell the parser how to parse the file */
SomeRandomBloke 0:a29a0225f203 154 file_parser.set_enclosed_char(enclosure_char, ENCLOSURE_OPTIONAL);
SomeRandomBloke 0:a29a0225f203 155 file_parser.set_field_term_char(field_terminator);
SomeRandomBloke 0:a29a0225f203 156 file_parser.set_line_term_char(line_terminator);
SomeRandomBloke 0:a29a0225f203 157
SomeRandomBloke 0:a29a0225f203 158 /* Check to see if there are more records, then grab each row one at a time */
SomeRandomBloke 0:a29a0225f203 159
SomeRandomBloke 0:a29a0225f203 160 while (file_parser.has_more_rows()) {
SomeRandomBloke 0:a29a0225f203 161 csv_row row = file_parser.get_row();
SomeRandomBloke 0:a29a0225f203 162 if (row.size()<6) {
SomeRandomBloke 0:a29a0225f203 163 printf("row too short %d\n", row.size());
SomeRandomBloke 0:a29a0225f203 164 continue;
SomeRandomBloke 0:a29a0225f203 165 }
SomeRandomBloke 0:a29a0225f203 166 addRoutingToList( atoi(row[0].c_str()), atoi(row[1].c_str()), atof(row[2].c_str()), atoi(row[3].c_str()),
SomeRandomBloke 0:a29a0225f203 167 (char*)row[4].c_str(), (char*)row[5].c_str(), (char*)row[6].c_str(), (char*)row[7].c_str() );
SomeRandomBloke 0:a29a0225f203 168 }
SomeRandomBloke 0:a29a0225f203 169
SomeRandomBloke 0:a29a0225f203 170 fclose(fp);
SomeRandomBloke 0:a29a0225f203 171
SomeRandomBloke 0:a29a0225f203 172 // printf("Finished loading routing data\n");
SomeRandomBloke 0:a29a0225f203 173
SomeRandomBloke 0:a29a0225f203 174 // if(!mqtt.connect("IoTGateway")){
SomeRandomBloke 0:a29a0225f203 175 // printf("\r\nConnect to server failed ..\r\n");
SomeRandomBloke 0:a29a0225f203 176 // return -1;
SomeRandomBloke 0:a29a0225f203 177 // }
SomeRandomBloke 0:a29a0225f203 178 }
SomeRandomBloke 0:a29a0225f203 179
SomeRandomBloke 0:a29a0225f203 180 // Write the current nodelist back to file
SomeRandomBloke 0:a29a0225f203 181 // First rename original file to iotsetup.bak
SomeRandomBloke 0:a29a0225f203 182 bool IoTRouting::writeNodeList() {
SomeRandomBloke 0:a29a0225f203 183
SomeRandomBloke 0:a29a0225f203 184 // Rename original file
SomeRandomBloke 0:a29a0225f203 185 // if( rename ( iotConfigFile.c_str(), iotConfigFileBak.c_str() ) != 0 ) {
SomeRandomBloke 0:a29a0225f203 186 // printf("Could not rename file %s\n", iotConfigFile);
SomeRandomBloke 0:a29a0225f203 187 // return false;
SomeRandomBloke 0:a29a0225f203 188 // }
SomeRandomBloke 0:a29a0225f203 189
SomeRandomBloke 0:a29a0225f203 190 FILE *fp = fopen(iotNodeDefFile, "w");
SomeRandomBloke 0:a29a0225f203 191 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 192 printf("Could not open file %s for write\n", iotNodeDefFile);
SomeRandomBloke 0:a29a0225f203 193 return false;
SomeRandomBloke 0:a29a0225f203 194 }
SomeRandomBloke 0:a29a0225f203 195
SomeRandomBloke 0:a29a0225f203 196 for (short i=0; i<(int)_nodeDefList.size(); i++) {
SomeRandomBloke 0:a29a0225f203 197 IoTNodeDef *nd = (IoTNodeDef*)_nodeDefList.at(i);
SomeRandomBloke 0:a29a0225f203 198 // printf("%d,%d,%d,%d\n",nd->groupId,nd->nodeId, nd->length,nd->type );
SomeRandomBloke 0:a29a0225f203 199 fprintf(fp, "%d,%d,%d,%d\n",nd->groupId,nd->nodeId, nd->length,nd->type );
SomeRandomBloke 0:a29a0225f203 200 }
SomeRandomBloke 0:a29a0225f203 201
SomeRandomBloke 0:a29a0225f203 202 fclose(fp);
SomeRandomBloke 0:a29a0225f203 203
SomeRandomBloke 0:a29a0225f203 204 return true;
SomeRandomBloke 0:a29a0225f203 205 }
SomeRandomBloke 0:a29a0225f203 206
SomeRandomBloke 0:a29a0225f203 207 // Write the current nodelist back to file
SomeRandomBloke 0:a29a0225f203 208 // First rename original file to iotsetup.bak
SomeRandomBloke 0:a29a0225f203 209 bool IoTRouting::writeRoutingList() {
SomeRandomBloke 0:a29a0225f203 210
SomeRandomBloke 0:a29a0225f203 211 // Rename original file
SomeRandomBloke 0:a29a0225f203 212 // if( rename ( iotConfigFile.c_str(), iotConfigFileBak.c_str() ) != 0 ) {
SomeRandomBloke 0:a29a0225f203 213 // printf("Could not rename file %s\n", iotRoutingFile);
SomeRandomBloke 0:a29a0225f203 214 // return false;
SomeRandomBloke 0:a29a0225f203 215 // }
SomeRandomBloke 0:a29a0225f203 216
SomeRandomBloke 0:a29a0225f203 217 FILE *fp = fopen(iotRoutingFile, "w");
SomeRandomBloke 0:a29a0225f203 218 if (fp == NULL) {
SomeRandomBloke 0:a29a0225f203 219 printf("Could not open file %s for write\n", iotRoutingFile);
SomeRandomBloke 0:a29a0225f203 220 return false;
SomeRandomBloke 0:a29a0225f203 221 }
SomeRandomBloke 0:a29a0225f203 222
SomeRandomBloke 0:a29a0225f203 223 for ( short i=0; i<(short)_routing.size(); i++ ) {
SomeRandomBloke 0:a29a0225f203 224 PayloadRouting *pr = (PayloadRouting*)_routing.at(i);
SomeRandomBloke 0:a29a0225f203 225 // printf("%d,%d,%f,%d,%s,%s,%s,%s\n",pr->nodeId, pr->sensorId, pr->factor, pr->outType, pr->param1, pr->param2, pr->param3, pr->param4);
SomeRandomBloke 0:a29a0225f203 226 fprintf(fp, "%d,%d,%f,%d,%s,%s,%s,%s\n",pr->nodeId, pr->sensorId, pr->factor, pr->outType, pr->param1, pr->param2, pr->param3, pr->param4);
SomeRandomBloke 0:a29a0225f203 227 }
SomeRandomBloke 0:a29a0225f203 228
SomeRandomBloke 0:a29a0225f203 229 fclose(fp);
SomeRandomBloke 0:a29a0225f203 230
SomeRandomBloke 0:a29a0225f203 231 return true;
SomeRandomBloke 0:a29a0225f203 232 }
SomeRandomBloke 0:a29a0225f203 233
SomeRandomBloke 0:a29a0225f203 234 void IoTRouting::addOutput( OutputDef *output, short outType ) {
SomeRandomBloke 0:a29a0225f203 235 switch ( outType ) {
SomeRandomBloke 0:a29a0225f203 236 case OUTPUT_TYPE_PACHUBE:
SomeRandomBloke 0:a29a0225f203 237 pachubeOutput = output;
SomeRandomBloke 0:a29a0225f203 238 break;
SomeRandomBloke 0:a29a0225f203 239 case OUTPUT_TYPE_MQTT:
SomeRandomBloke 0:a29a0225f203 240 mqttOutput = output;
SomeRandomBloke 0:a29a0225f203 241 break;
SomeRandomBloke 0:a29a0225f203 242 default:
SomeRandomBloke 0:a29a0225f203 243 break;
SomeRandomBloke 0:a29a0225f203 244 }
SomeRandomBloke 0:a29a0225f203 245 }
SomeRandomBloke 0:a29a0225f203 246
SomeRandomBloke 0:a29a0225f203 247 PayloadRouting* IoTRouting::getRouting( short nodeId, short sensorId ) {
SomeRandomBloke 0:a29a0225f203 248 printf("Getting routing info for node %d, sensor %d size %d - ", nodeId, sensorId, (int)_routing.size());
SomeRandomBloke 0:a29a0225f203 249 for ( short i=0; i<(short)_routing.size(); i++ ) {
SomeRandomBloke 0:a29a0225f203 250
SomeRandomBloke 0:a29a0225f203 251 PayloadRouting *pr = (PayloadRouting*)_routing.at(i);
SomeRandomBloke 0:a29a0225f203 252 // printf("Node %d, sensor %d\n", pr->nodeId, pr->sensorId);
SomeRandomBloke 0:a29a0225f203 253 if ( pr->nodeId == nodeId && pr->sensorId == sensorId ) {
SomeRandomBloke 0:a29a0225f203 254 printf("Found!\n");
SomeRandomBloke 0:a29a0225f203 255 return pr;
SomeRandomBloke 0:a29a0225f203 256 }
SomeRandomBloke 0:a29a0225f203 257 }
SomeRandomBloke 0:a29a0225f203 258 printf("NOT found\n");
SomeRandomBloke 0:a29a0225f203 259 // Add to routing list
SomeRandomBloke 0:a29a0225f203 260 addRoutingToList( nodeId, sensorId, 1.0, OUTPUT_UNKNOWN,"","","","");
SomeRandomBloke 0:a29a0225f203 261 // Save Routing list
SomeRandomBloke 0:a29a0225f203 262 writeRoutingList();
SomeRandomBloke 0:a29a0225f203 263
SomeRandomBloke 0:a29a0225f203 264 return NULL;
SomeRandomBloke 0:a29a0225f203 265 }
SomeRandomBloke 0:a29a0225f203 266
SomeRandomBloke 0:a29a0225f203 267
SomeRandomBloke 0:a29a0225f203 268 short IoTRouting::getPayloadType( uint8_t *data, short dataLen ) {
SomeRandomBloke 0:a29a0225f203 269 printf("Getting payload type, size is %d - ",(int)_nodeDefList.size() );
SomeRandomBloke 0:a29a0225f203 270 for (short i=0; i<(int)_nodeDefList.size(); i++) {
SomeRandomBloke 0:a29a0225f203 271 // printf("%d, %ld, ",i, (int)_nodeDefList.at(i));
SomeRandomBloke 0:a29a0225f203 272 IoTNodeDef *nd = (IoTNodeDef*)_nodeDefList.at(i);
SomeRandomBloke 0:a29a0225f203 273 if ( nd->groupId == data[0] && nd->nodeId == (data[1] & 0x1f) && nd->length == data[2] ) {
SomeRandomBloke 0:a29a0225f203 274 printf("Found %d\n", nd->type);
SomeRandomBloke 0:a29a0225f203 275 return nd->type;
SomeRandomBloke 0:a29a0225f203 276 }
SomeRandomBloke 0:a29a0225f203 277 }
SomeRandomBloke 0:a29a0225f203 278 printf("NOT found\n");
SomeRandomBloke 0:a29a0225f203 279 // Add to node list
SomeRandomBloke 0:a29a0225f203 280 addNodeToList(data[0], data[1] & 0x1f, data[2], PAYLOAD_TYPE_UNKNOWN );
SomeRandomBloke 0:a29a0225f203 281 // Save NodeList
SomeRandomBloke 0:a29a0225f203 282 writeNodeList();
SomeRandomBloke 0:a29a0225f203 283 return PAYLOAD_TYPE_UNKNOWN;
SomeRandomBloke 0:a29a0225f203 284 }
SomeRandomBloke 0:a29a0225f203 285
SomeRandomBloke 0:a29a0225f203 286
SomeRandomBloke 0:a29a0225f203 287 bool IoTRouting::routePayload( uint8_t *data, short dataLen ) {
SomeRandomBloke 0:a29a0225f203 288 bool routed = false;
SomeRandomBloke 0:a29a0225f203 289 uint8_t *ptr = data;
SomeRandomBloke 0:a29a0225f203 290 PayloadSimple psimp;
SomeRandomBloke 0:a29a0225f203 291 PayloadV1 pv1;
SomeRandomBloke 0:a29a0225f203 292 PayloadV2 pv2;
SomeRandomBloke 0:a29a0225f203 293 PayloadRouting *pr = NULL;
SomeRandomBloke 0:a29a0225f203 294 char tmpBuf[42];
SomeRandomBloke 0:a29a0225f203 295
SomeRandomBloke 0:a29a0225f203 296 pachubeOutput->init(); // Just to be sure
SomeRandomBloke 0:a29a0225f203 297 printf("routePayload: ");
SomeRandomBloke 0:a29a0225f203 298 for ( int i = 0; i < dataLen; i++ )
SomeRandomBloke 0:a29a0225f203 299 printf("%02X ", *ptr++ );
SomeRandomBloke 0:a29a0225f203 300
SomeRandomBloke 0:a29a0225f203 301 printf("\n");
SomeRandomBloke 0:a29a0225f203 302
SomeRandomBloke 0:a29a0225f203 303 short payloadType = getPayloadType( data, dataLen );
SomeRandomBloke 0:a29a0225f203 304
SomeRandomBloke 0:a29a0225f203 305 printf("Group ID: %d Node ID: %d Length: %d Status: %02x, Payload type %d\n", data[0], data[1] & 0x1f, data[2], data[3], payloadType );
SomeRandomBloke 0:a29a0225f203 306
SomeRandomBloke 0:a29a0225f203 307 switch ( payloadType ) {
SomeRandomBloke 0:a29a0225f203 308 case PAYLOAD_TYPE_SIMPLE:
SomeRandomBloke 0:a29a0225f203 309 psimp = PayloadSimple( data, dataLen);
SomeRandomBloke 0:a29a0225f203 310 printf("SIMPLE NumReadings %d\n", psimp.numReadings());
SomeRandomBloke 0:a29a0225f203 311 for ( int n = 0; n<psimp.numReadings(); n++ ) {
SomeRandomBloke 0:a29a0225f203 312 printf("%d: %d - %d\n", n, psimp.sensorId(n), psimp.reading(n) );
SomeRandomBloke 0:a29a0225f203 313 // Get list of routing objects
SomeRandomBloke 0:a29a0225f203 314 pr = getRouting( psimp.nodeId(), psimp.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 315 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 316 if ( pr->output != NULL ) {
SomeRandomBloke 0:a29a0225f203 317 // printf("Pachube %d, %d, %f, %s, %s\n",pr->nodeId, pr->sensorId, pr->factor, pr->param1, pr->param2);
SomeRandomBloke 0:a29a0225f203 318 snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(psimp.reading(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 319 printf("Add to output %s, %s, %s\n", pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 320 pr->output->addReading( pr->param1, pr->param2,tmpBuf );
SomeRandomBloke 0:a29a0225f203 321 }
SomeRandomBloke 0:a29a0225f203 322 }
SomeRandomBloke 0:a29a0225f203 323 }
SomeRandomBloke 0:a29a0225f203 324 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 325 if ( pr->output != NULL )
SomeRandomBloke 0:a29a0225f203 326 pr->output->send();
SomeRandomBloke 0:a29a0225f203 327 }
SomeRandomBloke 0:a29a0225f203 328 routed = true;
SomeRandomBloke 0:a29a0225f203 329
SomeRandomBloke 0:a29a0225f203 330 break;
SomeRandomBloke 0:a29a0225f203 331 case PAYLOAD_TYPE_V1:
SomeRandomBloke 0:a29a0225f203 332 pv1 = PayloadV1( data, dataLen);
SomeRandomBloke 0:a29a0225f203 333 printf("V1 NumReadings %d, Node %d\n", pv1.numReadings(), pv1.nodeId() );
SomeRandomBloke 0:a29a0225f203 334
SomeRandomBloke 0:a29a0225f203 335 pr = getRouting( pv1.nodeId(), -1 );
SomeRandomBloke 0:a29a0225f203 336 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 337 // Output to destination
SomeRandomBloke 0:a29a0225f203 338 // printf("Updating low battery feed\n");
SomeRandomBloke 0:a29a0225f203 339 if ( data[3] & STATUS_LOW_BATTERY ) {
SomeRandomBloke 0:a29a0225f203 340 printf("LOW Battery detected\n");
SomeRandomBloke 0:a29a0225f203 341 }
SomeRandomBloke 0:a29a0225f203 342 if ( pr->output != NULL ) {
SomeRandomBloke 0:a29a0225f203 343 snprintf(tmpBuf, DATABUF_SIZE, "%d", (int)( data[3] & STATUS_LOW_BATTERY ));
SomeRandomBloke 0:a29a0225f203 344 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 345 }
SomeRandomBloke 0:a29a0225f203 346 }
SomeRandomBloke 0:a29a0225f203 347 // Determine output
SomeRandomBloke 0:a29a0225f203 348 for ( int n = 0; n<pv1.numReadings(); n++ ) {
SomeRandomBloke 0:a29a0225f203 349 pr = getRouting(pv1.nodeId(), pv1.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 350 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 351 tmpBuf[0] = '\0';
SomeRandomBloke 0:a29a0225f203 352 // printf("Pachube %d, %d, %f, %s, %s\n",pr->nodeId, pr->sensorId, pr->factor, pr->param1, pr->param2);
SomeRandomBloke 0:a29a0225f203 353 if ( pr->output != NULL ) {
SomeRandomBloke 0:a29a0225f203 354 snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv1.reading(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 355 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 356 }
SomeRandomBloke 0:a29a0225f203 357 printf("%d: %d - %s\n", n, pv1.sensorId(n), tmpBuf );
SomeRandomBloke 0:a29a0225f203 358
SomeRandomBloke 0:a29a0225f203 359 }
SomeRandomBloke 0:a29a0225f203 360 }
SomeRandomBloke 0:a29a0225f203 361 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 362 if ( pr->output != NULL )
SomeRandomBloke 0:a29a0225f203 363 pr->output->send();
SomeRandomBloke 0:a29a0225f203 364 }
SomeRandomBloke 0:a29a0225f203 365 routed = true;
SomeRandomBloke 0:a29a0225f203 366 break;
SomeRandomBloke 0:a29a0225f203 367 case PAYLOAD_TYPE_V2:
SomeRandomBloke 0:a29a0225f203 368 pv2 = PayloadV2( data, dataLen );
SomeRandomBloke 0:a29a0225f203 369 // printf("V2 NumReadings %d\n", pv2.numReadings());
SomeRandomBloke 0:a29a0225f203 370 pr = getRouting( pv2.nodeId(), -1 );
SomeRandomBloke 0:a29a0225f203 371 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 372 // Output to destination
SomeRandomBloke 0:a29a0225f203 373 // printf("Updating low battery feed\n");
SomeRandomBloke 0:a29a0225f203 374 if ( data[3] & STATUS_LOW_BATTERY ) {
SomeRandomBloke 0:a29a0225f203 375 printf("LOW Battery detected\n");
SomeRandomBloke 0:a29a0225f203 376 }
SomeRandomBloke 0:a29a0225f203 377 if ( pr->output != NULL ) {
SomeRandomBloke 0:a29a0225f203 378 snprintf(tmpBuf, DATABUF_SIZE, "%d", (int)( data[3] & STATUS_LOW_BATTERY ));
SomeRandomBloke 0:a29a0225f203 379 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 380 }
SomeRandomBloke 0:a29a0225f203 381 // Need to update add reading to detect change in feed ID and send.
SomeRandomBloke 0:a29a0225f203 382 }
SomeRandomBloke 0:a29a0225f203 383
SomeRandomBloke 0:a29a0225f203 384 for ( int n = 0; n < pv2.numReadings(); n++ ) {
SomeRandomBloke 0:a29a0225f203 385 // printf("Getting reading %d node %d sensor id %d\n",n, pv2.nodeId(), pv2.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 386 pr = getRouting( pv2.nodeId(), pv2.sensorId(n) );
SomeRandomBloke 0:a29a0225f203 387 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 388 // printf("Item: pr %ld, out type %d\n", (int)pr, pr->outType);
SomeRandomBloke 0:a29a0225f203 389
SomeRandomBloke 0:a29a0225f203 390 // printf("readingType = %d\n",pv2.readingType( n ));
SomeRandomBloke 0:a29a0225f203 391 // printf("IoTRouting: output = %ld\n",(int)pr->output);
SomeRandomBloke 0:a29a0225f203 392
SomeRandomBloke 0:a29a0225f203 393 if ( pr->output != NULL ) {
SomeRandomBloke 0:a29a0225f203 394 tmpBuf[0] = '\0';
SomeRandomBloke 0:a29a0225f203 395
SomeRandomBloke 0:a29a0225f203 396 switch ( pv2.readingType( n ) ) {
SomeRandomBloke 0:a29a0225f203 397 case V2_DATATYPE_BYTE:
SomeRandomBloke 0:a29a0225f203 398 snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv2.readingByte(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 399 break;
SomeRandomBloke 0:a29a0225f203 400 case V2_DATATYPE_SHORT:
SomeRandomBloke 0:a29a0225f203 401 snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv2.readingShort(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 402 break;
SomeRandomBloke 0:a29a0225f203 403 case V2_DATATYPE_LONG:
SomeRandomBloke 0:a29a0225f203 404 snprintf(tmpBuf, DATABUF_SIZE, "%.3f", (float)(pv2.readingLong(n) * pr->factor));
SomeRandomBloke 0:a29a0225f203 405 break;
SomeRandomBloke 0:a29a0225f203 406 case V2_DATATYPE_STRING:
SomeRandomBloke 0:a29a0225f203 407 break;
SomeRandomBloke 0:a29a0225f203 408 default:
SomeRandomBloke 0:a29a0225f203 409 break;
SomeRandomBloke 0:a29a0225f203 410 }
SomeRandomBloke 0:a29a0225f203 411 pr->output->addReading( pr->param1, pr->param2, tmpBuf );
SomeRandomBloke 0:a29a0225f203 412 }
SomeRandomBloke 0:a29a0225f203 413 }
SomeRandomBloke 0:a29a0225f203 414 }
SomeRandomBloke 0:a29a0225f203 415 if ( pr != NULL ) {
SomeRandomBloke 0:a29a0225f203 416 if ( pr->output != NULL )
SomeRandomBloke 0:a29a0225f203 417 pr->output->send();
SomeRandomBloke 0:a29a0225f203 418 }
SomeRandomBloke 0:a29a0225f203 419
SomeRandomBloke 0:a29a0225f203 420 routed = true;
SomeRandomBloke 0:a29a0225f203 421 break;
SomeRandomBloke 0:a29a0225f203 422 case PAYLOAD_TYPE_UNKNOWN: // Unknown node found
SomeRandomBloke 0:a29a0225f203 423 printf("Unknown payload type found\n");
SomeRandomBloke 0:a29a0225f203 424 break;
SomeRandomBloke 0:a29a0225f203 425 default:
SomeRandomBloke 0:a29a0225f203 426 printf("Unknown\n");
SomeRandomBloke 0:a29a0225f203 427 break;
SomeRandomBloke 0:a29a0225f203 428 }
SomeRandomBloke 0:a29a0225f203 429
SomeRandomBloke 0:a29a0225f203 430 pachubeOutput->send(); // Just in case anything left to send
SomeRandomBloke 0:a29a0225f203 431 printf("Finished routing\n");
SomeRandomBloke 0:a29a0225f203 432 return routed;
SomeRandomBloke 0:a29a0225f203 433 }
SomeRandomBloke 0:a29a0225f203 434