Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnCommWin.cpp
- Committer:
- uci1
- Date:
- 2012-08-08
- Revision:
- 8:95a325df1f6b
- Parent:
- 6:6f002d202f59
- Child:
- 10:3c93db1cfb12
File content as of revision 8:95a325df1f6b:
#include "SnCommWin.h" #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) { printf("SnCommWin::SendData\r\n"); ECommWinResult res = kUndefFail; const uint32_t to = (conf.IsObeyingTimeout()) ? timeout : kSecsPerYear; if (conf.IsSendingAllFiles()) { printf("sending all files\r\n"); res = SnSDUtils::SendAllFiles(this, conf.IsDeletingFiles(), to, genBuf, bsize, conf, evt, pow); } else { if (conf.GetCommSendData()==0) { printf("no data to send\r\n"); res = kOkNoMsg; } else { const uint32_t nev = (conf.GetCommSendData()>0) ? conf.GetCommSendData() // send N events : 0u; // send all events in last file res = SendData(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), conf, evt, pow, genBuf, bsize, nev, to); printf("after send data cur file, res=%d\r\n",(int)res); } } return res; } 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, const uint32_t timeout_clock, const uint32_t firstEvt) { // nevts==0 ==> send all events printf("SnCommWin::SendData cur file\r\n"); ECommWinResult res = kUndefFail; if (inf!=0) { // send the file name res = SendFilename(infn, genBuf, timeout_clock); if (res>kAllFails) { if (genBuf!=0) { // send the contents res = SendFileContents(inf, curConf, evt, pow, genBuf, nevts, timeout_clock, firstEvt); if (res>SnCommWin::kAllFails) { // wait for handshake uint8_t hndshk=0; res = WaitHandshake(timeout_clock, genBuf, bsize, hndshk); if ( (res==SnCommWin::kOkWithMsg) // got handshake && (nevts==0) // sent whole file && curConf.IsDeletingFiles() // want to delete //&& (strcmp(infn, SnSDUtils::GetCurFileName()!=0) // not current file (TODO?) && (hndshk==SnHeaderFrame::kHnShOkComplCode)) { // whole file received // delete it SnSDUtilsWhisperer::DeleteFile(inf, infn); } } } } } 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; }