Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: SnSDUtils.cpp
- Revision:
- 56:0bba0ef15697
- Parent:
- 47:fbe956b10a91
- Child:
- 63:4820a4460f00
--- a/SnSDUtils.cpp Fri Jan 03 13:03:01 2014 +0000 +++ b/SnSDUtils.cpp Thu Oct 30 06:42:17 2014 +0000 @@ -19,6 +19,9 @@ const char* const SnSDUtils::kSDdir = "/sd"; const char* const SnSDUtils::kSDsubDir = "/sd/data"; +const char* const SnSDUtils::kRunSeqListFilenm = "/sd/RunSeqLC.txt"; +const uint16_t SnSDUtils::kMaxSeqNum = 64000; // max "normal" seq +const uint16_t SnSDUtils::kBadSeqNum = 65000; // should be larger than kMaxSeqNum to separate "normal" and "bad" seqs char SnSDUtils::fgCurFileName[kFNBufSize]={0}; FILE* SnSDUtils::fgCurFile = 0; uint16_t SnSDUtils::fgCurSeq = 0; @@ -29,14 +32,18 @@ +(sizeof(uint8_t)+(2u*sizeof(uint16_t))); // power frame v1 SnSDUtils::InitSDFcn SnSDUtils::fgDoInit = 0; +bool SnSDUtils::fgInitOk = false; static const uint16_t __kMaxUShort = ~0; -void SnSDUtils::InitSDCard(const bool force) { +bool SnSDUtils::InitSDCard(const bool force) { if ((fgNeedToInit || force) && (fgDoInit!=0)) { - (*fgDoInit)(); - fgNeedToInit = false; + fgInitOk = (*fgDoInit)() == 0; + if (IsInitOk()) { + fgNeedToInit = false; + } } + return fgInitOk; } const char* SnSDUtils::GetSubDirFor(const uint32_t run, const uint16_t seq, @@ -155,113 +162,130 @@ #ifdef DEBUG printf("open dir %s\r\n",dirname); #endif - InitSDCard(); + if (InitSDCard()) { - DIR* rd( opendir(dirname) ); - if (rd==NULL) { - // try making the directory + DIR* rd( opendir(dirname) ); + if (rd==NULL) { + // try making the directory #ifdef DEBUG - printf("making dir %s\r\n",dirname); + printf("making dir %s\r\n",dirname); #endif - mkdir(dirname, 0777); + mkdir(dirname, 0777); #ifdef DEBUG - printf("opening dir %s\r\n",dirname); + printf("opening dir %s\r\n",dirname); #endif - rd = opendir(dirname); - } + rd = opendir(dirname); + } #ifdef DEBUG - printf("returning rd=%p\r\n",(void*)rd); + printf("returning rd=%p\r\n",(void*)rd); #endif - return rd; + return rd; + } else { + return 0; + } } uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr, const uint32_t run) { // count the files having expected filename format - InitSDCard(); + + uint16_t maxs(kBadSeqNum); - // get the run dir - uint32_t rdlen(0); - std::string rdnms ( GetSubDirFor(run, 0, rdlen, false) ); - const char* rdnm = rdnms.c_str(); - // open/make the run directory - FATDirHandle* rd(static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) )); - struct dirent* rdent; - uint16_t dseq(0), maxs(0); + if (InitSDCard()) { + + maxs = 0; // change back from kBadSeqNum! + + // get the run dir + uint32_t rdlen(0); + std::string rdnms ( GetSubDirFor(run, 0, rdlen, false) ); + const char* rdnm = rdnms.c_str(); + // open/make the run directory + FATDirHandle* rd(static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) )); + struct dirent* rdent; + uint16_t dseq(0); #ifdef DEBUG - printf("starting readdir loop over %p\r\n",(void*)rd); + printf("starting readdir loop over %p\r\n",(void*)rd); #endif - while ( (rdent = readdir(rd))!=NULL ) { + while ( (rdent = readdir(rd))!=NULL ) { #ifdef DEBUG - printf("rdent = %p\r\n",(void*)rdent); + printf("rdent = %p\r\n",(void*)rdent); #endif - if ((rd->filinfo()->fattrib & AM_DIR)!=0) { + if ((rd->filinfo()->fattrib & AM_DIR)!=0) { #ifdef DEBUG - printf("is a dir\r\n"); + printf("is a dir\r\n"); #endif - // is a directory - const int ncm = sscanf(rdent->d_name, "s%hu", &dseq); - if (ncm==1) { - if (dseq>maxs) { - maxs = dseq; + // is a directory + const int ncm = sscanf(rdent->d_name, "s%hu", &dseq); + if (ncm==1) { +#ifdef DEBUG + printf("dseq=%hu, maxs=%hu\r\n",dseq,maxs); +#endif + if ( (dseq>maxs) && (dseq<kMaxSeqNum) ) { + maxs = dseq; + } } } +#ifdef DEBUG + else { + printf("not a dir\r\n"); + } +#endif } #ifdef DEBUG - else { - printf("not a dir\r\n"); - } + printf("closing directory %p\r\n",(void*)rd); #endif - } + closedir(rd); #ifdef DEBUG - printf("closing directory %p\r\n",(void*)rd); -#endif - closedir(rd); -#ifdef DEBUG - printf("Found max seq dir num %hu for run %u\r\n",maxs,run); + printf("Found max seq dir num %hu for run %u\r\n",maxs,run); #endif - // open up the seq dir - rdnms = GetSubDirFor(run, maxs, rdlen, true); - rdnm = rdnms.c_str(); - // runXseq0 filename (fn points to a static buffer) - const char* fn = GetOutFileName(macadr, run, maxs) - + rdlen + 1; // take out dir and '/'s - // don't compare seq#. don't use num of chars in case seq is >999 - const int32_t ncomp = strrchr(fn, 's') - fn; - // open (or make) the run/seq dir - rd = static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) ); - // get the new sequence number (ok if it overflows this seq "bin") - maxs=0; - while ( (rdent = readdir(rd))!=NULL ) { - Watchdog::kick(); // don't reset - if ((rd->filinfo()->fattrib & AM_DIR)==0) { - // is a file. - // don't just count files, in case one seq was - // transferred and erased in the middle of a run - if (strncmp(rdent->d_name, fn, ncomp)==0) { - // allow for deleted files to make gaps. - // search for highest seq number and increase that - if (sscanf((rdent->d_name)+ncomp,"s%hu.dat",&dseq)==1) { + // open up the seq dir + rdnms = GetSubDirFor(run, maxs, rdlen, true); + rdnm = rdnms.c_str(); + // runXseq0 filename (fn points to a static buffer) + const char* fn = GetOutFileName(macadr, run, maxs) + + rdlen + 1; // take out dir and '/'s + // don't compare seq#. don't use num of chars in case seq is >999 + const int32_t ncomp = strrchr(fn, 's') - fn; + // open (or make) the run/seq dir + rd = static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) ); + // get the new sequence number (ok if it overflows this seq "bin") + maxs=0; + while ( (rdent = readdir(rd))!=NULL ) { + Watchdog::kick(); // don't reset + if ((rd->filinfo()->fattrib & AM_DIR)==0) { + // is a file. + // don't just count files, in case one seq was + // transferred and erased in the middle of a run + if (strncmp(rdent->d_name, fn, ncomp)==0) { + // allow for deleted files to make gaps. + // search for highest seq number and increase that + if (sscanf((rdent->d_name)+ncomp,"s%hu.dat",&dseq)==1) { #ifdef DEBUG - printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n", - rdent->d_name, dseq, __kMaxUShort); + printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n", + rdent->d_name, dseq, __kMaxUShort); #endif - if (dseq==__kMaxUShort) { - maxs = dseq; - break; - } - if (dseq>=maxs) { - maxs=dseq+1; - } - if (maxs==__kMaxUShort) { - break; + if (dseq==__kMaxUShort) { + maxs = dseq; + break; + } +#ifdef DEBUG + printf("dseq=%hu, maxs=%hu\r\n",dseq,maxs); +#endif + if ( (dseq>=maxs) && (dseq<kMaxSeqNum)) { + maxs=dseq+1; + } + if (maxs==__kMaxUShort) { + break; + } } } } } + closedir(rd); + } else { + // no SD card + } - closedir(rd); - #ifdef DEBUG printf("return maxs=%hu\r\n",maxs); #endif @@ -270,21 +294,22 @@ FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent, const bool redoDir) { - InitSDCard(); FILE* f = 0; - //if ((name!=NULL) && ((*name)!=0) ) { // simple check if filename not set - if (name!=NULL) { // simple check if filename not set + if (InitSDCard()) { + //if ((name!=NULL) && ((*name)!=0) ) { // simple check if filename not set + if (name!=NULL) { // simple check if filename not set #ifdef DEBUG - printf("opening SD file. name=[%s]\r\n",name); + printf("opening SD file. name=[%s]\r\n",name); #endif - f = OpenSDFile(name, "rb", redoDir); - /* - if (setcurrent) { - fgCurFile = f; - strncpy(fgCurFileName, name, kFNBufSize-1); - fgCurSeq = GetSeqNumFromFileName(fgCurFileName); + f = OpenSDFile(name, "rb", redoDir); + /* + if (setcurrent) { + fgCurFile = f; + strncpy(fgCurFileName, name, kFNBufSize-1); + fgCurSeq = GetSeqNumFromFileName(fgCurFileName); + } + */ } - */ } return f; } @@ -333,57 +358,58 @@ #ifdef DEBUG printf("OpenSDFile: Trying to open %s.\r\n",name); #endif - InitSDCard(); + FILE* f = 0; + if (InitSDCard()) { - std::string ffn; - FILE* f = 0; - bool ok = true; + std::string ffn; + bool ok = true; +#ifdef DEBUG + printf("redoDir=%d\r\n",(int)redoDir); +#endif + if (redoDir) { +#ifdef DEBUG + printf("calling GetFullFilename\r\n"); +#endif + ok = GetFullFilename(name, ffn); +#ifdef DEBUG + printf("ffn=%s\r\n",ffn.c_str()); +#endif + } else { +#ifdef DEBUG + printf("looking for /\r\n"); +#endif + // make sure the directory exists + const char* ld = strrchr(name, '/'); #ifdef DEBUG - printf("redoDir=%d\r\n",(int)redoDir); + printf("ld=%p, ld-name = %d\r\n",ld,(int)(ld-name)); #endif - if (redoDir) { + if ((ld!=0) && (ld>name)) { + std::string dn(name, ld-name); + DIR* d = OpenOrMakeAllDirs(dn.c_str()); #ifdef DEBUG - printf("calling GetFullFilename\r\n"); + printf("d=%p\r\n",d); #endif - ok = GetFullFilename(name, ffn); + if (d!=NULL) { + closedir(d); + } + } + // now just copy the (already-) full name + ffn = name; + } + if ( ok && ffn.size()>0 ) { +#ifdef DEBUG + printf("OpenSDFile: %s, mode %s\r\n",ffn.c_str(),mode); +#endif + f = fopen(ffn.c_str(), mode); + //setvbuf(f, 0, _IONBF, 0); // no buffering +#ifdef DEBUG + printf("OpenSDFile: f=%p\r\n",(void*)f); +#endif + } #ifdef DEBUG printf("ffn=%s\r\n",ffn.c_str()); #endif - } else { -#ifdef DEBUG - printf("looking for /\r\n"); -#endif - // make sure the directory exists - const char* ld = strrchr(name, '/'); -#ifdef DEBUG - printf("ld=%p, ld-name = %d\r\n",ld,(int)(ld-name)); -#endif - if ((ld!=0) && (ld>name)) { - std::string dn(name, ld-name); - DIR* d = OpenOrMakeAllDirs(dn.c_str()); -#ifdef DEBUG - printf("d=%p\r\n",d); -#endif - if (d!=NULL) { - closedir(d); - } - } - // now just copy the (already-) full name - ffn = name; } - if ( ok && ffn.size()>0 ) { -#ifdef DEBUG - printf("OpenSDFile: %s, mode %s\r\n",ffn.c_str(),mode); -#endif - f = fopen(ffn.c_str(), mode); - //setvbuf(f, 0, _IONBF, 0); // no buffering -#ifdef DEBUG - printf("OpenSDFile: f=%p\r\n",(void*)f); -#endif - } -#ifdef DEBUG - printf("ffn=%s\r\n",ffn.c_str()); -#endif return f; } @@ -397,115 +423,123 @@ printf("getting seq num for run %u, minseq %hu\r\n", run, minseq); #endif - InitSDCard(); - + fgCurFile = 0; fgCurSeq = GetSeqNum(macadr, run); - if (fgCurSeq<minseq) { - fgCurSeq=minseq; - } #ifdef DEBUG printf("fgCurSeq=%hu\r\n",fgCurSeq); - printf("getting output file name\r\n"); +#endif + if (InitSDCard()) { + if (fgCurSeq<minseq) { + fgCurSeq=minseq; + } +#ifdef DEBUG + printf("getting output file name\r\n"); #endif - memset(fgCurFileName, 0, sizeof(char)*kFNBufSize); - strncpy(fgCurFileName,GetOutFileName(macadr, run, fgCurSeq),kFNBufSize-1); - //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,fgCurSeq); + memset(fgCurFileName, 0, sizeof(char)*kFNBufSize); + strncpy(fgCurFileName,GetOutFileName(macadr, run, fgCurSeq),kFNBufSize-1); + //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,fgCurSeq); #ifdef DEBUG - printf("fgCurFileName=%s\r\n",fgCurFileName); + printf("fgCurFileName=%s\r\n",fgCurFileName); #endif - fgCurFile = 0; - if (fgCurFileName!=NULL) { + fgCurFile = 0; + if (fgCurFileName!=NULL) { #ifdef DEBUG - printf("opening SD file\r\n"); + printf("opening SD file\r\n"); #endif - fgCurFile = OpenSDFile(fgCurFileName, "wb", false); - if (fgCurFile!=NULL && ferror(fgCurFile)==0) { + fgCurFile = OpenSDFile(fgCurFileName, "wb", false); + if (fgCurFile!=NULL && ferror(fgCurFile)==0) { #ifdef DEBUG - printf("Writing file header\r\n"); + printf("Writing file header\r\n"); #endif - WriteFileHeader(fgCurFile, macadr, run, fgCurSeq); + WriteFileHeader(fgCurFile, macadr, run, fgCurSeq); + + AddToRunSeqList(run, fgCurSeq); + } } +#ifdef DEBUG + printf("fgCurFile=%p\r\n",(void*)fgCurFile); +#endif } -#ifdef DEBUG - printf("fgCurFile=%p\r\n",(void*)fgCurFile); -#endif return fgCurFile; } void SnSDUtils::PrintFilesInDirs(const char* dirname) { - InitSDCard(); + if (InitSDCard()) { - DIR* d; - struct dirent* dent; - Watchdog::kick(); // don't reset - if ( (d = opendir( dirname ))!=NULL ) { - FATDirHandle* dir = static_cast<FATDirHandle*>(d); - while ( (dent = readdir(d))!=NULL ) { - printf("dn=%s. datr=%02x. dir=%d\r\n", - dent->d_name, - dir->filinfo()->fattrib, - dir->filinfo()->fattrib & AM_DIR); - if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) { - std::string dnm(dirname); - dnm += "/"; - dnm += dent->d_name; - PrintFilesInDirs(dnm.c_str()); + DIR* d; + struct dirent* dent; + Watchdog::kick(); // don't reset + if ( (d = opendir( dirname ))!=NULL ) { + FATDirHandle* dir = static_cast<FATDirHandle*>(d); + while ( (dent = readdir(d))!=NULL ) { + printf("dn=%s. datr=%02x. dir=%d\r\n", + dent->d_name, + dir->filinfo()->fattrib, + dir->filinfo()->fattrib & AM_DIR); + if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) { + std::string dnm(dirname); + dnm += "/"; + dnm += dent->d_name; + PrintFilesInDirs(dnm.c_str()); + } } + closedir(d); } - closedir(d); } - } float SnSDUtils::GetFreeBytes() { - InitSDCard(); + float frs(0); + if (InitSDCard()) { - FATFS* fs; - DWORD fre_clust; - f_getfree("0:",&fre_clust,&fs); - const float frs = static_cast<float>(fs->csize) - *static_cast<float>(fs->free_clust) + FATFS* fs; + DWORD fre_clust; + f_getfree("0:",&fre_clust,&fs); + frs = static_cast<float>(fs->csize) + *static_cast<float>(fs->free_clust) #if _MAX_SS != 512 - *(fs->ssize); + *(fs->ssize); #else - *512; + *512; #endif #ifdef DEBUG - printf("free space = %g b (%g GB, %g MB, %g KB)\r\n", - frs, frs/1073741824.0, frs/1048576.0, frs/1024.0); + printf("free space = %g b (%g GB, %g MB, %g KB)\r\n", + frs, frs/1073741824.0, frs/1048576.0, frs/1024.0); #endif + } return frs; } void SnSDUtils::GetDirProps(const char* dirname, uint32_t& nfiles, float& totbytes) { - InitSDCard(); - nfiles = 0; totbytes = 0; - struct dirent* dent; - FATDirHandle* d = static_cast<FATDirHandle*>( opendir(dirname) ); - if (d!=0) { - while ( (dent = readdir(d))!=NULL ) { - Watchdog::kick(); // don't reset - if ( (d->filinfo()->fattrib & AM_DIR)!=0 ) { - // a subdirectory - std::string dnm(dirname); - dnm += "/"; - dnm += dent->d_name; - uint32_t sdnf; - float sdtb; - GetDirProps(dnm.c_str(), sdnf, sdtb); - nfiles += sdnf; - totbytes += sdtb; - } else { - // a file - ++nfiles; - totbytes += d->filinfo()->fsize; - } + if (InitSDCard()) { + + struct dirent* dent; + FATDirHandle* d = static_cast<FATDirHandle*>( opendir(dirname) ); + if (d!=0) { + while ( (dent = readdir(d))!=NULL ) { + Watchdog::kick(); // don't reset + if ( (d->filinfo()->fattrib & AM_DIR)!=0 ) { + // a subdirectory + std::string dnm(dirname); + dnm += "/"; + dnm += dent->d_name; + uint32_t sdnf; + float sdtb; + GetDirProps(dnm.c_str(), sdnf, sdtb); + nfiles += sdnf; + totbytes += sdtb; + } else { + // a file + ++nfiles; + totbytes += d->filinfo()->fsize; + } + } + closedir(d); } - closedir(d); } #ifdef DEBUG printf("GetDirProps: %s :: nf=%u, tb=%g\r\n", @@ -517,87 +551,87 @@ const uint32_t time, const uint32_t num) { if (file!=0) { - InitSDCard(); - - const bool r1 = - SnHeaderFrame::WriteTo(file, SnHeaderFrame::kHeartbeatCode, - SnHeartbeatFrame::SizeOf(SnHeartbeatFrame::kIOVers)); - const bool r2 = - SnHeartbeatFrame::WriteTo(file, time, num); - return (r1 && r2); - } else { - return false; + if (InitSDCard()) { + + const bool r1 = + SnHeaderFrame::WriteTo(file, SnHeaderFrame::kHeartbeatCode, + SnHeartbeatFrame::SizeOf(SnHeartbeatFrame::kIOVers)); + const bool r2 = + SnHeartbeatFrame::WriteTo(file, time, num); + return (r1 && r2); + } } + return false; } bool SnSDUtils::WriteTrigWaitWinTime(FILE* file, SnClockSetFrame& clkset, const bool isStart) { if (file!=0) { - InitSDCard(); - - bool ok = SnHeaderFrame::WriteTo(file, - (isStart) ? (SnHeaderFrame::kFileTrgStrtCode) - : (SnHeaderFrame::kFileTrgStopCode), - clkset.SizeOf()); - ok &= (SnCommWin::kOkMsgSent == clkset.WriteTo(file)); - return ok; - } else { - return false; + if (InitSDCard()) { + + bool ok = SnHeaderFrame::WriteTo(file, + (isStart) ? (SnHeaderFrame::kFileTrgStrtCode) + : (SnHeaderFrame::kFileTrgStopCode), + clkset.SizeOf()); + ok &= (SnCommWin::kOkMsgSent == clkset.WriteTo(file)); + return ok; + } } + return false; } bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf, const SnEventFrame& evt, const SnConfigFrame& conf) { // write event to SD card - + bool ret = false; if (efile!=0) { - InitSDCard(); - - uint8_t sLoseLSB=0, sLoseMSB=0; - uint16_t sWvBase=0; - conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase); - SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode, - evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB)); - const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase); - fflush(efile); - return ret; - } else { - return false; + if (InitSDCard()) { + + uint8_t sLoseLSB=0, sLoseMSB=0; + uint16_t sWvBase=0; + conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase); + SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode, + evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB)); + ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase); + fflush(efile); + } } + return ret; } bool SnSDUtils::WriteConfig(FILE* efile, const SnConfigFrame& conf) { if (efile!=0) { - InitSDCard(); + if (InitSDCard()) { - SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode, - conf.SizeOf(SnConfigFrame::kIOVers)); - conf.WriteTo(efile); - return true; - } else { - return false; + SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode, + conf.SizeOf(SnConfigFrame::kIOVers)); + conf.WriteTo(efile); + return true; + } } + return false; } void SnSDUtils::DeleteFile(FILE*& f, const char* fname) { #ifdef DEBUG printf("try to delete %s at %p\r\n",fname,f); #endif - InitSDCard(); + if (InitSDCard()) { - if (f!=0) { - fclose(f); - f=0; - } - std::string fn(""); - if (GetFullFilename(fname, fn)) { + if (f!=0) { + fclose(f); + f=0; + } + std::string fn(""); + if (GetFullFilename(fname, fn)) { #ifdef DEBUG - printf("calling remove [%s]\r\n",fn.c_str()); + printf("calling remove [%s]\r\n",fn.c_str()); #endif - remove(fn.c_str()); + remove(fn.c_str()); + } } } @@ -614,69 +648,326 @@ #ifdef DEBUG printf("deleting ALL files in %s\r\n",dirname); #endif - InitSDCard(); + if (InitSDCard()) { - DIR* d; - struct dirent* dent; - if ( (d = opendir( dirname ))!=NULL ) { - FATDirHandle* dir = static_cast<FATDirHandle*>(d); - while ( (dent = readdir(d))!=NULL ) { - Watchdog::kick(); // don't reset - if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) { - // a subdirectory - std::string dnm(dirname); - dnm += "/"; - dnm += dent->d_name; - // delete all the files in this new subdir + DIR* d; + struct dirent* dent; + if ( (d = opendir( dirname ))!=NULL ) { + FATDirHandle* dir = static_cast<FATDirHandle*>(d); + while ( (dent = readdir(d))!=NULL ) { + Watchdog::kick(); // don't reset + if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) { + // a subdirectory + std::string dnm(dirname); + dnm += "/"; + dnm += dent->d_name; + // delete all the files in this new subdir #ifdef DEBUG - printf("call DeleteAllFiles(%s)\r\n",dnm.c_str()); + printf("call DeleteAllFiles(%s)\r\n",dnm.c_str()); #endif - DeleteAllFiles(dnm.c_str()); - } else if (strncmp(dent->d_name, "SnEvts", 6)==0) { - // a data file (delete it) - const bool isCurFile = - (strcmp(dent->d_name, GetCurFileName())==0); - if (isCurFile==false) { // don't delete the current file - FILE* f(0); // dummy - DeleteFile(f, dent->d_name); + DeleteAllFiles(dnm.c_str()); + } else if (strncmp(dent->d_name, "SnEvts", 6)==0) { + // a data file (delete it) + const bool isCurFile = + (strcmp(dent->d_name, GetCurFileName())==0); + if (isCurFile==false) { // don't delete the current file + FILE* f(0); // dummy + DeleteFile(f, dent->d_name); + } } - } - } // loop over stuff in this dir - closedir(d); - DeleteDirIfEmpty(dirname); + } // loop over stuff in this dir + closedir(d); + DeleteDirIfEmpty(dirname); + } } } -void SnSDUtils::DeleteDirIfEmpty(const char* dirname) { +bool SnSDUtils::DeleteDirIfEmpty(const char* dirname) { #ifdef DEBUG printf("DeleteDirIfEmpty(%s)\r\n",dirname); #endif - InitSDCard(); + bool doDel = false; + if (InitSDCard()) { - DIR* d; - struct dirent* dent; - if ( (d = opendir(dirname))!=NULL ) { - dent = readdir(d); - bool doDel = false; - if ( dent==NULL ) { - // then this directory is empty - static const size_t subdsz = strlen(kSDsubDir); - // just double check that this directory is - // a subdirectory of the data dir - if (strlen(dirname)>subdsz) { - doDel = true; + DIR* d; + struct dirent* dent; + if ( (d = opendir(dirname))!=NULL ) { + dent = readdir(d); + if ( dent==NULL ) { + // then this directory is empty + static const size_t subdsz = strlen(kSDsubDir); + // just double check that this directory is + // a subdirectory of the data dir + if (strlen(dirname)>subdsz) { + doDel = true; + } + } // else this dir isn't empty + closedir(d); + if (doDel) { +#ifdef DEBUG + printf("removing directory [%s]\r\n",dirname); +#endif + remove(dirname); } - } // else this dir isn't empty - closedir(d); - if (doDel) { -#ifdef DEBUG - printf("removing directory [%s]\r\n",dirname); -#endif - remove(dirname); } } + return doDel; } +SnCommWin::ECommWinResult +SnSDUtils::SendOneFile(const char* dfn, + SnCommWin* comm, + const uint32_t timeout, + char* const buf, + const uint32_t bsize, + const SnConfigFrame& curConf, + SnEventFrame& evt, + SnPowerFrame& pow) { + +#ifdef DEBUG + printf("SendOneFile (%s)\r\n",dfn); +#endif + + SnCommWin::ECommWinResult res = SnCommWin::kOkMsgSent; + + // open the file + const bool isCurFile = (strcmp(dfn, GetCurFileName())==0); + FILE* f(0); + if (isCurFile) { + // file must already be written out! + f = GetCurFile(); + } else { + f = OpenExistingFile(dfn, false, false); + } + +#ifdef DEBUG + printf("SendOneFile: isCurFile=%d, f=%p, fn=%s\r\n", + (int)isCurFile, (void*)f, dfn); +#endif + + uint8_t hndres = SnHeaderFrame::kHnShFailNonCode; + if (f!=0) { +#ifdef DEBUG + printf("SendOneFile: calling SendDataFromFile\r\n"); +#endif + res = comm->SendDataFromFile(f, dfn, + curConf, evt, pow, buf, bsize, + 0, timeout, + &hndres); + + if (isCurFile) { + // move (back) to the end of the file + // altho hopefully no writing will happen after this + fseek(fgCurFile, 0, SEEK_END); + } + } +#ifdef DEBUG + printf("isCurFile=%d, res=%d, deleting=%d, hndres=%02x\r\n", + (int)isCurFile, (int)res, (int)(curConf.IsDeletingFiles()), + hndres); +#endif + + return res; +} + +bool SnSDUtils::ClearRunSeqList() { + if (InitSDCard()) { + FILE* rslistf = fopen(kRunSeqListFilenm,"w"); + const bool ok = rslistf!=0; + fclose(rslistf); +#ifdef DEBUG + printf("ClearRunSeqList. ok=%s\r\n",(ok?"true":"false")); +#endif + return ok; + } + return false; +} + +bool SnSDUtils::AddToRunSeqList(const uint32_t run, + const uint16_t seq) { + if (InitSDCard()) { + FILE* rslistf = fopen(kRunSeqListFilenm,"a"); + bool ok = false; + if (rslistf!=0) { + ok = fprintf(rslistf, "%u %hu\n", run, seq) > 0; + ok &= 0==ferror(rslistf); +#ifdef DEBUG + printf("AddToRunSeqList: run=%u, seq=%hu, ok=%s\r\n", + run, seq, (ok?"true":"false")); +#endif + } + fclose(rslistf); + return ok; + } + return false; +} + +SnCommWin::ECommWinResult +SnSDUtils::SendFileWithRunSeq(SnCommWin* comm, + const uint32_t timeout, + char* const buf, + const uint32_t bsize, + const SnConfigFrame& curConf, + SnEventFrame& evt, + SnPowerFrame& pow, + const uint32_t run, + const uint16_t seq) { + +#ifdef DEBUG + printf("SendFileWithRunSeq\r\n"); +#endif + + // get the file name + std::string dfn = + GetOutFileName(SnConfigFrame::GetMacAddress(), run, seq); + + // send it + const SnCommWin::ECommWinResult res = + SendOneFile(dfn.c_str(), comm, timeout, buf, bsize, + curConf, evt, pow); + + // see if we need to remove this directory now + if (curConf.IsDeletingFiles()) { + // get run/seq directory name + uint32_t rdlen(0); + std::string rdnm( GetSubDirFor(run, seq, rdlen, true) ); +#ifdef DEBUG + printf("Checking removal of dir [%s]\r\n",rdnm.c_str()); +#endif + if ( DeleteDirIfEmpty(rdnm.c_str()) ) { + // removed the seq dir. do we need to remove + // the run dir too? + rdnm = GetSubDirFor(run, seq, rdlen, false); +#ifdef DEBUG + printf("Checking removal of dir [%s]\r\n",rdnm.c_str()); +#endif + DeleteDirIfEmpty(rdnm.c_str()); + } + } + + return res; +} + +SnCommWin::ECommWinResult +SnSDUtils::SendFilesInRunSeqList(SnCommWin* comm, + const uint32_t timeout, + char* const buf, + const uint32_t bsize, + const SnConfigFrame& curConf, + SnEventFrame& evt, + SnPowerFrame& pow) { +#ifdef DEBUG + printf("SendFilesInRunSeqList\r\n"); +#endif + + SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent; + + if (InitSDCard()) { + + // open up the run/seq list file and send each corresponding file + FILE* rslistf = fopen(kRunSeqListFilenm,"r"); +#ifdef DEBUG + printf("fslistf=%p\r\n",(void*)rslistf); +#endif + if (rslistf!=0) { + uint32_t run(0); + uint16_t seq(0); + while ( (feof(rslistf)==0) + && (ferror(rslistf)==0) ) { +#ifdef DEBUG + printf("feof=%d, ferror=%d\r\n", + (int)(feof(rslistf)), (int)(ferror(rslistf))); +#endif + const int nfilled = fscanf(rslistf, "%u %hu\n", &run ,&seq); + +#ifdef DEBUG + printf("nfilled=%d\r\n", nfilled); +#endif + + if ( 2==nfilled ) { + +#ifdef DEBUG + printf("run=%u, seq=%hu\r\n",run,seq); +#endif + + SnCommWin::ECommWinResult res = + SendFileWithRunSeq(comm, timeout, buf, bsize, + curConf, evt, pow, + run, seq); + + if ((res<rs) || (res==SnCommWin::kOkStopComm)) { + rs = res; + } + // don't necessarily stop if rs is bad. don't want one bad file to + // prevent sending the others + if (rs<=SnCommWin::kFailTimeout) { + break; + } else if (rs==SnCommWin::kOkStopComm) { + break; + } + + } + + } + + // do we need to clear the list? + if (curConf.IsRunSeqListOneCommWinOnly()==false) { + if (rs >= SnCommWin::kOkMsgSent) { + // all sent ok + ClearRunSeqList(); + } + } + + } + fclose(rslistf); + } + return rs; +} + +SnCommWin::ECommWinResult +SnSDUtils::SendPartOfRun(SnCommWin* comm, + const uint32_t timeout, + char* const buf, + const uint32_t bsize, + const SnConfigFrame& curConf, + SnEventFrame& evt, + SnPowerFrame& pow, + const uint32_t run, + const uint16_t minseq, + const uint16_t maxseq) { + // send files with run number 'run' + // and seq number in [minseq,maxseq] (min/max inclusive) + +#ifdef DEBUG + printf("SendPartOfRun\r\n"); +#endif + + SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent; + + for (uint16_t seq=minseq; seq<=maxseq; ++seq) { + SnCommWin::ECommWinResult res = + SendFileWithRunSeq(comm, + timeout, buf, bsize, + curConf, evt, pow, + run, seq); + + if ((res<rs) || (res==SnCommWin::kOkStopComm)) { + rs = res; + } + // don't necessarily stop if rs is bad. don't want one bad file to + // prevent sending the others + if (rs<=SnCommWin::kFailTimeout) { + break; + } else if (rs==SnCommWin::kOkStopComm) { + break; + } + + } + + return rs; +} + + SnCommWin::ECommWinResult SnSDUtils::SendAllOfRun(SnCommWin* comm, const uint32_t timeout, char* const buf, @@ -703,83 +994,52 @@ SnPowerFrame& pow, const char* dirname) { // send all files in the specified directory + + SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail; - InitSDCard(); - - SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent; + if (InitSDCard()) { - DIR* d; - struct dirent* dent; - if ( (d = opendir( dirname ))!=NULL ) { - FATDirHandle* dir = static_cast<FATDirHandle*>(d); - while ( (dent = readdir(d))!=NULL ) { - Watchdog::kick(); // don't reset - SnCommWin::ECommWinResult res = rs; - if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) { - // a subdirectory - std::string dnm(dirname); - dnm += "/"; - dnm += dent->d_name; - // send all the files in this new subdir - res = SendAllFiles(comm, timeout, buf, bsize, - curConf, evt, pow, - dnm.c_str()); - } else if (strncmp(dent->d_name, "SnEvts", 6)==0) { - // a data file (send it) - const bool isCurFile = - (strcmp(dent->d_name, GetCurFileName())==0); - FILE* f(0); - if (isCurFile) { - // file must already be written out! - f = GetCurFile(); - } else { - std::string ffn(dirname); - ffn += "/"; - ffn += dent->d_name; - f = OpenExistingFile(ffn.c_str(), false, false); + rs = SnCommWin::kOkMsgSent; + + DIR* d; + struct dirent* dent; + if ( (d = opendir( dirname ))!=NULL ) { + FATDirHandle* dir = static_cast<FATDirHandle*>(d); + while ( (dent = readdir(d))!=NULL ) { + Watchdog::kick(); // don't reset + SnCommWin::ECommWinResult res = rs; + if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) { + // a subdirectory + std::string dnm(dirname); + dnm += "/"; + dnm += dent->d_name; + // send all the files in this new subdir + res = SendAllFiles(comm, timeout, buf, bsize, + curConf, evt, pow, + dnm.c_str()); + } else if (strncmp(dent->d_name, "SnEvts", 6)==0) { + // a data file (send it) + res = SendOneFile(dent->d_name, comm, timeout, buf, bsize, + curConf, evt, pow); } -#ifdef DEBUG - printf("calling senddata: f=%p (cur %p), fn=%s\r\n", - f, GetCurFile(), dent->d_name); -#endif - uint8_t hndres = SnHeaderFrame::kHnShFailNonCode; - if (f!=0) { - res = comm->SendDataFromFile(f, dent->d_name, - curConf, evt, pow, buf, bsize, - 0, timeout, - &hndres); - - if (isCurFile) { - // move (back) to the end of the file - // altho hopefully no writing will happen after this - fseek(fgCurFile, 0, SEEK_END); - } - } -#ifdef DEBUG - printf("isCurFile=%d, res=%d, deleting=%d, hndres=%02x\r\n", - (int)isCurFile, (int)res, (int)(curConf.IsDeletingFiles()), - hndres); -#endif - + if ((res<rs) || (res==SnCommWin::kOkStopComm)) { + rs = res; + } + // don't necessarily stop if rs is bad. don't want one bad file to + // prevent sending the others + if (rs<=SnCommWin::kFailTimeout) { + break; + } else if (rs==SnCommWin::kOkStopComm) { + break; + } + } // loop over stuff in this directory + closedir(d); + // see if we need to remove this directory now + if (curConf.IsDeletingFiles()) { + DeleteDirIfEmpty(dirname); } - if ((res<rs) || (res==SnCommWin::kOkStopComm)) { - rs = res; - } - // don't necessarily stop if rs is bad. don't want one bad file to - // prevent sending the others - if (rs<=SnCommWin::kFailTimeout) { - break; - } else if (rs==SnCommWin::kOkStopComm) { - break; - } - } // loop over stuff in this directory - closedir(d); - // see if we need to remove this directory now - if (curConf.IsDeletingFiles()) { - DeleteDirIfEmpty(dirname); } } - return rs; }