Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Sun Feb 22 20:42:44 2015 +0000
Revision:
76:f8383f0292c2
Parent:
65:2cb3e99ce466
Child:
84:80b15993944e
Stn14 mac adr. Allow SD to be ignored. Only access run/seq list if going to send the list.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 2:e67f7c158087 1 #include "SnCommWin.h"
uci1 2:e67f7c158087 2
uci1 6:6f002d202f59 3 #include "SnHeaderFrame.h"
uci1 2:e67f7c158087 4 #include "SnConfigFrame.h"
uci1 8:95a325df1f6b 5 #include "SnEventFrame.h"
uci1 8:95a325df1f6b 6 #include "SnPowerFrame.h"
uci1 8:95a325df1f6b 7 #include "SnStatusFrame.h"
uci1 41:d6f5e2f09e07 8 #include "SnSignalStrengthFrame.h"
uci1 2:e67f7c158087 9 #include "SnSDUtils.h"
uci1 16:744ce85aede2 10 #include "SnConstants.h"
uci1 21:ce51bb0ba4a5 11 #include "SnCRCUtils.h"
uci1 37:ff95e7070f26 12 #include "SnCommPeripheral.h"
uci1 21:ce51bb0ba4a5 13
uci1 21:ce51bb0ba4a5 14 #include <algorithm>
uci1 21:ce51bb0ba4a5 15 #include <ctype.h>
uci1 21:ce51bb0ba4a5 16 extern "C" void mbed_reset();
uci1 16:744ce85aede2 17
uci1 65:2cb3e99ce466 18 //#define DEBUG
uci1 16:744ce85aede2 19
uci1 27:efc4d654b139 20 const char* SnCommWin::kLocalDir = "/local";
uci1 27:efc4d654b139 21 const char* SnCommWin::kDelAllConfCodeStr = "fj2io32FIJ(#jd;;.O@++/]ewavk2[49ojv";
uci1 27:efc4d654b139 22 const uint8_t SnCommWin::kDelAllConfCodeLen = 35; // length of the above string
uci1 25:57b2627fe756 23
uci1 37:ff95e7070f26 24 SnCommWin::SnCommWin(SnCommPeripheral* p) :
uci1 56:0bba0ef15697 25 fSendingInHandshake(false), fComm(p) {
uci1 37:ff95e7070f26 26 if (p==0) {
uci1 37:ff95e7070f26 27 error("SnCommWin - must have peripheral! Received 0.\r\n");
uci1 37:ff95e7070f26 28 }
uci1 37:ff95e7070f26 29 }
uci1 37:ff95e7070f26 30
uci1 37:ff95e7070f26 31 SnCommWin::~SnCommWin() {
uci1 37:ff95e7070f26 32 delete fComm;
uci1 37:ff95e7070f26 33 }
uci1 37:ff95e7070f26 34
uci1 40:1324da35afd4 35 bool SnCommWin::TrySetSysTimeUnix(const uint32_t timeout,
uci1 40:1324da35afd4 36 uint32_t& prvTime,
uci1 40:1324da35afd4 37 uint32_t& setTime) {
uci1 40:1324da35afd4 38 return (fComm!=0) ? (fComm->TrySetSysTimeUnix(timeout,prvTime,setTime))
uci1 40:1324da35afd4 39 : false;
uci1 37:ff95e7070f26 40 }
uci1 37:ff95e7070f26 41
uci1 37:ff95e7070f26 42 bool SnCommWin::Connect(const uint32_t timeout) {
uci1 64:6c7a316eafad 43 Watchdog::kick(); // don't reset
uci1 37:ff95e7070f26 44 return (fComm!=0) ? (fComm->Connect(timeout)) : false;
uci1 37:ff95e7070f26 45 }
uci1 37:ff95e7070f26 46
uci1 37:ff95e7070f26 47 bool SnCommWin::CloseConn(const uint32_t timeout) {
uci1 64:6c7a316eafad 48 Watchdog::kick(); // don't reset
uci1 37:ff95e7070f26 49 return (fComm!=0) ? (fComm->CloseConn(timeout)) : false;
uci1 12:d472f9811262 50 }
uci1 12:d472f9811262 51
uci1 40:1324da35afd4 52 bool SnCommWin::PowerDown(const uint32_t timeout) {
uci1 64:6c7a316eafad 53 Watchdog::kick(); // don't reset
uci1 40:1324da35afd4 54 return (fComm!=0) ? (fComm->PowerDown(timeout)) : false;
uci1 40:1324da35afd4 55 }
uci1 40:1324da35afd4 56
uci1 2:e67f7c158087 57 SnCommWin::ECommWinResult SnCommWin::SendData(SnConfigFrame& conf,
uci1 2:e67f7c158087 58 SnEventFrame& evt,
uci1 8:95a325df1f6b 59 SnPowerFrame& pow,
uci1 2:e67f7c158087 60 char* const genBuf,
uci1 3:24c5f0f50bf1 61 const uint32_t bsize,
uci1 40:1324da35afd4 62 const uint32_t timeout) {
uci1 12:d472f9811262 63 #ifdef DEBUG
uci1 3:24c5f0f50bf1 64 printf("SnCommWin::SendData\r\n");
uci1 12:d472f9811262 65 #endif
uci1 64:6c7a316eafad 66 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 67
uci1 2:e67f7c158087 68 ECommWinResult res = kUndefFail;
uci1 15:f2569d8e4176 69 if ( (GetCommType() != SnConfigFrame::kIrid) ||
uci1 15:f2569d8e4176 70 (conf.IsForcingSBDdata()) ) {
uci1 15:f2569d8e4176 71 // only send large amounts if we're not communicating by Iridum,
uci1 15:f2569d8e4176 72 // or if we are being forced to send the data over SBD
uci1 15:f2569d8e4176 73 if (conf.IsSendingAllFiles()) {
uci1 12:d472f9811262 74 #ifdef DEBUG
uci1 15:f2569d8e4176 75 printf("sending all files\r\n");
uci1 12:d472f9811262 76 #endif
uci1 15:f2569d8e4176 77 res = SnSDUtils::SendAllFiles(this, timeout,
uci1 40:1324da35afd4 78 genBuf, bsize, conf, evt, pow);
uci1 40:1324da35afd4 79 // handshakes handled after each file, in SendDataFromFile
uci1 15:f2569d8e4176 80 } else {
uci1 15:f2569d8e4176 81 if (conf.GetCommSendData()==0) {
uci1 12:d472f9811262 82 #ifdef DEBUG
uci1 15:f2569d8e4176 83 printf("no data to send\r\n");
uci1 12:d472f9811262 84 #endif
uci1 15:f2569d8e4176 85 res = kOkNoMsg;
uci1 56:0bba0ef15697 86 } else if (conf.IsSendingFilesRunSeqList()) {
uci1 56:0bba0ef15697 87 #ifdef DEBUG
uci1 56:0bba0ef15697 88 printf ("calling SendFilesInRunSeqList\r\n");
uci1 56:0bba0ef15697 89 #endif
uci1 56:0bba0ef15697 90 res = SnSDUtils::SendFilesInRunSeqList(
uci1 56:0bba0ef15697 91 this, timeout,
uci1 56:0bba0ef15697 92 genBuf, bsize, conf, evt, pow);
uci1 56:0bba0ef15697 93 #ifdef DEBUG
uci1 56:0bba0ef15697 94 printf ("res = %d after SendFilesInRunSeqList\r\n",
uci1 56:0bba0ef15697 95 static_cast<int>(res));
uci1 56:0bba0ef15697 96 #endif
uci1 15:f2569d8e4176 97 } else {
uci1 56:0bba0ef15697 98 // send most recent file or a few events from that file
uci1 15:f2569d8e4176 99 const uint32_t nev = (conf.GetCommSendData()>0) ?
uci1 15:f2569d8e4176 100 conf.GetCommSendData() // send N events
uci1 15:f2569d8e4176 101 : 0u; // send all events in last file
uci1 12:d472f9811262 102 #ifdef DEBUG
uci1 40:1324da35afd4 103 printf("calling SendDataFromFile. f=%s, nev=%u\r\n",
uci1 40:1324da35afd4 104 SnSDUtils::GetCurFileName(), nev);
uci1 12:d472f9811262 105 #endif
uci1 40:1324da35afd4 106 uint8_t hndcode(0);
uci1 40:1324da35afd4 107 uint32_t hndlen(0);
uci1 40:1324da35afd4 108 res = SendDataFromFile(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(),
uci1 40:1324da35afd4 109 conf, evt, pow, genBuf, bsize, nev, timeout,
uci1 40:1324da35afd4 110 &hndcode, &hndlen);
uci1 40:1324da35afd4 111 // handshake handled in SendData
uci1 12:d472f9811262 112 #ifdef DEBUG
uci1 15:f2569d8e4176 113 printf("after send data cur file, res=%d\r\n",(int)res);
uci1 12:d472f9811262 114 #endif
uci1 15:f2569d8e4176 115 }
uci1 2:e67f7c158087 116 }
uci1 15:f2569d8e4176 117 } else {
uci1 15:f2569d8e4176 118 return kOkNoMsg;
uci1 2:e67f7c158087 119 }
uci1 2:e67f7c158087 120 return res;
uci1 2:e67f7c158087 121 }
uci1 2:e67f7c158087 122
uci1 40:1324da35afd4 123 SnCommWin::ECommWinResult SnCommWin::SendDataFromFile(FILE* inf, const char* infn,
uci1 2:e67f7c158087 124 const SnConfigFrame& curConf,
uci1 2:e67f7c158087 125 SnEventFrame& evt,
uci1 8:95a325df1f6b 126 SnPowerFrame& pow,
uci1 2:e67f7c158087 127 char* const genBuf,
uci1 6:6f002d202f59 128 const uint32_t bsize,
uci1 2:e67f7c158087 129 const uint32_t nevts,
uci1 40:1324da35afd4 130 const uint32_t timeout,
uci1 40:1324da35afd4 131 uint8_t* hndcode,
uci1 40:1324da35afd4 132 uint32_t* hndlen) {
uci1 2:e67f7c158087 133 // nevts==0 ==> send all events
uci1 21:ce51bb0ba4a5 134 // handshakeTimeout is never a clock time -- always a delta(t)
uci1 2:e67f7c158087 135
uci1 12:d472f9811262 136 #ifdef DEBUG
uci1 40:1324da35afd4 137 printf("SnCommWin::SendDataFromFile file (%p), fn=%s\r\n",inf,infn);
uci1 12:d472f9811262 138 #endif
uci1 64:6c7a316eafad 139 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 140
uci1 2:e67f7c158087 141 ECommWinResult res = kUndefFail;
uci1 12:d472f9811262 142 bool didDel = false;
uci1 40:1324da35afd4 143
uci1 40:1324da35afd4 144 // allow up to the full window if we're not obeying timeout
uci1 40:1324da35afd4 145 const uint32_t timeout_clock = curConf.IsObeyingTimeout() ?
uci1 40:1324da35afd4 146 timeout :
uci1 40:1324da35afd4 147 curConf.GetTimeoutTime(time(0),
uci1 40:1324da35afd4 148 curConf.GetCommWinDuration());
uci1 40:1324da35afd4 149
uci1 40:1324da35afd4 150
uci1 2:e67f7c158087 151 if (inf!=0) {
uci1 12:d472f9811262 152 #ifdef DEBUG
uci1 12:d472f9811262 153 printf("sending file name %s\r\n",infn);
uci1 12:d472f9811262 154 #endif
uci1 40:1324da35afd4 155
uci1 6:6f002d202f59 156 // send the file name
uci1 40:1324da35afd4 157 int32_t btogo(0), ttogo(0);
uci1 40:1324da35afd4 158 int32_t bsent = SendFilename(infn, genBuf, btogo, timeout_clock);
uci1 40:1324da35afd4 159 if (genBuf!=0) {
uci1 12:d472f9811262 160 #ifdef DEBUG
uci1 40:1324da35afd4 161 printf("calling send file contents\r\n");
uci1 12:d472f9811262 162 #endif
uci1 16:744ce85aede2 163
uci1 40:1324da35afd4 164 // send the contents
uci1 40:1324da35afd4 165 bsent += SendFileContents(inf, curConf, evt, pow, genBuf,
uci1 40:1324da35afd4 166 nevts, ttogo, timeout_clock);
uci1 40:1324da35afd4 167 btogo += ttogo;
uci1 40:1324da35afd4 168 bsent += fComm->FinishSending(timeout_clock);
uci1 40:1324da35afd4 169 res = (bsent==btogo) ? SnCommWin::kOkMsgSent
uci1 40:1324da35afd4 170 : SnCommWin::kFailPartSent;
uci1 12:d472f9811262 171 #ifdef DEBUG
uci1 40:1324da35afd4 172 printf("res=%d (fails=%d)\r\n",(int)res,(int)kAllFails);
uci1 12:d472f9811262 173 #endif
uci1 40:1324da35afd4 174 if (res>kAllFails) {
uci1 12:d472f9811262 175 #ifdef DEBUG
uci1 40:1324da35afd4 176 printf("calling wait handshake\r\n");
uci1 12:d472f9811262 177 #endif
uci1 64:6c7a316eafad 178 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 179
uci1 40:1324da35afd4 180 // wait for handshake
uci1 40:1324da35afd4 181 uint8_t hndshk(0); uint32_t hndshkLen(0);
uci1 40:1324da35afd4 182 res = WaitHandshake(curConf, timeout_clock, genBuf, bsize, hndshk,
uci1 40:1324da35afd4 183 &hndshkLen);
uci1 40:1324da35afd4 184 if (hndcode!=0) {
uci1 40:1324da35afd4 185 *hndcode = hndshk;
uci1 40:1324da35afd4 186 }
uci1 40:1324da35afd4 187 if (hndlen!=0) {
uci1 40:1324da35afd4 188 *hndlen = hndshkLen;
uci1 40:1324da35afd4 189 }
uci1 26:b3180073c8ec 190 #ifdef DEBUG
uci1 40:1324da35afd4 191 printf("res=%d, nevts=%u, isdel=%d, inf=%p, curfile=%p, hndshk=%02x\r\n",
uci1 40:1324da35afd4 192 res, nevts, curConf.IsDeletingFiles(), inf,
uci1 40:1324da35afd4 193 SnSDUtils::GetCurFile(), hndshk);
uci1 21:ce51bb0ba4a5 194 #endif
uci1 40:1324da35afd4 195 if (SnCommWin::kOkWithMsg==res) {
uci1 56:0bba0ef15697 196 res = HandleHandshake(
uci1 56:0bba0ef15697 197 //SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(),
uci1 56:0bba0ef15697 198 inf, infn,
uci1 40:1324da35afd4 199 curConf, evt, pow, genBuf, bsize, timeout_clock,
uci1 40:1324da35afd4 200 hndshk, hndshkLen, &nevts);
uci1 40:1324da35afd4 201 didDel = (SnCommWin::kOkWthMsgDidDel==res);
uci1 40:1324da35afd4 202 }
uci1 2:e67f7c158087 203 }
uci1 40:1324da35afd4 204 } // if genBuf!=0
uci1 12:d472f9811262 205 } else {
uci1 12:d472f9811262 206 #ifdef DEBUG
uci1 12:d472f9811262 207 printf("inf=0!\r\n");
uci1 12:d472f9811262 208 #endif
uci1 56:0bba0ef15697 209 res = kOkNoMsg;
uci1 12:d472f9811262 210 }
uci1 12:d472f9811262 211 if ( (inf!=SnSDUtils::GetCurFile()) && (didDel==false) ) {
uci1 12:d472f9811262 212 SnSDUtils::CloseOutputFile(inf);
uci1 2:e67f7c158087 213 }
uci1 37:ff95e7070f26 214 if ( fComm->IsTimedOut(timeout_clock) ) {
uci1 25:57b2627fe756 215 if ( kFailTimeout < res ) {
uci1 25:57b2627fe756 216 res = kFailTimeout;
uci1 25:57b2627fe756 217 }
uci1 25:57b2627fe756 218 }
uci1 2:e67f7c158087 219 return res;
uci1 2:e67f7c158087 220 }
uci1 8:95a325df1f6b 221
uci1 40:1324da35afd4 222 SnCommWin::ECommWinResult SnCommWin::HandleHandshake(FILE* inf, const char* infn,
uci1 40:1324da35afd4 223 const SnConfigFrame& curConf,
uci1 40:1324da35afd4 224 SnEventFrame& evt,
uci1 40:1324da35afd4 225 SnPowerFrame& pow,
uci1 40:1324da35afd4 226 char* const genBuf,
uci1 40:1324da35afd4 227 const uint32_t bsize,
uci1 40:1324da35afd4 228 const uint32_t handshakeTimeout,
uci1 40:1324da35afd4 229 const uint8_t hndshk,
uci1 40:1324da35afd4 230 const uint32_t hndlen,
uci1 40:1324da35afd4 231 const uint32_t* nevts) {
uci1 40:1324da35afd4 232
uci1 40:1324da35afd4 233 SnCommWin::ECommWinResult res = SnCommWin::kUnexpectedRec;
uci1 40:1324da35afd4 234
uci1 64:6c7a316eafad 235 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 236
uci1 40:1324da35afd4 237 if ( (hndshk==SnHeaderFrame::kHnShNoReplyCode)
uci1 40:1324da35afd4 238 || (hndshk==SnHeaderFrame::kHnShOkPartlCode) ) {
uci1 40:1324da35afd4 239 // nothing to do
uci1 40:1324da35afd4 240 res = SnCommWin::kOkWithMsg;
uci1 40:1324da35afd4 241 } else if (hndshk==SnHeaderFrame::kHnShFailNonCode) {
uci1 40:1324da35afd4 242 res = SnCommWin::kFailNoneSent;
uci1 40:1324da35afd4 243 } else if (hndshk==SnHeaderFrame::kHnShFailPrtCode) {
uci1 40:1324da35afd4 244 res = SnCommWin::kFailPartSent;
uci1 40:1324da35afd4 245 } else if (hndshk==SnHeaderFrame::kHnShOkComplCode) {
uci1 40:1324da35afd4 246 // file received
uci1 56:0bba0ef15697 247 #ifdef DEBUG
uci1 56:0bba0ef15697 248 printf("HnShOkCompl: isdel=%d, isCurFil=%d (%p,%p), nevts_ptr=%p\r\n",
uci1 56:0bba0ef15697 249 (int)(curConf.IsDeletingFiles()),
uci1 56:0bba0ef15697 250 (int)(inf==SnSDUtils::GetCurFile()),
uci1 56:0bba0ef15697 251 (void*)inf, (void*)(SnSDUtils::GetCurFile()),
uci1 56:0bba0ef15697 252 (void*)(nevts));
uci1 56:0bba0ef15697 253 if (nevts!=0) {
uci1 56:0bba0ef15697 254 printf("*nevts=%u\r\n",*nevts);
uci1 56:0bba0ef15697 255 }
uci1 56:0bba0ef15697 256 #endif
uci1 40:1324da35afd4 257 if ( (curConf.IsDeletingFiles())
uci1 40:1324da35afd4 258 && (inf!=SnSDUtils::GetCurFile())
uci1 40:1324da35afd4 259 && ((nevts!=0) && (*nevts==0)) ) { // whole file was received
uci1 40:1324da35afd4 260 // delete this file
uci1 40:1324da35afd4 261 #ifdef DEBUG
uci1 40:1324da35afd4 262 printf("deleting file %p, %s\r\n",inf,infn);
uci1 40:1324da35afd4 263 #endif
uci1 40:1324da35afd4 264 SnSDUtilsWhisperer::DeleteFile(inf, infn);
uci1 40:1324da35afd4 265 res = SnCommWin::kOkWthMsgDidDel;
uci1 40:1324da35afd4 266 } else {
uci1 40:1324da35afd4 267 res = SnCommWin::kOkWithMsg;
uci1 40:1324da35afd4 268 }
uci1 40:1324da35afd4 269 } else if ( hndshk==SnHeaderFrame::kHnShOkStopCode ) {
uci1 40:1324da35afd4 270 res = SnCommWin::kOkStopComm;
uci1 40:1324da35afd4 271 } else if ( (hndshk==SnHeaderFrame::kHnShOkDelAlCode) ||
uci1 40:1324da35afd4 272 (hndshk==SnHeaderFrame::kHnShOkDelRnCode) ) {
uci1 40:1324da35afd4 273 if ( GetDeleteAllConfirmCode(curConf,
uci1 40:1324da35afd4 274 kDelAllConfCodeLen,
uci1 40:1324da35afd4 275 handshakeTimeout,
uci1 40:1324da35afd4 276 genBuf, bsize) ) {
uci1 40:1324da35afd4 277 if (hndshk==SnHeaderFrame::kHnShOkDelAlCode) {
uci1 40:1324da35afd4 278 #ifdef DEBUG
uci1 40:1324da35afd4 279 printf("delete all\r\n");
uci1 40:1324da35afd4 280 #endif
uci1 40:1324da35afd4 281 SnSDUtilsWhisperer::DeleteAllFiles();
uci1 40:1324da35afd4 282 } else if (hndshk==SnHeaderFrame::kHnShOkDelRnCode) {
uci1 40:1324da35afd4 283 #ifdef DEBUG
uci1 40:1324da35afd4 284 printf("delete run %u\r\n",hndlen);
uci1 40:1324da35afd4 285 #endif
uci1 40:1324da35afd4 286 SnSDUtilsWhisperer::DeleteFilesOfRun(hndlen);
uci1 40:1324da35afd4 287 }
uci1 40:1324da35afd4 288 res = SnCommWin::kOkStopComm;
uci1 40:1324da35afd4 289 }
uci1 56:0bba0ef15697 290 } else if ( hndshk==SnHeaderFrame::kHnShOkClRSLCode ) {
uci1 56:0bba0ef15697 291 #ifdef DEBUG
uci1 56:0bba0ef15697 292 printf("clear run seq list requested\r\n");
uci1 56:0bba0ef15697 293 #endif
uci1 76:f8383f0292c2 294 SnSDUtils::ClearRunSeqList(curConf.IsSendingFilesRunSeqList());
uci1 40:1324da35afd4 295 } else if ( hndshk==SnHeaderFrame::kHnShOkReqRnCode ) {
uci1 40:1324da35afd4 296 #ifdef DEBUG
uci1 40:1324da35afd4 297 printf("run %u requested\r\n",hndlen);
uci1 40:1324da35afd4 298 #endif
uci1 56:0bba0ef15697 299 if (fSendingInHandshake==false) {
uci1 56:0bba0ef15697 300 // prevent another SendAllOfRun handshake request until we're done
uci1 56:0bba0ef15697 301 // (allowing it could lead to a stack overflow)
uci1 56:0bba0ef15697 302 fSendingInHandshake = true;
uci1 56:0bba0ef15697 303 SnSDUtils::SendAllOfRun(this, handshakeTimeout,
uci1 56:0bba0ef15697 304 genBuf, bsize, curConf, evt, pow,
uci1 56:0bba0ef15697 305 hndlen);
uci1 56:0bba0ef15697 306 fSendingInHandshake = false;
uci1 56:0bba0ef15697 307 res = SnCommWin::kOkStopComm;
uci1 56:0bba0ef15697 308 }
uci1 56:0bba0ef15697 309 } else if ( hndshk==SnHeaderFrame::kHnShOkRqPtRnCode ) {
uci1 56:0bba0ef15697 310 #ifdef DEBUG
uci1 56:0bba0ef15697 311 printf("part of run %u requested\r\n",hndlen);
uci1 56:0bba0ef15697 312 #endif
uci1 56:0bba0ef15697 313 // need the seq limits -- another handshake message
uci1 56:0bba0ef15697 314 SendHndshkReq(genBuf, handshakeTimeout);
uci1 56:0bba0ef15697 315 uint8_t shndshk(0); uint32_t shndshkLen(0);
uci1 56:0bba0ef15697 316 res = WaitHandshake(curConf, handshakeTimeout, genBuf, bsize, shndshk,
uci1 56:0bba0ef15697 317 &shndshkLen);
uci1 56:0bba0ef15697 318 if (SnCommWin::kOkWithMsg==res) {
uci1 56:0bba0ef15697 319 if ( shndshk==SnHeaderFrame::kHnShOkRqPtSqCode ) {
uci1 56:0bba0ef15697 320 // ok got the min/max seq's as expected
uci1 56:0bba0ef15697 321 const uint16_t minseq = GetMinSeqFrom(shndshkLen);
uci1 56:0bba0ef15697 322 const uint16_t maxseq = GetMaxSeqFrom(shndshkLen);
uci1 56:0bba0ef15697 323 #ifdef DEBUG
uci1 56:0bba0ef15697 324 printf("[minseq=%hu, maxseq=%hu]\r\n",minseq,maxseq);
uci1 56:0bba0ef15697 325 #endif
uci1 56:0bba0ef15697 326 if (fSendingInHandshake==false) {
uci1 56:0bba0ef15697 327 // prevent another SendAllOfRun handshake request
uci1 56:0bba0ef15697 328 // until we're done
uci1 56:0bba0ef15697 329 // (allowing it could lead to a stack overflow)
uci1 56:0bba0ef15697 330 fSendingInHandshake = true;
uci1 56:0bba0ef15697 331 SnSDUtils::SendPartOfRun(this, handshakeTimeout,
uci1 56:0bba0ef15697 332 genBuf, bsize, curConf, evt, pow,
uci1 56:0bba0ef15697 333 hndlen, // the run num
uci1 56:0bba0ef15697 334 minseq, maxseq);
uci1 56:0bba0ef15697 335 fSendingInHandshake = false;
uci1 56:0bba0ef15697 336 }
uci1 56:0bba0ef15697 337 }
uci1 56:0bba0ef15697 338 }
uci1 40:1324da35afd4 339 res = SnCommWin::kOkStopComm;
uci1 40:1324da35afd4 340 }
uci1 40:1324da35afd4 341
uci1 40:1324da35afd4 342 return res;
uci1 40:1324da35afd4 343 }
uci1 40:1324da35afd4 344
uci1 40:1324da35afd4 345
uci1 27:efc4d654b139 346 bool SnCommWin::GetDeleteAllConfirmCode(const SnConfigFrame& conf,
uci1 27:efc4d654b139 347 const uint32_t length,
uci1 27:efc4d654b139 348 const uint32_t timeout,
uci1 27:efc4d654b139 349 char* const buf,
uci1 27:efc4d654b139 350 const uint32_t bsize) {
uci1 27:efc4d654b139 351 bool ret = false;
uci1 27:efc4d654b139 352 #ifdef DEBUG
uci1 40:1324da35afd4 353 printf("GetDeleteAllConfirmCode, timeout=%u\r\n",timeout);
uci1 27:efc4d654b139 354 #endif
uci1 64:6c7a316eafad 355 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 356
uci1 27:efc4d654b139 357 // better pull all the bytes no matter the buffer size
uci1 27:efc4d654b139 358 const uint32_t ll = (bsize<length) ? bsize : length;
uci1 27:efc4d654b139 359 int mlen = 0;
uci1 27:efc4d654b139 360 while ( mlen<length ) {
uci1 40:1324da35afd4 361 mlen += fComm->ReceiveAll(buf, ll, timeout);
uci1 40:1324da35afd4 362 if (fComm->IsTimedOut(timeout)) {
uci1 27:efc4d654b139 363 break;
uci1 27:efc4d654b139 364 }
uci1 27:efc4d654b139 365 }
uci1 64:6c7a316eafad 366
uci1 64:6c7a316eafad 367 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 368
uci1 27:efc4d654b139 369 if (mlen==length) {
uci1 27:efc4d654b139 370 const char* b = buf;
uci1 27:efc4d654b139 371 const char* c = kDelAllConfCodeStr;
uci1 27:efc4d654b139 372 bool match = true;
uci1 27:efc4d654b139 373 for (uint8_t i=0; (i<kDelAllConfCodeLen) && match; ++i, ++b, ++c) {
uci1 27:efc4d654b139 374 match = ((*b)==(*c));
uci1 27:efc4d654b139 375 }
uci1 27:efc4d654b139 376 ret = match;
uci1 27:efc4d654b139 377 }
uci1 27:efc4d654b139 378 return ret;
uci1 27:efc4d654b139 379 }
uci1 27:efc4d654b139 380
uci1 21:ce51bb0ba4a5 381 SnCommWin::ECommWinResult SnCommWin::WaitHandshake(const SnConfigFrame& conf,
uci1 21:ce51bb0ba4a5 382 const uint32_t timeout,
uci1 8:95a325df1f6b 383 char* const buf,
uci1 8:95a325df1f6b 384 const uint32_t bsize,
uci1 27:efc4d654b139 385 uint8_t& hndShkCode,
uci1 27:efc4d654b139 386 uint32_t* hndShkLen) {
uci1 12:d472f9811262 387 #ifdef DEBUG
uci1 40:1324da35afd4 388 printf("WaitHandshake, timeout=%u\r\n",timeout);
uci1 12:d472f9811262 389 #endif
uci1 8:95a325df1f6b 390
uci1 64:6c7a316eafad 391 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 392
uci1 40:1324da35afd4 393 const int mlen = fComm->ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeout);
uci1 8:95a325df1f6b 394 if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) {
uci1 8:95a325df1f6b 395 uint32_t msgLen=0;
uci1 8:95a325df1f6b 396 const char* b = buf;
uci1 8:95a325df1f6b 397 SnHeaderFrame::ReadFrom(b, hndShkCode, msgLen);
uci1 12:d472f9811262 398 #ifdef DEBUG
uci1 12:d472f9811262 399 printf("got handshake code=%02x, len=%u\r\n",hndShkCode,msgLen);
uci1 12:d472f9811262 400 #endif
uci1 8:95a325df1f6b 401 if ((hndShkCode & SnHeaderFrame::kHndShkBits)!=0) {
uci1 27:efc4d654b139 402 if (hndShkLen!=0) {
uci1 27:efc4d654b139 403 *hndShkLen = msgLen;
uci1 27:efc4d654b139 404 }
uci1 8:95a325df1f6b 405 return SnCommWin::kOkWithMsg;
uci1 8:95a325df1f6b 406 } else {
uci1 8:95a325df1f6b 407 // TODO: somehow handle unexpected message?
uci1 8:95a325df1f6b 408 return SnCommWin::kUnexpectedRec;
uci1 8:95a325df1f6b 409 }
uci1 8:95a325df1f6b 410 }
uci1 8:95a325df1f6b 411 return SnCommWin::kOkNoMsg;
uci1 8:95a325df1f6b 412 }
uci1 8:95a325df1f6b 413
uci1 21:ce51bb0ba4a5 414 SnCommWin::ECommWinResult SnCommWin::GetFilename(const uint32_t timeout,
uci1 21:ce51bb0ba4a5 415 char* const buf,
uci1 21:ce51bb0ba4a5 416 const uint32_t namelen) {
uci1 21:ce51bb0ba4a5 417 // called by GetConfig upon receipt of a kMbedFilenameCode
uci1 21:ce51bb0ba4a5 418
uci1 21:ce51bb0ba4a5 419 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 420 printf("GetMbedFile, to=%u\r\n",timeout);
uci1 21:ce51bb0ba4a5 421 #endif
uci1 64:6c7a316eafad 422
uci1 64:6c7a316eafad 423 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 424
uci1 37:ff95e7070f26 425 const int mlen = fComm->ReceiveAll(buf, namelen, timeout);
uci1 21:ce51bb0ba4a5 426 if (mlen>0 && static_cast<uint32_t>(mlen) == namelen) {
uci1 21:ce51bb0ba4a5 427 return SnCommWin::kOkWithMsg;
uci1 21:ce51bb0ba4a5 428 }
uci1 21:ce51bb0ba4a5 429 return SnCommWin::kUnexpectedRec;
uci1 21:ce51bb0ba4a5 430 }
uci1 21:ce51bb0ba4a5 431
uci1 21:ce51bb0ba4a5 432 SnCommWin::ECommWinResult SnCommWin::GetLocalFile(std::string fname,
uci1 21:ce51bb0ba4a5 433 char* const buf,
uci1 21:ce51bb0ba4a5 434 const uint32_t bsize,
uci1 21:ce51bb0ba4a5 435 const uint32_t timeout) {
uci1 21:ce51bb0ba4a5 436 // get a file and save it locally with the specified name
uci1 21:ce51bb0ba4a5 437
uci1 64:6c7a316eafad 438 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 439
uci1 21:ce51bb0ba4a5 440 // get the header for the file
uci1 21:ce51bb0ba4a5 441 uint8_t mcode=0; uint32_t mlen=0;
uci1 21:ce51bb0ba4a5 442 SnCommWin::ECommWinResult res =
uci1 21:ce51bb0ba4a5 443 GetHeader(timeout, buf, bsize, mcode, mlen);
uci1 54:ea1234a44fe8 444 #ifdef DEBUG
uci1 54:ea1234a44fe8 445 printf("Got header code %x, len %u\r\n",mcode,mlen);
uci1 54:ea1234a44fe8 446 #endif
uci1 54:ea1234a44fe8 447
uci1 21:ce51bb0ba4a5 448 if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileCode) ) {
uci1 21:ce51bb0ba4a5 449 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 450 printf("Got mbed file header. File length = %u\r\n",mlen);
uci1 21:ce51bb0ba4a5 451 #endif
uci1 21:ce51bb0ba4a5 452 // got the header.. make the file..
uci1 21:ce51bb0ba4a5 453 // make the file name ALLCAPS, since LocalFileSystem will do it anyway
uci1 37:ff95e7070f26 454 SnCommPeripheral::CapitalizeInPlace(fname.begin(), fname.end());
uci1 21:ce51bb0ba4a5 455 // now ensure the file name is 8.3 only -- for LocalFileSystem
uci1 21:ce51bb0ba4a5 456 const size_t ldlen = strlen(kLocalDir);
uci1 21:ce51bb0ba4a5 457 // 12 = 8.3 filename format, 1 for / and 1 for \0
uci1 21:ce51bb0ba4a5 458 const uint32_t fbs = ldlen+1+12+1;
uci1 21:ce51bb0ba4a5 459 char fnb[fbs];
uci1 36:87865913ae6f 460 memset(fnb, 0, sizeof(char)*fbs);
uci1 64:6c7a316eafad 461
uci1 64:6c7a316eafad 462 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 463
uci1 40:1324da35afd4 464 // find the extension
uci1 40:1324da35afd4 465 const size_t xdot = fname.rfind('.');
uci1 40:1324da35afd4 466 if (xdot!=string::npos && (fname.size()==(4+xdot))) {
uci1 40:1324da35afd4 467 const size_t fnpl = (xdot>8) ? 8 : xdot;
uci1 40:1324da35afd4 468 char* fb = fnb;
uci1 40:1324da35afd4 469 memcpy(fb, kLocalDir, ldlen); fb+=ldlen; // /local
uci1 40:1324da35afd4 470 *fb = '/'; ++fb; // /
uci1 40:1324da35afd4 471 strncpy(fb, fname.c_str(), fnpl); fb+=fnpl; // FILENAME
uci1 40:1324da35afd4 472 *fb = '.'; ++fb; // .
uci1 40:1324da35afd4 473 strncpy(fb, fname.c_str()+xdot+1, 3); // EXT
uci1 64:6c7a316eafad 474
uci1 64:6c7a316eafad 475 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 476
uci1 40:1324da35afd4 477 // all that just for the file name!
uci1 40:1324da35afd4 478 FILE* lf = fopen(fnb,"wb");
uci1 21:ce51bb0ba4a5 479 #ifdef DEBUG
uci1 40:1324da35afd4 480 printf("tried to open file [%s]. lf=%p\r\n",fnb,(void*)lf);
uci1 21:ce51bb0ba4a5 481 #endif
uci1 40:1324da35afd4 482 // get all the data and dump it into the file
uci1 40:1324da35afd4 483 int b = 0, toget = 0;
uci1 40:1324da35afd4 484 while ( mlen>b ) {
uci1 40:1324da35afd4 485 if (fComm->IsTimedOut(timeout)) {
uci1 36:87865913ae6f 486 #ifdef DEBUG
uci1 40:1324da35afd4 487 printf("timeout while getting file\r\n");
uci1 36:87865913ae6f 488 #endif
uci1 40:1324da35afd4 489 res = kFailTimeout;
uci1 21:ce51bb0ba4a5 490 break;
uci1 21:ce51bb0ba4a5 491 }
uci1 40:1324da35afd4 492 toget = mlen - b;
uci1 40:1324da35afd4 493 if (toget>bsize) {
uci1 40:1324da35afd4 494 toget = bsize;
uci1 40:1324da35afd4 495 }
uci1 40:1324da35afd4 496 const int got = fComm->ReceiveAll(buf, toget, timeout);
uci1 40:1324da35afd4 497 if (lf!=NULL) {
uci1 36:87865913ae6f 498 #ifdef DEBUG
uci1 40:1324da35afd4 499 printf("writing %d bytes to file\r\n", got);
uci1 36:87865913ae6f 500 #endif
uci1 64:6c7a316eafad 501 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 502
uci1 40:1324da35afd4 503 SnBitUtils::WriteTo(lf, buf, got);
uci1 40:1324da35afd4 504 }
uci1 40:1324da35afd4 505 b += got;
uci1 40:1324da35afd4 506 } // file data receive loop
uci1 64:6c7a316eafad 507
uci1 64:6c7a316eafad 508 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 509
uci1 40:1324da35afd4 510 uint32_t crc=0;
uci1 40:1324da35afd4 511 if (lf!=NULL) {
uci1 40:1324da35afd4 512 // calculate the crc from what's actually in the file
uci1 40:1324da35afd4 513 fclose(lf); // to flush it
uci1 36:87865913ae6f 514 #ifdef DEBUG
uci1 40:1324da35afd4 515 printf("fopen: %s\r\n",fnb);
uci1 36:87865913ae6f 516 #endif
uci1 40:1324da35afd4 517 lf = fopen(fnb,"rb");
uci1 76:f8383f0292c2 518 if (lf!=0) {
uci1 76:f8383f0292c2 519 fseek(lf, 0, SEEK_END);
uci1 76:f8383f0292c2 520 int32_t fend = ftell(lf);
uci1 76:f8383f0292c2 521 fseek(lf, 0, SEEK_SET);
uci1 76:f8383f0292c2 522 char c;
uci1 76:f8383f0292c2 523 for (int32_t i=0; i<fend; ++i) {
uci1 76:f8383f0292c2 524
uci1 76:f8383f0292c2 525 Watchdog::kick(); // don't reset
uci1 76:f8383f0292c2 526
uci1 76:f8383f0292c2 527 SnBitUtils::ReadFrom(lf, c);
uci1 76:f8383f0292c2 528 if (feof(lf)==0 && ferror(lf)==0) {
uci1 76:f8383f0292c2 529 crc = SnCRCUtils::update_crc32_xfer(crc, c);
uci1 76:f8383f0292c2 530 } else {
uci1 76:f8383f0292c2 531 break;
uci1 76:f8383f0292c2 532 }
uci1 40:1324da35afd4 533 }
uci1 76:f8383f0292c2 534 fclose(lf);
uci1 21:ce51bb0ba4a5 535 }
uci1 40:1324da35afd4 536 #ifdef DEBUG
uci1 40:1324da35afd4 537 printf("closed file. crc = %u\r\n", crc);
uci1 40:1324da35afd4 538 #endif
uci1 40:1324da35afd4 539 } // if output file not 0
uci1 40:1324da35afd4 540 #ifdef DEBUG
uci1 40:1324da35afd4 541 printf("mlen=%u, b=%d, eq=%s\r\n",mlen,b,
uci1 40:1324da35afd4 542 (mlen==b)?"true":"false");
uci1 40:1324da35afd4 543 #endif
uci1 40:1324da35afd4 544 if ( mlen!=b ) {
uci1 40:1324da35afd4 545 if (res > kUnexpectedRec) {
uci1 40:1324da35afd4 546 res = kUnexpectedRec;
uci1 40:1324da35afd4 547 } // otherwise it's already worse
uci1 40:1324da35afd4 548 } else {
uci1 64:6c7a316eafad 549
uci1 64:6c7a316eafad 550 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 551
uci1 40:1324da35afd4 552 // check that the file is ok
uci1 40:1324da35afd4 553 // get the checksum
uci1 40:1324da35afd4 554 res = GetHeader(timeout, buf, bsize, mcode, mlen);
uci1 40:1324da35afd4 555 if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileChksCode) ) {
uci1 40:1324da35afd4 556 #ifdef DEBUG
uci1 40:1324da35afd4 557 printf("received chksum=%u, crc=%u, eq=%s\r\n",
uci1 40:1324da35afd4 558 mlen,crc,(crc==mlen)?"true":"false");
uci1 40:1324da35afd4 559 #endif
uci1 40:1324da35afd4 560 if (crc != mlen) {
uci1 36:87865913ae6f 561 #ifdef DEBUG
uci1 40:1324da35afd4 562 printf("checksums differ! unexpected.\r\n");
uci1 40:1324da35afd4 563 #endif
uci1 40:1324da35afd4 564 res = kUnexpectedRec; // important!
uci1 40:1324da35afd4 565 }
uci1 40:1324da35afd4 566 }
uci1 40:1324da35afd4 567 } // end get remote file checksum
uci1 40:1324da35afd4 568
uci1 40:1324da35afd4 569 if (lf!=NULL) {
uci1 40:1324da35afd4 570 if ( res<kOkWithMsg ) {
uci1 40:1324da35afd4 571 // timeout, bad checksum, something else bad?
uci1 40:1324da35afd4 572 #ifdef DEBUG
uci1 40:1324da35afd4 573 printf("removing %s\r\n",fnb);
uci1 36:87865913ae6f 574 #endif
uci1 40:1324da35afd4 575 remove(fnb); // delete the file
uci1 40:1324da35afd4 576 } else {
uci1 40:1324da35afd4 577 // if we got a new program, remove the old ones.
uci1 40:1324da35afd4 578 // (schedule myself for immediate de-resolution)
uci1 40:1324da35afd4 579 //
uci1 40:1324da35afd4 580 // first just count how many we would save
uci1 40:1324da35afd4 581 const uint16_t nSavedBins = LoopLocalDirBinFiles(false, fname);
uci1 36:87865913ae6f 582 #ifdef DEBUG
uci1 40:1324da35afd4 583 printf("nSavedBins=%hu",nSavedBins);
uci1 36:87865913ae6f 584 #endif
uci1 40:1324da35afd4 585 if (nSavedBins==1) {
uci1 40:1324da35afd4 586 // ok. new program will be the only one. remove the others
uci1 40:1324da35afd4 587 // hope the new program works!
uci1 40:1324da35afd4 588 LoopLocalDirBinFiles(true, fname);
uci1 36:87865913ae6f 589
uci1 36:87865913ae6f 590 #ifdef DEBUG
uci1 40:1324da35afd4 591 printf("rebooting\r\n");
uci1 36:87865913ae6f 592 #endif
uci1 40:1324da35afd4 593 // goodbye cruel world, it's over. walk on by...
uci1 40:1324da35afd4 594 mbed_reset();
uci1 40:1324da35afd4 595 }
uci1 40:1324da35afd4 596 } // end check new program block
uci1 40:1324da35afd4 597 } // if output file not 0
uci1 40:1324da35afd4 598 } else {
uci1 40:1324da35afd4 599 // filename mangled. either doesn't contain a '.'
uci1 40:1324da35afd4 600 // or the extension is longer than 3 letters
uci1 54:ea1234a44fe8 601 #ifdef DEBUG
uci1 54:ea1234a44fe8 602 printf("filname mangled. (%s) size=%u, xdot=%u",
uci1 54:ea1234a44fe8 603 fname.c_str(), fname.size(), xdot);
uci1 54:ea1234a44fe8 604 #endif
uci1 40:1324da35afd4 605 res = SnCommWin::kUnexpectedRec;
uci1 21:ce51bb0ba4a5 606 }
uci1 40:1324da35afd4 607 } // if header ok
uci1 54:ea1234a44fe8 608
uci1 21:ce51bb0ba4a5 609 return res;
uci1 21:ce51bb0ba4a5 610 }
uci1 21:ce51bb0ba4a5 611
uci1 21:ce51bb0ba4a5 612 int16_t SnCommWin::LoopLocalDirBinFiles(const bool doRemove,
uci1 21:ce51bb0ba4a5 613 const std::string& fname) {
uci1 21:ce51bb0ba4a5 614 // loop over the local directory, count the BIN files that match 'fname'
uci1 21:ce51bb0ba4a5 615 //
uci1 21:ce51bb0ba4a5 616 // fname is assumed to be all caps already!
uci1 21:ce51bb0ba4a5 617 //
uci1 21:ce51bb0ba4a5 618 // if doRemove==true, will actually delete non-matching files
uci1 21:ce51bb0ba4a5 619 //
uci1 21:ce51bb0ba4a5 620 // return number of non-matching files
uci1 64:6c7a316eafad 621
uci1 64:6c7a316eafad 622 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 623
uci1 21:ce51bb0ba4a5 624 uint16_t nSavedBins = 0;
uci1 21:ce51bb0ba4a5 625 DIR* d( opendir(kLocalDir) );
uci1 21:ce51bb0ba4a5 626 struct dirent* dent;
uci1 21:ce51bb0ba4a5 627 if ( d!=NULL ) {
uci1 21:ce51bb0ba4a5 628 while ( (dent = readdir(d))!=NULL ) {
uci1 64:6c7a316eafad 629
uci1 64:6c7a316eafad 630 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 631
uci1 21:ce51bb0ba4a5 632 const size_t flen = strlen(dent->d_name);
uci1 21:ce51bb0ba4a5 633 const char* dext = dent->d_name + flen - 4;
uci1 21:ce51bb0ba4a5 634 if ( strncmp(dext,".BIN",4)==0 || strncmp(dext,".bin",4)==0 ) {
uci1 21:ce51bb0ba4a5 635 // ends with .BIN
uci1 21:ce51bb0ba4a5 636 if (strncmp(dent->d_name, fname.c_str(), fname.size())!=0) {
uci1 21:ce51bb0ba4a5 637 // some other mbed program than our new one
uci1 21:ce51bb0ba4a5 638 std::string dfn(kLocalDir);
uci1 21:ce51bb0ba4a5 639 dfn += "/";
uci1 21:ce51bb0ba4a5 640 dfn += dent->d_name;
uci1 21:ce51bb0ba4a5 641 if (doRemove) {
uci1 21:ce51bb0ba4a5 642 remove(dfn.c_str());
uci1 21:ce51bb0ba4a5 643 }
uci1 21:ce51bb0ba4a5 644 } else {
uci1 21:ce51bb0ba4a5 645 ++nSavedBins;
uci1 21:ce51bb0ba4a5 646 }
uci1 21:ce51bb0ba4a5 647 } // else not an mbed program
uci1 21:ce51bb0ba4a5 648 }
uci1 21:ce51bb0ba4a5 649 closedir(d);
uci1 21:ce51bb0ba4a5 650 }
uci1 21:ce51bb0ba4a5 651 return nSavedBins;
uci1 21:ce51bb0ba4a5 652 }
uci1 21:ce51bb0ba4a5 653
uci1 21:ce51bb0ba4a5 654 SnCommWin::ECommWinResult SnCommWin::GetHeader(const uint32_t timeOut,
uci1 21:ce51bb0ba4a5 655 char* const buf,
uci1 21:ce51bb0ba4a5 656 const uint32_t bsize,
uci1 21:ce51bb0ba4a5 657 uint8_t& mcode,
uci1 21:ce51bb0ba4a5 658 uint32_t& mlen) {
uci1 21:ce51bb0ba4a5 659 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 64:6c7a316eafad 660
uci1 64:6c7a316eafad 661 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 662
uci1 21:ce51bb0ba4a5 663 if (bsize>=SnHeaderFrame::kMaxSizeOf) {
uci1 21:ce51bb0ba4a5 664 // get header
uci1 37:ff95e7070f26 665 const int hlen = fComm->ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeOut);
uci1 21:ce51bb0ba4a5 666 if (hlen>0 && static_cast<uint32_t>(hlen)==SnHeaderFrame::SizeOf()) {
uci1 21:ce51bb0ba4a5 667 mcode=0;
uci1 21:ce51bb0ba4a5 668 mlen=0;
uci1 21:ce51bb0ba4a5 669 const char* b = buf;
uci1 21:ce51bb0ba4a5 670 SnHeaderFrame::ReadFrom(b, mcode, mlen);
uci1 21:ce51bb0ba4a5 671 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 672 printf("mcode=%02x, mlen=%u\r\n", mcode, mlen);
uci1 21:ce51bb0ba4a5 673 #endif
uci1 21:ce51bb0ba4a5 674 res = SnCommWin::kOkWithMsg;
uci1 21:ce51bb0ba4a5 675 }
uci1 21:ce51bb0ba4a5 676 }
uci1 21:ce51bb0ba4a5 677 return res;
uci1 21:ce51bb0ba4a5 678 }
uci1 21:ce51bb0ba4a5 679
uci1 8:95a325df1f6b 680 SnCommWin::ECommWinResult SnCommWin::GetConfig(SnConfigFrame& conf,
uci1 8:95a325df1f6b 681 const uint32_t timeOut,
uci1 8:95a325df1f6b 682 char* const confBuf,
uci1 8:95a325df1f6b 683 const uint32_t bsize) {
uci1 8:95a325df1f6b 684 // confBuf assumed to alread be of allocated size
uci1 8:95a325df1f6b 685
uci1 12:d472f9811262 686 #ifdef DEBUG
uci1 8:95a325df1f6b 687 printf("GetConfig, to=%u\r\n",timeOut);
uci1 12:d472f9811262 688 #endif
uci1 8:95a325df1f6b 689
uci1 64:6c7a316eafad 690 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 691
uci1 8:95a325df1f6b 692 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 21:ce51bb0ba4a5 693 if (bsize>=SnConfigFrame::kMaxSizeOf) {
uci1 8:95a325df1f6b 694 // get header
uci1 21:ce51bb0ba4a5 695 uint8_t mcode=0; uint32_t mlen=0;
uci1 21:ce51bb0ba4a5 696 res = GetHeader(timeOut, confBuf, bsize, mcode, mlen);
uci1 21:ce51bb0ba4a5 697 if (res>=SnCommWin::kOkWithMsg) {
uci1 12:d472f9811262 698 if (mcode==SnHeaderFrame::kNoConfigCode) {
uci1 12:d472f9811262 699 // no config to get
uci1 16:744ce85aede2 700 res = SnCommWin::kOkWthMsgNoConf;
uci1 21:ce51bb0ba4a5 701 } else if (mcode==SnHeaderFrame::kMbedFilenameCode) {
uci1 21:ce51bb0ba4a5 702 res = GetFilename(timeOut, confBuf, mlen);
uci1 21:ce51bb0ba4a5 703 if (res>kAllFails) {
uci1 54:ea1234a44fe8 704 std::string fnameb(confBuf, mlen); // the filename
uci1 54:ea1234a44fe8 705 std::string fname(fnameb.c_str()); // mlen may include the \0 which would be counted in size()
uci1 21:ce51bb0ba4a5 706 #ifdef DEBUG
uci1 54:ea1234a44fe8 707 printf("got filename = [%s] (%u)\r\n", fname.c_str(), fname.size());
uci1 21:ce51bb0ba4a5 708 #endif
uci1 21:ce51bb0ba4a5 709 res = GetLocalFile(fname, confBuf, bsize, timeOut);
uci1 21:ce51bb0ba4a5 710 }
uci1 12:d472f9811262 711 } else if (mcode!=SnHeaderFrame::kConfigCode) {
uci1 8:95a325df1f6b 712 res = SnCommWin::kUnexpectedRec;
uci1 8:95a325df1f6b 713 } else {
uci1 8:95a325df1f6b 714 // get config
uci1 37:ff95e7070f26 715 const int clen = fComm->ReceiveAll(confBuf, mlen, timeOut);
uci1 8:95a325df1f6b 716 if (clen>0 && static_cast<uint32_t>(clen)==mlen) {
uci1 40:1324da35afd4 717 const uint8_t Rv = SnConfigFrame::PeekIOversion(confBuf);
uci1 40:1324da35afd4 718 if (SnConfigFrame::IsIOversionOk(Rv)) {
uci1 40:1324da35afd4 719 const char* b = confBuf;
uci1 40:1324da35afd4 720 conf.ReadFrom(b);
uci1 40:1324da35afd4 721 res = SnCommWin::kOkWithMsg;
uci1 40:1324da35afd4 722 } else {
uci1 40:1324da35afd4 723 res = SnCommWin::kUnexpectedRec;
uci1 40:1324da35afd4 724 char s[256];
uci1 40:1324da35afd4 725 sprintf(s,"Cannot accept config version [%hhu]. "
uci1 40:1324da35afd4 726 "Expect [%hhu].",Rv,SnConfigFrame::kIOVers);
uci1 40:1324da35afd4 727 SendString(s, timeOut);
uci1 40:1324da35afd4 728 }
uci1 8:95a325df1f6b 729 } else {
uci1 8:95a325df1f6b 730 res = SnCommWin::kUnexpectedRec;
uci1 8:95a325df1f6b 731 }
uci1 8:95a325df1f6b 732 }
uci1 8:95a325df1f6b 733 } else {
uci1 21:ce51bb0ba4a5 734 // not a problem if we get nothing (or no config)
uci1 16:744ce85aede2 735 res = SnCommWin::kOkNoMsg;
uci1 8:95a325df1f6b 736 }
uci1 8:95a325df1f6b 737 }
uci1 8:95a325df1f6b 738 return res;
uci1 8:95a325df1f6b 739 }
uci1 8:95a325df1f6b 740
uci1 40:1324da35afd4 741 int32_t SnCommWin::SendHndshkReq(char* const genBuf,
uci1 40:1324da35afd4 742 const uint32_t timeout_clock) {
uci1 40:1324da35afd4 743 // send a request demanding a handshake
uci1 40:1324da35afd4 744 // as we will be waiting for a response after this,
uci1 40:1324da35afd4 745 // FinishSending is also called
uci1 64:6c7a316eafad 746
uci1 64:6c7a316eafad 747 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 748
uci1 40:1324da35afd4 749 char* b = genBuf;
uci1 40:1324da35afd4 750 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kHnShDemandCode, 0);
uci1 40:1324da35afd4 751 const uint32_t bytesToBeSent = b-genBuf;
uci1 40:1324da35afd4 752 const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock);
uci1 40:1324da35afd4 753 const int32_t flen = fComm->FinishSending(timeout_clock);
uci1 40:1324da35afd4 754 #ifdef DEBUG
uci1 40:1324da35afd4 755 printf("SendHndshkReq: time = %u, timeout = %u, mlen=%d, flen=%d\r\n",
uci1 40:1324da35afd4 756 time(0), timeout_clock, mlen, flen);
uci1 40:1324da35afd4 757 #endif
uci1 40:1324da35afd4 758 return mlen+flen;
uci1 40:1324da35afd4 759 }
uci1 40:1324da35afd4 760
uci1 41:d6f5e2f09e07 761 SnCommWin::ECommWinResult SnCommWin::SendSignalStrength(char* const genBuf,
uci1 41:d6f5e2f09e07 762 SnSignalStrengthFrame& sigstr,
uci1 41:d6f5e2f09e07 763 const uint32_t timeout_clock) {
uci1 41:d6f5e2f09e07 764 // try to get the signal strength and send it if possible
uci1 64:6c7a316eafad 765
uci1 64:6c7a316eafad 766 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 767
uci1 41:d6f5e2f09e07 768 float ss;
uci1 41:d6f5e2f09e07 769 if ( fComm->CheckSignalStrength(timeout_clock, ss) ) {
uci1 41:d6f5e2f09e07 770 char* b = genBuf;
uci1 41:d6f5e2f09e07 771 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kSignalStrCode, sigstr.SizeOf());
uci1 41:d6f5e2f09e07 772 sigstr.SetSigStr(ss, time(0));
uci1 41:d6f5e2f09e07 773 sigstr.SetCommType( static_cast<uint8_t>(GetCommType()) );
uci1 41:d6f5e2f09e07 774 sigstr.WriteTo(b);
uci1 41:d6f5e2f09e07 775 const uint32_t bytesToBeSent = b - genBuf;
uci1 41:d6f5e2f09e07 776 const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock);
uci1 41:d6f5e2f09e07 777 const int32_t flen = fComm->FinishSending(timeout_clock);
uci1 41:d6f5e2f09e07 778 if (bytesToBeSent==(mlen+flen)) {
uci1 41:d6f5e2f09e07 779 return SnCommWin::kOkMsgSent;
uci1 41:d6f5e2f09e07 780 } else {
uci1 41:d6f5e2f09e07 781 return SnCommWin::kFailPartSent;
uci1 41:d6f5e2f09e07 782 }
uci1 41:d6f5e2f09e07 783 }
uci1 41:d6f5e2f09e07 784 return SnCommWin::kFailNoneSent;
uci1 41:d6f5e2f09e07 785 }
uci1 41:d6f5e2f09e07 786
uci1 8:95a325df1f6b 787 SnCommWin::ECommWinResult SnCommWin::SendStatus(const SnConfigFrame& conf,
uci1 8:95a325df1f6b 788 const SnEventFrame& evt,
uci1 8:95a325df1f6b 789 const SnPowerFrame& pow,
uci1 10:3c93db1cfb12 790 const uint16_t seq,
uci1 10:3c93db1cfb12 791 const float thmrate,
uci1 10:3c93db1cfb12 792 const float evtrate,
uci1 56:0bba0ef15697 793 const uint32_t powerOnTime,
uci1 56:0bba0ef15697 794 const SnTempFrame& temper,
uci1 8:95a325df1f6b 795 char* const genBuf,
uci1 8:95a325df1f6b 796 const uint32_t timeout_clock) {
uci1 8:95a325df1f6b 797 // TODO: check if connected?
uci1 12:d472f9811262 798 #ifdef DEBUG
uci1 12:d472f9811262 799 printf("########### Send Status\r\n");
uci1 12:d472f9811262 800 #endif
uci1 64:6c7a316eafad 801
uci1 64:6c7a316eafad 802 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 803
uci1 21:ce51bb0ba4a5 804 uint8_t loseLSB=0, loseMSB=0;
uci1 21:ce51bb0ba4a5 805 uint16_t wvBase=0;
uci1 21:ce51bb0ba4a5 806 conf.GetPackParsFor(GetCommType(), loseLSB, loseMSB, wvBase);
uci1 8:95a325df1f6b 807 const uint32_t ssize = SnStatusFrame::SizeOf(SnStatusFrame::kIOVers, conf);
uci1 8:95a325df1f6b 808 char* b = genBuf;
uci1 8:95a325df1f6b 809 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kStatusCode, ssize);
uci1 56:0bba0ef15697 810 SnStatusFrame::WriteTo(b, conf, evt, genBuf, seq, thmrate, evtrate,
uci1 56:0bba0ef15697 811 powerOnTime, temper,
uci1 21:ce51bb0ba4a5 812 loseLSB, loseMSB, wvBase);
uci1 10:3c93db1cfb12 813 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode,
uci1 10:3c93db1cfb12 814 pow.SizeOf(SnPowerFrame::kIOvers));
uci1 10:3c93db1cfb12 815 pow.WriteTo(b);
uci1 40:1324da35afd4 816 int32_t msiz = b-genBuf;
uci1 18:55f1581f2ee4 817 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 818 printf("calling SendAll (status)\r\n");
uci1 18:55f1581f2ee4 819 #endif
uci1 40:1324da35afd4 820 int32_t mlen = fComm->SendAll(genBuf, msiz, timeout_clock);
uci1 41:d6f5e2f09e07 821 #ifdef DEBUG
uci1 41:d6f5e2f09e07 822 printf("SendAll returned %d\r\n",mlen);
uci1 41:d6f5e2f09e07 823 #endif
uci1 40:1324da35afd4 824 mlen += fComm->FinishSending(timeout_clock);
uci1 8:95a325df1f6b 825 #ifdef DEBUG
uci1 41:d6f5e2f09e07 826 printf("mlen=%d after FinishSending. msiz=%d\r\n",mlen,msiz);
uci1 8:95a325df1f6b 827 printf("status frame:\r\n");
uci1 15:f2569d8e4176 828 for (uint32_t i=0; i<msiz; i++) {
uci1 8:95a325df1f6b 829 printf("%02X ",genBuf[i]);
uci1 8:95a325df1f6b 830 }
uci1 8:95a325df1f6b 831 printf("\r\n");
uci1 8:95a325df1f6b 832 #endif
uci1 8:95a325df1f6b 833 if (mlen==msiz) {
uci1 12:d472f9811262 834 #ifdef DEBUG
uci1 10:3c93db1cfb12 835 printf("status+power sent\r\n");
uci1 12:d472f9811262 836 #endif
uci1 64:6c7a316eafad 837
uci1 64:6c7a316eafad 838 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 839
uci1 21:ce51bb0ba4a5 840 // event compression parameters must be the same
uci1 21:ce51bb0ba4a5 841 // as those sent in the status update
uci1 8:95a325df1f6b 842 b = genBuf;
uci1 10:3c93db1cfb12 843 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode,
uci1 21:ce51bb0ba4a5 844 evt.SizeOf(SnEventFrame::kIOVers, loseLSB, loseMSB));
uci1 21:ce51bb0ba4a5 845 b = evt.WriteTo(b, loseLSB, loseMSB, wvBase);
uci1 21:ce51bb0ba4a5 846 msiz = b-genBuf;
uci1 16:744ce85aede2 847 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 848 printf("calling SendAll (event) %d:\r\n",msiz);
uci1 21:ce51bb0ba4a5 849 for (uint32_t i=0; i<msiz; i++) {
uci1 21:ce51bb0ba4a5 850 printf("%02X ",genBuf[i]);
uci1 21:ce51bb0ba4a5 851 }
uci1 21:ce51bb0ba4a5 852 printf("\r\n");
uci1 21:ce51bb0ba4a5 853 #endif
uci1 37:ff95e7070f26 854 mlen = fComm->SendAll(genBuf, msiz, timeout_clock);
uci1 40:1324da35afd4 855 mlen += fComm->FinishSending(timeout_clock);
uci1 21:ce51bb0ba4a5 856 if (mlen==msiz) {
uci1 21:ce51bb0ba4a5 857 return SnCommWin::kOkMsgSent;
uci1 21:ce51bb0ba4a5 858 }
uci1 8:95a325df1f6b 859 }
uci1 8:95a325df1f6b 860 return SnCommWin::kFailPartSent;
uci1 8:95a325df1f6b 861 }
uci1 8:95a325df1f6b 862
uci1 27:efc4d654b139 863
uci1 23:ccf39298f205 864 SnCommWin::ECommWinResult SnCommWin::SendString(const char* str,
uci1 23:ccf39298f205 865 const uint32_t timeout) {
uci1 23:ccf39298f205 866 #ifdef DEBUG
uci1 23:ccf39298f205 867 printf("SnCommWin::SendString %s\r\n",str);
uci1 23:ccf39298f205 868 #endif
uci1 64:6c7a316eafad 869 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 870
uci1 37:ff95e7070f26 871 const bool ok = fComm->SendString(str, timeout);
uci1 37:ff95e7070f26 872 return (ok) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
uci1 23:ccf39298f205 873 }
uci1 23:ccf39298f205 874
uci1 40:1324da35afd4 875 int32_t SnCommWin::SendFilename(const char* inf,
uci1 40:1324da35afd4 876 char* const genBuf,
uci1 40:1324da35afd4 877 int32_t& bytesToBeSent,
uci1 40:1324da35afd4 878 const uint32_t timeout_clock) {
uci1 12:d472f9811262 879 #ifdef DEBUG
uci1 12:d472f9811262 880 printf("SnCommWin::SendFilename %s\r\n",inf);
uci1 12:d472f9811262 881 #endif
uci1 64:6c7a316eafad 882
uci1 64:6c7a316eafad 883 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 884
uci1 12:d472f9811262 885 // remove the directory
uci1 12:d472f9811262 886 const char* fn = strrchr(inf, '/');
uci1 12:d472f9811262 887 if (fn==0) {
uci1 12:d472f9811262 888 // no directory
uci1 12:d472f9811262 889 fn = inf;
uci1 12:d472f9811262 890 } else if (fn!=inf) {
uci1 12:d472f9811262 891 ++fn; // move past the '/' if it was found
uci1 12:d472f9811262 892 }
uci1 12:d472f9811262 893 #ifdef DEBUG
uci1 12:d472f9811262 894 printf("send %s\r\n",fn);
uci1 12:d472f9811262 895 #endif
uci1 8:95a325df1f6b 896 const size_t flen = strlen(fn);
uci1 8:95a325df1f6b 897 char* b = genBuf;
uci1 8:95a325df1f6b 898 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFilenameCode, flen);
uci1 12:d472f9811262 899 b = SnBitUtils::WriteTo(b, fn, flen);
uci1 40:1324da35afd4 900 bytesToBeSent = b-genBuf;
uci1 40:1324da35afd4 901 const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock);
uci1 12:d472f9811262 902 #ifdef DEBUG
uci1 12:d472f9811262 903 printf("time = %u, timeout = %u\r\n",time(0), timeout_clock);
uci1 12:d472f9811262 904 #endif
uci1 40:1324da35afd4 905 return mlen;
uci1 8:95a325df1f6b 906 }
uci1 8:95a325df1f6b 907
uci1 40:1324da35afd4 908 int32_t SnCommWin::SendFileBlock(FILE* inf,
uci1 40:1324da35afd4 909 const uint8_t blockHeaderCode,
uci1 40:1324da35afd4 910 const uint32_t blockSize,
uci1 40:1324da35afd4 911 char* const genBuf,
uci1 40:1324da35afd4 912 int32_t& bytesToSend,
uci1 40:1324da35afd4 913 const uint32_t timeout) {
uci1 12:d472f9811262 914 // sends the block from the file. does not check if the file has sufficient bytes
uci1 12:d472f9811262 915 // this should be done before calling this function
uci1 12:d472f9811262 916 // (where the number of bytes in the file can be cached)
uci1 40:1324da35afd4 917 //
uci1 40:1324da35afd4 918 // bytesToSend will be set to the total bytes that should be delivered eventually
uci1 40:1324da35afd4 919 // the number of bytes actually shipped out by SendAll is returned
uci1 64:6c7a316eafad 920
uci1 64:6c7a316eafad 921 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 922
uci1 12:d472f9811262 923 char* b = genBuf;
uci1 12:d472f9811262 924 SnHeaderFrame::WriteTo(b, blockHeaderCode, blockSize);
uci1 12:d472f9811262 925 SnBitUtils::ReadFrom(inf, b, blockSize);
uci1 12:d472f9811262 926 #ifdef DEBUG
uci1 12:d472f9811262 927 printf("Sending block hc %02x, len=%u\r\n",blockHeaderCode,blockSize+SnHeaderFrame::SizeOf());
uci1 12:d472f9811262 928 #endif
uci1 40:1324da35afd4 929 bytesToSend = blockSize+SnHeaderFrame::SizeOf();
uci1 40:1324da35afd4 930 return fComm->SendAll(genBuf, bytesToSend, timeout);
uci1 12:d472f9811262 931 }
uci1 12:d472f9811262 932
uci1 40:1324da35afd4 933 int32_t SnCommWin::SendFileContents(FILE* inf,
uci1 40:1324da35afd4 934 const SnConfigFrame& curConf,
uci1 40:1324da35afd4 935 SnEventFrame& evt,
uci1 40:1324da35afd4 936 SnPowerFrame& pow,
uci1 40:1324da35afd4 937 char* const genBuf,
uci1 40:1324da35afd4 938 uint32_t nevts,
uci1 40:1324da35afd4 939 int32_t& bytesToBeSent,
uci1 40:1324da35afd4 940 const uint32_t timeout_clock) {
uci1 12:d472f9811262 941 // firstEvt==0 ==> start at beginning
uci1 12:d472f9811262 942 // nevts==0 ==> all events
uci1 40:1324da35afd4 943 //
uci1 40:1324da35afd4 944 // bytesToSend will be set to the total bytes that should be delivered eventually
uci1 40:1324da35afd4 945 // the number of bytes actually shipped out by SendAll is returned
uci1 12:d472f9811262 946
uci1 12:d472f9811262 947 #ifdef DEBUG
uci1 12:d472f9811262 948 printf("SendFileContents (byte streaming)\r\n");
uci1 12:d472f9811262 949 #endif
uci1 12:d472f9811262 950
uci1 64:6c7a316eafad 951 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 952
uci1 12:d472f9811262 953 // store position in file so we can go back to it afterwards
uci1 12:d472f9811262 954 // this is probably not necessary, because if this file is open
uci1 12:d472f9811262 955 // in write-only mode, we're screwed..
uci1 12:d472f9811262 956 const int fpos = ftell(inf);
uci1 12:d472f9811262 957 if (fpos>0) {
uci1 12:d472f9811262 958 fseek(inf, 0, SEEK_SET);
uci1 12:d472f9811262 959 }
uci1 12:d472f9811262 960 // how many bytes?
uci1 12:d472f9811262 961 fseek(inf, 0, SEEK_END); // go to end
uci1 12:d472f9811262 962 const int fend = ftell(inf);
uci1 12:d472f9811262 963 fseek(inf, 0, SEEK_SET); // go to start
uci1 12:d472f9811262 964 #ifdef DEBUG
uci1 12:d472f9811262 965 printf("fend=%d\r\n",fend);
uci1 12:d472f9811262 966 printf("fpos=%d\r\n",fpos);
uci1 12:d472f9811262 967 #endif
uci1 12:d472f9811262 968
uci1 12:d472f9811262 969 // variables used when sending data
uci1 12:d472f9811262 970 char* b = genBuf;
uci1 40:1324da35afd4 971 int32_t msiz(0), mlen(0), mtogo(0), tsent(0);
uci1 21:ce51bb0ba4a5 972 // count number of events / power readings sent
uci1 40:1324da35afd4 973 uint32_t evtsSent=0, powsSent=0, crc=0;
uci1 12:d472f9811262 974
uci1 64:6c7a316eafad 975 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 976
uci1 12:d472f9811262 977 // first is the file header, which has no SnHeaderFrame
uci1 12:d472f9811262 978 msiz = SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers);
uci1 12:d472f9811262 979 bool ok = (ftell(inf)+msiz)<=fend;
uci1 12:d472f9811262 980 if (ok) {
uci1 12:d472f9811262 981 mlen = SendFileBlock(inf, SnHeaderFrame::kFileHeadrCode,
uci1 40:1324da35afd4 982 msiz, genBuf, mtogo, timeout_clock);
uci1 40:1324da35afd4 983 //ok &= (msiz+SnHeaderFrame::SizeOf())==mlen;
uci1 40:1324da35afd4 984 bytesToBeSent += mtogo;
uci1 40:1324da35afd4 985 tsent += mlen;
uci1 12:d472f9811262 986 #ifdef DEBUG
uci1 12:d472f9811262 987 printf("sent file header. ok=%d\r\n",(int)ok);
uci1 12:d472f9811262 988 #endif
uci1 64:6c7a316eafad 989
uci1 64:6c7a316eafad 990 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 991
uci1 40:1324da35afd4 992 // calc crc w/o the header block of the file header, as
uci1 40:1324da35afd4 993 // this does not get stored in the file
uci1 40:1324da35afd4 994 crc = SnCRCUtils::GetUpdatedCRC32for(crc, genBuf+SnHeaderFrame::SizeOf(),
uci1 40:1324da35afd4 995 mtogo-SnHeaderFrame::SizeOf());
uci1 40:1324da35afd4 996
uci1 12:d472f9811262 997 // the header info for each block
uci1 40:1324da35afd4 998 uint8_t hcode(0);
uci1 40:1324da35afd4 999 uint32_t hlen(0);
uci1 12:d472f9811262 1000
uci1 12:d472f9811262 1001 // now just loop through file and send each block
uci1 18:55f1581f2ee4 1002 bool fok = true;
uci1 18:55f1581f2ee4 1003 while ( fok
uci1 12:d472f9811262 1004 && (feof(inf)==0)
uci1 12:d472f9811262 1005 && (ferror(inf)==0)
uci1 12:d472f9811262 1006 && ((ftell(inf)+SnHeaderFrame::SizeOf())<=fend) ) {
uci1 64:6c7a316eafad 1007
uci1 64:6c7a316eafad 1008 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 1009
uci1 12:d472f9811262 1010 // read the header for the block
uci1 12:d472f9811262 1011 SnSDUtils::ReadBlockHeader(inf, hcode, hlen);
uci1 18:55f1581f2ee4 1012 fok &= (ftell(inf)+hlen)<=fend;
uci1 12:d472f9811262 1013 #ifdef DEBUG
uci1 18:55f1581f2ee4 1014 printf("new block: hc=%02x, hl=%u, ftell=%d, fend=%d, "
uci1 18:55f1581f2ee4 1015 "ok=%d, fok=%d\r\n",
uci1 18:55f1581f2ee4 1016 hcode, hlen, ftell(inf), fend, (int)ok, (int)fok);
uci1 12:d472f9811262 1017 #endif
uci1 40:1324da35afd4 1018 if (fok) {
uci1 12:d472f9811262 1019 // send the block
uci1 12:d472f9811262 1020 // TODO: repack events?
uci1 40:1324da35afd4 1021 mlen = SendFileBlock(inf, hcode, hlen, genBuf,
uci1 40:1324da35afd4 1022 mtogo, timeout_clock);
uci1 40:1324da35afd4 1023 bytesToBeSent += mtogo;
uci1 40:1324da35afd4 1024 tsent += mlen;
uci1 40:1324da35afd4 1025 crc = SnCRCUtils::GetUpdatedCRC32for(crc, genBuf, mtogo);
uci1 40:1324da35afd4 1026
uci1 40:1324da35afd4 1027 if (hcode==SnHeaderFrame::kEventCode) {
uci1 40:1324da35afd4 1028 ++evtsSent;
uci1 40:1324da35afd4 1029 if (nevts>0) {
uci1 40:1324da35afd4 1030 if (evtsSent>=nevts) {
uci1 12:d472f9811262 1031 #ifdef DEBUG
uci1 56:0bba0ef15697 1032 printf("sent %u events. stop\r\n",evtsSent);
uci1 12:d472f9811262 1033 #endif
uci1 40:1324da35afd4 1034 break;
uci1 12:d472f9811262 1035 }
uci1 12:d472f9811262 1036 }
uci1 40:1324da35afd4 1037 } else if (hcode==SnHeaderFrame::kPowerCode) {
uci1 40:1324da35afd4 1038 ++powsSent;
uci1 40:1324da35afd4 1039 }
uci1 40:1324da35afd4 1040 } // otherwise file size not sufficient for this block
uci1 21:ce51bb0ba4a5 1041 } // loop over file contents
uci1 21:ce51bb0ba4a5 1042 } else {
uci1 21:ce51bb0ba4a5 1043 // otherwise file size not sufficient for file header
uci1 21:ce51bb0ba4a5 1044 // so it's either 0 or corrupted.
uci1 21:ce51bb0ba4a5 1045 // proceed as normal even tho no contents were sent.
uci1 21:ce51bb0ba4a5 1046 // if we're deleting files, this one will be deleted.
uci1 21:ce51bb0ba4a5 1047 ok = true;
uci1 21:ce51bb0ba4a5 1048 }
uci1 12:d472f9811262 1049 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1050 printf("loop done. ok=%d\r\n",(int)ok);
uci1 12:d472f9811262 1051 #endif
uci1 40:1324da35afd4 1052
uci1 64:6c7a316eafad 1053 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 1054
uci1 40:1324da35afd4 1055 // send the crc
uci1 40:1324da35afd4 1056 #ifdef DEBUG
uci1 40:1324da35afd4 1057 printf("sending crc (%u)\r\n",crc);
uci1 40:1324da35afd4 1058 #endif
uci1 40:1324da35afd4 1059 b = genBuf;
uci1 40:1324da35afd4 1060 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kMbedFileChksCode, sizeof(uint32_t));
uci1 40:1324da35afd4 1061 b = SnBitUtils::WriteTo(b, crc);
uci1 40:1324da35afd4 1062 msiz = b - genBuf;
uci1 40:1324da35afd4 1063 mlen = fComm->SendAll(genBuf, msiz, timeout_clock);
uci1 40:1324da35afd4 1064 bytesToBeSent += msiz;
uci1 40:1324da35afd4 1065 tsent += mlen;
uci1 40:1324da35afd4 1066
uci1 40:1324da35afd4 1067 #ifdef DEBUG
uci1 40:1324da35afd4 1068 printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen);
uci1 40:1324da35afd4 1069 #endif
uci1 40:1324da35afd4 1070
uci1 64:6c7a316eafad 1071 Watchdog::kick(); // don't reset
uci1 21:ce51bb0ba4a5 1072
uci1 21:ce51bb0ba4a5 1073 // send number of events sent
uci1 12:d472f9811262 1074 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1075 printf("sending evtsSent (%u)\r\n",evtsSent);
uci1 12:d472f9811262 1076 #endif
uci1 21:ce51bb0ba4a5 1077 b = genBuf;
uci1 21:ce51bb0ba4a5 1078 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t));
uci1 21:ce51bb0ba4a5 1079 b = SnBitUtils::WriteTo(b, evtsSent);
uci1 21:ce51bb0ba4a5 1080 msiz = b - genBuf;
uci1 37:ff95e7070f26 1081 mlen = fComm->SendAll(genBuf, msiz, timeout_clock);
uci1 40:1324da35afd4 1082 bytesToBeSent += msiz;
uci1 40:1324da35afd4 1083 tsent += mlen;
uci1 40:1324da35afd4 1084
uci1 18:55f1581f2ee4 1085 #ifdef DEBUG
uci1 40:1324da35afd4 1086 printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen);
uci1 18:55f1581f2ee4 1087 #endif
uci1 21:ce51bb0ba4a5 1088
uci1 64:6c7a316eafad 1089 Watchdog::kick(); // don't reset
uci1 64:6c7a316eafad 1090
uci1 21:ce51bb0ba4a5 1091 // send number of power readings sent
uci1 12:d472f9811262 1092 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1093 printf("sending powsSent (%u)\r\n",powsSent);
uci1 12:d472f9811262 1094 #endif
uci1 21:ce51bb0ba4a5 1095 b = genBuf;
uci1 21:ce51bb0ba4a5 1096 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t));
uci1 21:ce51bb0ba4a5 1097 b = SnBitUtils::WriteTo(b, powsSent);
uci1 21:ce51bb0ba4a5 1098 msiz = b - genBuf;
uci1 37:ff95e7070f26 1099 mlen = fComm->SendAll(genBuf, msiz, timeout_clock);
uci1 40:1324da35afd4 1100 bytesToBeSent += msiz;
uci1 40:1324da35afd4 1101 tsent += mlen;
uci1 21:ce51bb0ba4a5 1102
uci1 18:55f1581f2ee4 1103 #ifdef DEBUG
uci1 40:1324da35afd4 1104 printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen);
uci1 18:55f1581f2ee4 1105 #endif
uci1 12:d472f9811262 1106
uci1 12:d472f9811262 1107 // put file position back
uci1 12:d472f9811262 1108 fseek(inf, fpos, SEEK_SET);
uci1 12:d472f9811262 1109
uci1 12:d472f9811262 1110 #ifdef DEBUG
uci1 12:d472f9811262 1111 printf("end contents: ok=%d\r\n",(int)ok);
uci1 12:d472f9811262 1112 #endif
uci1 12:d472f9811262 1113
uci1 40:1324da35afd4 1114 return tsent;
uci1 8:95a325df1f6b 1115
uci1 40:1324da35afd4 1116 //return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
uci1 8:95a325df1f6b 1117 }