Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Oct 23 20:07:57 2012 +0000
Revision:
23:ccf39298f205
Parent:
21:ce51bb0ba4a5
Child:
24:7d725fc8201e
SBD communication enabled. Fix bug in which the SBD message number would be repeatedly increased upon failed sending attempts. Add check in SBD recv in case message is longer than buffer. Add SendString to SnCommWin

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 2:e67f7c158087 8 #include "SnSDUtils.h"
uci1 16:744ce85aede2 9 #include "SnConstants.h"
uci1 21:ce51bb0ba4a5 10 #include "SnCRCUtils.h"
uci1 21:ce51bb0ba4a5 11
uci1 21:ce51bb0ba4a5 12 #include <algorithm>
uci1 21:ce51bb0ba4a5 13 #include <ctype.h>
uci1 21:ce51bb0ba4a5 14 extern "C" void mbed_reset();
uci1 16:744ce85aede2 15
uci1 16:744ce85aede2 16 //#define DEBUG
uci1 16:744ce85aede2 17
uci1 16:744ce85aede2 18 uint32_t SnCommWin::GetConnectTimeout() const { return kConnectTimeout; }
uci1 16:744ce85aede2 19 uint32_t SnCommWin::GetListenTimeout() const { return kListenTimeout; }
uci1 2:e67f7c158087 20
uci1 12:d472f9811262 21 bool SnCommWin::IsTimedOut(const uint32_t timeout_clock) const {
uci1 16:744ce85aede2 22 if (timeout_clock==0) {
uci1 16:744ce85aede2 23 // for not obeying timeout option
uci1 16:744ce85aede2 24 return false;
uci1 16:744ce85aede2 25 } else {
uci1 16:744ce85aede2 26 const uint32_t ct = time(0);
uci1 16:744ce85aede2 27 if ( (ct==0) ||
uci1 16:744ce85aede2 28 (abs(static_cast<double>(timeout_clock-ct))>kSecsPerDay) ) {
uci1 16:744ce85aede2 29 // clock problems!
uci1 16:744ce85aede2 30 // timeout now. hope the clock problems
uci1 16:744ce85aede2 31 // get fixed in the next comm window
uci1 12:d472f9811262 32 return true;
uci1 16:744ce85aede2 33 } else {
uci1 16:744ce85aede2 34 return (ct>timeout_clock);
uci1 12:d472f9811262 35 }
uci1 12:d472f9811262 36 }
uci1 12:d472f9811262 37 }
uci1 12:d472f9811262 38
uci1 2:e67f7c158087 39 SnCommWin::ECommWinResult SnCommWin::SendData(SnConfigFrame& conf,
uci1 2:e67f7c158087 40 SnEventFrame& evt,
uci1 8:95a325df1f6b 41 SnPowerFrame& pow,
uci1 2:e67f7c158087 42 char* const genBuf,
uci1 3:24c5f0f50bf1 43 const uint32_t bsize,
uci1 12:d472f9811262 44 const uint32_t timeout,
uci1 12:d472f9811262 45 const uint32_t handshakeTimeout) {
uci1 12:d472f9811262 46 #ifdef DEBUG
uci1 3:24c5f0f50bf1 47 printf("SnCommWin::SendData\r\n");
uci1 12:d472f9811262 48 #endif
uci1 2:e67f7c158087 49 ECommWinResult res = kUndefFail;
uci1 15:f2569d8e4176 50 if ( (GetCommType() != SnConfigFrame::kIrid) ||
uci1 15:f2569d8e4176 51 (conf.IsForcingSBDdata()) ) {
uci1 15:f2569d8e4176 52 // only send large amounts if we're not communicating by Iridum,
uci1 15:f2569d8e4176 53 // or if we are being forced to send the data over SBD
uci1 15:f2569d8e4176 54 if (conf.IsSendingAllFiles()) {
uci1 12:d472f9811262 55 #ifdef DEBUG
uci1 15:f2569d8e4176 56 printf("sending all files\r\n");
uci1 12:d472f9811262 57 #endif
uci1 15:f2569d8e4176 58 res = SnSDUtils::SendAllFiles(this, timeout,
uci1 15:f2569d8e4176 59 genBuf, bsize, conf, evt, pow,
uci1 15:f2569d8e4176 60 handshakeTimeout);
uci1 15:f2569d8e4176 61 } else {
uci1 15:f2569d8e4176 62 if (conf.GetCommSendData()==0) {
uci1 12:d472f9811262 63 #ifdef DEBUG
uci1 15:f2569d8e4176 64 printf("no data to send\r\n");
uci1 12:d472f9811262 65 #endif
uci1 15:f2569d8e4176 66 res = kOkNoMsg;
uci1 15:f2569d8e4176 67 } else {
uci1 15:f2569d8e4176 68 const uint32_t nev = (conf.GetCommSendData()>0) ?
uci1 15:f2569d8e4176 69 conf.GetCommSendData() // send N events
uci1 15:f2569d8e4176 70 : 0u; // send all events in last file
uci1 12:d472f9811262 71 #ifdef DEBUG
uci1 16:744ce85aede2 72 printf("calling SendData. f=%s, nev=%u\r\n",SnSDUtils::GetCurFileName(), nev);
uci1 12:d472f9811262 73 #endif
uci1 15:f2569d8e4176 74 res = SendData(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(),
uci1 15:f2569d8e4176 75 conf, evt, pow, genBuf, bsize, nev, timeout, handshakeTimeout);
uci1 12:d472f9811262 76 #ifdef DEBUG
uci1 15:f2569d8e4176 77 printf("after send data cur file, res=%d\r\n",(int)res);
uci1 12:d472f9811262 78 #endif
uci1 15:f2569d8e4176 79 }
uci1 2:e67f7c158087 80 }
uci1 15:f2569d8e4176 81 } else {
uci1 15:f2569d8e4176 82 return kOkNoMsg;
uci1 2:e67f7c158087 83 }
uci1 2:e67f7c158087 84 return res;
uci1 2:e67f7c158087 85 }
uci1 2:e67f7c158087 86
uci1 2:e67f7c158087 87 SnCommWin::ECommWinResult SnCommWin::SendData(FILE* inf, const char* infn,
uci1 2:e67f7c158087 88 const SnConfigFrame& curConf,
uci1 2:e67f7c158087 89 SnEventFrame& evt,
uci1 8:95a325df1f6b 90 SnPowerFrame& pow,
uci1 2:e67f7c158087 91 char* const genBuf,
uci1 6:6f002d202f59 92 const uint32_t bsize,
uci1 2:e67f7c158087 93 const uint32_t nevts,
uci1 6:6f002d202f59 94 const uint32_t timeout_clock,
uci1 12:d472f9811262 95 const uint32_t handshakeTimeout) {
uci1 2:e67f7c158087 96 // nevts==0 ==> send all events
uci1 21:ce51bb0ba4a5 97 // handshakeTimeout is never a clock time -- always a delta(t)
uci1 2:e67f7c158087 98
uci1 12:d472f9811262 99 #ifdef DEBUG
uci1 12:d472f9811262 100 printf("SnCommWin::SendData file (%p), fn=%s\r\n",inf,infn);
uci1 12:d472f9811262 101 #endif
uci1 2:e67f7c158087 102 ECommWinResult res = kUndefFail;
uci1 12:d472f9811262 103 bool didDel = false;
uci1 2:e67f7c158087 104 if (inf!=0) {
uci1 12:d472f9811262 105 #ifdef DEBUG
uci1 12:d472f9811262 106 printf("sending file name %s\r\n",infn);
uci1 12:d472f9811262 107 #endif
uci1 16:744ce85aede2 108
uci1 6:6f002d202f59 109 // send the file name
uci1 6:6f002d202f59 110 res = SendFilename(infn, genBuf, timeout_clock);
uci1 3:24c5f0f50bf1 111 if (res>kAllFails) {
uci1 6:6f002d202f59 112 if (genBuf!=0) {
uci1 12:d472f9811262 113 #ifdef DEBUG
uci1 12:d472f9811262 114 printf("calling send file contents\r\n");
uci1 12:d472f9811262 115 #endif
uci1 16:744ce85aede2 116
uci1 6:6f002d202f59 117 // send the contents
uci1 8:95a325df1f6b 118 res = SendFileContents(inf, curConf, evt, pow, genBuf,
uci1 12:d472f9811262 119 nevts, timeout_clock);
uci1 12:d472f9811262 120 #ifdef DEBUG
uci1 12:d472f9811262 121 printf("res=%d (fails=%d)\r\n",(int)res,(int)kAllFails);
uci1 12:d472f9811262 122 #endif
uci1 12:d472f9811262 123 if (res>kAllFails) {
uci1 12:d472f9811262 124 #ifdef DEBUG
uci1 12:d472f9811262 125 printf("calling wait handshake\r\n");
uci1 12:d472f9811262 126 #endif
uci1 6:6f002d202f59 127 // wait for handshake
uci1 6:6f002d202f59 128 uint8_t hndshk=0;
uci1 21:ce51bb0ba4a5 129 res = WaitHandshake(curConf, handshakeTimeout, genBuf, bsize, hndshk);
uci1 21:ce51bb0ba4a5 130 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 131 printf("res=%d, nevts=%u, isdel=%d, inf=%p, curfile=%p, hndshk=%02x\r\n",
uci1 21:ce51bb0ba4a5 132 res, nevts, curConf.IsDeletingFiles(), inf,
uci1 21:ce51bb0ba4a5 133 SnSDUtils::GetCurFile(), hndshk);
uci1 21:ce51bb0ba4a5 134 #endif
uci1 6:6f002d202f59 135 if ( (res==SnCommWin::kOkWithMsg) // got handshake
uci1 6:6f002d202f59 136 && (nevts==0) // sent whole file
uci1 6:6f002d202f59 137 && curConf.IsDeletingFiles() // want to delete
uci1 12:d472f9811262 138 && (inf!=SnSDUtils::GetCurFile()) // not current file
uci1 6:6f002d202f59 139 && (hndshk==SnHeaderFrame::kHnShOkComplCode)) { // whole file received
uci1 6:6f002d202f59 140 // delete it
uci1 21:ce51bb0ba4a5 141 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 142 printf("deleting file %p, %s\r\n",inf,infn);
uci1 21:ce51bb0ba4a5 143 #endif
uci1 6:6f002d202f59 144 SnSDUtilsWhisperer::DeleteFile(inf, infn);
uci1 12:d472f9811262 145 didDel=true;
uci1 6:6f002d202f59 146 }
uci1 3:24c5f0f50bf1 147 }
uci1 2:e67f7c158087 148 }
uci1 2:e67f7c158087 149 }
uci1 12:d472f9811262 150 } else {
uci1 12:d472f9811262 151 #ifdef DEBUG
uci1 12:d472f9811262 152 printf("inf=0!\r\n");
uci1 12:d472f9811262 153 #endif
uci1 12:d472f9811262 154 }
uci1 12:d472f9811262 155 if ( (inf!=SnSDUtils::GetCurFile()) && (didDel==false) ) {
uci1 12:d472f9811262 156 SnSDUtils::CloseOutputFile(inf);
uci1 2:e67f7c158087 157 }
uci1 2:e67f7c158087 158 return res;
uci1 2:e67f7c158087 159 }
uci1 8:95a325df1f6b 160
uci1 21:ce51bb0ba4a5 161 SnCommWin::ECommWinResult SnCommWin::WaitHandshake(const SnConfigFrame& conf,
uci1 21:ce51bb0ba4a5 162 const uint32_t timeout,
uci1 8:95a325df1f6b 163 char* const buf,
uci1 8:95a325df1f6b 164 const uint32_t bsize,
uci1 8:95a325df1f6b 165 uint8_t& hndShkCode) {
uci1 12:d472f9811262 166 // ensure we don't wait forever
uci1 21:ce51bb0ba4a5 167 const uint32_t to = ((timeout>0) && (timeout<kAbsMaxTimer))
uci1 21:ce51bb0ba4a5 168 ? conf.GetTimeoutTime(time(0), timeout)
uci1 21:ce51bb0ba4a5 169 : conf.GetTimeoutTime(time(0), kListenTimeout);
uci1 12:d472f9811262 170 #ifdef DEBUG
uci1 12:d472f9811262 171 printf("WaitHandshake, to=%u\r\n",to);
uci1 12:d472f9811262 172 #endif
uci1 8:95a325df1f6b 173
uci1 12:d472f9811262 174 const int mlen = ReceiveAll(buf, SnHeaderFrame::SizeOf(), to);
uci1 8:95a325df1f6b 175 if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) {
uci1 8:95a325df1f6b 176 uint32_t msgLen=0;
uci1 8:95a325df1f6b 177 const char* b = buf;
uci1 8:95a325df1f6b 178 SnHeaderFrame::ReadFrom(b, hndShkCode, msgLen);
uci1 12:d472f9811262 179 #ifdef DEBUG
uci1 12:d472f9811262 180 printf("got handshake code=%02x, len=%u\r\n",hndShkCode,msgLen);
uci1 12:d472f9811262 181 #endif
uci1 8:95a325df1f6b 182 if ((hndShkCode & SnHeaderFrame::kHndShkBits)!=0) {
uci1 8:95a325df1f6b 183 return SnCommWin::kOkWithMsg;
uci1 8:95a325df1f6b 184 } else {
uci1 8:95a325df1f6b 185 // TODO: somehow handle unexpected message?
uci1 8:95a325df1f6b 186 return SnCommWin::kUnexpectedRec;
uci1 8:95a325df1f6b 187 }
uci1 8:95a325df1f6b 188 }
uci1 8:95a325df1f6b 189 return SnCommWin::kOkNoMsg;
uci1 8:95a325df1f6b 190 }
uci1 8:95a325df1f6b 191
uci1 21:ce51bb0ba4a5 192 SnCommWin::ECommWinResult SnCommWin::GetFilename(const uint32_t timeout,
uci1 21:ce51bb0ba4a5 193 char* const buf,
uci1 21:ce51bb0ba4a5 194 const uint32_t namelen) {
uci1 21:ce51bb0ba4a5 195 // called by GetConfig upon receipt of a kMbedFilenameCode
uci1 21:ce51bb0ba4a5 196
uci1 21:ce51bb0ba4a5 197 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 198 printf("GetMbedFile, to=%u\r\n",timeout);
uci1 21:ce51bb0ba4a5 199 #endif
uci1 21:ce51bb0ba4a5 200 const int mlen = ReceiveAll(buf, namelen, timeout);
uci1 21:ce51bb0ba4a5 201 if (mlen>0 && static_cast<uint32_t>(mlen) == namelen) {
uci1 21:ce51bb0ba4a5 202 return SnCommWin::kOkWithMsg;
uci1 21:ce51bb0ba4a5 203 }
uci1 21:ce51bb0ba4a5 204 return SnCommWin::kUnexpectedRec;
uci1 21:ce51bb0ba4a5 205 }
uci1 21:ce51bb0ba4a5 206
uci1 21:ce51bb0ba4a5 207 SnCommWin::ECommWinResult SnCommWin::GetLocalFile(std::string fname,
uci1 21:ce51bb0ba4a5 208 char* const buf,
uci1 21:ce51bb0ba4a5 209 const uint32_t bsize,
uci1 21:ce51bb0ba4a5 210 const uint32_t timeout) {
uci1 21:ce51bb0ba4a5 211 // get a file and save it locally with the specified name
uci1 21:ce51bb0ba4a5 212
uci1 21:ce51bb0ba4a5 213 // get the header for the file
uci1 21:ce51bb0ba4a5 214 uint8_t mcode=0; uint32_t mlen=0;
uci1 21:ce51bb0ba4a5 215 SnCommWin::ECommWinResult res =
uci1 21:ce51bb0ba4a5 216 GetHeader(timeout, buf, bsize, mcode, mlen);
uci1 21:ce51bb0ba4a5 217 if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileCode) ) {
uci1 21:ce51bb0ba4a5 218 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 219 printf("Got mbed file header. File length = %u\r\n",mlen);
uci1 21:ce51bb0ba4a5 220 #endif
uci1 21:ce51bb0ba4a5 221 // got the header.. make the file..
uci1 21:ce51bb0ba4a5 222 // make the file name ALLCAPS, since LocalFileSystem will do it anyway
uci1 21:ce51bb0ba4a5 223 std::transform(fname.begin(), fname.end(), fname.begin(), toupper);
uci1 21:ce51bb0ba4a5 224 // now ensure the file name is 8.3 only -- for LocalFileSystem
uci1 21:ce51bb0ba4a5 225 const size_t ldlen = strlen(kLocalDir);
uci1 21:ce51bb0ba4a5 226 // 12 = 8.3 filename format, 1 for / and 1 for \0
uci1 21:ce51bb0ba4a5 227 const uint32_t fbs = ldlen+1+12+1;
uci1 21:ce51bb0ba4a5 228 char fnb[fbs];
uci1 21:ce51bb0ba4a5 229 char* fb = fnb;
uci1 21:ce51bb0ba4a5 230 memcpy(fb, kLocalDir, ldlen); fb+=ldlen; // /local
uci1 21:ce51bb0ba4a5 231 memset(fb, '/', 1); fb+=1; // /
uci1 21:ce51bb0ba4a5 232 strncpy(fb, fname.c_str(), 8); fb+=8; // FILENAME
uci1 21:ce51bb0ba4a5 233 *fb = '.'; ++fb; // .
uci1 21:ce51bb0ba4a5 234 strncpy(fb, fname.c_str()+fname.size()-3, 3); // EXT
uci1 21:ce51bb0ba4a5 235 // all that just for the file name!
uci1 21:ce51bb0ba4a5 236 FILE* lf = fopen(fnb,"wb");
uci1 21:ce51bb0ba4a5 237 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 238 printf("tried to open file [%s]. lf=%p\r\n",fnb,(void*)lf);
uci1 21:ce51bb0ba4a5 239 #endif
uci1 21:ce51bb0ba4a5 240 // get all the data and dump it into the file
uci1 21:ce51bb0ba4a5 241 int b = 0, toget = 0;
uci1 21:ce51bb0ba4a5 242 while ( mlen>b ) {
uci1 21:ce51bb0ba4a5 243 if (IsTimedOut(timeout)) {
uci1 21:ce51bb0ba4a5 244 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 245 printf("timeout while getting file\r\n");
uci1 21:ce51bb0ba4a5 246 #endif
uci1 21:ce51bb0ba4a5 247 res = kFailTimeout;
uci1 21:ce51bb0ba4a5 248 break;
uci1 21:ce51bb0ba4a5 249 }
uci1 21:ce51bb0ba4a5 250 toget = mlen - b;
uci1 21:ce51bb0ba4a5 251 if (toget>bsize) {
uci1 21:ce51bb0ba4a5 252 toget = bsize;
uci1 21:ce51bb0ba4a5 253 }
uci1 21:ce51bb0ba4a5 254 const int got = ReceiveAll(buf, toget, timeout);
uci1 21:ce51bb0ba4a5 255 if (lf!=NULL) {
uci1 21:ce51bb0ba4a5 256 SnBitUtils::WriteTo(lf, buf, got);
uci1 21:ce51bb0ba4a5 257 }
uci1 21:ce51bb0ba4a5 258 b += got;
uci1 21:ce51bb0ba4a5 259 }
uci1 21:ce51bb0ba4a5 260 uint32_t crc=0;
uci1 21:ce51bb0ba4a5 261 if (lf!=NULL) {
uci1 21:ce51bb0ba4a5 262 // calculate the crc from what's actually in the file
uci1 21:ce51bb0ba4a5 263 fclose(lf); // to flush it
uci1 21:ce51bb0ba4a5 264 lf = fopen(fnb,"rb");
uci1 21:ce51bb0ba4a5 265 fseek(lf, 0, SEEK_END);
uci1 21:ce51bb0ba4a5 266 int32_t fend = ftell(lf);
uci1 21:ce51bb0ba4a5 267 fseek(lf, 0, SEEK_SET);
uci1 21:ce51bb0ba4a5 268 char c;
uci1 21:ce51bb0ba4a5 269 for (int32_t i=0; i<fend; ++i) {
uci1 21:ce51bb0ba4a5 270 SnBitUtils::ReadFrom(lf, c);
uci1 21:ce51bb0ba4a5 271 if (feof(lf)==0 && ferror(lf)==0) {
uci1 21:ce51bb0ba4a5 272 crc = update_crc32_xfer(crc, c);
uci1 21:ce51bb0ba4a5 273 } else {
uci1 21:ce51bb0ba4a5 274 break;
uci1 21:ce51bb0ba4a5 275 }
uci1 21:ce51bb0ba4a5 276 }
uci1 21:ce51bb0ba4a5 277 fclose(lf);
uci1 21:ce51bb0ba4a5 278 }
uci1 21:ce51bb0ba4a5 279 if ( mlen!=b ) {
uci1 21:ce51bb0ba4a5 280 if (res > kUnexpectedRec) {
uci1 21:ce51bb0ba4a5 281 res = kUnexpectedRec;
uci1 21:ce51bb0ba4a5 282 } // otherwise it's already worse
uci1 21:ce51bb0ba4a5 283 } else {
uci1 21:ce51bb0ba4a5 284 // check that the file is ok
uci1 21:ce51bb0ba4a5 285 // get the checksum
uci1 21:ce51bb0ba4a5 286 res = GetHeader(timeout, buf, bsize, mcode, mlen);
uci1 21:ce51bb0ba4a5 287 if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileChksCode) ) {
uci1 21:ce51bb0ba4a5 288 if (crc != mlen) {
uci1 21:ce51bb0ba4a5 289 res = kUnexpectedRec; // important!
uci1 21:ce51bb0ba4a5 290 }
uci1 21:ce51bb0ba4a5 291 }
uci1 21:ce51bb0ba4a5 292 }
uci1 21:ce51bb0ba4a5 293 //TODO: REMOVE
uci1 21:ce51bb0ba4a5 294 /*
uci1 21:ce51bb0ba4a5 295 char dbg[250]; memset(dbg, 0, 250);
uci1 21:ce51bb0ba4a5 296 char* dd = buf;
uci1 21:ce51bb0ba4a5 297 sprintf(dbg,"lf=%s (%p), my crc=%d, b=%d, mlen=%d\r\n",fnb,(void*)lf,crc,crc,b,mlen);
uci1 21:ce51bb0ba4a5 298 SnHeaderFrame::WriteTo(dd, SnHeaderFrame::kStringCode, strlen(dbg));
uci1 21:ce51bb0ba4a5 299 strcpy(buf+SnHeaderFrame::SizeOf(),dbg);
uci1 21:ce51bb0ba4a5 300 SendAll(buf, SnHeaderFrame::SizeOf() + strlen(dbg), timeout);
uci1 21:ce51bb0ba4a5 301 */
uci1 21:ce51bb0ba4a5 302 ///////////
uci1 21:ce51bb0ba4a5 303 if (lf!=NULL) {
uci1 21:ce51bb0ba4a5 304 if ( res<kOkWithMsg ) {
uci1 21:ce51bb0ba4a5 305 // timeout, bad checksum, something else bad?
uci1 21:ce51bb0ba4a5 306 remove(fnb); // delete the file
uci1 21:ce51bb0ba4a5 307 } else {
uci1 21:ce51bb0ba4a5 308 // if we got a new program, remove the old ones.
uci1 21:ce51bb0ba4a5 309 // (schedule myself for immediate de-resolution)
uci1 21:ce51bb0ba4a5 310 //
uci1 21:ce51bb0ba4a5 311 // first just count how many we would save
uci1 21:ce51bb0ba4a5 312 const uint16_t nSavedBins = LoopLocalDirBinFiles(false, fname);
uci1 21:ce51bb0ba4a5 313 if (nSavedBins==1) {
uci1 21:ce51bb0ba4a5 314 // ok. new program will be the only one. remove the others
uci1 21:ce51bb0ba4a5 315 // hope the new program works!
uci1 21:ce51bb0ba4a5 316 LoopLocalDirBinFiles(true, fname);
uci1 21:ce51bb0ba4a5 317
uci1 21:ce51bb0ba4a5 318 // goodbye cruel world, it's over. walk on by...
uci1 21:ce51bb0ba4a5 319 mbed_reset();
uci1 21:ce51bb0ba4a5 320 }
uci1 21:ce51bb0ba4a5 321 }
uci1 21:ce51bb0ba4a5 322 }
uci1 21:ce51bb0ba4a5 323 }
uci1 21:ce51bb0ba4a5 324
uci1 21:ce51bb0ba4a5 325 return res;
uci1 21:ce51bb0ba4a5 326 }
uci1 21:ce51bb0ba4a5 327
uci1 21:ce51bb0ba4a5 328 int16_t SnCommWin::LoopLocalDirBinFiles(const bool doRemove,
uci1 21:ce51bb0ba4a5 329 const std::string& fname) {
uci1 21:ce51bb0ba4a5 330 // loop over the local directory, count the BIN files that match 'fname'
uci1 21:ce51bb0ba4a5 331 //
uci1 21:ce51bb0ba4a5 332 // fname is assumed to be all caps already!
uci1 21:ce51bb0ba4a5 333 //
uci1 21:ce51bb0ba4a5 334 // if doRemove==true, will actually delete non-matching files
uci1 21:ce51bb0ba4a5 335 //
uci1 21:ce51bb0ba4a5 336 // return number of non-matching files
uci1 21:ce51bb0ba4a5 337 uint16_t nSavedBins = 0;
uci1 21:ce51bb0ba4a5 338 DIR* d( opendir(kLocalDir) );
uci1 21:ce51bb0ba4a5 339 struct dirent* dent;
uci1 21:ce51bb0ba4a5 340 if ( d!=NULL ) {
uci1 21:ce51bb0ba4a5 341 while ( (dent = readdir(d))!=NULL ) {
uci1 21:ce51bb0ba4a5 342 const size_t flen = strlen(dent->d_name);
uci1 21:ce51bb0ba4a5 343 const char* dext = dent->d_name + flen - 4;
uci1 21:ce51bb0ba4a5 344 if ( strncmp(dext,".BIN",4)==0 || strncmp(dext,".bin",4)==0 ) {
uci1 21:ce51bb0ba4a5 345 // ends with .BIN
uci1 21:ce51bb0ba4a5 346 if (strncmp(dent->d_name, fname.c_str(), fname.size())!=0) {
uci1 21:ce51bb0ba4a5 347 // some other mbed program than our new one
uci1 21:ce51bb0ba4a5 348 std::string dfn(kLocalDir);
uci1 21:ce51bb0ba4a5 349 dfn += "/";
uci1 21:ce51bb0ba4a5 350 dfn += dent->d_name;
uci1 21:ce51bb0ba4a5 351 if (doRemove) {
uci1 21:ce51bb0ba4a5 352 remove(dfn.c_str());
uci1 21:ce51bb0ba4a5 353 }
uci1 21:ce51bb0ba4a5 354 } else {
uci1 21:ce51bb0ba4a5 355 ++nSavedBins;
uci1 21:ce51bb0ba4a5 356 }
uci1 21:ce51bb0ba4a5 357 } // else not an mbed program
uci1 21:ce51bb0ba4a5 358 }
uci1 21:ce51bb0ba4a5 359 closedir(d);
uci1 21:ce51bb0ba4a5 360 }
uci1 21:ce51bb0ba4a5 361 return nSavedBins;
uci1 21:ce51bb0ba4a5 362 }
uci1 21:ce51bb0ba4a5 363
uci1 21:ce51bb0ba4a5 364 SnCommWin::ECommWinResult SnCommWin::GetHeader(const uint32_t timeOut,
uci1 21:ce51bb0ba4a5 365 char* const buf,
uci1 21:ce51bb0ba4a5 366 const uint32_t bsize,
uci1 21:ce51bb0ba4a5 367 uint8_t& mcode,
uci1 21:ce51bb0ba4a5 368 uint32_t& mlen) {
uci1 21:ce51bb0ba4a5 369 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 21:ce51bb0ba4a5 370 if (bsize>=SnHeaderFrame::kMaxSizeOf) {
uci1 21:ce51bb0ba4a5 371 // get header
uci1 21:ce51bb0ba4a5 372 const int hlen = ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeOut);
uci1 21:ce51bb0ba4a5 373 if (hlen>0 && static_cast<uint32_t>(hlen)==SnHeaderFrame::SizeOf()) {
uci1 21:ce51bb0ba4a5 374 mcode=0;
uci1 21:ce51bb0ba4a5 375 mlen=0;
uci1 21:ce51bb0ba4a5 376 const char* b = buf;
uci1 21:ce51bb0ba4a5 377 SnHeaderFrame::ReadFrom(b, mcode, mlen);
uci1 21:ce51bb0ba4a5 378 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 379 printf("mcode=%02x, mlen=%u\r\n", mcode, mlen);
uci1 21:ce51bb0ba4a5 380 #endif
uci1 21:ce51bb0ba4a5 381 res = SnCommWin::kOkWithMsg;
uci1 21:ce51bb0ba4a5 382 }
uci1 21:ce51bb0ba4a5 383 }
uci1 21:ce51bb0ba4a5 384 return res;
uci1 21:ce51bb0ba4a5 385 }
uci1 21:ce51bb0ba4a5 386
uci1 8:95a325df1f6b 387 SnCommWin::ECommWinResult SnCommWin::GetConfig(SnConfigFrame& conf,
uci1 8:95a325df1f6b 388 const uint32_t timeOut,
uci1 8:95a325df1f6b 389 char* const confBuf,
uci1 8:95a325df1f6b 390 const uint32_t bsize) {
uci1 8:95a325df1f6b 391 // confBuf assumed to alread be of allocated size
uci1 8:95a325df1f6b 392
uci1 12:d472f9811262 393 #ifdef DEBUG
uci1 8:95a325df1f6b 394 printf("GetConfig, to=%u\r\n",timeOut);
uci1 12:d472f9811262 395 #endif
uci1 8:95a325df1f6b 396
uci1 8:95a325df1f6b 397 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 21:ce51bb0ba4a5 398 if (bsize>=SnConfigFrame::kMaxSizeOf) {
uci1 8:95a325df1f6b 399 // get header
uci1 21:ce51bb0ba4a5 400 uint8_t mcode=0; uint32_t mlen=0;
uci1 21:ce51bb0ba4a5 401 res = GetHeader(timeOut, confBuf, bsize, mcode, mlen);
uci1 21:ce51bb0ba4a5 402 if (res>=SnCommWin::kOkWithMsg) {
uci1 12:d472f9811262 403 if (mcode==SnHeaderFrame::kNoConfigCode) {
uci1 12:d472f9811262 404 // no config to get
uci1 16:744ce85aede2 405 res = SnCommWin::kOkWthMsgNoConf;
uci1 21:ce51bb0ba4a5 406 } else if (mcode==SnHeaderFrame::kMbedFilenameCode) {
uci1 21:ce51bb0ba4a5 407 res = GetFilename(timeOut, confBuf, mlen);
uci1 21:ce51bb0ba4a5 408 if (res>kAllFails) {
uci1 21:ce51bb0ba4a5 409 std::string fname(confBuf, mlen); // the filename
uci1 21:ce51bb0ba4a5 410 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 411 printf("got filename = [%s]\r\n", fname.c_str());
uci1 21:ce51bb0ba4a5 412 #endif
uci1 21:ce51bb0ba4a5 413 res = GetLocalFile(fname, confBuf, bsize, timeOut);
uci1 21:ce51bb0ba4a5 414 }
uci1 12:d472f9811262 415 } else if (mcode!=SnHeaderFrame::kConfigCode) {
uci1 8:95a325df1f6b 416 res = SnCommWin::kUnexpectedRec;
uci1 8:95a325df1f6b 417 } else {
uci1 8:95a325df1f6b 418 // get config
uci1 8:95a325df1f6b 419 const int clen = ReceiveAll(confBuf, mlen, timeOut);
uci1 8:95a325df1f6b 420 if (clen>0 && static_cast<uint32_t>(clen)==mlen) {
uci1 21:ce51bb0ba4a5 421 const char* b = confBuf;
uci1 8:95a325df1f6b 422 conf.ReadFrom(b);
uci1 16:744ce85aede2 423 res = SnCommWin::kOkWithMsg;
uci1 8:95a325df1f6b 424 } else {
uci1 8:95a325df1f6b 425 res = SnCommWin::kUnexpectedRec;
uci1 8:95a325df1f6b 426 }
uci1 8:95a325df1f6b 427 }
uci1 8:95a325df1f6b 428 } else {
uci1 21:ce51bb0ba4a5 429 // not a problem if we get nothing (or no config)
uci1 16:744ce85aede2 430 res = SnCommWin::kOkNoMsg;
uci1 8:95a325df1f6b 431 }
uci1 8:95a325df1f6b 432 }
uci1 8:95a325df1f6b 433 return res;
uci1 8:95a325df1f6b 434 }
uci1 8:95a325df1f6b 435
uci1 8:95a325df1f6b 436 SnCommWin::ECommWinResult SnCommWin::SendStatus(const SnConfigFrame& conf,
uci1 8:95a325df1f6b 437 const SnEventFrame& evt,
uci1 8:95a325df1f6b 438 const SnPowerFrame& pow,
uci1 10:3c93db1cfb12 439 const uint16_t seq,
uci1 10:3c93db1cfb12 440 const float thmrate,
uci1 10:3c93db1cfb12 441 const float evtrate,
uci1 8:95a325df1f6b 442 char* const genBuf,
uci1 8:95a325df1f6b 443 const uint32_t timeout_clock) {
uci1 8:95a325df1f6b 444 // TODO: check if connected?
uci1 12:d472f9811262 445 #ifdef DEBUG
uci1 12:d472f9811262 446 printf("########### Send Status\r\n");
uci1 12:d472f9811262 447 #endif
uci1 21:ce51bb0ba4a5 448 uint8_t loseLSB=0, loseMSB=0;
uci1 21:ce51bb0ba4a5 449 uint16_t wvBase=0;
uci1 21:ce51bb0ba4a5 450 conf.GetPackParsFor(GetCommType(), loseLSB, loseMSB, wvBase);
uci1 8:95a325df1f6b 451 const uint32_t ssize = SnStatusFrame::SizeOf(SnStatusFrame::kIOVers, conf);
uci1 8:95a325df1f6b 452 char* b = genBuf;
uci1 8:95a325df1f6b 453 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kStatusCode, ssize);
uci1 21:ce51bb0ba4a5 454 SnStatusFrame::WriteTo(b, conf, evt, genBuf, seq, thmrate, evtrate,
uci1 21:ce51bb0ba4a5 455 loseLSB, loseMSB, wvBase);
uci1 10:3c93db1cfb12 456 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode,
uci1 10:3c93db1cfb12 457 pow.SizeOf(SnPowerFrame::kIOvers));
uci1 10:3c93db1cfb12 458 pow.WriteTo(b);
uci1 10:3c93db1cfb12 459 int msiz = b-genBuf;
uci1 18:55f1581f2ee4 460 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 461 printf("calling SendAll (status)\r\n");
uci1 18:55f1581f2ee4 462 #endif
uci1 10:3c93db1cfb12 463 int mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 8:95a325df1f6b 464 #ifdef DEBUG
uci1 8:95a325df1f6b 465 printf("status frame:\r\n");
uci1 15:f2569d8e4176 466 for (uint32_t i=0; i<msiz; i++) {
uci1 8:95a325df1f6b 467 printf("%02X ",genBuf[i]);
uci1 8:95a325df1f6b 468 }
uci1 8:95a325df1f6b 469 printf("\r\n");
uci1 8:95a325df1f6b 470 #endif
uci1 8:95a325df1f6b 471 if (mlen==msiz) {
uci1 12:d472f9811262 472 #ifdef DEBUG
uci1 10:3c93db1cfb12 473 printf("status+power sent\r\n");
uci1 12:d472f9811262 474 #endif
uci1 21:ce51bb0ba4a5 475 // event compression parameters must be the same
uci1 21:ce51bb0ba4a5 476 // as those sent in the status update
uci1 8:95a325df1f6b 477 b = genBuf;
uci1 10:3c93db1cfb12 478 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode,
uci1 21:ce51bb0ba4a5 479 evt.SizeOf(SnEventFrame::kIOVers, loseLSB, loseMSB));
uci1 21:ce51bb0ba4a5 480 b = evt.WriteTo(b, loseLSB, loseMSB, wvBase);
uci1 21:ce51bb0ba4a5 481 msiz = b-genBuf;
uci1 16:744ce85aede2 482 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 483 printf("calling SendAll (event) %d:\r\n",msiz);
uci1 21:ce51bb0ba4a5 484 for (uint32_t i=0; i<msiz; i++) {
uci1 21:ce51bb0ba4a5 485 printf("%02X ",genBuf[i]);
uci1 21:ce51bb0ba4a5 486 }
uci1 21:ce51bb0ba4a5 487 printf("\r\n");
uci1 21:ce51bb0ba4a5 488 #endif
uci1 21:ce51bb0ba4a5 489 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 21:ce51bb0ba4a5 490 if (mlen==msiz) {
uci1 21:ce51bb0ba4a5 491 return SnCommWin::kOkMsgSent;
uci1 21:ce51bb0ba4a5 492 }
uci1 8:95a325df1f6b 493 }
uci1 8:95a325df1f6b 494 return SnCommWin::kFailPartSent;
uci1 8:95a325df1f6b 495 }
uci1 8:95a325df1f6b 496
uci1 23:ccf39298f205 497 SnCommWin::ECommWinResult SnCommWin::SendString(const char* str,
uci1 23:ccf39298f205 498 const uint32_t timeout) {
uci1 23:ccf39298f205 499 #ifdef DEBUG
uci1 23:ccf39298f205 500 printf("SnCommWin::SendString %s\r\n",str);
uci1 23:ccf39298f205 501 #endif
uci1 23:ccf39298f205 502 const size_t rlen = strlen(str);
uci1 23:ccf39298f205 503 const size_t slen = rlen > kMaxStrLen ? kMaxStrLen : rlen;
uci1 23:ccf39298f205 504 const int msiz = slen+SnHeaderFrame::SizeOf();
uci1 23:ccf39298f205 505 char* const ts = new char[msiz];
uci1 23:ccf39298f205 506 char* t = ts;
uci1 23:ccf39298f205 507 SnHeaderFrame::WriteTo(t, SnHeaderFrame::kStringCode, slen);
uci1 23:ccf39298f205 508 const int mlen = SendAll(ts, msiz, timeout);
uci1 23:ccf39298f205 509 delete[] ts;
uci1 23:ccf39298f205 510 return (msiz==mlen) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
uci1 23:ccf39298f205 511 }
uci1 23:ccf39298f205 512
uci1 12:d472f9811262 513 SnCommWin::ECommWinResult SnCommWin::SendFilename(const char* inf,
uci1 8:95a325df1f6b 514 char* const genBuf,
uci1 8:95a325df1f6b 515 const uint32_t timeout_clock) {
uci1 12:d472f9811262 516 #ifdef DEBUG
uci1 12:d472f9811262 517 printf("SnCommWin::SendFilename %s\r\n",inf);
uci1 12:d472f9811262 518 #endif
uci1 16:744ce85aede2 519
uci1 12:d472f9811262 520 // remove the directory
uci1 12:d472f9811262 521 const char* fn = strrchr(inf, '/');
uci1 12:d472f9811262 522 if (fn==0) {
uci1 12:d472f9811262 523 // no directory
uci1 12:d472f9811262 524 fn = inf;
uci1 12:d472f9811262 525 } else if (fn!=inf) {
uci1 12:d472f9811262 526 ++fn; // move past the '/' if it was found
uci1 12:d472f9811262 527 }
uci1 12:d472f9811262 528 #ifdef DEBUG
uci1 12:d472f9811262 529 printf("send %s\r\n",fn);
uci1 12:d472f9811262 530 #endif
uci1 8:95a325df1f6b 531 const size_t flen = strlen(fn);
uci1 8:95a325df1f6b 532 char* b = genBuf;
uci1 8:95a325df1f6b 533 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFilenameCode, flen);
uci1 12:d472f9811262 534 b = SnBitUtils::WriteTo(b, fn, flen);
uci1 12:d472f9811262 535 const int msiz = b-genBuf;
uci1 8:95a325df1f6b 536 const int mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 12:d472f9811262 537 #ifdef DEBUG
uci1 12:d472f9811262 538 printf("time = %u, timeout = %u\r\n",time(0), timeout_clock);
uci1 12:d472f9811262 539 #endif
uci1 8:95a325df1f6b 540 return (msiz==mlen) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
uci1 8:95a325df1f6b 541 }
uci1 8:95a325df1f6b 542
uci1 12:d472f9811262 543 int SnCommWin::SendFileBlock(FILE* inf,
uci1 12:d472f9811262 544 const uint8_t blockHeaderCode,
uci1 12:d472f9811262 545 const uint32_t blockSize,
uci1 12:d472f9811262 546 char* const genBuf,
uci1 12:d472f9811262 547 const uint32_t timeout) {
uci1 12:d472f9811262 548 // sends the block from the file. does not check if the file has sufficient bytes
uci1 12:d472f9811262 549 // this should be done before calling this function
uci1 12:d472f9811262 550 // (where the number of bytes in the file can be cached)
uci1 12:d472f9811262 551 char* b = genBuf;
uci1 12:d472f9811262 552 SnHeaderFrame::WriteTo(b, blockHeaderCode, blockSize);
uci1 12:d472f9811262 553 SnBitUtils::ReadFrom(inf, b, blockSize);
uci1 12:d472f9811262 554 #ifdef DEBUG
uci1 12:d472f9811262 555 printf("Sending block hc %02x, len=%u\r\n",blockHeaderCode,blockSize+SnHeaderFrame::SizeOf());
uci1 12:d472f9811262 556 #endif
uci1 12:d472f9811262 557 return SendAll(genBuf, blockSize+SnHeaderFrame::SizeOf(), timeout);
uci1 12:d472f9811262 558 }
uci1 12:d472f9811262 559
uci1 12:d472f9811262 560 SnCommWin::ECommWinResult SnCommWin::SendFileContents(FILE* inf,
uci1 12:d472f9811262 561 const SnConfigFrame& curConf,
uci1 12:d472f9811262 562 SnEventFrame& evt,
uci1 12:d472f9811262 563 SnPowerFrame& pow,
uci1 12:d472f9811262 564 char* const genBuf,
uci1 12:d472f9811262 565 uint32_t nevts,
uci1 12:d472f9811262 566 const uint32_t timeout_clock) {
uci1 12:d472f9811262 567 // firstEvt==0 ==> start at beginning
uci1 12:d472f9811262 568 // nevts==0 ==> all events
uci1 12:d472f9811262 569
uci1 12:d472f9811262 570 #ifdef DEBUG
uci1 12:d472f9811262 571 printf("SendFileContents (byte streaming)\r\n");
uci1 12:d472f9811262 572 #endif
uci1 12:d472f9811262 573
uci1 12:d472f9811262 574 // store position in file so we can go back to it afterwards
uci1 12:d472f9811262 575 // this is probably not necessary, because if this file is open
uci1 12:d472f9811262 576 // in write-only mode, we're screwed..
uci1 12:d472f9811262 577 const int fpos = ftell(inf);
uci1 12:d472f9811262 578 if (fpos>0) {
uci1 12:d472f9811262 579 fseek(inf, 0, SEEK_SET);
uci1 12:d472f9811262 580 }
uci1 12:d472f9811262 581 // how many bytes?
uci1 12:d472f9811262 582 fseek(inf, 0, SEEK_END); // go to end
uci1 12:d472f9811262 583 const int fend = ftell(inf);
uci1 12:d472f9811262 584 fseek(inf, 0, SEEK_SET); // go to start
uci1 12:d472f9811262 585 #ifdef DEBUG
uci1 12:d472f9811262 586 printf("fend=%d\r\n",fend);
uci1 12:d472f9811262 587 printf("fpos=%d\r\n",fpos);
uci1 12:d472f9811262 588 #endif
uci1 12:d472f9811262 589
uci1 12:d472f9811262 590 // variables used when sending data
uci1 12:d472f9811262 591 char* b = genBuf;
uci1 12:d472f9811262 592 int msiz, mlen;
uci1 21:ce51bb0ba4a5 593 // count number of events / power readings sent
uci1 21:ce51bb0ba4a5 594 uint32_t evtsSent=0, powsSent=0;
uci1 12:d472f9811262 595
uci1 12:d472f9811262 596 // first is the file header, which has no SnHeaderFrame
uci1 12:d472f9811262 597 msiz = SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers);
uci1 12:d472f9811262 598 bool ok = (ftell(inf)+msiz)<=fend;
uci1 12:d472f9811262 599 if (ok) {
uci1 12:d472f9811262 600 mlen = SendFileBlock(inf, SnHeaderFrame::kFileHeadrCode,
uci1 12:d472f9811262 601 msiz, genBuf, timeout_clock);
uci1 12:d472f9811262 602 ok &= (msiz+SnHeaderFrame::SizeOf())==mlen;
uci1 12:d472f9811262 603
uci1 12:d472f9811262 604 #ifdef DEBUG
uci1 12:d472f9811262 605 printf("sent file header. ok=%d\r\n",(int)ok);
uci1 12:d472f9811262 606 #endif
uci1 12:d472f9811262 607
uci1 12:d472f9811262 608 // the header info for each block
uci1 12:d472f9811262 609 uint8_t hcode;
uci1 12:d472f9811262 610 uint32_t hlen;
uci1 12:d472f9811262 611
uci1 12:d472f9811262 612 // now just loop through file and send each block
uci1 18:55f1581f2ee4 613 bool fok = true;
uci1 18:55f1581f2ee4 614 while ( fok
uci1 12:d472f9811262 615 && (feof(inf)==0)
uci1 12:d472f9811262 616 && (ferror(inf)==0)
uci1 12:d472f9811262 617 && ((ftell(inf)+SnHeaderFrame::SizeOf())<=fend) ) {
uci1 12:d472f9811262 618 // read the header for the block
uci1 12:d472f9811262 619 SnSDUtils::ReadBlockHeader(inf, hcode, hlen);
uci1 18:55f1581f2ee4 620 fok &= (ftell(inf)+hlen)<=fend;
uci1 12:d472f9811262 621 #ifdef DEBUG
uci1 18:55f1581f2ee4 622 printf("new block: hc=%02x, hl=%u, ftell=%d, fend=%d, "
uci1 18:55f1581f2ee4 623 "ok=%d, fok=%d\r\n",
uci1 18:55f1581f2ee4 624 hcode, hlen, ftell(inf), fend, (int)ok, (int)fok);
uci1 12:d472f9811262 625 #endif
uci1 12:d472f9811262 626 if (ok) {
uci1 12:d472f9811262 627 // send the block
uci1 12:d472f9811262 628 // TODO: repack events?
uci1 12:d472f9811262 629 msiz = hlen + SnHeaderFrame::SizeOf();
uci1 12:d472f9811262 630 mlen = SendFileBlock(inf, hcode, hlen, genBuf, timeout_clock);
uci1 12:d472f9811262 631 ok &= msiz==mlen;
uci1 12:d472f9811262 632 if (ok) {
uci1 12:d472f9811262 633 if (hcode==SnHeaderFrame::kEventCode) {
uci1 12:d472f9811262 634 ++evtsSent;
uci1 12:d472f9811262 635 if (nevts>0) {
uci1 12:d472f9811262 636 if (evtsSent>=nevts) {
uci1 12:d472f9811262 637 #ifdef DEBUG
uci1 12:d472f9811262 638 printf("send %u events. stop\r\n",evtsSent);
uci1 12:d472f9811262 639 #endif
uci1 12:d472f9811262 640 break;
uci1 12:d472f9811262 641 }
uci1 12:d472f9811262 642 }
uci1 12:d472f9811262 643 } else if (hcode==SnHeaderFrame::kPowerCode) {
uci1 12:d472f9811262 644 ++powsSent;
uci1 12:d472f9811262 645 }
uci1 12:d472f9811262 646 } else {
uci1 12:d472f9811262 647 #ifdef DEBUG
uci1 12:d472f9811262 648 printf("not ok when sending hcode=%02x\r\n",hcode);
uci1 12:d472f9811262 649 #endif
uci1 21:ce51bb0ba4a5 650 } // if ok after sending block
uci1 21:ce51bb0ba4a5 651 } // if ok after sending block header
uci1 21:ce51bb0ba4a5 652 } // loop over file contents
uci1 21:ce51bb0ba4a5 653 } else {
uci1 21:ce51bb0ba4a5 654 // otherwise file size not sufficient for file header
uci1 21:ce51bb0ba4a5 655 // so it's either 0 or corrupted.
uci1 21:ce51bb0ba4a5 656 // proceed as normal even tho no contents were sent.
uci1 21:ce51bb0ba4a5 657 // if we're deleting files, this one will be deleted.
uci1 21:ce51bb0ba4a5 658 ok = true;
uci1 21:ce51bb0ba4a5 659 }
uci1 12:d472f9811262 660 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 661 printf("loop done. ok=%d\r\n",(int)ok);
uci1 12:d472f9811262 662 #endif
uci1 21:ce51bb0ba4a5 663
uci1 21:ce51bb0ba4a5 664 // send number of events sent
uci1 12:d472f9811262 665 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 666 printf("sending evtsSent (%u)\r\n",evtsSent);
uci1 12:d472f9811262 667 #endif
uci1 21:ce51bb0ba4a5 668 b = genBuf;
uci1 21:ce51bb0ba4a5 669 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t));
uci1 21:ce51bb0ba4a5 670 b = SnBitUtils::WriteTo(b, evtsSent);
uci1 21:ce51bb0ba4a5 671 msiz = b - genBuf;
uci1 21:ce51bb0ba4a5 672 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 21:ce51bb0ba4a5 673 ok &= msiz==mlen;
uci1 18:55f1581f2ee4 674
uci1 18:55f1581f2ee4 675 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 676 printf("ok=%d (msiz=%d, mlen=%d)\r\n", (int)ok, msiz, mlen);
uci1 18:55f1581f2ee4 677 #endif
uci1 21:ce51bb0ba4a5 678
uci1 21:ce51bb0ba4a5 679 // send number of power readings sent
uci1 12:d472f9811262 680 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 681 printf("sending powsSent (%u)\r\n",powsSent);
uci1 12:d472f9811262 682 #endif
uci1 21:ce51bb0ba4a5 683 b = genBuf;
uci1 21:ce51bb0ba4a5 684 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t));
uci1 21:ce51bb0ba4a5 685 b = SnBitUtils::WriteTo(b, powsSent);
uci1 21:ce51bb0ba4a5 686 msiz = b - genBuf;
uci1 21:ce51bb0ba4a5 687 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 21:ce51bb0ba4a5 688 ok &= msiz==mlen;
uci1 21:ce51bb0ba4a5 689
uci1 18:55f1581f2ee4 690 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 691 printf("ok=%d (msiz=%d, mlen=%d)\r\n", (int)ok, msiz, mlen);
uci1 18:55f1581f2ee4 692 #endif
uci1 12:d472f9811262 693
uci1 12:d472f9811262 694
uci1 12:d472f9811262 695 // put file position back
uci1 12:d472f9811262 696 fseek(inf, fpos, SEEK_SET);
uci1 12:d472f9811262 697
uci1 12:d472f9811262 698 #ifdef DEBUG
uci1 12:d472f9811262 699 printf("end contents: ok=%d\r\n",(int)ok);
uci1 12:d472f9811262 700 #endif
uci1 12:d472f9811262 701
uci1 12:d472f9811262 702 return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
uci1 12:d472f9811262 703 }
uci1 12:d472f9811262 704
uci1 12:d472f9811262 705 /*
uci1 8:95a325df1f6b 706 SnCommWin::ECommWinResult SnCommWin::SendFileContents(FILE* inf,
uci1 8:95a325df1f6b 707 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 708 SnEventFrame& evt,
uci1 8:95a325df1f6b 709 SnPowerFrame& pow,
uci1 8:95a325df1f6b 710 char* const genBuf,
uci1 8:95a325df1f6b 711 uint32_t nevts,
uci1 8:95a325df1f6b 712 const uint32_t timeout_clock,
uci1 8:95a325df1f6b 713 const uint32_t firstEvt) {
uci1 12:d472f9811262 714 printf("comm win send file contents\r\n");
uci1 8:95a325df1f6b 715 // firstEvt==0 ==> start at beginning
uci1 8:95a325df1f6b 716 // nevts==0 ==> all events
uci1 8:95a325df1f6b 717
uci1 8:95a325df1f6b 718 const int fpos = ftell(inf);
uci1 8:95a325df1f6b 719 if (fpos>0) {
uci1 8:95a325df1f6b 720 fseek(inf, 0, SEEK_SET);
uci1 8:95a325df1f6b 721 }
uci1 12:d472f9811262 722 // how many bytes?
uci1 12:d472f9811262 723 fseek(inf, 0, SEEK_END); // go to end
uci1 12:d472f9811262 724 const int fend = ftell(inf);
uci1 12:d472f9811262 725 fseek(inf, 0, SEEK_SET); // go to start
uci1 12:d472f9811262 726 printf("fend=%d\r\n",fend);
uci1 8:95a325df1f6b 727 printf("fpos=%d\r\n",fpos);
uci1 8:95a325df1f6b 728 // get file header
uci1 8:95a325df1f6b 729 uint64_t macadr;
uci1 8:95a325df1f6b 730 uint32_t run;
uci1 8:95a325df1f6b 731 uint16_t seq;
uci1 12:d472f9811262 732 bool ok = (ftell(inf)+SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers))<=fend;
uci1 12:d472f9811262 733 if (ok) {
uci1 12:d472f9811262 734 SnSDUtils::ReadFileHeader(inf, macadr, run, seq, &pow);
uci1 12:d472f9811262 735 printf("read file header: run %u, seq %hu\r\n",run,seq);
uci1 12:d472f9811262 736 }
uci1 12:d472f9811262 737
uci1 12:d472f9811262 738 printf(">>> file hdr read ftell(inf)=%d\r\n",ftell(inf));
uci1 8:95a325df1f6b 739
uci1 8:95a325df1f6b 740 // check block
uci1 8:95a325df1f6b 741 uint8_t hcode;
uci1 8:95a325df1f6b 742 uint32_t hlen;
uci1 12:d472f9811262 743 ok &= (ftell(inf)+SnHeaderFrame::SizeOf())<=fend;
uci1 12:d472f9811262 744 if (ok) {
uci1 12:d472f9811262 745 SnSDUtils::ReadBlockHeader(inf, hcode, hlen);
uci1 12:d472f9811262 746 printf("read block hd %02x, len %u\r\n",hcode,hlen);
uci1 12:d472f9811262 747 if (hcode==SnHeaderFrame::kPowerCode) {
uci1 12:d472f9811262 748 ok &= (ftell(inf)+SnPowerFrame::SizeOf(SnPowerFrame::kIOvers))<=fend;
uci1 12:d472f9811262 749 if (ok) {
uci1 12:d472f9811262 750 pow.ReadFrom(inf);
uci1 12:d472f9811262 751 printf("read power: v1=%g, v2=%g\r\n",pow.GetAveV1(), pow.GetAveV2());
uci1 12:d472f9811262 752 // now read the next header
uci1 12:d472f9811262 753 ok &= (ftell(inf)+SnHeaderFrame::SizeOf())<=fend;
uci1 12:d472f9811262 754 if (ok) {
uci1 12:d472f9811262 755 SnSDUtils::ReadBlockHeader(inf, hcode, hlen);
uci1 12:d472f9811262 756 printf("read new header: hc %02x, hlen=%u\r\n",hcode,hlen);
uci1 12:d472f9811262 757 }
uci1 12:d472f9811262 758 }
uci1 12:d472f9811262 759 }
uci1 8:95a325df1f6b 760 }
uci1 8:95a325df1f6b 761
uci1 12:d472f9811262 762 printf(">>> power tried ftell(inf)=%d\r\n",ftell(inf));
uci1 12:d472f9811262 763
uci1 12:d472f9811262 764 printf("hcode=%02x\r\n",hcode);
uci1 12:d472f9811262 765 printf("ok=%d\r\n",(int)ok);
uci1 12:d472f9811262 766 printf("feof=%d\r\n",feof(inf));
uci1 12:d472f9811262 767 printf("ferror=%d\r\n",ferror(inf));
uci1 12:d472f9811262 768 printf("%d+%u <= %d ? %d\r\n",ftell(inf),hlen,fend,
uci1 12:d472f9811262 769 (int)((ftell(inf)+hlen)<=fend));
uci1 12:d472f9811262 770
uci1 8:95a325df1f6b 771 // TODO: check memory for temporary config/event frames?
uci1 8:95a325df1f6b 772 // get config
uci1 8:95a325df1f6b 773 while ((hcode!=SnHeaderFrame::kConfigCode)
uci1 12:d472f9811262 774 && ok
uci1 8:95a325df1f6b 775 && (feof(inf)==0)
uci1 12:d472f9811262 776 && (ferror(inf)==0)
uci1 12:d472f9811262 777 && ((ftell(inf)+hlen) <= fend) ) {
uci1 12:d472f9811262 778 printf("skip: ftell=%d, hlen=%u\r\n",ftell(inf),hlen);
uci1 8:95a325df1f6b 779 fseek(inf, hlen, SEEK_CUR); // skip this block
uci1 12:d472f9811262 780 ok = (ftell(inf)+SnHeaderFrame::SizeOf())<=fend;
uci1 12:d472f9811262 781 if (ok) {
uci1 12:d472f9811262 782 SnSDUtils::ReadBlockHeader(inf, hcode, hlen);
uci1 12:d472f9811262 783 printf("hcs >>> ftell(inf)=%d, hcode=%02x, hlen=%u\r\n",ftell(inf),hcode,hlen);
uci1 12:d472f9811262 784 printf("feof=%d, ferror=%d\r\n",feof(inf),ferror(inf));
uci1 12:d472f9811262 785 }
uci1 8:95a325df1f6b 786 }
uci1 8:95a325df1f6b 787
uci1 12:d472f9811262 788 printf("checking ftell\r\n");
uci1 12:d472f9811262 789 bool gotConf = false;
uci1 12:d472f9811262 790 ok = (ftell(inf)+hlen) <= fend;
uci1 12:d472f9811262 791 printf("making temp config\r\n");
uci1 12:d472f9811262 792 SnConfigFrame conf; // TODO: SOMETIMES STALLS HERE!
uci1 12:d472f9811262 793 printf("trying to read\r\n");
uci1 12:d472f9811262 794 if (ok && (hcode==SnHeaderFrame::kConfigCode)) {
uci1 12:d472f9811262 795 printf("reading config from ftell=%d, hcode=%02x, hlen=%u, ok=%d\r\n",
uci1 12:d472f9811262 796 ftell(inf), hcode, hlen, (int)ok);
uci1 12:d472f9811262 797 conf.ReadFrom(inf);
uci1 12:d472f9811262 798 gotConf = (ftell(inf) <= fend) && (feof(inf)==0) && (ferror(inf)==0);
uci1 12:d472f9811262 799 }
uci1 12:d472f9811262 800 printf(">>> conf. ftell(inf)=%d, gotconf=%d\r\n",ftell(inf),(int)gotConf);
uci1 8:95a325df1f6b 801
uci1 8:95a325df1f6b 802 char* b = genBuf;
uci1 12:d472f9811262 803 int msiz, mlen;
uci1 12:d472f9811262 804 if (ok && gotConf) {
uci1 12:d472f9811262 805 // get event size
uci1 12:d472f9811262 806 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 12:d472f9811262 807 uint16_t sWvBase=0;
uci1 12:d472f9811262 808 curConf.GetPackParsFor(GetCommType(), sLoseLSB, sLoseMSB, sWvBase);
uci1 12:d472f9811262 809
uci1 12:d472f9811262 810 // size of event in file
uci1 12:d472f9811262 811 const uint32_t esize = SnEventFrame::SizeOf(SnEventFrame::kIOVers,
uci1 12:d472f9811262 812 conf.GetWvLoseLSB(),
uci1 12:d472f9811262 813 conf.GetWvLoseMSB());
uci1 12:d472f9811262 814
uci1 12:d472f9811262 815 printf("esize=%u\r\n",esize);
uci1 12:d472f9811262 816
uci1 12:d472f9811262 817 // number of events / power readings we will send
uci1 12:d472f9811262 818 uint32_t evtsSent=0, powsSent=0;
uci1 8:95a325df1f6b 819 b = genBuf;
uci1 12:d472f9811262 820 // send the file header
uci1 12:d472f9811262 821 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileHeadrCode,
uci1 12:d472f9811262 822 SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers));
uci1 12:d472f9811262 823 SnSDUtils::WriteFileHeader(b, macadr, run, seq);
uci1 8:95a325df1f6b 824 msiz = b-genBuf;
uci1 8:95a325df1f6b 825 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 8:95a325df1f6b 826 if (mlen==msiz) {
uci1 12:d472f9811262 827 // send power header
uci1 8:95a325df1f6b 828 b = genBuf;
uci1 12:d472f9811262 829 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode,
uci1 12:d472f9811262 830 pow.SizeOf(SnPowerFrame::kIOvers));
uci1 12:d472f9811262 831 pow.WriteTo(b);
uci1 8:95a325df1f6b 832 msiz = b-genBuf;
uci1 8:95a325df1f6b 833 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 12:d472f9811262 834 ++powsSent;
uci1 8:95a325df1f6b 835 if (mlen==msiz) {
uci1 12:d472f9811262 836 // send the config
uci1 12:d472f9811262 837 b = genBuf;
uci1 12:d472f9811262 838 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kConfigCode,
uci1 12:d472f9811262 839 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 12:d472f9811262 840 conf.WriteTo(b);
uci1 12:d472f9811262 841 msiz = b-genBuf;
uci1 12:d472f9811262 842 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 12:d472f9811262 843 if (mlen==msiz) {
uci1 12:d472f9811262 844 ok = true;
uci1 12:d472f9811262 845 }
uci1 8:95a325df1f6b 846 }
uci1 8:95a325df1f6b 847 }
uci1 12:d472f9811262 848
uci1 12:d472f9811262 849 printf("ok=%d, nevts=%u\r\n",(int)ok,nevts);
uci1 8:95a325df1f6b 850
uci1 12:d472f9811262 851 if (ok) {
uci1 12:d472f9811262 852 // size of event sent over afar
uci1 12:d472f9811262 853 const uint32_t ssize = SnEventFrame::SizeOf(SnEventFrame::kIOVers,
uci1 12:d472f9811262 854 sLoseLSB, sLoseMSB);
uci1 12:d472f9811262 855
uci1 12:d472f9811262 856 // loop over blocks. send event & power frames
uci1 12:d472f9811262 857 // until EOF or nevets have been sent
uci1 12:d472f9811262 858 uint8_t hc; uint32_t hl;
uci1 12:d472f9811262 859 while (ok && (feof(inf)==0)
uci1 12:d472f9811262 860 && (ferror(inf)==0)
uci1 12:d472f9811262 861 && (ftell(inf)<fend) ) { // feof doesn't seem to work
uci1 12:d472f9811262 862 printf(">>> ftell(inf)=%d\r\n",ftell(inf));
uci1 12:d472f9811262 863 if ((ftell(inf)+SnHeaderFrame::SizeOf())<=fend) {
uci1 12:d472f9811262 864 SnSDUtils::ReadBlockHeader(inf, hc, hl);
uci1 12:d472f9811262 865 if (hc==SnHeaderFrame::kEventCode) {
uci1 12:d472f9811262 866 if ((ftell(inf)+ssize)<=fend) {
uci1 12:d472f9811262 867 evt.ReadFrom(inf, genBuf,
uci1 12:d472f9811262 868 conf.GetWvLoseLSB(), conf.GetWvLoseMSB(),
uci1 12:d472f9811262 869 conf.GetWvBaseline());
uci1 12:d472f9811262 870 if (evt.GetEvtNum()>=firstEvt) {
uci1 12:d472f9811262 871 ++evtsSent;
uci1 12:d472f9811262 872 printf("sending evt %u\r\n",evtsSent);
uci1 12:d472f9811262 873 // must be after evt.Read, since that uses the buffer
uci1 12:d472f9811262 874 b = genBuf;
uci1 12:d472f9811262 875 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode, ssize);
uci1 12:d472f9811262 876 evt.WriteTo(b, sLoseLSB, sLoseMSB, sWvBase); // will repack if necessary
uci1 12:d472f9811262 877 msiz = b-genBuf; //SnHeaderFrame::SizeOf()+ssize;
uci1 12:d472f9811262 878 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 12:d472f9811262 879 ok &= mlen==msiz;
uci1 12:d472f9811262 880 }
uci1 12:d472f9811262 881 } else {
uci1 12:d472f9811262 882 printf("event header, but not enough bytes in file\r\n");
uci1 12:d472f9811262 883 ok = false;
uci1 12:d472f9811262 884 }
uci1 12:d472f9811262 885 } else if (hc==SnHeaderFrame::kPowerCode) {
uci1 12:d472f9811262 886 if ((ftell(inf)+SnPowerFrame::SizeOf(SnPowerFrame::kIOvers))<=fend) {
uci1 12:d472f9811262 887 ++powsSent;
uci1 12:d472f9811262 888 pow.ReadFrom(inf);
uci1 12:d472f9811262 889 printf("sending power frame %u, v1=%g, v2=%g, t=%u\r\n",
uci1 12:d472f9811262 890 powsSent, pow.GetAveV1(), pow.GetAveV2(), pow.GetTime());
uci1 12:d472f9811262 891 b = genBuf;
uci1 12:d472f9811262 892 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode,
uci1 12:d472f9811262 893 SnPowerFrame::SizeOf(SnPowerFrame::kIOvers));
uci1 12:d472f9811262 894 pow.WriteTo(b);
uci1 12:d472f9811262 895 msiz = b-genBuf;
uci1 12:d472f9811262 896 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 12:d472f9811262 897 ok &= mlen==msiz;
uci1 12:d472f9811262 898 } else {
uci1 12:d472f9811262 899 printf("power header, but not enough bytes in file\r\n");
uci1 12:d472f9811262 900 ok = false;
uci1 12:d472f9811262 901 }
uci1 12:d472f9811262 902 } else {
uci1 12:d472f9811262 903 printf("unhandled block. hc=%hhu, hl=%u\r\n",
uci1 12:d472f9811262 904 hc, hl);
uci1 12:d472f9811262 905 if ((ftell(inf)+hl)<=fend) {
uci1 12:d472f9811262 906 fseek(inf, hl, SEEK_CUR); // skip this block
uci1 12:d472f9811262 907 } else {
uci1 12:d472f9811262 908 printf("not enough bytes in file to skip block\r\n");
uci1 12:d472f9811262 909 ok = false;
uci1 12:d472f9811262 910 }
uci1 8:95a325df1f6b 911 }
uci1 8:95a325df1f6b 912 } else {
uci1 12:d472f9811262 913 printf("not enough bytes in file to read header\r\n");
uci1 12:d472f9811262 914 printf("feof=%d\r\n",feof(inf));
uci1 12:d472f9811262 915 printf("ftell(inf)=%d, hdr size=%u, fend=%u\r\n",
uci1 12:d472f9811262 916 (ftell(inf)), SnHeaderFrame::SizeOf(), fend);
uci1 8:95a325df1f6b 917 ok = false;
uci1 8:95a325df1f6b 918 }
uci1 8:95a325df1f6b 919 }
uci1 12:d472f9811262 920 // send number of events sent
uci1 12:d472f9811262 921 b = genBuf;
uci1 12:d472f9811262 922 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t));
uci1 12:d472f9811262 923 b = SnBitUtils::WriteTo(b, evtsSent);
uci1 12:d472f9811262 924 msiz = b - genBuf;
uci1 12:d472f9811262 925 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 12:d472f9811262 926 ok &= msiz==mlen;
uci1 12:d472f9811262 927 // send number of power readings sent
uci1 12:d472f9811262 928 b = genBuf;
uci1 12:d472f9811262 929 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t));
uci1 12:d472f9811262 930 b = SnBitUtils::WriteTo(b, powsSent);
uci1 12:d472f9811262 931 msiz = b - genBuf;
uci1 12:d472f9811262 932 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 12:d472f9811262 933 ok &= msiz==mlen;
uci1 8:95a325df1f6b 934 }
uci1 12:d472f9811262 935 } else {
uci1 12:d472f9811262 936 printf("failed to get config from file\r\n");
uci1 12:d472f9811262 937 // send corrupted file handshake
uci1 8:95a325df1f6b 938 b = genBuf;
uci1 12:d472f9811262 939 SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileReadFailCode, 0u);
uci1 12:d472f9811262 940 msiz = b-genBuf;
uci1 8:95a325df1f6b 941 mlen = SendAll(genBuf, msiz, timeout_clock);
uci1 8:95a325df1f6b 942 ok &= msiz==mlen;
uci1 8:95a325df1f6b 943 }
uci1 12:d472f9811262 944
uci1 8:95a325df1f6b 945 // put file position back
uci1 8:95a325df1f6b 946 fseek(inf, fpos, SEEK_SET);
uci1 8:95a325df1f6b 947
uci1 8:95a325df1f6b 948 return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
uci1 8:95a325df1f6b 949 }
uci1 12:d472f9811262 950 */