![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: SnCommWin.cpp
- Revision:
- 8:95a325df1f6b
- Parent:
- 6:6f002d202f59
- Child:
- 10:3c93db1cfb12
--- a/SnCommWin.cpp Sat Aug 04 01:48:55 2012 +0000 +++ b/SnCommWin.cpp Wed Aug 08 23:27:37 2012 +0000 @@ -2,10 +2,14 @@ #include "SnHeaderFrame.h" #include "SnConfigFrame.h" +#include "SnEventFrame.h" +#include "SnPowerFrame.h" +#include "SnStatusFrame.h" #include "SnSDUtils.h" SnCommWin::ECommWinResult SnCommWin::SendData(SnConfigFrame& conf, SnEventFrame& evt, + SnPowerFrame& pow, char* const genBuf, const uint32_t bsize, const uint32_t timeout) { @@ -15,7 +19,7 @@ if (conf.IsSendingAllFiles()) { printf("sending all files\r\n"); res = SnSDUtils::SendAllFiles(this, conf.IsDeletingFiles(), to, - genBuf, bsize, conf, evt); + genBuf, bsize, conf, evt, pow); } else { if (conf.GetCommSendData()==0) { printf("no data to send\r\n"); @@ -25,7 +29,7 @@ conf.GetCommSendData() // send N events : 0u; // send all events in last file res = SendData(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), - conf, evt, genBuf, bsize, nev, to); + conf, evt, pow, genBuf, bsize, nev, to); printf("after send data cur file, res=%d\r\n",(int)res); } } @@ -35,6 +39,7 @@ SnCommWin::ECommWinResult SnCommWin::SendData(FILE* inf, const char* infn, const SnConfigFrame& curConf, SnEventFrame& evt, + SnPowerFrame& pow, char* const genBuf, const uint32_t bsize, const uint32_t nevts, @@ -50,7 +55,7 @@ if (res>kAllFails) { if (genBuf!=0) { // send the contents - res = SendFileContents(inf, curConf, evt, genBuf, + res = SendFileContents(inf, curConf, evt, pow, genBuf, nevts, timeout_clock, firstEvt); if (res>SnCommWin::kAllFails) { // wait for handshake @@ -70,3 +75,287 @@ } return res; } + +SnCommWin::ECommWinResult SnCommWin::WaitHandshake(const uint32_t timeout, + char* const buf, + const uint32_t bsize, + uint8_t& hndShkCode) { + printf("WaitHandshake, to=%u\r\n",timeout); + + const int mlen = ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeout); + if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) { + uint32_t msgLen=0; + const char* b = buf; + SnHeaderFrame::ReadFrom(b, hndShkCode, msgLen); + if ((hndShkCode & SnHeaderFrame::kHndShkBits)!=0) { + return SnCommWin::kOkWithMsg; + } else { + // TODO: somehow handle unexpected message? + return SnCommWin::kUnexpectedRec; + } + } + return SnCommWin::kOkNoMsg; +} + +SnCommWin::ECommWinResult SnCommWin::GetConfig(SnConfigFrame& conf, + const uint32_t timeOut, + char* const confBuf, + const uint32_t bsize) { + // confBuf assumed to alread be of allocated size + + printf("GetConfig, to=%u\r\n",timeOut); + + SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; + if (bsize<SnHeaderFrame::kMaxSizeOf || bsize<SnConfigFrame::kMaxSizeOf) { + res = SnCommWin::kUndefFail; + } else { + // get header + const int hlen = ReceiveAll(confBuf, SnHeaderFrame::SizeOf(), timeOut); + if (hlen>0 && static_cast<uint32_t>(hlen)==SnHeaderFrame::SizeOf()) { + uint8_t mcode=0; uint32_t mlen=0; + const char* b = confBuf; + SnHeaderFrame::ReadFrom(b, mcode, mlen); + printf("mcode=%02x, mlen=%u\r\n", mcode, mlen); + if (mcode!=SnHeaderFrame::kConfigCode) { + res = SnCommWin::kUnexpectedRec; + } else { + // get config + const int clen = ReceiveAll(confBuf, mlen, timeOut); + if (clen>0 && static_cast<uint32_t>(clen)==mlen) { + b = confBuf; + conf.ReadFrom(b); + res = SnCommWin::kOkWithMsg; + } else { + res = SnCommWin::kUnexpectedRec; + } + } + } else { + res = SnCommWin::kUnexpectedRec; + } + } + return res; +} + +SnCommWin::ECommWinResult SnCommWin::SendStatus(const SnConfigFrame& conf, + const SnEventFrame& evt, + const SnPowerFrame& pow, + char* const genBuf, + const uint32_t timeout_clock) { + // TODO: check if connected? + const uint32_t ssize = SnStatusFrame::SizeOf(SnStatusFrame::kIOVers, conf); + char* b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kStatusCode, ssize); + SnStatusFrame::WriteTo(b, GetCommType(), conf, evt, genBuf); +#ifdef DEBUG + printf("status frame:\r\n"); + for (uint32_t i=0; i<msize; i++) { + printf("%02X ",genBuf[i]); + } + printf("\r\n"); +#endif + int msiz = b-genBuf; + int mlen = SendAll(genBuf, msiz, timeout_clock); + if (mlen==msiz) { + printf("status sent\r\n"); + b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, + pow.SizeOf(SnPowerFrame::kIOvers)); + //SnPowerFrame::WriteTo(b, pow.GetAveV1(), pow.GetAveV2(), pow.GetTime()); + pow.WriteTo(b); + msiz = b-genBuf; + mlen = SendAll(genBuf, msiz, timeout_clock); + if (mlen==msiz) { + return SnCommWin::kOkMsgSent; + } + } + return SnCommWin::kFailPartSent; +} + +SnCommWin::ECommWinResult SnCommWin::SendFilename(const char* fn, + char* const genBuf, + const uint32_t timeout_clock) { + printf("afar send filename %s\r\n",fn); + const size_t flen = strlen(fn); + char* b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFilenameCode, flen); + sprintf(b, "%s", fn); + const int msiz = SnHeaderFrame::SizeOf()+flen; + const int mlen = SendAll(genBuf, msiz, timeout_clock); + return (msiz==mlen) ? 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 conf and events\r\n"); + // firstEvt==0 ==> start at beginning + // nevts==0 ==> all events + + const int fpos = ftell(inf); + if (fpos>0) { + fseek(inf, 0, SEEK_SET); + } + + printf("fpos=%d\r\n",fpos); + + // get file header + uint64_t macadr; + uint32_t run; + uint16_t seq; + SnSDUtils::ReadFileHeader(inf, macadr, run, seq, &pow); + + // check block + uint8_t hcode; + uint32_t hlen; + SnSDUtils::ReadBlockHeader(inf, hcode, hlen); + if (hcode==SnHeaderFrame::kPowerCode) { + pow.ReadFrom(inf); + } + + // TODO: check memory for temporary config/event frames? + // get config + while ((hcode!=SnHeaderFrame::kConfigCode) + && (feof(inf)==0) + && (ferror(inf)==0) ) { + fseek(inf, hlen, SEEK_CUR); // skip this block + SnSDUtils::ReadBlockHeader(inf, hcode, hlen); + } + SnConfigFrame conf; + conf.ReadFrom(inf); + + // 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); + + // how many more bytes? + const int fcur = ftell(inf); + fseek(inf, 0, SEEK_END); // go to end + const int fend = ftell(inf); + fseek(inf, fcur, SEEK_SET); // go back + + bool ok = false; + char* b = genBuf; + // send the file header + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileHeadrCode, + SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers)); + SnSDUtils::WriteFileHeader(b, macadr, run, seq); + int msiz = b-genBuf; + int 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); + 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 + uint32_t evtsSent=0, powsSent=0; + uint8_t hc; uint32_t hl; + while (ok && (feof(inf)==0) + && (ferror(inf)==0) ) { + 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; + } + } + } + // 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; + } + + // put file position back + fseek(inf, fpos, SEEK_SET); + + return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; +}