Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: SnCommWin.cpp
- Revision:
- 40:1324da35afd4
- Parent:
- 38:9070c17536cd
- Child:
- 41:d6f5e2f09e07
--- a/SnCommWin.cpp Tue Jul 30 02:03:21 2013 +0000 +++ b/SnCommWin.cpp Sat Oct 05 04:45:22 2013 +0000 @@ -31,11 +31,11 @@ delete fComm; } -uint32_t SnCommWin::GetConnectTimeout() const { return kConnectTimeout; } -uint32_t SnCommWin::GetListenTimeout() const { return kListenTimeout; } - -bool SnCommWin::TrySetSysTimeUnix(const uint32_t timeout) { - return (fComm!=0) ? (fComm->TrySetSysTimeUnix(timeout)) : false; +bool SnCommWin::TrySetSysTimeUnix(const uint32_t timeout, + uint32_t& prvTime, + uint32_t& setTime) { + return (fComm!=0) ? (fComm->TrySetSysTimeUnix(timeout,prvTime,setTime)) + : false; } bool SnCommWin::Connect(const uint32_t timeout) { @@ -46,13 +46,16 @@ return (fComm!=0) ? (fComm->CloseConn(timeout)) : false; } +bool SnCommWin::PowerDown(const uint32_t timeout) { + return (fComm!=0) ? (fComm->PowerDown(timeout)) : false; +} + SnCommWin::ECommWinResult SnCommWin::SendData(SnConfigFrame& conf, SnEventFrame& evt, SnPowerFrame& pow, char* const genBuf, const uint32_t bsize, - const uint32_t timeout, - const uint32_t handshakeTimeout) { + const uint32_t timeout) { #ifdef DEBUG printf("SnCommWin::SendData\r\n"); #endif @@ -66,8 +69,8 @@ printf("sending all files\r\n"); #endif res = SnSDUtils::SendAllFiles(this, timeout, - genBuf, bsize, conf, evt, pow, - handshakeTimeout); + genBuf, bsize, conf, evt, pow); + // handshakes handled after each file, in SendDataFromFile } else { if (conf.GetCommSendData()==0) { #ifdef DEBUG @@ -79,10 +82,15 @@ conf.GetCommSendData() // send N events : 0u; // send all events in last file #ifdef DEBUG - printf("calling SendData. f=%s, nev=%u\r\n",SnSDUtils::GetCurFileName(), nev); + printf("calling SendDataFromFile. f=%s, nev=%u\r\n", + SnSDUtils::GetCurFileName(), nev); #endif - res = SendData(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), - conf, evt, pow, genBuf, bsize, nev, timeout, handshakeTimeout); + uint8_t hndcode(0); + uint32_t hndlen(0); + res = SendDataFromFile(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), + conf, evt, pow, genBuf, bsize, nev, timeout, + &hndcode, &hndlen); + // handshake handled in SendData #ifdef DEBUG printf("after send data cur file, res=%d\r\n",(int)res); #endif @@ -94,90 +102,114 @@ return res; } -SnCommWin::ECommWinResult SnCommWin::SendData(FILE* inf, const char* infn, +SnCommWin::ECommWinResult SnCommWin::SendDataFromFile(FILE* inf, const char* infn, const SnConfigFrame& curConf, SnEventFrame& evt, SnPowerFrame& pow, char* const genBuf, const uint32_t bsize, const uint32_t nevts, - const uint32_t timeout_clock, - const uint32_t handshakeTimeout, - uint8_t* hndres) { + const uint32_t timeout, + uint8_t* hndcode, + uint32_t* hndlen) { // nevts==0 ==> send all events // handshakeTimeout is never a clock time -- always a delta(t) #ifdef DEBUG - printf("SnCommWin::SendData file (%p), fn=%s\r\n",inf,infn); + printf("SnCommWin::SendDataFromFile file (%p), fn=%s\r\n",inf,infn); #endif ECommWinResult res = kUndefFail; bool didDel = false; + + // allow up to the full window if we're not obeying timeout + const uint32_t timeout_clock = curConf.IsObeyingTimeout() ? + timeout : + curConf.GetTimeoutTime(time(0), + curConf.GetCommWinDuration()); + + if (inf!=0) { #ifdef DEBUG printf("sending file name %s\r\n",infn); #endif - + // send the file name - res = SendFilename(infn, genBuf, timeout_clock); - if (res>kAllFails) { - if (genBuf!=0) { + int32_t btogo(0), ttogo(0); + int32_t bsent = SendFilename(infn, genBuf, btogo, timeout_clock); + if (genBuf!=0) { #ifdef DEBUG - printf("calling send file contents\r\n"); + printf("calling send file contents\r\n"); #endif - // send the contents - res = SendFileContents(inf, curConf, evt, pow, genBuf, - nevts, timeout_clock); + // send the contents + bsent += SendFileContents(inf, curConf, evt, pow, genBuf, + nevts, ttogo, timeout_clock); + btogo += ttogo; + bsent += fComm->FinishSending(timeout_clock); + res = (bsent==btogo) ? SnCommWin::kOkMsgSent + : SnCommWin::kFailPartSent; #ifdef DEBUG - printf("res=%d (fails=%d)\r\n",(int)res,(int)kAllFails); + printf("res=%d (fails=%d)\r\n",(int)res,(int)kAllFails); #endif - if (res>kAllFails) { + if (res>kAllFails) { #ifdef DEBUG - printf("calling wait handshake\r\n"); + printf("calling wait handshake\r\n"); #endif - // wait for handshake - uint8_t hndshk(0); uint32_t hndshkLen(0); - res = WaitHandshake(curConf, handshakeTimeout, genBuf, bsize, hndshk, - &hndshkLen); - if (hndres!=0) { - *hndres = hndshk; - } + // wait for handshake + uint8_t hndshk(0); uint32_t hndshkLen(0); + res = WaitHandshake(curConf, timeout_clock, genBuf, bsize, hndshk, + &hndshkLen); + if (hndcode!=0) { + *hndcode = hndshk; + } + if (hndlen!=0) { + *hndlen = hndshkLen; + } #ifdef DEBUG - printf("res=%d, nevts=%u, isdel=%d, inf=%p, curfile=%p, hndshk=%02x\r\n", - res, nevts, curConf.IsDeletingFiles(), inf, - SnSDUtils::GetCurFile(), hndshk); + printf("res=%d, nevts=%u, isdel=%d, inf=%p, curfile=%p, hndshk=%02x\r\n", + res, nevts, curConf.IsDeletingFiles(), inf, + SnSDUtils::GetCurFile(), hndshk); #endif - if ( (res==SnCommWin::kOkWithMsg) // got handshake - && (nevts==0) // sent whole file - && (inf!=SnSDUtils::GetCurFile()) ) { // not current file - if ( curConf.IsDeletingFiles() // want to delete - && (hndshk==SnHeaderFrame::kHnShOkComplCode)) { // whole file received + if (SnCommWin::kOkWithMsg==res) { + res = HandleHandshake(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), + curConf, evt, pow, genBuf, bsize, timeout_clock, + hndshk, hndshkLen, &nevts); + didDel = (SnCommWin::kOkWthMsgDidDel==res); + } +/* + if ( (res==SnCommWin::kOkWithMsg) // got handshake + && (nevts==0) // sent whole file + && (inf!=SnSDUtils::GetCurFile()) ) { // not current file + if ( curConf.IsDeletingFiles() // want to delete + && (hndshk==SnHeaderFrame::kHnShOkComplCode)) { // whole file received - // delete it + // delete it #ifdef DEBUG - printf("deleting file %p, %s\r\n",inf,infn); + printf("deleting file %p, %s\r\n",inf,infn); #endif - SnSDUtilsWhisperer::DeleteFile(inf, infn); - didDel=true; - } else if ( hndshk==SnHeaderFrame::kHnShOkStopCode ) { + SnSDUtilsWhisperer::DeleteFile(inf, infn); + didDel=true; + } else if ( hndshk==SnHeaderFrame::kHnShOkStopCode ) { + res = SnCommWin::kOkStopComm; + } else if ( (hndshk==SnHeaderFrame::kHnShOkDelAlCode) || + (hndshk==SnHeaderFrame::kHnShOkDelRnCode) ) { + if ( GetDeleteAllConfirmCode(curConf, + kDelAllConfCodeLen, handshakeTimeout, + genBuf, bsize) ) { + if (hndshk==SnHeaderFrame::kHnShOkDelAlCode) { + SnSDUtilsWhisperer::DeleteAllFiles(); + } else if (hndshk==SnHeaderFrame::kHnShOkDelRnCode) { + SnSDUtilsWhisperer::DeleteFilesOfRun(hndshkLen); + } res = SnCommWin::kOkStopComm; - } else if ( (hndshk==SnHeaderFrame::kHnShOkDelAlCode) || - (hndshk==SnHeaderFrame::kHnShOkDelRnCode) ) { - if ( GetDeleteAllConfirmCode(curConf, - kDelAllConfCodeLen, handshakeTimeout, - genBuf, bsize) ) { - if (hndshk==SnHeaderFrame::kHnShOkDelAlCode) { - SnSDUtilsWhisperer::DeleteAllFiles(); - } else if (hndshk==SnHeaderFrame::kHnShOkDelRnCode) { - SnSDUtilsWhisperer::DeleteFilesOfRun(hndshkLen); - } - res = SnCommWin::kOkStopComm; - } } + } else if ( hndshk==SnHeaderFrame::kHnShOkReqRnCode ) { + res = SnCommWin::kOkWthMsgReqRun; } } +*/ } - } + } // if genBuf!=0 } else { #ifdef DEBUG printf("inf=0!\r\n"); @@ -194,25 +226,91 @@ return res; } +SnCommWin::ECommWinResult SnCommWin::HandleHandshake(FILE* inf, const char* infn, + const SnConfigFrame& curConf, + SnEventFrame& evt, + SnPowerFrame& pow, + char* const genBuf, + const uint32_t bsize, + const uint32_t handshakeTimeout, + const uint8_t hndshk, + const uint32_t hndlen, + const uint32_t* nevts) { + + SnCommWin::ECommWinResult res = SnCommWin::kUnexpectedRec; + + if ( (hndshk==SnHeaderFrame::kHnShNoReplyCode) + || (hndshk==SnHeaderFrame::kHnShOkPartlCode) ) { + // nothing to do + res = SnCommWin::kOkWithMsg; + } else if (hndshk==SnHeaderFrame::kHnShFailNonCode) { + res = SnCommWin::kFailNoneSent; + } else if (hndshk==SnHeaderFrame::kHnShFailPrtCode) { + res = SnCommWin::kFailPartSent; + } else if (hndshk==SnHeaderFrame::kHnShOkComplCode) { + // file received + if ( (curConf.IsDeletingFiles()) + && (inf!=SnSDUtils::GetCurFile()) + && ((nevts!=0) && (*nevts==0)) ) { // whole file was received + // delete this file +#ifdef DEBUG + printf("deleting file %p, %s\r\n",inf,infn); +#endif + SnSDUtilsWhisperer::DeleteFile(inf, infn); + res = SnCommWin::kOkWthMsgDidDel; + } else { + res = SnCommWin::kOkWithMsg; + } + } else if ( hndshk==SnHeaderFrame::kHnShOkStopCode ) { + res = SnCommWin::kOkStopComm; + } else if ( (hndshk==SnHeaderFrame::kHnShOkDelAlCode) || + (hndshk==SnHeaderFrame::kHnShOkDelRnCode) ) { + if ( GetDeleteAllConfirmCode(curConf, + kDelAllConfCodeLen, + handshakeTimeout, + genBuf, bsize) ) { + if (hndshk==SnHeaderFrame::kHnShOkDelAlCode) { +#ifdef DEBUG + printf("delete all\r\n"); +#endif + SnSDUtilsWhisperer::DeleteAllFiles(); + } else if (hndshk==SnHeaderFrame::kHnShOkDelRnCode) { +#ifdef DEBUG + printf("delete run %u\r\n",hndlen); +#endif + SnSDUtilsWhisperer::DeleteFilesOfRun(hndlen); + } + res = SnCommWin::kOkStopComm; + } + } else if ( hndshk==SnHeaderFrame::kHnShOkReqRnCode ) { +#ifdef DEBUG + printf("run %u requested\r\n",hndlen); +#endif + SnSDUtils::SendAllOfRun(this, handshakeTimeout, + genBuf, bsize, curConf, evt, pow, + hndlen); + res = SnCommWin::kOkStopComm; + } + + return res; +} + + bool SnCommWin::GetDeleteAllConfirmCode(const SnConfigFrame& conf, const uint32_t length, const uint32_t timeout, char* const buf, const uint32_t bsize) { bool ret = false; - // ensure we don't wait forever - const uint32_t to = ((timeout>0) && (timeout<kAbsMaxTimer)) - ? conf.GetTimeoutTime(time(0), timeout) - : conf.GetTimeoutTime(time(0), kListenTimeout); #ifdef DEBUG - printf("GetDeleteAllConfirmCode, to=%u\r\n",to); + printf("GetDeleteAllConfirmCode, timeout=%u\r\n",timeout); #endif // better pull all the bytes no matter the buffer size const uint32_t ll = (bsize<length) ? bsize : length; int mlen = 0; while ( mlen<length ) { - mlen += fComm->ReceiveAll(buf, ll, to); - if (fComm->IsTimedOut(to)) { + mlen += fComm->ReceiveAll(buf, ll, timeout); + if (fComm->IsTimedOut(timeout)) { break; } } @@ -234,15 +332,11 @@ const uint32_t bsize, uint8_t& hndShkCode, uint32_t* hndShkLen) { - // ensure we don't wait forever - const uint32_t to = ((timeout>0) && (timeout<kAbsMaxTimer)) - ? conf.GetTimeoutTime(time(0), timeout) - : conf.GetTimeoutTime(time(0), kListenTimeout); #ifdef DEBUG - printf("WaitHandshake, to=%u\r\n",to); + printf("WaitHandshake, timeout=%u\r\n",timeout); #endif - const int mlen = fComm->ReceiveAll(buf, SnHeaderFrame::SizeOf(), to); + const int mlen = fComm->ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeout); if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) { uint32_t msgLen=0; const char* b = buf; @@ -301,130 +395,130 @@ const uint32_t fbs = ldlen+1+12+1; char fnb[fbs]; memset(fnb, 0, sizeof(char)*fbs); - char* fb = fnb; - memcpy(fb, kLocalDir, ldlen); fb+=ldlen; // /local - memset(fb, '/', 1); fb+=1; // / - strncpy(fb, fname.c_str(), 8); fb+=8; // FILENAME - *fb = '.'; ++fb; // . - strncpy(fb, fname.c_str()+fname.size()-3, 3); // EXT - // all that just for the file name! - FILE* lf = fopen(fnb,"wb"); + // find the extension + const size_t xdot = fname.rfind('.'); + if (xdot!=string::npos && (fname.size()==(4+xdot))) { + const size_t fnpl = (xdot>8) ? 8 : xdot; + char* fb = fnb; + memcpy(fb, kLocalDir, ldlen); fb+=ldlen; // /local + *fb = '/'; ++fb; // / + strncpy(fb, fname.c_str(), fnpl); fb+=fnpl; // FILENAME + *fb = '.'; ++fb; // . + strncpy(fb, fname.c_str()+xdot+1, 3); // EXT + // all that just for the file name! + FILE* lf = fopen(fnb,"wb"); #ifdef DEBUG - printf("tried to open file [%s]. lf=%p\r\n",fnb,(void*)lf); -#endif - // get all the data and dump it into the file - int b = 0, toget = 0; - while ( mlen>b ) { - if (fComm->IsTimedOut(timeout)) { -#ifdef DEBUG - printf("timeout while getting file\r\n"); + printf("tried to open file [%s]. lf=%p\r\n",fnb,(void*)lf); #endif - res = kFailTimeout; - break; - } - toget = mlen - b; - if (toget>bsize) { - toget = bsize; - } - const int got = fComm->ReceiveAll(buf, toget, timeout); - if (lf!=NULL) { + // get all the data and dump it into the file + int b = 0, toget = 0; + while ( mlen>b ) { + if (fComm->IsTimedOut(timeout)) { #ifdef DEBUG - printf("writing %d bytes to file\r\n", got); + printf("timeout while getting file\r\n"); #endif - SnBitUtils::WriteTo(lf, buf, got); - } - b += got; - } - uint32_t crc=0; - if (lf!=NULL) { - // calculate the crc from what's actually in the file - fclose(lf); // to flush it -#ifdef DEBUG - printf("fopen: %s\r\n",fnb); -#endif - lf = fopen(fnb,"rb"); - fseek(lf, 0, SEEK_END); - int32_t fend = ftell(lf); - fseek(lf, 0, SEEK_SET); - char c; - for (int32_t i=0; i<fend; ++i) { - SnBitUtils::ReadFrom(lf, c); - if (feof(lf)==0 && ferror(lf)==0) { - crc = SnCRCUtils::update_crc32_xfer(crc, c); - } else { + res = kFailTimeout; break; } - } - fclose(lf); + toget = mlen - b; + if (toget>bsize) { + toget = bsize; + } + const int got = fComm->ReceiveAll(buf, toget, timeout); + if (lf!=NULL) { #ifdef DEBUG - printf("closed file. crc = %u\r\n", crc); -#endif - } -#ifdef DEBUG - printf("mlen=%u, b=%d, eq=%s\r\n",mlen,b, - (mlen==b)?"true":"false"); + printf("writing %d bytes to file\r\n", got); #endif - if ( mlen!=b ) { - if (res > kUnexpectedRec) { - res = kUnexpectedRec; - } // otherwise it's already worse - } else { - // check that the file is ok - // get the checksum - res = GetHeader(timeout, buf, bsize, mcode, mlen); - if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileChksCode) ) { + SnBitUtils::WriteTo(lf, buf, got); + } + b += got; + } // file data receive loop + uint32_t crc=0; + if (lf!=NULL) { + // calculate the crc from what's actually in the file + fclose(lf); // to flush it #ifdef DEBUG - printf("received chksum=%u, crc=%u, eq=%s\r\n", - mlen,crc,(crc==mlen)?"true":"false"); + printf("fopen: %s\r\n",fnb); #endif - if (crc != mlen) { -#ifdef DEBUG - printf("checksums differ! unexpected.\r\n"); -#endif - res = kUnexpectedRec; // important! + lf = fopen(fnb,"rb"); + fseek(lf, 0, SEEK_END); + int32_t fend = ftell(lf); + fseek(lf, 0, SEEK_SET); + char c; + for (int32_t i=0; i<fend; ++i) { + SnBitUtils::ReadFrom(lf, c); + if (feof(lf)==0 && ferror(lf)==0) { + crc = SnCRCUtils::update_crc32_xfer(crc, c); + } else { + break; + } } - } - } - //TODO: REMOVE - /* - char dbg[250]; memset(dbg, 0, 250); - char* dd = buf; - sprintf(dbg,"lf=%s (%p), my crc=%d, b=%d, mlen=%d\r\n",fnb,(void*)lf,crc,crc,b,mlen); - SnHeaderFrame::WriteTo(dd, SnHeaderFrame::kStringCode, strlen(dbg)); - strcpy(buf+SnHeaderFrame::SizeOf(),dbg); - SendAll(buf, SnHeaderFrame::SizeOf() + strlen(dbg), timeout); - */ - /////////// - if (lf!=NULL) { - if ( res<kOkWithMsg ) { - // timeout, bad checksum, something else bad? + fclose(lf); +#ifdef DEBUG + printf("closed file. crc = %u\r\n", crc); +#endif + } // if output file not 0 +#ifdef DEBUG + printf("mlen=%u, b=%d, eq=%s\r\n",mlen,b, + (mlen==b)?"true":"false"); +#endif + if ( mlen!=b ) { + if (res > kUnexpectedRec) { + res = kUnexpectedRec; + } // otherwise it's already worse + } else { + // check that the file is ok + // get the checksum + res = GetHeader(timeout, buf, bsize, mcode, mlen); + if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileChksCode) ) { +#ifdef DEBUG + printf("received chksum=%u, crc=%u, eq=%s\r\n", + mlen,crc,(crc==mlen)?"true":"false"); +#endif + if (crc != mlen) { #ifdef DEBUG - printf("removing %s\r\n",fnb); + printf("checksums differ! unexpected.\r\n"); +#endif + res = kUnexpectedRec; // important! + } + } + } // end get remote file checksum + + if (lf!=NULL) { + if ( res<kOkWithMsg ) { + // timeout, bad checksum, something else bad? +#ifdef DEBUG + printf("removing %s\r\n",fnb); #endif - remove(fnb); // delete the file - } else { - // if we got a new program, remove the old ones. - // (schedule myself for immediate de-resolution) - // - // first just count how many we would save - const uint16_t nSavedBins = LoopLocalDirBinFiles(false, fname); + remove(fnb); // delete the file + } else { + // if we got a new program, remove the old ones. + // (schedule myself for immediate de-resolution) + // + // first just count how many we would save + const uint16_t nSavedBins = LoopLocalDirBinFiles(false, fname); #ifdef DEBUG - printf("nSavedBins=%hu",nSavedBins); + printf("nSavedBins=%hu",nSavedBins); #endif - if (nSavedBins==1) { - // ok. new program will be the only one. remove the others - // hope the new program works! - LoopLocalDirBinFiles(true, fname); + if (nSavedBins==1) { + // ok. new program will be the only one. remove the others + // hope the new program works! + LoopLocalDirBinFiles(true, fname); #ifdef DEBUG - printf("rebooting\r\n"); + printf("rebooting\r\n"); #endif - // goodbye cruel world, it's over. walk on by... - mbed_reset(); - } - } + // goodbye cruel world, it's over. walk on by... + mbed_reset(); + } + } // end check new program block + } // if output file not 0 + } else { + // filename mangled. either doesn't contain a '.' + // or the extension is longer than 3 letters + res = SnCommWin::kUnexpectedRec; } - } + } // if header ok return res; } @@ -522,9 +616,18 @@ // get config const int clen = fComm->ReceiveAll(confBuf, mlen, timeOut); if (clen>0 && static_cast<uint32_t>(clen)==mlen) { - const char* b = confBuf; - conf.ReadFrom(b); - res = SnCommWin::kOkWithMsg; + const uint8_t Rv = SnConfigFrame::PeekIOversion(confBuf); + if (SnConfigFrame::IsIOversionOk(Rv)) { + const char* b = confBuf; + conf.ReadFrom(b); + res = SnCommWin::kOkWithMsg; + } else { + res = SnCommWin::kUnexpectedRec; + char s[256]; + sprintf(s,"Cannot accept config version [%hhu]. " + "Expect [%hhu].",Rv,SnConfigFrame::kIOVers); + SendString(s, timeOut); + } } else { res = SnCommWin::kUnexpectedRec; } @@ -537,6 +640,23 @@ return res; } +int32_t SnCommWin::SendHndshkReq(char* const genBuf, + const uint32_t timeout_clock) { + // send a request demanding a handshake + // as we will be waiting for a response after this, + // FinishSending is also called + char* b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kHnShDemandCode, 0); + const uint32_t bytesToBeSent = b-genBuf; + const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock); + const int32_t flen = fComm->FinishSending(timeout_clock); +#ifdef DEBUG + printf("SendHndshkReq: time = %u, timeout = %u, mlen=%d, flen=%d\r\n", + time(0), timeout_clock, mlen, flen); +#endif + return mlen+flen; +} + SnCommWin::ECommWinResult SnCommWin::SendStatus(const SnConfigFrame& conf, const SnEventFrame& evt, const SnPowerFrame& pow, @@ -560,11 +680,12 @@ SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, pow.SizeOf(SnPowerFrame::kIOvers)); pow.WriteTo(b); - int msiz = b-genBuf; + int32_t msiz = b-genBuf; #ifdef DEBUG printf("calling SendAll (status)\r\n"); #endif - int mlen = fComm->SendAll(genBuf, msiz, timeout_clock); + int32_t mlen = fComm->SendAll(genBuf, msiz, timeout_clock); + mlen += fComm->FinishSending(timeout_clock); #ifdef DEBUG printf("status frame:\r\n"); for (uint32_t i=0; i<msiz; i++) { @@ -591,6 +712,7 @@ printf("\r\n"); #endif mlen = fComm->SendAll(genBuf, msiz, timeout_clock); + mlen += fComm->FinishSending(timeout_clock); if (mlen==msiz) { return SnCommWin::kOkMsgSent; } @@ -608,9 +730,10 @@ return (ok) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; } -SnCommWin::ECommWinResult SnCommWin::SendFilename(const char* inf, - char* const genBuf, - const uint32_t timeout_clock) { +int32_t SnCommWin::SendFilename(const char* inf, + char* const genBuf, + int32_t& bytesToBeSent, + const uint32_t timeout_clock) { #ifdef DEBUG printf("SnCommWin::SendFilename %s\r\n",inf); #endif @@ -630,40 +753,49 @@ char* b = genBuf; SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFilenameCode, flen); b = SnBitUtils::WriteTo(b, fn, flen); - const int msiz = b-genBuf; - const int mlen = fComm->SendAll(genBuf, msiz, timeout_clock); + bytesToBeSent = b-genBuf; + const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock); #ifdef DEBUG printf("time = %u, timeout = %u\r\n",time(0), timeout_clock); #endif - return (msiz==mlen) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; + return mlen; } -int SnCommWin::SendFileBlock(FILE* inf, - const uint8_t blockHeaderCode, - const uint32_t blockSize, - char* const genBuf, - const uint32_t timeout) { +int32_t SnCommWin::SendFileBlock(FILE* inf, + const uint8_t blockHeaderCode, + const uint32_t blockSize, + char* const genBuf, + int32_t& bytesToSend, + const uint32_t timeout) { // sends the block from the file. does not check if the file has sufficient bytes // this should be done before calling this function // (where the number of bytes in the file can be cached) + // + // bytesToSend will be set to the total bytes that should be delivered eventually + // the number of bytes actually shipped out by SendAll is returned char* b = genBuf; SnHeaderFrame::WriteTo(b, blockHeaderCode, blockSize); SnBitUtils::ReadFrom(inf, b, blockSize); #ifdef DEBUG printf("Sending block hc %02x, len=%u\r\n",blockHeaderCode,blockSize+SnHeaderFrame::SizeOf()); #endif - return fComm->SendAll(genBuf, blockSize+SnHeaderFrame::SizeOf(), timeout); + bytesToSend = blockSize+SnHeaderFrame::SizeOf(); + return fComm->SendAll(genBuf, bytesToSend, timeout); } -SnCommWin::ECommWinResult SnCommWin::SendFileContents(FILE* inf, - const SnConfigFrame& curConf, - SnEventFrame& evt, - SnPowerFrame& pow, - char* const genBuf, - uint32_t nevts, - const uint32_t timeout_clock) { +int32_t SnCommWin::SendFileContents(FILE* inf, + const SnConfigFrame& curConf, + SnEventFrame& evt, + SnPowerFrame& pow, + char* const genBuf, + uint32_t nevts, + int32_t& bytesToBeSent, + const uint32_t timeout_clock) { // firstEvt==0 ==> start at beginning // nevts==0 ==> all events + // + // bytesToSend will be set to the total bytes that should be delivered eventually + // the number of bytes actually shipped out by SendAll is returned #ifdef DEBUG printf("SendFileContents (byte streaming)\r\n"); @@ -687,25 +819,30 @@ // variables used when sending data char* b = genBuf; - int msiz, mlen; + int32_t msiz(0), mlen(0), mtogo(0), tsent(0); // count number of events / power readings sent - uint32_t evtsSent=0, powsSent=0; + uint32_t evtsSent=0, powsSent=0, crc=0; // first is the file header, which has no SnHeaderFrame msiz = SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers); bool ok = (ftell(inf)+msiz)<=fend; if (ok) { mlen = SendFileBlock(inf, SnHeaderFrame::kFileHeadrCode, - msiz, genBuf, timeout_clock); - ok &= (msiz+SnHeaderFrame::SizeOf())==mlen; - + msiz, genBuf, mtogo, timeout_clock); + //ok &= (msiz+SnHeaderFrame::SizeOf())==mlen; + bytesToBeSent += mtogo; + tsent += mlen; #ifdef DEBUG printf("sent file header. ok=%d\r\n",(int)ok); #endif - + // calc crc w/o the header block of the file header, as + // this does not get stored in the file + crc = SnCRCUtils::GetUpdatedCRC32for(crc, genBuf+SnHeaderFrame::SizeOf(), + mtogo-SnHeaderFrame::SizeOf()); + // the header info for each block - uint8_t hcode; - uint32_t hlen; + uint8_t hcode(0); + uint32_t hlen(0); // now just loop through file and send each block bool fok = true; @@ -721,32 +858,29 @@ "ok=%d, fok=%d\r\n", hcode, hlen, ftell(inf), fend, (int)ok, (int)fok); #endif - if (ok) { + if (fok) { // send the block // TODO: repack events? - msiz = hlen + SnHeaderFrame::SizeOf(); - mlen = SendFileBlock(inf, hcode, hlen, genBuf, timeout_clock); - ok &= msiz==mlen; - if (ok) { - if (hcode==SnHeaderFrame::kEventCode) { - ++evtsSent; - if (nevts>0) { - if (evtsSent>=nevts) { + mlen = SendFileBlock(inf, hcode, hlen, genBuf, + mtogo, timeout_clock); + bytesToBeSent += mtogo; + tsent += mlen; + crc = SnCRCUtils::GetUpdatedCRC32for(crc, genBuf, mtogo); + + if (hcode==SnHeaderFrame::kEventCode) { + ++evtsSent; + if (nevts>0) { + if (evtsSent>=nevts) { #ifdef DEBUG - printf("send %u events. stop\r\n",evtsSent); + printf("send %u events. stop\r\n",evtsSent); #endif - break; - } + break; } - } else if (hcode==SnHeaderFrame::kPowerCode) { - ++powsSent; } - } else { -#ifdef DEBUG - printf("not ok when sending hcode=%02x\r\n",hcode); -#endif - } // if ok after sending block - } // if ok after sending block header + } else if (hcode==SnHeaderFrame::kPowerCode) { + ++powsSent; + } + } // otherwise file size not sufficient for this block } // loop over file contents } else { // otherwise file size not sufficient for file header @@ -758,6 +892,23 @@ #ifdef DEBUG printf("loop done. ok=%d\r\n",(int)ok); #endif + + // send the crc +#ifdef DEBUG + printf("sending crc (%u)\r\n",crc); +#endif + b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kMbedFileChksCode, sizeof(uint32_t)); + b = SnBitUtils::WriteTo(b, crc); + msiz = b - genBuf; + mlen = fComm->SendAll(genBuf, msiz, timeout_clock); + bytesToBeSent += msiz; + tsent += mlen; + +#ifdef DEBUG + printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen); +#endif + // send number of events sent #ifdef DEBUG @@ -768,10 +919,11 @@ b = SnBitUtils::WriteTo(b, evtsSent); msiz = b - genBuf; mlen = fComm->SendAll(genBuf, msiz, timeout_clock); - ok &= msiz==mlen; - + bytesToBeSent += msiz; + tsent += mlen; + #ifdef DEBUG - printf("ok=%d (msiz=%d, mlen=%d)\r\n", (int)ok, msiz, mlen); + printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen); #endif // send number of power readings sent @@ -783,13 +935,13 @@ b = SnBitUtils::WriteTo(b, powsSent); msiz = b - genBuf; mlen = fComm->SendAll(genBuf, msiz, timeout_clock); - ok &= msiz==mlen; + bytesToBeSent += msiz; + tsent += mlen; #ifdef DEBUG - printf("ok=%d (msiz=%d, mlen=%d)\r\n", (int)ok, msiz, mlen); + printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen); #endif - // put file position back fseek(inf, fpos, SEEK_SET); @@ -797,252 +949,7 @@ printf("end contents: ok=%d\r\n",(int)ok); #endif - return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; -} - -/* -SnCommWin::ECommWinResult SnCommWin::SendFileContents(FILE* inf, - const SnConfigFrame& curConf, - SnEventFrame& evt, - SnPowerFrame& pow, - char* const genBuf, - uint32_t nevts, - const uint32_t timeout_clock, - const uint32_t firstEvt) { - printf("comm win send file contents\r\n"); - // firstEvt==0 ==> start at beginning - // nevts==0 ==> all events - - const int fpos = ftell(inf); - if (fpos>0) { - fseek(inf, 0, SEEK_SET); - } - // how many bytes? - fseek(inf, 0, SEEK_END); // go to end - const int fend = ftell(inf); - fseek(inf, 0, SEEK_SET); // go to start - printf("fend=%d\r\n",fend); - printf("fpos=%d\r\n",fpos); - // get file header - uint64_t macadr; - uint32_t run; - uint16_t seq; - bool ok = (ftell(inf)+SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers))<=fend; - if (ok) { - SnSDUtils::ReadFileHeader(inf, macadr, run, seq, &pow); - printf("read file header: run %u, seq %hu\r\n",run,seq); - } - - printf(">>> file hdr read ftell(inf)=%d\r\n",ftell(inf)); - - // check block - uint8_t hcode; - uint32_t hlen; - ok &= (ftell(inf)+SnHeaderFrame::SizeOf())<=fend; - if (ok) { - SnSDUtils::ReadBlockHeader(inf, hcode, hlen); - printf("read block hd %02x, len %u\r\n",hcode,hlen); - if (hcode==SnHeaderFrame::kPowerCode) { - ok &= (ftell(inf)+SnPowerFrame::SizeOf(SnPowerFrame::kIOvers))<=fend; - if (ok) { - pow.ReadFrom(inf); - printf("read power: v1=%g, v2=%g\r\n",pow.GetAveV1(), pow.GetAveV2()); - // now read the next header - ok &= (ftell(inf)+SnHeaderFrame::SizeOf())<=fend; - if (ok) { - SnSDUtils::ReadBlockHeader(inf, hcode, hlen); - printf("read new header: hc %02x, hlen=%u\r\n",hcode,hlen); - } - } - } - } - - printf(">>> power tried ftell(inf)=%d\r\n",ftell(inf)); - - printf("hcode=%02x\r\n",hcode); - printf("ok=%d\r\n",(int)ok); - printf("feof=%d\r\n",feof(inf)); - printf("ferror=%d\r\n",ferror(inf)); - printf("%d+%u <= %d ? %d\r\n",ftell(inf),hlen,fend, - (int)((ftell(inf)+hlen)<=fend)); - - // TODO: check memory for temporary config/event frames? - // get config - while ((hcode!=SnHeaderFrame::kConfigCode) - && ok - && (feof(inf)==0) - && (ferror(inf)==0) - && ((ftell(inf)+hlen) <= fend) ) { - printf("skip: ftell=%d, hlen=%u\r\n",ftell(inf),hlen); - fseek(inf, hlen, SEEK_CUR); // skip this block - ok = (ftell(inf)+SnHeaderFrame::SizeOf())<=fend; - if (ok) { - SnSDUtils::ReadBlockHeader(inf, hcode, hlen); - printf("hcs >>> ftell(inf)=%d, hcode=%02x, hlen=%u\r\n",ftell(inf),hcode,hlen); - printf("feof=%d, ferror=%d\r\n",feof(inf),ferror(inf)); - } - } - - printf("checking ftell\r\n"); - bool gotConf = false; - ok = (ftell(inf)+hlen) <= fend; - printf("making temp config\r\n"); - SnConfigFrame conf; // TODO: SOMETIMES STALLS HERE! - printf("trying to read\r\n"); - if (ok && (hcode==SnHeaderFrame::kConfigCode)) { - printf("reading config from ftell=%d, hcode=%02x, hlen=%u, ok=%d\r\n", - ftell(inf), hcode, hlen, (int)ok); - conf.ReadFrom(inf); - gotConf = (ftell(inf) <= fend) && (feof(inf)==0) && (ferror(inf)==0); - } - printf(">>> conf. ftell(inf)=%d, gotconf=%d\r\n",ftell(inf),(int)gotConf); + return tsent; - char* b = genBuf; - int msiz, mlen; - if (ok && gotConf) { - // get event size - uint8_t sLoseLSB=0, sLoseMSB=0; - uint16_t sWvBase=0; - curConf.GetPackParsFor(GetCommType(), sLoseLSB, sLoseMSB, sWvBase); - - // size of event in file - const uint32_t esize = SnEventFrame::SizeOf(SnEventFrame::kIOVers, - conf.GetWvLoseLSB(), - conf.GetWvLoseMSB()); - - printf("esize=%u\r\n",esize); - - // number of events / power readings we will send - uint32_t evtsSent=0, powsSent=0; - b = genBuf; - // send the file header - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileHeadrCode, - SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers)); - SnSDUtils::WriteFileHeader(b, macadr, run, seq); - msiz = b-genBuf; - mlen = SendAll(genBuf, msiz, timeout_clock); - if (mlen==msiz) { - // send power header - b = genBuf; - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, - pow.SizeOf(SnPowerFrame::kIOvers)); - pow.WriteTo(b); - msiz = b-genBuf; - mlen = SendAll(genBuf, msiz, timeout_clock); - ++powsSent; - if (mlen==msiz) { - // send the config - b = genBuf; - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kConfigCode, - conf.SizeOf(SnConfigFrame::kIOVers)); - conf.WriteTo(b); - msiz = b-genBuf; - mlen = SendAll(genBuf, msiz, timeout_clock); - if (mlen==msiz) { - ok = true; - } - } - } - - printf("ok=%d, nevts=%u\r\n",(int)ok,nevts); - - if (ok) { - // size of event sent over afar - const uint32_t ssize = SnEventFrame::SizeOf(SnEventFrame::kIOVers, - sLoseLSB, sLoseMSB); - - // loop over blocks. send event & power frames - // until EOF or nevets have been sent - uint8_t hc; uint32_t hl; - while (ok && (feof(inf)==0) - && (ferror(inf)==0) - && (ftell(inf)<fend) ) { // feof doesn't seem to work - printf(">>> ftell(inf)=%d\r\n",ftell(inf)); - if ((ftell(inf)+SnHeaderFrame::SizeOf())<=fend) { - SnSDUtils::ReadBlockHeader(inf, hc, hl); - if (hc==SnHeaderFrame::kEventCode) { - if ((ftell(inf)+ssize)<=fend) { - evt.ReadFrom(inf, genBuf, - conf.GetWvLoseLSB(), conf.GetWvLoseMSB(), - conf.GetWvBaseline()); - if (evt.GetEvtNum()>=firstEvt) { - ++evtsSent; - printf("sending evt %u\r\n",evtsSent); - // must be after evt.Read, since that uses the buffer - b = genBuf; - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode, ssize); - evt.WriteTo(b, sLoseLSB, sLoseMSB, sWvBase); // will repack if necessary - msiz = b-genBuf; //SnHeaderFrame::SizeOf()+ssize; - mlen = SendAll(genBuf, msiz, timeout_clock); - ok &= mlen==msiz; - } - } else { - printf("event header, but not enough bytes in file\r\n"); - ok = false; - } - } else if (hc==SnHeaderFrame::kPowerCode) { - if ((ftell(inf)+SnPowerFrame::SizeOf(SnPowerFrame::kIOvers))<=fend) { - ++powsSent; - pow.ReadFrom(inf); - printf("sending power frame %u, v1=%g, v2=%g, t=%u\r\n", - powsSent, pow.GetAveV1(), pow.GetAveV2(), pow.GetTime()); - b = genBuf; - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, - SnPowerFrame::SizeOf(SnPowerFrame::kIOvers)); - pow.WriteTo(b); - msiz = b-genBuf; - mlen = SendAll(genBuf, msiz, timeout_clock); - ok &= mlen==msiz; - } else { - printf("power header, but not enough bytes in file\r\n"); - ok = false; - } - } else { - printf("unhandled block. hc=%hhu, hl=%u\r\n", - hc, hl); - if ((ftell(inf)+hl)<=fend) { - fseek(inf, hl, SEEK_CUR); // skip this block - } else { - printf("not enough bytes in file to skip block\r\n"); - ok = false; - } - } - } else { - printf("not enough bytes in file to read header\r\n"); - printf("feof=%d\r\n",feof(inf)); - printf("ftell(inf)=%d, hdr size=%u, fend=%u\r\n", - (ftell(inf)), SnHeaderFrame::SizeOf(), fend); - ok = false; - } - } - // send number of events sent - b = genBuf; - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t)); - b = SnBitUtils::WriteTo(b, evtsSent); - msiz = b - genBuf; - mlen = SendAll(genBuf, msiz, timeout_clock); - ok &= msiz==mlen; - // send number of power readings sent - b = genBuf; - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t)); - b = SnBitUtils::WriteTo(b, powsSent); - msiz = b - genBuf; - mlen = SendAll(genBuf, msiz, timeout_clock); - ok &= msiz==mlen; - } - } else { - printf("failed to get config from file\r\n"); - // send corrupted file handshake - b = genBuf; - SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileReadFailCode, 0u); - msiz = b-genBuf; - mlen = SendAll(genBuf, msiz, timeout_clock); - ok &= msiz==mlen; - } - - // put file position back - fseek(inf, fpos, SEEK_SET); - - return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; + //return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; } -*/