Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: SnSDUtils.cpp
- Revision:
- 0:664899e0b988
- Child:
- 1:e392595b4b76
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SnSDUtils.cpp Sat Jun 30 02:03:51 2012 +0000 @@ -0,0 +1,148 @@ +#include "SnSDUtils.h" + +#include "mbed.h" +#include "SDFileSystem.h" +#include <string.h> + +#include "SnConfigFrame.h" +#include "SnEventFrame.h" + + +const char* SnSDUtils::kSDsubDir = "/sd"; +char SnSDUtils::fgCurFileName[kFNBufSize]; +const uint8_t SnSDUtils::kIOvers = 1; + +const char* SnSDUtils::GetOutFileName(const uint64_t macadr, + const uint32_t run, + const uint16_t seq) { + // returns the formatted file name, or NULL if the directory is too long + // and the full name cannot fit in the buffer + // NOTE: this fcn uses a static buffer, and so should not be called + // multiple times in the same line (that includes the calling of functions + // that call this function!) + // + // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat + // 35 chars 7 + 12 +1+ 5 +1+ 5 + 4 + + if (strlen(kSDsubDir)<(kFNBufSize-37)) { + static char tbuf[kFNBufSize]; + memset(tbuf, 0, sizeof(char)*kFNBufSize); + // if file name format changes, GetSeqNum must be changed too + sprintf(tbuf, "%s/SnEvtsM%012llXr%05ds%05d.dat", + kSDsubDir, + macadr>>16, // 64 -> 48 bits + run, seq); + return tbuf; + } else { + return NULL; + } +} + +uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr, + const uint32_t run) { + // count the files having expected filename format + + const char* fn = GetOutFileName(macadr, run, 0) + + strlen(kSDsubDir) + 1; // take out dir and '/'s + + DIR* d; + struct dirent* dent; + + uint16_t seq=0; + if ( (d = opendir( kSDsubDir ))!=NULL ) { + // don't compare seq#. don't use num of chars in case seq is >999 + const uint32_t ncomp = strrchr(fn, 's') - fn; + while ( (dent = readdir(d))!=NULL ) { + if (strncmp(dent->d_name, fn, ncomp)==0) { + seq++; + } + } + closedir(d); + } + + return seq; +} + +FILE* SnSDUtils::OpenExistingFile(const char* name) { + FILE* f = 0; + if (name!=NULL) { + f = fopen(name, "wb"); + } + return f; +} + +FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr, + const uint32_t run) { + // opens a new file in the specified directory and writes this + // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes) + // + const uint16_t seq = GetSeqNum(macadr, run); + memset(fgCurFileName, 0, sizeof(char)*kFNBufSize); + strcpy(fgCurFileName,GetOutFileName(macadr, run, seq)); + //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,seq); + FILE* f = 0; + if (fgCurFileName!=NULL) { + f = fopen(fgCurFileName, "wb"); + } + return f; +} + +bool SnSDUtils::WriteFileHeader(FILE* f, const uint64_t macadr) { + // MUST INCREMENT kIOvers if these writes are altered + fwrite(&kIOvers, sizeof(uint8_t), 1, f); + fwrite(&macadr, sizeof(uint64_t), 1, f); + return ferror(f); +} + +bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf, + const SnEventFrame& evt, + const SnConfigFrame& conf) { + // write event to SD card + + uint8_t sLoseLSB=0, sLoseMSB=0; + uint16_t sWvBase=0; + conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase); + const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase); + fflush(efile); + return ret; +} + +bool SnSDUtils::WriteConfig(FILE* efile, + const SnConfigFrame& conf) { + conf.WriteTo(efile); + return true; +} + +void SnSDUtils::DeleteFile(FILE*& f, const char* fname) { + fclose(f); + f=0; + remove(fname); +} + +SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm, + const bool doDelete) { + + DIR* d; + struct dirent* dent; + + SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail; + + if ( (d = opendir( kSDsubDir ))!=NULL ) { + FILE* f; + while ( (dent = readdir(d))!=NULL ) { + if (strncmp(dent->d_name, "SnEvts", 6)==0) { + f = SnSDUtils::OpenExistingFile(dent->d_name); + rs = comm->SendData(f); + if (rs<SnCommWin::kAllFails) { + break; + } else if (doDelete) { + DeleteFile(f, dent->d_name); + } + } + } + closedir(d); + } + + return rs; +} +