Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu May 23 22:26:39 2013 +0000
Revision:
36:87865913ae6f
Parent:
27:efc4d654b139
Child:
37:ff95e7070f26
this will not compile. just starting to modularize the comms and essential packages for extraction (to use in both the DAQ and monitoring station)

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