Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: SnCommAfarTCP.cpp
- Revision:
- 5:9cea89700c66
- Parent:
- 4:a91682e19d6b
- Child:
- 6:6f002d202f59
--- a/SnCommAfarTCP.cpp Thu Aug 02 05:42:47 2012 +0000 +++ b/SnCommAfarTCP.cpp Fri Aug 03 00:04:34 2012 +0000 @@ -1,6 +1,10 @@ /* #include "SnCommAfarTCP.h" +#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) + +const int SnCommAfarTCP::kSockTimeoutMs = 10; + SnCommAfarTCP::SnCommAfarTCP(const bool useb64, char* const b64buf, const uint32_t bblen) : fUseB64(useb64), fB64buf(b64buf), fbblen(bblen), fRmtServ(remote), @@ -20,18 +24,15 @@ delete fSock; } -int SnCommAfarTCP::Receive(char* const buf, const uin32_t mlen, - const uint32_t bsize, - const uint32_t timeout_clock) { - -} - -int SnCommAfarTCP::SendAll(const char* const data, const uint32_t length, - const uint32_t timeout_clock) { +int SnCommAfarTCP::DoIO(const char* const data, + const uint32_t length, + const uint32_t timeout_clock, + TCPSendRecv fcn) { + // TODO: if B64, must return number of bytes of raw (non encoded) message int res=0; uint32_t b=0; while ( (length>b) && (time(0)<timeout_clock) ) { - res = fSock->send_all(data+b, length-b); + res = CALL_MEMBER_FN(*fSock, fcn)(data+b, length-b, kSockTimeoutMs); switch (res) { case -1: // TODO: how to check the error? @@ -45,6 +46,18 @@ return res; // timeout } +int SnCommAfarTCP::ReceiveAll(char* const buf, const uin32_t mlen, + const uint32_t timeout_clock) { + // TODO: if B64, must return number of bytes of raw (non encoded) message + return DoIO(data, length, timeout_clock, &(TCPSocketConnection::receive_all)); +} + +int SnCommAfarTCP::SendAll(const char* const data, const uint32_t length, + const uint32_t timeout_clock) { + // TODO: if B64, must return number of bytes of raw (non encoded) message + return DoIO(data, length, timeout_clock, &(TCPSocketConnection::send_all)); +} + bool SnCommAfarTCP::Connect(const uint32_t timeout) { bool isConn = false; @@ -81,17 +94,16 @@ SnCommWin::ECommWinResult SnCommAfarTCP::WaitHandshake(const uint32_t timeout, char* const buf, - const uint32_t bsize) { + const uint32_t bsize, + uint8_t& hndShkCode) { printf("WaitHandshake, to=%u\r\n",timeout); - uint32_t mlen=0; // this message length - const bool rd = Receive(buf, mlen, bsize, timeout, fB64buf, fbblen); - if (rd) { + const int mlen = ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeout); + if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) { uint32_t msgLen=0; - uint8_t msgCode=0; const char* b = buf; - SnHeaderFrame::ReadFrom(b, msgCode, msgLen); - if (msgCode==SnHeaderFrame::kHandshakeCode) { + SnHeaderFrame::ReadFrom(b, hndShkCode, msgLen); + if ((hndShkCode & SnHeaderFrame::kHndShkBits)!=0) { return SnCommWin::kOkWithMsg; } else { // TODO: somehow handle unexpected message? @@ -100,4 +112,201 @@ } return SnCommWin::kOkNoMsg; } + +SnCommWin::ECommWinResult SnCommAfarTCP::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::SizeOf() || bsize<conf.SizeOf()) { + 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; + 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) { + conf.ReadFrom(confBuf); + res = SnCommWin::kOkWithMsg; + } else { + res = SnCommWin::kUnexpectedRec; + } + } + } else { + res = SnCommWin::kUnexpectedRec; + } + } + return res; +} + +SnCommWin::ECommWinResult SnCommAfarTCP::SendStatus(const SnConfigFrame& conf, + const SnEventFrame& evt, + char* const genBuf, + const uint32_t timeout_clock) { + // TODO: check if connected? + const uint32_t ssize = SnStatusFrame::SizeOf(conf); + char* b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kStatusCode, ssize); + SnStatusFrame::WriteTo(b, SnConfigFrame::kAfar, 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 + const int mlen = SendAll(genBuf, b-genBuf, timeout_clock); + printf("status sent\r\n"); + return (b-genBuf==mlen) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; +} + +SnCommWin::ECommWinResult SnCommAfarTCP::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 SnCommAfar::SendFileContents(FILE* inf, + const SnConfigFrame& curConf, + SnEventFrame& evt, + char* const genBuf, + uint32_t nevts, + const uint32_t timeout_clock, + const uint32_t firstEvt) { + printf("afar 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, v1, v2; + SnSDUtils::ReadFileHeader(inf, macadr, run, seq, v1, v2); + + // TODO: check memory for temporary config/event frames? + // get config + SnConfigFrame conf; + conf.ReadFrom(inf); + + // get event size + uint8_t sLoseLSB=0, sLoseMSB=0; + uint16_t sWvBase=0; + curConf.GetPackParsFor(SnConfigFrame::kAfar, sLoseLSB, sLoseMSB, sWvBase); + // do we have to unpack & repack events? + const bool repack = (sLoseLSB != conf.GetWvLoseLSB()) + && (sLoseMSB != conf.GetWvLoseMSB()) + && (sWvBase != conf.GetWvBaseline()); + // size of event in file + const uint32_t esize = SnEventFrame::SizeOf(conf.GetWvLoseLSB(), + conf.GetWvLoseMSB()); + + printf("repack=%d, esize=%u\r\n",(int)repack,esize); + + // how many events? + // move up to first event + if (firstEvt>0) { + printf("skip ahead %d\r\n",firstEvt*esize); + fseek(inf, (firstEvt*esize), SEEK_CUR); + } + // get remaining file size + const int fcur = ftell(inf); + fseek(inf, 0, SEEK_END); + const int fend = ftell(inf); + fseek(inf, fcur, SEEK_SET); + const int nevtsLeft = (fend-fcur)/esize; // TODO: check for remainder? + if (nevts==0 || nevtsLeft<nevts) { + nevts = nevtsLeft; + } + + // send number of events to expect + bool ok = false; + char* b = genBuf; + SnHeaderFrame::WriteTo(genBuf, SnHeaderFrame::kFileNevtsCode, nevts); + int mlen = SendAll(genBuf, SnHeaderFrame::SizeOf(), timeout_clock); + if (mlen==SnHeaderFrame::SizeOf()) { + // send the file header + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileHeadrCode, SnSDUtils::SizeOfFileHeader()); + SnSDUtils::WriteFileHeader(b, macadr, run, seq, v1, v2); + int msiz = SnHeaderFrame::SizeOf()+SnSDUtils::SizeOfFileHeader(); + mlen = SendAll(genBuf, msiz, timeout_clock); + if (mlen==msiz) { + // send the config + b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kConfAndEvtsCode, conf.SizeOf()); + conf.WriteTo(b); + msiz = SnHeaderFrame::SizeOf()+conf.SizeOf(); + mlen = SendAll(genBuf, msiz, timeout_clock); + if (mlen==msiz) { + ok = true; + } + } + } + + printf("ok=%d, nevts=%u\r\n",(int)ok,nevts); +//TODO HERE + + if (ok) { + // size of event sent over afar + const uint32_t ssize = (repack) ? + SnEventFrame::SizeOf(sLoseLSB, sLoseMSB) : + esize; + + for (uint32_t i=0; (i<nevts) && ok; i++) { + if (feof(inf)==0 && ferror(inf)==0 && ((ftell(inf)+ssize)<=fend)) { + printf("sending evt %u\r\n",i); + if (repack) { + evt.ReadFrom(inf, genBuf, + conf.GetWvLoseLSB(), conf.GetWvLoseMSB(), + conf.GetWvBaseline()); + // must be after evt.Read, since that uses the buffer + b = genBuf; + SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode, ssize); + evt.WriteTo(b, sLoseLSB, sLoseMSB, sWvBase); + ok &= GetWS().sendBinary( + genBuf, ssize+SnHeaderFrame::SizeOf(), + fB64buf); + } else { + ok &= GetWS().sendBinary( + SnHeaderFrame::GetHdBuf(SnHeaderFrame::kEventCode, + ssize), + SnHeaderFrame::SizeOf(), + inf, ssize, + fB64buf); + } + } else { + printf("cannot send requested event\r\n"); + ok=false; + } + } + } + + fseek(inf, fpos, SEEK_SET); + + return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; +} */ \ No newline at end of file