Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnCommAfarTCP.cpp
- Committer:
- uci1
- Date:
- 2012-08-04
- Revision:
- 7:079617408fec
- Parent:
- 6:6f002d202f59
- Child:
- 8:95a325df1f6b
File content as of revision 7:079617408fec:
#include "SnCommAfarTCP.h" #include "EthernetInterface.h" #include "TCPSocketConnection.h" #include "SnSDUtils.h" #include "SnHeaderFrame.h" #include "SnConfigFrame.h" #include "SnEventFrame.h" #include "SnStatusFrame.h" #define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) SnCommAfarTCP::SnCommAfarTCP(const bool useb64, const char* remote, const int32_t rport) : fUseB64(useb64), fRserv(remote), fRport(rport), fEth(new EthernetInterface), fSock(new TCPSocketConnection) { fEth->init("128.195.204.148", // my IP "255.255.255.0", // mask "128.195.204.1"); // gateway //fRserv = "128.195.204.151"; //fRport = 6655; } SnCommAfarTCP::~SnCommAfarTCP() { delete fEth; delete fSock; } int SnCommAfarTCP::DoIO(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 = CALL_MEMBER_FN(*fSock, fcn)(data+b, length-b); switch (res) { case -1: // TODO: how to check the error? continue; case 0: return res; default: b += res; }; } return res; // timeout } int SnCommAfarTCP::ReceiveAll(char* const buf, const uint32_t mlen, const uint32_t timeout_clock) { // TODO: if B64, must return number of bytes of raw (non encoded) message return DoIO(buf, mlen, timeout_clock, &TCPSocketConnection::receive_all); } int SnCommAfarTCP::SendAll(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; while ( (isConn==false) && ( time(0) < timeout) ) { wait_ms(250); isConn = (fEth->connect()==0); } while ( (isConn==false) && ( time(0) < timeout) ) { wait_ms(250); isConn = (fSock->connect(fRserv.c_str(), fRport)==0); } return isConn; } SnCommWin::ECommWinResult SnCommAfarTCP::OpenWindow(const uint32_t timeout, const bool sendStatus, const SnConfigFrame& conf, const SnEventFrame& evt, char* const genBuf) { const bool canCon = Connect(timeout); SnCommWin::ECommWinResult ret = canCon ? SnCommWin::kConnected : SnCommWin::kCanNotConnect; if (canCon && sendStatus) { ret = SendStatus(conf, evt, genBuf, timeout); } return ret; } SnCommWin::ECommWinResult SnCommAfarTCP::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 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; 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 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 SnCommAfarTCP::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); // size of event in file const uint32_t esize = SnEventFrame::SizeOf(conf.GetWvLoseLSB(), conf.GetWvLoseMSB()); printf("esize=%u\r\n",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(b, SnHeaderFrame::kFileNevtsCode, nevts); int msiz; int mlen = SendAll(genBuf, SnHeaderFrame::SizeOf(), timeout_clock); if (mlen==SnHeaderFrame::SizeOf()) { // send the file header b = genBuf; SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileHeadrCode, SnSDUtils::SizeOfFileHeader()); SnSDUtils::WriteFileHeader(b, macadr, run, seq, v1, v2); msiz = SnHeaderFrame::SizeOf()+SnSDUtils::SizeOfFileHeader(); mlen = SendAll(genBuf, msiz, timeout_clock); if (mlen==msiz) { // send the config b = genBuf; SnHeaderFrame::WriteTo(b, SnHeaderFrame::kConfigCode, 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); if (ok) { // size of event sent over afar const uint32_t ssize = SnEventFrame::SizeOf(sLoseLSB, sLoseMSB); 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); 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); // will repack if necessary msiz = SnHeaderFrame::SizeOf()+ssize; mlen = SendAll(genBuf, msiz, timeout_clock); ok &= mlen==msiz; } else { printf("cannot send requested event\r\n"); ok=false; } } } fseek(inf, fpos, SEEK_SET); return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; }