Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

SnCommAfar.cpp

Committer:
uci1
Date:
2012-06-30
Revision:
0:664899e0b988
Child:
1:e392595b4b76

File content as of revision 0:664899e0b988:

#include "SnCommAfar.h"

#include "Websocket.h"
#include "SnConfigFrame.h"
#include "SnEventFrame.h"
#include "SnStatusFrame.h"

Websocket& SnCommAfar::GetWS() {
    // only one make one socket
    static Websocket* ws = new Websocket("ws://snowflake.ps.uci.edu:6767/ws");
    return *ws;
}

bool SnCommAfar::Connect(Timer& timer, const uint32_t timeout) {
    bool isConn = GetWS().connected();

    while ( (isConn==false) && (timer.read() < timeout) ) {
        wait_ms(250);
        
        isConn = GetWS().connect(&timer, timeout);
    }
    
    return isConn;
}

SnCommWin::ECommWinResult SnCommAfar::OpenWindow(Timer& timer,
                                                 const uint32_t timeout,
                                                 const bool sendStatus,
                                                 const SnConfigFrame& conf,
                                                 const SnEventFrame& evt,
                                                 char* const evtBuf,
                                                 char* const statBuf) {
    // timer = timer for full window
    // timeout = number of seconds to try to connect (not full window)
    
    const bool canCon = Connect(timer, timeout);
    
    SnCommWin::ECommWinResult ret = canCon ? SnCommWin::kConnected
                                           : SnCommWin::kCanNotConnect;
    
    if (canCon && sendStatus) {
        ret = SendStatus(conf, evt, evtBuf, statBuf);
    }
    
    return ret;
}


SnCommWin::ECommWinResult SnCommAfar::GetConfig(SnConfigFrame& conf,
                                                Timer& timer,
                                                const uint32_t timeOut,
                                                char* const confBuf) {
    // confBuf assumed to alread be of allocated size
    
    SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
    
    const uint32_t rto = (timeOut < 3u) ? timeOut : 3u;
    bool readConf = false;
    while ( (readConf==false) && (timer.read() < timeOut) ) {
        // TODO: check if read works (for binary)
        readConf = GetWS().read(confBuf, &timer, rto);
        if (readConf) {
            const char* b = confBuf;
            conf.ReadFrom(b);
            res = SnCommWin::kOkWithMsg;
        }
    }
    if (readConf==false) {
        res = SnCommWin::kOkNoMsg;
    }

    return res;
}

SnCommWin::ECommWinResult SnCommAfar::SendStatus(const SnConfigFrame& conf,
                                                 const SnEventFrame& evt,
                                                 char* const evtBuf,
                                                 char* const statBuf) {
    // TODO: check if connected?
    SnStatusFrame::WriteTo(statBuf, SnConfigFrame::kAfar, conf, evt, evtBuf);
    GetWS().sendBinary(statBuf, SnStatusFrame::SizeOf(conf));
    return SnCommWin::kOkMsgSent;
}

SnCommWin::ECommWinResult SnCommAfar::SendData(FILE* inf) {
    fseek(inf, 0, SEEK_END);
    const uint32_t fsize = ftell(inf);
    fseek(inf, 0, SEEK_SET);
    const bool ok = GetWS().sendBinary(inf, fsize);
    return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
}

SnCommWin::ECommWinResult SnCommAfar::SendConfAndEvents(FILE* inf,
                                                    const SnConfigFrame& curConf,
                                                    SnEventFrame& evt,
                                                    char* const evtBuf,
                                                    char* const confBuf,
                                                    const uint32_t nevts,
                                                    const uint32_t firstEvt) {
    // firstEvt==0 ==> start at beginning
    // nevts==0 ==> NO events! (see SnCommWin::SendData
    //    for the fcn to send the full file)
    
    // TODO: check memory for temporary config/event frames?
    SnConfigFrame conf;
    conf.ReadFrom(inf);
    char* b = confBuf;
    conf.WriteTo(b);
    bool ok = GetWS().sendBinary(confBuf, conf.SizeOf());

    if (ok) {
        uint8_t sLoseLSB=0, sLoseMSB=0;
        uint16_t sWvBase=0;
        conf.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());
        // move up to first event
        fseek(inf, conf.SizeOf() + (firstEvt*esize), SEEK_SET);
        if (repack) {
            // repack ==> send event by event
            // size of event sent over afar
            const uint32_t ssize = SnEventFrame::SizeOf(sLoseLSB, sLoseMSB);
            for (uint32_t i=0; (i<nevts) && ok; i++) {
                evt.ReadFrom(inf, evtBuf,
                    conf.GetWvLoseLSB(), conf.GetWvLoseMSB(),
                    conf.GetWvBaseline());
                evt.WriteTo(evtBuf, sLoseLSB, sLoseMSB, sWvBase);
                ok = GetWS().sendBinary(evtBuf, ssize);
            }
        } else {
            // no repacking ==> just send the bytes from the file
            ok = GetWS().sendBinary(inf, nevts*esize);
        }
    }
    return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
}