Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

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