Erick / Mbed 2 deprecated ICE_BLE_TEST

Dependencies:   NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed

Fork of ICE by Erick

Committer:
davidjhoward
Date:
Tue Oct 11 15:31:49 2016 +0000
Revision:
214:52ef35bc44ec
Parent:
197:594afd088f32
Child:
224:9ea8925c61e0
more work towards virtual tags

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidjhoward 27:38205cebc3da 1 #include "CloudFileReceiver.h"
davidjhoward 116:7337ed514891 2 #include "CloudDataHandler.h"
davidjhoward 27:38205cebc3da 3 #include "MTSLog.h"
davidjhoward 27:38205cebc3da 4 #include "MbedJSONValue.h"
davidjhoward 31:4b1587034318 5 #include "global.h"
davidjhoward 27:38205cebc3da 6
jmarkel44 177:9ec90c8e3ce1 7 char CloudFileReceiverWriteBuf[MAX_FILE_SIZE];
jmarkel44 177:9ec90c8e3ce1 8 char CloudFileReceiverReadBuf[MAX_FILE_SIZE];
davidjhoward 27:38205cebc3da 9
davidjhoward 49:0456ee2271be 10 bool StoreReceivedFile( mDot *dot, MbedJSONValue &from_json )
davidjhoward 49:0456ee2271be 11 {
davidjhoward 99:55317f374a94 12 FILENAME_STRING filename;
davidjhoward 27:38205cebc3da 13
davidjhoward 99:55317f374a94 14 memset( filename, '\0', sizeof(FILENAME_STRING) );
davidjhoward 27:38205cebc3da 15
davidjhoward 99:55317f374a94 16 int mType = from_json["pay"]["mtype"].get<int>();
davidjhoward 99:55317f374a94 17 logInfo("mtype=%d", mType);
davidjhoward 99:55317f374a94 18 switch( mType ) {
davidjhoward 99:55317f374a94 19 case SETPOINT_CONTROL_MTYPE: {
davidjhoward 99:55317f374a94 20 logInfo("PROCESSING SETPONT CONTROL FILE");
davidjhoward 134:f90154ff33ec 21 snprintf( filename, sizeof(FILENAME_STRING), "control_sp_%s.json",
davidjhoward 134:f90154ff33ec 22 from_json["pay"]["spcontrol"]["id"].get<std::string>().c_str() );
davidjhoward 99:55317f374a94 23 logInfo("SETPONT CONTROL FILENAME=%s", filename);
davidjhoward 134:f90154ff33ec 24
jmarkel44 177:9ec90c8e3ce1 25 memset( CloudFileReceiverWriteBuf, '\0', MAX_FILE_SIZE );
davidjhoward 134:f90154ff33ec 26 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf),
davidjhoward 134:f90154ff33ec 27 "{ "
davidjhoward 134:f90154ff33ec 28 "\"id\": \"%s\", "
davidjhoward 134:f90154ff33ec 29 "\"priority\": \"%s\","
davidjhoward 134:f90154ff33ec 30 "\"input\": \"%s\", "
davidjhoward 134:f90154ff33ec 31 "\"output\": \"%s\", "
davidjhoward 134:f90154ff33ec 32 "\"setpoint\": \"%s\","
davidjhoward 134:f90154ff33ec 33 "\"prodfact\": \"%s\","
davidjhoward 134:f90154ff33ec 34 "\"actingDir\": \"%s\", "
davidjhoward 134:f90154ff33ec 35 "\"halert\": \"%s\","
davidjhoward 134:f90154ff33ec 36 "\"lalert\": \"%s\", "
davidjhoward 134:f90154ff33ec 37 "\"hfs\": \"%s\","
davidjhoward 134:f90154ff33ec 38 "\"lfs\": \"%s\", "
davidjhoward 134:f90154ff33ec 39 "\"tol\": \"%s\" }",
davidjhoward 134:f90154ff33ec 40 from_json["pay"]["spcontrol"]["id"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 41 from_json["pay"]["spcontrol"]["priority"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 42 from_json["pay"]["spcontrol"]["input"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 43 from_json["pay"]["spcontrol"]["output"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 44 from_json["pay"]["spcontrol"]["setpoint"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 45 from_json["pay"]["spcontrol"]["prodfact"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 46 from_json["pay"]["spcontrol"]["actingDir"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 47 from_json["pay"]["spcontrol"]["halert"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 48 from_json["pay"]["spcontrol"]["lalert"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 49 from_json["pay"]["spcontrol"]["hfs"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 50 from_json["pay"]["spcontrol"]["lfs"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 51 from_json["pay"]["spcontrol"]["tol"].get<std::string>().c_str()
davidjhoward 134:f90154ff33ec 52 );
davidjhoward 134:f90154ff33ec 53
davidjhoward 134:f90154ff33ec 54 logInfo("saving string%s", CloudFileReceiverWriteBuf);
jmarkel44 177:9ec90c8e3ce1 55 bool status = GLOBAL_mdot->saveUserFile(filename, (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 134:f90154ff33ec 56 if( status != true ) {
davidjhoward 134:f90154ff33ec 57 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 134:f90154ff33ec 58 }
davidjhoward 134:f90154ff33ec 59
davidjhoward 134:f90154ff33ec 60 // send a message to the configuration handler to create the control
davidjhoward 134:f90154ff33ec 61 Message_t *msg = MailBox.alloc();
davidjhoward 134:f90154ff33ec 62 memset(msg, 0, sizeof(Message_t));
davidjhoward 134:f90154ff33ec 63 msg->action = ACTION_CREATE;
davidjhoward 134:f90154ff33ec 64 msg->control = CONTROL_SETPOINT;
davidjhoward 134:f90154ff33ec 65 strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
davidjhoward 134:f90154ff33ec 66
davidjhoward 134:f90154ff33ec 67 printf("%s: Sending a create request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control);
davidjhoward 134:f90154ff33ec 68
davidjhoward 134:f90154ff33ec 69 MailBox.put(msg);
davidjhoward 134:f90154ff33ec 70 break;
davidjhoward 134:f90154ff33ec 71 }
davidjhoward 145:c1dfbb5eed0e 72 case MANUAL_CONTROL_MTYPE: {
davidjhoward 134:f90154ff33ec 73 logInfo("PROCESSING MANUAL CONTROL FILE");
davidjhoward 134:f90154ff33ec 74 snprintf( filename, sizeof(FILENAME_STRING), "control_mn_%s.json",
davidjhoward 134:f90154ff33ec 75 from_json["pay"]["mncontrol"]["id"].get<std::string>().c_str() );
davidjhoward 134:f90154ff33ec 76 logInfo("MANUAL CONTROL FILENAME=%s", filename);
davidjhoward 134:f90154ff33ec 77
jmarkel44 177:9ec90c8e3ce1 78 memset( CloudFileReceiverWriteBuf, '\0', MAX_FILE_SIZE );
davidjhoward 134:f90154ff33ec 79 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf),
davidjhoward 134:f90154ff33ec 80 "{ "
davidjhoward 134:f90154ff33ec 81 "\"id\": \"%s\", "
davidjhoward 134:f90154ff33ec 82 "\"output\": \"%s\", "
davidjhoward 134:f90154ff33ec 83 "\"type\": \"%s\", "
davidjhoward 134:f90154ff33ec 84 "\"priority\": \"%s\", "
davidjhoward 134:f90154ff33ec 85 "\"duration\": \"%s\", "
davidjhoward 134:f90154ff33ec 86 "\"setpoint\": \"%s\", "
davidjhoward 134:f90154ff33ec 87 "\"state\": \"%s\", "
davidjhoward 134:f90154ff33ec 88 "\"percent\": \"%s\" }",
davidjhoward 134:f90154ff33ec 89 from_json["pay"]["mncontrol"]["id"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 90 from_json["pay"]["mncontrol"]["output"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 91 from_json["pay"]["mncontrol"]["type"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 92 from_json["pay"]["mncontrol"]["priority"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 93 from_json["pay"]["mncontrol"]["duration"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 94 from_json["pay"]["mncontrol"]["setpoint"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 95 from_json["pay"]["mncontrol"]["state"].get<std::string>().c_str(),
davidjhoward 134:f90154ff33ec 96 from_json["pay"]["mncontrol"]["percent"].get<std::string>().c_str()
davidjhoward 134:f90154ff33ec 97 );
davidjhoward 134:f90154ff33ec 98
davidjhoward 134:f90154ff33ec 99 logInfo("saving string%s", CloudFileReceiverWriteBuf);
jmarkel44 177:9ec90c8e3ce1 100 bool status = GLOBAL_mdot->saveUserFile(filename, (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 134:f90154ff33ec 101 if( status != true ) {
davidjhoward 134:f90154ff33ec 102 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 134:f90154ff33ec 103 }
davidjhoward 134:f90154ff33ec 104
davidjhoward 134:f90154ff33ec 105 // send a message to the configuration handler to create the control
davidjhoward 134:f90154ff33ec 106 Message_t *msg = MailBox.alloc();
davidjhoward 134:f90154ff33ec 107 memset(msg, 0, sizeof(Message_t));
davidjhoward 134:f90154ff33ec 108 msg->action = ACTION_CREATE;
davidjhoward 134:f90154ff33ec 109 msg->control = CONTROL_MANUAL;
davidjhoward 134:f90154ff33ec 110 strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
davidjhoward 134:f90154ff33ec 111
davidjhoward 134:f90154ff33ec 112 printf("%s: Sending a create manual for control %s type = %u\r\n", __func__, msg->controlFile, msg->control);
davidjhoward 134:f90154ff33ec 113
davidjhoward 134:f90154ff33ec 114 MailBox.put(msg);
davidjhoward 99:55317f374a94 115 break;
davidjhoward 99:55317f374a94 116 }
davidjhoward 139:f1f4a523399f 117 case TIMER_CONTROL_MTYPE: {
davidjhoward 139:f1f4a523399f 118 logInfo("PROCESSING TIMER CONTROL FILE");
davidjhoward 139:f1f4a523399f 119 snprintf( filename, sizeof(FILENAME_STRING), "control_tm_%s.json",
davidjhoward 139:f1f4a523399f 120 from_json["pay"]["tmcontrol"]["id"].get<std::string>().c_str() );
davidjhoward 139:f1f4a523399f 121 logInfo("TIMER CONTROL FILENAME=%s", filename);
davidjhoward 139:f1f4a523399f 122
jmarkel44 177:9ec90c8e3ce1 123 memset( CloudFileReceiverWriteBuf, '\0', MAX_FILE_SIZE );
davidjhoward 139:f1f4a523399f 124 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf),
davidjhoward 139:f1f4a523399f 125 "{ "
davidjhoward 139:f1f4a523399f 126 "\"id\": \"%s\", "
davidjhoward 139:f1f4a523399f 127 "\"output\": \"%s\", "
davidjhoward 139:f1f4a523399f 128 "\"priority\": \"%s\", "
davidjhoward 139:f1f4a523399f 129 "\"starttime\": \"%s\", "
davidjhoward 139:f1f4a523399f 130 "\"duration\": \"%s\", ",
davidjhoward 139:f1f4a523399f 131 from_json["pay"]["tmcontrol"]["id"].get<std::string>().c_str(),
davidjhoward 139:f1f4a523399f 132 from_json["pay"]["tmcontrol"]["output"].get<std::string>().c_str(),
davidjhoward 139:f1f4a523399f 133 from_json["pay"]["tmcontrol"]["priority"].get<std::string>().c_str(),
davidjhoward 139:f1f4a523399f 134 from_json["pay"]["tmcontrol"]["starttime"].get<std::string>().c_str(),
davidjhoward 139:f1f4a523399f 135 from_json["pay"]["tmcontrol"]["duration"].get<std::string>().c_str()
davidjhoward 139:f1f4a523399f 136 );
davidjhoward 139:f1f4a523399f 137
davidjhoward 139:f1f4a523399f 138 logInfo("saving string%s", CloudFileReceiverWriteBuf);
jmarkel44 177:9ec90c8e3ce1 139 bool status = GLOBAL_mdot->saveUserFile(filename, (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 139:f1f4a523399f 140 if( status != true ) {
davidjhoward 139:f1f4a523399f 141 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 139:f1f4a523399f 142 }
davidjhoward 139:f1f4a523399f 143
davidjhoward 139:f1f4a523399f 144 // send a message to the configuration handler to create the control
davidjhoward 139:f1f4a523399f 145 Message_t *msg = MailBox.alloc();
davidjhoward 139:f1f4a523399f 146 memset(msg, 0, sizeof(Message_t));
davidjhoward 139:f1f4a523399f 147 msg->action = ACTION_CREATE;
davidjhoward 139:f1f4a523399f 148 msg->control = CONTROL_TIMER;
davidjhoward 139:f1f4a523399f 149 strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
davidjhoward 139:f1f4a523399f 150
davidjhoward 139:f1f4a523399f 151 printf("%s: Sending a create request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control);
davidjhoward 139:f1f4a523399f 152
davidjhoward 139:f1f4a523399f 153 MailBox.put(msg);
davidjhoward 99:55317f374a94 154 break;
davidjhoward 139:f1f4a523399f 155 }
davidjhoward 149:950c90425f7c 156 case INPUT_CONFIG_MTYPE:
davidjhoward 149:950c90425f7c 157 case VINPUT_CONFIG_MTYPE: {
davidjhoward 149:950c90425f7c 158 std::string vcmd;
davidjhoward 99:55317f374a94 159 logInfo("id=%s", from_json["pay"]["input"]["id"].get<std::string>().c_str() );
davidjhoward 149:950c90425f7c 160 if( mType == INPUT_CONFIG_MTYPE ) {
davidjhoward 149:950c90425f7c 161 snprintf( filename, sizeof(FILENAME_STRING), "input_%s%s",
davidjhoward 149:950c90425f7c 162 from_json["pay"]["input"]["id"].get<std::string>().c_str(),
davidjhoward 149:950c90425f7c 163 ".json" );
davidjhoward 149:950c90425f7c 164 vcmd = "";
davidjhoward 149:950c90425f7c 165
davidjhoward 149:950c90425f7c 166 } else {
davidjhoward 149:950c90425f7c 167 snprintf( filename, sizeof(FILENAME_STRING), "vinput_%s%s",
davidjhoward 149:950c90425f7c 168 from_json["pay"]["input"]["id"].get<std::string>().c_str(),
davidjhoward 149:950c90425f7c 169 ".json" );
davidjhoward 149:950c90425f7c 170 vcmd = from_json["pay"]["input"]["vcmd"].get<std::string>();
davidjhoward 149:950c90425f7c 171 }
davidjhoward 99:55317f374a94 172 logInfo("INPUT CONFIG FILENAME=%s", filename);
davidjhoward 31:4b1587034318 173
jmarkel44 177:9ec90c8e3ce1 174 memset( CloudFileReceiverWriteBuf, '\0', MAX_FILE_SIZE );
davidjhoward 99:55317f374a94 175 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf),
davidjhoward 99:55317f374a94 176 "{ "
davidjhoward 99:55317f374a94 177 "\"id\":\"%s\", "
davidjhoward 99:55317f374a94 178 "\"name\":\"%s\", "
davidjhoward 99:55317f374a94 179 "\"units\":\"%s\", "
davidjhoward 99:55317f374a94 180 "\"min\":\"%s\", "
davidjhoward 99:55317f374a94 181 "\"max\":\"%s\", "
davidjhoward 99:55317f374a94 182 "\"node\":\"%s\", "
davidjhoward 99:55317f374a94 183 "\"reg\":\"%s\", "
davidjhoward 99:55317f374a94 184 "\"rtype\":\"%s\", "
davidjhoward 99:55317f374a94 185 "\"type\":\"%s\", "
davidjhoward 99:55317f374a94 186 "\"size\":\"%s\", "
davidjhoward 99:55317f374a94 187 "\"order\":\"%s\", "
davidjhoward 99:55317f374a94 188 "\"fmt\":\"%s\", "
davidjhoward 149:950c90425f7c 189 "\"vcmd\":\"%s\", "
davidjhoward 99:55317f374a94 190 "\"rfreq\":\"%s\" } ",
davidjhoward 99:55317f374a94 191 from_json["pay"]["input"]["id"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 192 from_json["pay"]["input"]["name"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 193 from_json["pay"]["input"]["units"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 194 from_json["pay"]["input"]["min"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 195 from_json["pay"]["input"]["max"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 196 from_json["pay"]["input"]["node"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 197 from_json["pay"]["input"]["reg"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 198 from_json["pay"]["input"]["rtype"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 199 from_json["pay"]["input"]["type"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 200 from_json["pay"]["input"]["size"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 201 from_json["pay"]["input"]["order"].get<std::string>().c_str(),
davidjhoward 99:55317f374a94 202 from_json["pay"]["input"]["fmt"].get<std::string>().c_str(),
davidjhoward 149:950c90425f7c 203 vcmd.c_str(),
davidjhoward 99:55317f374a94 204 from_json["pay"]["input"]["rfreq"].get<std::string>().c_str()
davidjhoward 99:55317f374a94 205 );
davidjhoward 45:3b9e1923cb15 206
davidjhoward 99:55317f374a94 207 logInfo("saving string%s", CloudFileReceiverWriteBuf);
jmarkel44 177:9ec90c8e3ce1 208 bool status = GLOBAL_mdot->saveUserFile(filename, (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 99:55317f374a94 209 if( status != true ) {
davidjhoward 99:55317f374a94 210 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 99:55317f374a94 211 }
davidjhoward 45:3b9e1923cb15 212
davidjhoward 99:55317f374a94 213 logInfo("Sending Mail To ModbusMasterMailBox, filename=%s", filename);
davidjhoward 99:55317f374a94 214 Message_t *mail = ModbusMasterMailBox.alloc();
davidjhoward 99:55317f374a94 215 mail->action = ACTION_READ_FILE;
davidjhoward 99:55317f374a94 216 strncpy( mail->controlFile, filename, (sizeof(mail->controlFile)-1));
davidjhoward 99:55317f374a94 217 ModbusMasterMailBox.put(mail);
davidjhoward 99:55317f374a94 218 break;
davidjhoward 27:38205cebc3da 219 }
davidjhoward 149:950c90425f7c 220 case OUTPUT_CONFIG_MTYPE:
davidjhoward 149:950c90425f7c 221 case VOUTPUT_CONFIG_MTYPE: {
davidjhoward 144:b32d6a6f445f 222 logInfo("id=%s", from_json["pay"]["output"]["id"].get<std::string>().c_str() );
davidjhoward 149:950c90425f7c 223 if( mType == OUTPUT_CONFIG_MTYPE ) {
davidjhoward 149:950c90425f7c 224 snprintf( filename, sizeof(FILENAME_STRING), "output_%s%s",
davidjhoward 149:950c90425f7c 225 from_json["pay"]["output"]["id"].get<std::string>().c_str(),
davidjhoward 149:950c90425f7c 226 ".json" );
davidjhoward 149:950c90425f7c 227 } else {
davidjhoward 149:950c90425f7c 228 snprintf( filename, sizeof(FILENAME_STRING), "voutput_%s%s",
davidjhoward 149:950c90425f7c 229 from_json["pay"]["output"]["id"].get<std::string>().c_str(),
davidjhoward 149:950c90425f7c 230 ".json" );
davidjhoward 149:950c90425f7c 231 }
davidjhoward 144:b32d6a6f445f 232 logInfo("OUTPUT CONFIG FILENAME=%s", filename);
davidjhoward 144:b32d6a6f445f 233
jmarkel44 177:9ec90c8e3ce1 234 memset( CloudFileReceiverWriteBuf, '\0', MAX_FILE_SIZE );
davidjhoward 144:b32d6a6f445f 235 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf),
davidjhoward 144:b32d6a6f445f 236 "{ "
davidjhoward 144:b32d6a6f445f 237 "\"id\":\"%s\", "
davidjhoward 144:b32d6a6f445f 238 "\"name\":\"%s\", "
davidjhoward 144:b32d6a6f445f 239 "\"units\":\"%s\", "
davidjhoward 144:b32d6a6f445f 240 "\"min\":\"%s\", "
davidjhoward 144:b32d6a6f445f 241 "\"max\":\"%s\", "
davidjhoward 144:b32d6a6f445f 242 "\"node\":\"%s\", "
davidjhoward 144:b32d6a6f445f 243 "\"reg\":\"%s\", "
davidjhoward 144:b32d6a6f445f 244 "\"rtype\":\"%s\", "
davidjhoward 144:b32d6a6f445f 245 "\"type\":\"%s\", "
davidjhoward 144:b32d6a6f445f 246 "\"size\":\"%s\", "
davidjhoward 144:b32d6a6f445f 247 "\"order\":\"%s\", "
davidjhoward 144:b32d6a6f445f 248 "\"fmt\":\"%s\", "
davidjhoward 144:b32d6a6f445f 249 "\"rfreq\":\"%s\", "
davidjhoward 144:b32d6a6f445f 250 "\"toperiod\":\"%s\", "
davidjhoward 144:b32d6a6f445f 251 "\"scalelo\":\"%s\", "
davidjhoward 144:b32d6a6f445f 252 "\"scalehi\":\"%s\" }",
davidjhoward 144:b32d6a6f445f 253 from_json["pay"]["output"]["id"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 254 from_json["pay"]["output"]["name"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 255 from_json["pay"]["output"]["units"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 256 from_json["pay"]["output"]["min"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 257 from_json["pay"]["output"]["max"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 258 from_json["pay"]["output"]["node"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 259 from_json["pay"]["output"]["reg"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 260 from_json["pay"]["output"]["rtype"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 261 from_json["pay"]["output"]["type"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 262 from_json["pay"]["output"]["size"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 263 from_json["pay"]["output"]["order"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 264 from_json["pay"]["output"]["fmt"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 265 from_json["pay"]["output"]["rfreq"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 266 from_json["pay"]["output"]["toperiod"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 267 from_json["pay"]["output"]["scalelo"].get<std::string>().c_str(),
davidjhoward 144:b32d6a6f445f 268 from_json["pay"]["output"]["scalehi"].get<std::string>().c_str()
davidjhoward 144:b32d6a6f445f 269 );
davidjhoward 144:b32d6a6f445f 270
davidjhoward 144:b32d6a6f445f 271 logInfo("saving string%s", CloudFileReceiverWriteBuf);
jmarkel44 177:9ec90c8e3ce1 272 bool status = GLOBAL_mdot->saveUserFile(filename, (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 144:b32d6a6f445f 273 if( status != true ) {
davidjhoward 144:b32d6a6f445f 274 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 144:b32d6a6f445f 275 }
davidjhoward 197:594afd088f32 276
jmarkel44 177:9ec90c8e3ce1 277 // send a message to the modbus master
davidjhoward 144:b32d6a6f445f 278 logInfo("Sending Mail To ModbusMasterMailBox, filename=%s", filename);
davidjhoward 144:b32d6a6f445f 279 Message_t *mail = ModbusMasterMailBox.alloc();
davidjhoward 144:b32d6a6f445f 280 mail->action = ACTION_READ_FILE;
davidjhoward 144:b32d6a6f445f 281 strncpy( mail->controlFile, filename, (sizeof(mail->controlFile)-1));
davidjhoward 144:b32d6a6f445f 282 ModbusMasterMailBox.put(mail);
jmarkel44 177:9ec90c8e3ce1 283
jmarkel44 177:9ec90c8e3ce1 284 // send a message to the output master
jmarkel44 177:9ec90c8e3ce1 285 logInfo("Sending mail to OutputMaster, filename = %s", filename);
jmarkel44 177:9ec90c8e3ce1 286 OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
jmarkel44 177:9ec90c8e3ce1 287 output_mail->action = ACTION_NEW;
jmarkel44 177:9ec90c8e3ce1 288 strncpy(output_mail->controlFile, filename, sizeof(output_mail->controlFile)-1);
jmarkel44 177:9ec90c8e3ce1 289 OutputMasterMailBox.put(output_mail);
davidjhoward 144:b32d6a6f445f 290 break;
davidjhoward 144:b32d6a6f445f 291 }
davidjhoward 145:c1dfbb5eed0e 292 case DESTROY_SETPOINT_MTYPE: {
davidjhoward 145:c1dfbb5eed0e 293 logInfo("PROCESSING DESTORY SETPOINT CONTROL MESSAGE");
davidjhoward 145:c1dfbb5eed0e 294 snprintf( filename, sizeof(FILENAME_STRING), "control_sp_%s.json",
davidjhoward 145:c1dfbb5eed0e 295 from_json["pay"]["destroy"]["id"].get<std::string>().c_str() );
davidjhoward 145:c1dfbb5eed0e 296 logInfo("SETPOINT CONTROL FILENAME=%s", filename);
davidjhoward 145:c1dfbb5eed0e 297
davidjhoward 145:c1dfbb5eed0e 298 // send a message to the configuration handler to create the control
davidjhoward 145:c1dfbb5eed0e 299 Message_t *msg = MailBox.alloc();
davidjhoward 145:c1dfbb5eed0e 300 memset(msg, 0, sizeof(Message_t));
davidjhoward 145:c1dfbb5eed0e 301 msg->action = ACTION_DESTROY;
davidjhoward 145:c1dfbb5eed0e 302 msg->control = CONTROL_SETPOINT;
davidjhoward 145:c1dfbb5eed0e 303 strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
davidjhoward 145:c1dfbb5eed0e 304
davidjhoward 145:c1dfbb5eed0e 305 printf("%s: Sending a destroy request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control);
davidjhoward 145:c1dfbb5eed0e 306
davidjhoward 145:c1dfbb5eed0e 307 MailBox.put(msg);
davidjhoward 145:c1dfbb5eed0e 308 break;
davidjhoward 145:c1dfbb5eed0e 309 }
davidjhoward 145:c1dfbb5eed0e 310 case DESTROY_MANUAL_MTYPE: {
davidjhoward 145:c1dfbb5eed0e 311 logInfo("PROCESSING DESTORY MANUAL CONTROL MESSAGE");
davidjhoward 145:c1dfbb5eed0e 312 snprintf( filename, sizeof(FILENAME_STRING), "control_mn_%s.json",
davidjhoward 145:c1dfbb5eed0e 313 from_json["pay"]["destroy"]["id"].get<std::string>().c_str() );
davidjhoward 145:c1dfbb5eed0e 314 logInfo("MANUAL CONTROL FILENAME=%s", filename);
davidjhoward 145:c1dfbb5eed0e 315
davidjhoward 145:c1dfbb5eed0e 316 // send a message to the configuration handler to create the control
davidjhoward 145:c1dfbb5eed0e 317 Message_t *msg = MailBox.alloc();
davidjhoward 145:c1dfbb5eed0e 318 memset(msg, 0, sizeof(Message_t));
davidjhoward 145:c1dfbb5eed0e 319 msg->action = ACTION_DESTROY;
davidjhoward 145:c1dfbb5eed0e 320 msg->control = CONTROL_MANUAL;
davidjhoward 145:c1dfbb5eed0e 321 strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
davidjhoward 145:c1dfbb5eed0e 322
davidjhoward 145:c1dfbb5eed0e 323 printf("%s: Sending a destroy request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control);
davidjhoward 145:c1dfbb5eed0e 324
davidjhoward 145:c1dfbb5eed0e 325 MailBox.put(msg);
davidjhoward 145:c1dfbb5eed0e 326 break;
davidjhoward 145:c1dfbb5eed0e 327 }
davidjhoward 145:c1dfbb5eed0e 328 case DESTROY_TIMER_MTYPE: {
davidjhoward 145:c1dfbb5eed0e 329 logInfo("PROCESSING DESTORY TIMER CONTROL MESSAGE");
davidjhoward 145:c1dfbb5eed0e 330 snprintf( filename, sizeof(FILENAME_STRING), "control_tm_%s.json",
davidjhoward 145:c1dfbb5eed0e 331 from_json["pay"]["destroy"]["id"].get<std::string>().c_str() );
davidjhoward 145:c1dfbb5eed0e 332 logInfo("TIMER CONTROL FILENAME=%s", filename);
davidjhoward 145:c1dfbb5eed0e 333
davidjhoward 145:c1dfbb5eed0e 334 // send a message to the configuration handler to create the control
davidjhoward 145:c1dfbb5eed0e 335 Message_t *msg = MailBox.alloc();
davidjhoward 145:c1dfbb5eed0e 336 memset(msg, 0, sizeof(Message_t));
davidjhoward 145:c1dfbb5eed0e 337 msg->action = ACTION_DESTROY;
davidjhoward 145:c1dfbb5eed0e 338 msg->control = CONTROL_TIMER;
davidjhoward 145:c1dfbb5eed0e 339 strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
davidjhoward 145:c1dfbb5eed0e 340
davidjhoward 145:c1dfbb5eed0e 341 printf("%s: Sending a destroy request for control %s type = %u\r\n", __func__, msg->controlFile, msg->control);
davidjhoward 145:c1dfbb5eed0e 342
davidjhoward 145:c1dfbb5eed0e 343 MailBox.put(msg);
davidjhoward 145:c1dfbb5eed0e 344 break;
davidjhoward 145:c1dfbb5eed0e 345 }
davidjhoward 149:950c90425f7c 346 case VIRTUAL_COMMAND_MTYPE: {
davidjhoward 149:950c90425f7c 347 logInfo("PROCESSING VIRTUAL COMMAND FILE");
davidjhoward 149:950c90425f7c 348 snprintf( filename, sizeof(FILENAME_STRING), "vcmd_%s.json",
davidjhoward 149:950c90425f7c 349 from_json["pay"]["vcommand"]["id"].get<std::string>().c_str() );
davidjhoward 149:950c90425f7c 350 logInfo("VIRTUAL COMMAND FILENAME=%s", filename);
davidjhoward 149:950c90425f7c 351
jmarkel44 177:9ec90c8e3ce1 352 memset( CloudFileReceiverWriteBuf, '\0', MAX_FILE_SIZE );
davidjhoward 149:950c90425f7c 353 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf),
davidjhoward 214:52ef35bc44ec 354 "{"
davidjhoward 214:52ef35bc44ec 355 "\"id\":\"%s\","
davidjhoward 214:52ef35bc44ec 356 "\"tag\":\"%s\","
davidjhoward 214:52ef35bc44ec 357 "\"c\":\"%f\","
davidjhoward 214:52ef35bc44ec 358 "\"opl\":\"%s\","
davidjhoward 214:52ef35bc44ec 359 "\"opr\":\"%s\","
davidjhoward 214:52ef35bc44ec 360 "\"op\":\"%s\"}",
davidjhoward 149:950c90425f7c 361 from_json["pay"]["vcommand"]["id"].get<std::string>().c_str(),
davidjhoward 214:52ef35bc44ec 362 from_json["pay"]["vcommand"]["tag"].get<std::string>().c_str(),
davidjhoward 214:52ef35bc44ec 363 atof(from_json["pay"]["vcommand"]["c"].get<std::string>().c_str()),
davidjhoward 149:950c90425f7c 364 from_json["pay"]["vcommand"]["opl"].get<std::string>().c_str(),
davidjhoward 149:950c90425f7c 365 from_json["pay"]["vcommand"]["opr"].get<std::string>().c_str(),
davidjhoward 149:950c90425f7c 366 from_json["pay"]["vcommand"]["op"].get<std::string>().c_str()
davidjhoward 149:950c90425f7c 367 );
davidjhoward 149:950c90425f7c 368
davidjhoward 149:950c90425f7c 369 logInfo("saving string%s", CloudFileReceiverWriteBuf);
jmarkel44 177:9ec90c8e3ce1 370 bool status = GLOBAL_mdot->saveUserFile(filename, (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 149:950c90425f7c 371 if( status != true ) {
davidjhoward 149:950c90425f7c 372 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 149:950c90425f7c 373 }
davidjhoward 149:950c90425f7c 374
davidjhoward 149:950c90425f7c 375 logInfo("Sending Mail To ModbusMasterMailBox, filename=%s", filename);
davidjhoward 149:950c90425f7c 376 Message_t *mail = ModbusMasterMailBox.alloc();
davidjhoward 149:950c90425f7c 377 mail->action = ACTION_READ_FILE;
davidjhoward 149:950c90425f7c 378 strncpy( mail->controlFile, filename, (sizeof(mail->controlFile)-1));
davidjhoward 149:950c90425f7c 379 ModbusMasterMailBox.put(mail);
davidjhoward 149:950c90425f7c 380 break;
davidjhoward 149:950c90425f7c 381 }
davidjhoward 197:594afd088f32 382 case MODBUS_COMMAND_MTYPE: {
davidjhoward 197:594afd088f32 383 logInfo("PROCESSING MODBUS COMMAND FILE");
davidjhoward 197:594afd088f32 384 snprintf( filename, sizeof(FILENAME_STRING), "mcmd_%s.json",
davidjhoward 197:594afd088f32 385 from_json["pay"]["mcommand"]["id"].get<std::string>().c_str() );
davidjhoward 197:594afd088f32 386 logInfo("MODBUS COMMAND FILENAME=%s", filename);
davidjhoward 197:594afd088f32 387
davidjhoward 197:594afd088f32 388 memset( CloudFileReceiverWriteBuf, '\0', MAX_FILE_SIZE );
davidjhoward 197:594afd088f32 389 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf),
davidjhoward 197:594afd088f32 390 "{ "
davidjhoward 197:594afd088f32 391 "\"id\":\"%s\","
davidjhoward 197:594afd088f32 392 "\"node\":\"%s\","
davidjhoward 197:594afd088f32 393 "\"func\":\"%s\","
davidjhoward 197:594afd088f32 394 "\"sreg\":\"%s\","
davidjhoward 197:594afd088f32 395 "\"nreg\":\"%s\" }"
davidjhoward 197:594afd088f32 396 "\"dtype\":\"%s\","
davidjhoward 197:594afd088f32 397 "\"order\":\"%s\","
davidjhoward 197:594afd088f32 398 "\"value\":\"%s\"}",
davidjhoward 197:594afd088f32 399 from_json["pay"]["mcommand"]["id"].get<std::string>().c_str(),
davidjhoward 197:594afd088f32 400 from_json["pay"]["mcommand"]["node"].get<std::string>().c_str(),
davidjhoward 197:594afd088f32 401 from_json["pay"]["mcommand"]["func"].get<std::string>().c_str(),
davidjhoward 197:594afd088f32 402 from_json["pay"]["mcommand"]["sreg"].get<std::string>().c_str(),
davidjhoward 197:594afd088f32 403 from_json["pay"]["mcommand"]["nreg"].get<std::string>().c_str(),
davidjhoward 197:594afd088f32 404 from_json["pay"]["mcommand"]["dtype"].get<std::string>().c_str(),
davidjhoward 197:594afd088f32 405 from_json["pay"]["mcommand"]["order"].get<std::string>().c_str(),
davidjhoward 197:594afd088f32 406 from_json["pay"]["mcommand"]["value"].get<std::string>().c_str()
davidjhoward 197:594afd088f32 407 );
davidjhoward 197:594afd088f32 408
davidjhoward 197:594afd088f32 409 logInfo("Sending Command To ModbusMasterMailBox: %s", CloudFileReceiverWriteBuf);
davidjhoward 197:594afd088f32 410 Message_t *mail = ModbusMasterMailBox.alloc();
davidjhoward 197:594afd088f32 411 mail->action = ACTION_EXEC_CMD;
davidjhoward 197:594afd088f32 412 strncpy( mail->controlFile, CloudFileReceiverWriteBuf, (sizeof(mail->controlFile)-1));
davidjhoward 197:594afd088f32 413 ModbusMasterMailBox.put(mail);
davidjhoward 197:594afd088f32 414 break;
davidjhoward 197:594afd088f32 415 }
davidjhoward 99:55317f374a94 416 default:
davidjhoward 99:55317f374a94 417 logInfo("DEFAULT");
davidjhoward 99:55317f374a94 418 break;
davidjhoward 99:55317f374a94 419 }
davidjhoward 99:55317f374a94 420 return true;
davidjhoward 49:0456ee2271be 421 }
davidjhoward 162:5e8948b8044d 422
davidjhoward 149:950c90425f7c 423 bool CloudDataHandler_RcvFile = false;
davidjhoward 49:0456ee2271be 424 bool CloudFileReceiver( std::string *recv_string, mDot *dot )
davidjhoward 49:0456ee2271be 425 {
davidjhoward 173:acfb464a4aec 426
davidjhoward 173:acfb464a4aec 427 MbedJSONValue incomingJson;
davidjhoward 173:acfb464a4aec 428
davidjhoward 49:0456ee2271be 429 bool status;
davidjhoward 173:acfb464a4aec 430 parse( incomingJson, recv_string->c_str() );
davidjhoward 173:acfb464a4aec 431 int sequence = incomingJson["seq"].get<int>();
davidjhoward 49:0456ee2271be 432
davidjhoward 149:950c90425f7c 433 CloudDataHandler_RcvFile = false;
davidjhoward 149:950c90425f7c 434
davidjhoward 49:0456ee2271be 435 // sequence of -1 means string sent in 1 chunk.
davidjhoward 49:0456ee2271be 436 if( sequence == -1 ) {
davidjhoward 173:acfb464a4aec 437 return StoreReceivedFile( dot, incomingJson );
davidjhoward 27:38205cebc3da 438 } else if( sequence == 0 ) {
davidjhoward 27:38205cebc3da 439
davidjhoward 49:0456ee2271be 440 memset(CloudFileReceiverWriteBuf,0,sizeof(CloudFileReceiverWriteBuf));
davidjhoward 175:5e533c43bffc 441 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf), "%s%s", "{\"seq\":-1, \"pay\":",incomingJson["pay"].get<std::string>().c_str() );
jmarkel44 177:9ec90c8e3ce1 442 logInfo("(%d)Writing String Length=%d, %s", __LINE__, MAX_FILE_SIZE, CloudFileReceiverWriteBuf );
davidjhoward 27:38205cebc3da 443
jmarkel44 177:9ec90c8e3ce1 444 status = dot->saveUserFile("scratch.json", (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 27:38205cebc3da 445 if( status != true ) {
davidjhoward 49:0456ee2271be 446 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 27:38205cebc3da 447 return false;
davidjhoward 27:38205cebc3da 448 }
davidjhoward 149:950c90425f7c 449 CloudDataHandler_RcvFile = true;
davidjhoward 49:0456ee2271be 450 logInfo("(%d)UPDATED scratch.json FILE, status:%d, strlen=%d", __LINE__, status, strlen(CloudFileReceiverWriteBuf));
davidjhoward 49:0456ee2271be 451
davidjhoward 27:38205cebc3da 452 } else if( sequence == -2 ) {
davidjhoward 27:38205cebc3da 453
davidjhoward 173:acfb464a4aec 454 MbedJSONValue finalJson;
davidjhoward 173:acfb464a4aec 455
davidjhoward 27:38205cebc3da 456 logInfo("(%d)READING BACK scratch.json FILE FOR LAST PACKET", __LINE__);
davidjhoward 27:38205cebc3da 457
davidjhoward 27:38205cebc3da 458 // read the file back
jmarkel44 177:9ec90c8e3ce1 459 status = dot->readUserFile("scratch.json", (void *)CloudFileReceiverReadBuf, MAX_FILE_SIZE);
davidjhoward 27:38205cebc3da 460 if( status != true ) {
davidjhoward 49:0456ee2271be 461 logError("(%d)read file failed, status=%d", __LINE__, status);
davidjhoward 27:38205cebc3da 462 return false;
davidjhoward 27:38205cebc3da 463 }
davidjhoward 27:38205cebc3da 464
davidjhoward 173:acfb464a4aec 465 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf), "%s%s%s", CloudFileReceiverReadBuf, incomingJson["pay"].get<std::string>().c_str(), "}" );
davidjhoward 49:0456ee2271be 466 logInfo("(%d)Final String Length=%d, %s", __LINE__, strlen(CloudFileReceiverWriteBuf), CloudFileReceiverWriteBuf );
davidjhoward 27:38205cebc3da 467
davidjhoward 173:acfb464a4aec 468 std::string err;
davidjhoward 173:acfb464a4aec 469 parse( finalJson, CloudFileReceiverWriteBuf, CloudFileReceiverWriteBuf + strlen(CloudFileReceiverWriteBuf), &err );
davidjhoward 173:acfb464a4aec 470 printf("finished parse\r\n" );
davidjhoward 49:0456ee2271be 471
davidjhoward 173:acfb464a4aec 472 Thread::wait(1000);
davidjhoward 173:acfb464a4aec 473
davidjhoward 173:acfb464a4aec 474 int sequence = finalJson["seq"].get<int>();
davidjhoward 173:acfb464a4aec 475 int mType = finalJson["pay"]["mtype"].get<int>();
davidjhoward 99:55317f374a94 476
davidjhoward 138:27c39d0e4e81 477 printf("MESSAGE TYPE=%d\r\n",mType);
davidjhoward 99:55317f374a94 478
davidjhoward 173:acfb464a4aec 479 status = StoreReceivedFile( dot, finalJson );
davidjhoward 27:38205cebc3da 480 if( status != true ) {
davidjhoward 49:0456ee2271be 481 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 27:38205cebc3da 482 }
davidjhoward 49:0456ee2271be 483
davidjhoward 49:0456ee2271be 484 status = dot->deleteUserFile("scratch.json");
davidjhoward 49:0456ee2271be 485 if( status != true ) {
davidjhoward 49:0456ee2271be 486 logError("(%d)delete file failed, status=%d", __LINE__, status);
davidjhoward 49:0456ee2271be 487 }
davidjhoward 49:0456ee2271be 488
davidjhoward 49:0456ee2271be 489 logInfo("(%d)DELETED scratch.json FILE, status:%d", __LINE__, status );
davidjhoward 49:0456ee2271be 490
davidjhoward 27:38205cebc3da 491 } else {
davidjhoward 27:38205cebc3da 492
davidjhoward 27:38205cebc3da 493 logInfo("(%d)READING BACK scratch.json FILE", __LINE__);
davidjhoward 27:38205cebc3da 494
davidjhoward 27:38205cebc3da 495 // read the file back
jmarkel44 177:9ec90c8e3ce1 496 status = dot->readUserFile("scratch.json", (void *)CloudFileReceiverReadBuf, MAX_FILE_SIZE);
davidjhoward 27:38205cebc3da 497 if( status != true ) {
davidjhoward 49:0456ee2271be 498 logError("(%d)read file failed, status=%d", __LINE__, status);
davidjhoward 27:38205cebc3da 499 return false;
davidjhoward 27:38205cebc3da 500 }
davidjhoward 27:38205cebc3da 501
davidjhoward 173:acfb464a4aec 502 snprintf(CloudFileReceiverWriteBuf, sizeof(CloudFileReceiverWriteBuf), "%s%s", CloudFileReceiverReadBuf, incomingJson["pay"].get<std::string>().c_str() );
davidjhoward 49:0456ee2271be 503 logInfo("(%d)Writing String Length=%d, %s", __LINE__, strlen(CloudFileReceiverWriteBuf), CloudFileReceiverWriteBuf );
davidjhoward 27:38205cebc3da 504
jmarkel44 177:9ec90c8e3ce1 505 status = dot->saveUserFile("scratch.json", (void *)CloudFileReceiverWriteBuf, MAX_FILE_SIZE);
davidjhoward 27:38205cebc3da 506 if( status != true ) {
davidjhoward 49:0456ee2271be 507 logError("(%d)save file failed, status=%d", __LINE__, status);
davidjhoward 27:38205cebc3da 508 return false;
davidjhoward 27:38205cebc3da 509 }
davidjhoward 149:950c90425f7c 510 CloudDataHandler_RcvFile = true;
davidjhoward 49:0456ee2271be 511 logInfo("(%d)UPDATED scratch.json FILE, status:%d, strlen=%d", __LINE__, status, strlen(CloudFileReceiverWriteBuf));
davidjhoward 49:0456ee2271be 512
davidjhoward 27:38205cebc3da 513 }
davidjhoward 27:38205cebc3da 514
davidjhoward 27:38205cebc3da 515 return true;
davidjhoward 27:38205cebc3da 516 }