Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Nov 28 05:41:42 2014 +0000
Revision:
63:4820a4460f00
Parent:
56:0bba0ef15697
Child:
64:6c7a316eafad
Revert to SDFileSystemFilInfo with no-stall changes to SDFileSystem.cpp . change watchdog to internal RC clock. move check power to after startup LED sequence. make InitSDCard try up to 26 init's. DEBUG ENABLED, NO SAFETY NETS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "SnSDUtils.h"
uci1 0:664899e0b988 2
uci1 0:664899e0b988 3 #include "mbed.h"
uci1 0:664899e0b988 4 #include "SDFileSystem.h"
uci1 21:ce51bb0ba4a5 5 #include "FATDirHandle.h"
uci1 0:664899e0b988 6 #include <string.h>
uci1 12:d472f9811262 7 #include <string>
uci1 0:664899e0b988 8
uci1 0:664899e0b988 9 #include "SnConfigFrame.h"
uci1 0:664899e0b988 10 #include "SnEventFrame.h"
uci1 22:f957c4f840ad 11 #include "SnHeartbeatFrame.h"
uci1 40:1324da35afd4 12 #include "SnClockSetFrame.h"
uci1 0:664899e0b988 13
uci1 25:57b2627fe756 14 #include "Watchdog.h"
uci1 25:57b2627fe756 15
uci1 63:4820a4460f00 16 #define DEBUG
uci1 0:664899e0b988 17
uci1 25:57b2627fe756 18 #define SUBDIRSEQ 100 // make a new subdir every X sequences
uci1 25:57b2627fe756 19
uci1 19:74155d652c37 20 const char* const SnSDUtils::kSDdir = "/sd";
uci1 19:74155d652c37 21 const char* const SnSDUtils::kSDsubDir = "/sd/data";
uci1 56:0bba0ef15697 22 const char* const SnSDUtils::kRunSeqListFilenm = "/sd/RunSeqLC.txt";
uci1 56:0bba0ef15697 23 const uint16_t SnSDUtils::kMaxSeqNum = 64000; // max "normal" seq
uci1 56:0bba0ef15697 24 const uint16_t SnSDUtils::kBadSeqNum = 65000; // should be larger than kMaxSeqNum to separate "normal" and "bad" seqs
uci1 2:e67f7c158087 25 char SnSDUtils::fgCurFileName[kFNBufSize]={0};
uci1 1:e392595b4b76 26 FILE* SnSDUtils::fgCurFile = 0;
uci1 12:d472f9811262 27 uint16_t SnSDUtils::fgCurSeq = 0;
uci1 40:1324da35afd4 28 bool SnSDUtils::fgNeedToInit = true;
uci1 40:1324da35afd4 29 const uint8_t SnSDUtils::kIOvers = 4;
uci1 5:9cea89700c66 30 const uint32_t SnSDUtils::kMaxSizeOfFileHdr =
uci1 5:9cea89700c66 31 sizeof(uint8_t)+sizeof(uint64_t)+sizeof(uint32_t)+sizeof(uint16_t)
uci1 8:95a325df1f6b 32 +(sizeof(uint8_t)+(2u*sizeof(uint16_t))); // power frame v1
uci1 4:a91682e19d6b 33
uci1 40:1324da35afd4 34 SnSDUtils::InitSDFcn SnSDUtils::fgDoInit = 0;
uci1 56:0bba0ef15697 35 bool SnSDUtils::fgInitOk = false;
uci1 40:1324da35afd4 36
uci1 4:a91682e19d6b 37 static const uint16_t __kMaxUShort = ~0;
uci1 0:664899e0b988 38
uci1 56:0bba0ef15697 39 bool SnSDUtils::InitSDCard(const bool force) {
uci1 40:1324da35afd4 40 if ((fgNeedToInit || force) && (fgDoInit!=0)) {
uci1 56:0bba0ef15697 41 fgInitOk = (*fgDoInit)() == 0;
uci1 56:0bba0ef15697 42 if (IsInitOk()) {
uci1 56:0bba0ef15697 43 fgNeedToInit = false;
uci1 56:0bba0ef15697 44 }
uci1 40:1324da35afd4 45 }
uci1 56:0bba0ef15697 46 return fgInitOk;
uci1 40:1324da35afd4 47 }
uci1 40:1324da35afd4 48
uci1 25:57b2627fe756 49 const char* SnSDUtils::GetSubDirFor(const uint32_t run, const uint16_t seq,
uci1 25:57b2627fe756 50 uint32_t& slen, const bool useSeq) {
uci1 40:1324da35afd4 51 // returns a STATIC string! (so make a copy of it before use)
uci1 25:57b2627fe756 52 // sets slen to the length of this string (same as strlen)
uci1 40:1324da35afd4 53 static const uint16_t tmplen = strlen(kSDsubDir)+50;
uci1 40:1324da35afd4 54 static char* tmpsd = new char[tmplen];
uci1 40:1324da35afd4 55 slen = snprintf(tmpsd, tmplen, "%s/r%05ld", kSDsubDir, run);
uci1 25:57b2627fe756 56 if (useSeq) {
uci1 40:1324da35afd4 57 slen += snprintf(tmpsd+slen, tmplen-slen, "/s%05d", (seq/SUBDIRSEQ)*SUBDIRSEQ);
uci1 40:1324da35afd4 58 }
uci1 40:1324da35afd4 59 if (slen > tmplen) {
uci1 40:1324da35afd4 60 slen = tmplen;
uci1 25:57b2627fe756 61 }
uci1 25:57b2627fe756 62 return tmpsd;
uci1 25:57b2627fe756 63 }
uci1 25:57b2627fe756 64
uci1 0:664899e0b988 65 const char* SnSDUtils::GetOutFileName(const uint64_t macadr,
uci1 0:664899e0b988 66 const uint32_t run,
uci1 0:664899e0b988 67 const uint16_t seq) {
uci1 0:664899e0b988 68 // returns the formatted file name, or NULL if the directory is too long
uci1 0:664899e0b988 69 // and the full name cannot fit in the buffer
uci1 0:664899e0b988 70 // NOTE: this fcn uses a static buffer, and so should not be called
uci1 0:664899e0b988 71 // multiple times in the same line (that includes the calling of functions
uci1 0:664899e0b988 72 // that call this function!)
uci1 0:664899e0b988 73 //
uci1 0:664899e0b988 74 // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat
uci1 0:664899e0b988 75 // 35 chars 7 + 12 +1+ 5 +1+ 5 + 4
uci1 25:57b2627fe756 76 uint32_t sdlen(0);
uci1 27:efc4d654b139 77 std::string subdirs( GetSubDirFor(run, seq, sdlen, true) );
uci1 27:efc4d654b139 78 const char* subdir = subdirs.c_str();
uci1 25:57b2627fe756 79 if (sdlen<(kFNBufSize-37)) {
uci1 0:664899e0b988 80 static char tbuf[kFNBufSize];
uci1 0:664899e0b988 81 memset(tbuf, 0, sizeof(char)*kFNBufSize);
uci1 0:664899e0b988 82 // if file name format changes, GetSeqNum must be changed too
uci1 25:57b2627fe756 83 sprintf(tbuf, "%s/SnEvtsM%012llXr%05lds%05d.dat",
uci1 25:57b2627fe756 84 subdir,
uci1 0:664899e0b988 85 macadr>>16, // 64 -> 48 bits
uci1 0:664899e0b988 86 run, seq);
uci1 0:664899e0b988 87 return tbuf;
uci1 0:664899e0b988 88 } else {
uci1 0:664899e0b988 89 return NULL;
uci1 0:664899e0b988 90 }
uci1 0:664899e0b988 91 }
uci1 25:57b2627fe756 92
uci1 25:57b2627fe756 93 bool SnSDUtils::GetRunSeqFromFilename(const char* fn,
uci1 25:57b2627fe756 94 uint32_t& run,
uci1 25:57b2627fe756 95 uint16_t& seq) {
uci1 25:57b2627fe756 96 bool ret = false;
uci1 25:57b2627fe756 97 const int32_t ncomp = strrchr(fn, 'r') - fn;
uci1 25:57b2627fe756 98 #ifdef DEBUG
uci1 25:57b2627fe756 99 printf("fn=%s, ncomp=%d\r\n",fn,ncomp);
uci1 25:57b2627fe756 100 #endif
uci1 25:57b2627fe756 101 if ((ncomp<strlen(fn)) && (ncomp>0)) {
uci1 25:57b2627fe756 102 if (sscanf(fn+ncomp,"r%lus%hu.dat",&run,&seq)==2) {
uci1 25:57b2627fe756 103 #ifdef DEBUG
uci1 25:57b2627fe756 104 printf("run=%u, seq=%hu\r\n",run,seq);
uci1 25:57b2627fe756 105 #endif
uci1 25:57b2627fe756 106 ret = true;
uci1 25:57b2627fe756 107 }
uci1 25:57b2627fe756 108 }
uci1 25:57b2627fe756 109 return ret;
uci1 25:57b2627fe756 110 }
uci1 25:57b2627fe756 111 /*
uci1 10:3c93db1cfb12 112 uint16_t SnSDUtils::GetSeqNumFromFileName(const char* fn) {
uci1 10:3c93db1cfb12 113 uint16_t seq=0;
uci1 10:3c93db1cfb12 114 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 10:3c93db1cfb12 115 if (ncomp<strlen(fn)) {
uci1 10:3c93db1cfb12 116 sscanf(fn+ncomp,"s%hu.dat",&seq);
uci1 10:3c93db1cfb12 117 }
uci1 10:3c93db1cfb12 118 return seq;
uci1 10:3c93db1cfb12 119 }
uci1 25:57b2627fe756 120 */
uci1 47:fbe956b10a91 121
uci1 47:fbe956b10a91 122 DIR* SnSDUtils::OpenOrMakeAllDirs(const char* dirname) {
uci1 47:fbe956b10a91 123 #ifdef DEBUG
uci1 47:fbe956b10a91 124 printf("OpenOrMakeAllDirs: [%s]\r\n",dirname);
uci1 47:fbe956b10a91 125 #endif
uci1 47:fbe956b10a91 126 // try making the subdir
uci1 47:fbe956b10a91 127 DIR* sd(0);
uci1 47:fbe956b10a91 128 std::string dn(dirname);
uci1 47:fbe956b10a91 129 std::size_t slash(0);
uci1 47:fbe956b10a91 130 std::string sdr;
uci1 47:fbe956b10a91 131 bool ok=true;
uci1 47:fbe956b10a91 132 while (ok) {
uci1 47:fbe956b10a91 133 slash=dn.find_first_of('/',slash+1);
uci1 47:fbe956b10a91 134 if (slash==std::string::npos) {
uci1 47:fbe956b10a91 135 sdr = dn; // no more slashes
uci1 47:fbe956b10a91 136 ok=false;
uci1 47:fbe956b10a91 137 } else {
uci1 47:fbe956b10a91 138 sdr = dn.substr(0, slash);
uci1 47:fbe956b10a91 139 }
uci1 47:fbe956b10a91 140 #ifdef DEBUG
uci1 47:fbe956b10a91 141 printf("slash=%d, sdr=[%s] (%d), ok=%s\r\n",
uci1 47:fbe956b10a91 142 (int)slash, sdr.c_str(), (int)sdr.size(),
uci1 47:fbe956b10a91 143 ok ? "true" : "false");
uci1 47:fbe956b10a91 144 #endif
uci1 47:fbe956b10a91 145 if (sd!=0) {
uci1 47:fbe956b10a91 146 // close the one from last time
uci1 47:fbe956b10a91 147 closedir(sd);
uci1 47:fbe956b10a91 148 }
uci1 47:fbe956b10a91 149 // skip the /sd, as it's not a real directory
uci1 47:fbe956b10a91 150 // should be skipped anyway, but..
uci1 47:fbe956b10a91 151 if (sdr.compare(kSDdir)!=0) {
uci1 47:fbe956b10a91 152 #ifdef DEBUG
uci1 47:fbe956b10a91 153 printf("calling OpenOrMakeDir [%s]\r\n",sdr.c_str());
uci1 47:fbe956b10a91 154 #endif
uci1 47:fbe956b10a91 155 sd = OpenOrMakeDir(sdr.c_str());
uci1 47:fbe956b10a91 156 }
uci1 47:fbe956b10a91 157 }
uci1 47:fbe956b10a91 158 return sd;
uci1 47:fbe956b10a91 159 }
uci1 47:fbe956b10a91 160
uci1 25:57b2627fe756 161 DIR* SnSDUtils::OpenOrMakeDir(const char* dirname) {
uci1 25:57b2627fe756 162 #ifdef DEBUG
uci1 25:57b2627fe756 163 printf("open dir %s\r\n",dirname);
uci1 25:57b2627fe756 164 #endif
uci1 56:0bba0ef15697 165 if (InitSDCard()) {
uci1 40:1324da35afd4 166
uci1 56:0bba0ef15697 167 DIR* rd( opendir(dirname) );
uci1 56:0bba0ef15697 168 if (rd==NULL) {
uci1 56:0bba0ef15697 169 // try making the directory
uci1 25:57b2627fe756 170 #ifdef DEBUG
uci1 56:0bba0ef15697 171 printf("making dir %s\r\n",dirname);
uci1 25:57b2627fe756 172 #endif
uci1 56:0bba0ef15697 173 mkdir(dirname, 0777);
uci1 36:87865913ae6f 174 #ifdef DEBUG
uci1 56:0bba0ef15697 175 printf("opening dir %s\r\n",dirname);
uci1 36:87865913ae6f 176 #endif
uci1 56:0bba0ef15697 177 rd = opendir(dirname);
uci1 56:0bba0ef15697 178 }
uci1 36:87865913ae6f 179 #ifdef DEBUG
uci1 56:0bba0ef15697 180 printf("returning rd=%p\r\n",(void*)rd);
uci1 36:87865913ae6f 181 #endif
uci1 56:0bba0ef15697 182 return rd;
uci1 56:0bba0ef15697 183 } else {
uci1 56:0bba0ef15697 184 return 0;
uci1 56:0bba0ef15697 185 }
uci1 25:57b2627fe756 186 }
uci1 10:3c93db1cfb12 187
uci1 0:664899e0b988 188 uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr,
uci1 0:664899e0b988 189 const uint32_t run) {
uci1 0:664899e0b988 190 // count the files having expected filename format
uci1 56:0bba0ef15697 191
uci1 56:0bba0ef15697 192 uint16_t maxs(kBadSeqNum);
uci1 0:664899e0b988 193
uci1 56:0bba0ef15697 194 if (InitSDCard()) {
uci1 56:0bba0ef15697 195
uci1 56:0bba0ef15697 196 maxs = 0; // change back from kBadSeqNum!
uci1 56:0bba0ef15697 197
uci1 56:0bba0ef15697 198 // get the run dir
uci1 56:0bba0ef15697 199 uint32_t rdlen(0);
uci1 56:0bba0ef15697 200 std::string rdnms ( GetSubDirFor(run, 0, rdlen, false) );
uci1 56:0bba0ef15697 201 const char* rdnm = rdnms.c_str();
uci1 56:0bba0ef15697 202 // open/make the run directory
uci1 56:0bba0ef15697 203 FATDirHandle* rd(static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) ));
uci1 56:0bba0ef15697 204 struct dirent* rdent;
uci1 56:0bba0ef15697 205 uint16_t dseq(0);
uci1 36:87865913ae6f 206 #ifdef DEBUG
uci1 56:0bba0ef15697 207 printf("starting readdir loop over %p\r\n",(void*)rd);
uci1 36:87865913ae6f 208 #endif
uci1 56:0bba0ef15697 209 while ( (rdent = readdir(rd))!=NULL ) {
uci1 36:87865913ae6f 210 #ifdef DEBUG
uci1 56:0bba0ef15697 211 printf("rdent = %p\r\n",(void*)rdent);
uci1 36:87865913ae6f 212 #endif
uci1 56:0bba0ef15697 213 if ((rd->filinfo()->fattrib & AM_DIR)!=0) {
uci1 36:87865913ae6f 214 #ifdef DEBUG
uci1 56:0bba0ef15697 215 printf("is a dir\r\n");
uci1 36:87865913ae6f 216 #endif
uci1 56:0bba0ef15697 217 // is a directory
uci1 56:0bba0ef15697 218 const int ncm = sscanf(rdent->d_name, "s%hu", &dseq);
uci1 56:0bba0ef15697 219 if (ncm==1) {
uci1 56:0bba0ef15697 220 #ifdef DEBUG
uci1 56:0bba0ef15697 221 printf("dseq=%hu, maxs=%hu\r\n",dseq,maxs);
uci1 56:0bba0ef15697 222 #endif
uci1 56:0bba0ef15697 223 if ( (dseq>maxs) && (dseq<kMaxSeqNum) ) {
uci1 56:0bba0ef15697 224 maxs = dseq;
uci1 56:0bba0ef15697 225 }
uci1 4:a91682e19d6b 226 }
uci1 0:664899e0b988 227 }
uci1 56:0bba0ef15697 228 #ifdef DEBUG
uci1 56:0bba0ef15697 229 else {
uci1 56:0bba0ef15697 230 printf("not a dir\r\n");
uci1 56:0bba0ef15697 231 }
uci1 56:0bba0ef15697 232 #endif
uci1 0:664899e0b988 233 }
uci1 36:87865913ae6f 234 #ifdef DEBUG
uci1 56:0bba0ef15697 235 printf("closing directory %p\r\n",(void*)rd);
uci1 36:87865913ae6f 236 #endif
uci1 56:0bba0ef15697 237 closedir(rd);
uci1 36:87865913ae6f 238 #ifdef DEBUG
uci1 56:0bba0ef15697 239 printf("Found max seq dir num %hu for run %u\r\n",maxs,run);
uci1 25:57b2627fe756 240 #endif
uci1 56:0bba0ef15697 241 // open up the seq dir
uci1 56:0bba0ef15697 242 rdnms = GetSubDirFor(run, maxs, rdlen, true);
uci1 56:0bba0ef15697 243 rdnm = rdnms.c_str();
uci1 56:0bba0ef15697 244 // runXseq0 filename (fn points to a static buffer)
uci1 56:0bba0ef15697 245 const char* fn = GetOutFileName(macadr, run, maxs)
uci1 56:0bba0ef15697 246 + rdlen + 1; // take out dir and '/'s
uci1 56:0bba0ef15697 247 // don't compare seq#. don't use num of chars in case seq is >999
uci1 56:0bba0ef15697 248 const int32_t ncomp = strrchr(fn, 's') - fn;
uci1 56:0bba0ef15697 249 // open (or make) the run/seq dir
uci1 56:0bba0ef15697 250 rd = static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) );
uci1 56:0bba0ef15697 251 // get the new sequence number (ok if it overflows this seq "bin")
uci1 56:0bba0ef15697 252 maxs=0;
uci1 56:0bba0ef15697 253 while ( (rdent = readdir(rd))!=NULL ) {
uci1 56:0bba0ef15697 254 Watchdog::kick(); // don't reset
uci1 56:0bba0ef15697 255 if ((rd->filinfo()->fattrib & AM_DIR)==0) {
uci1 56:0bba0ef15697 256 // is a file.
uci1 56:0bba0ef15697 257 // don't just count files, in case one seq was
uci1 56:0bba0ef15697 258 // transferred and erased in the middle of a run
uci1 56:0bba0ef15697 259 if (strncmp(rdent->d_name, fn, ncomp)==0) {
uci1 56:0bba0ef15697 260 // allow for deleted files to make gaps.
uci1 56:0bba0ef15697 261 // search for highest seq number and increase that
uci1 56:0bba0ef15697 262 if (sscanf((rdent->d_name)+ncomp,"s%hu.dat",&dseq)==1) {
uci1 25:57b2627fe756 263 #ifdef DEBUG
uci1 56:0bba0ef15697 264 printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n",
uci1 56:0bba0ef15697 265 rdent->d_name, dseq, __kMaxUShort);
uci1 25:57b2627fe756 266 #endif
uci1 56:0bba0ef15697 267 if (dseq==__kMaxUShort) {
uci1 56:0bba0ef15697 268 maxs = dseq;
uci1 56:0bba0ef15697 269 break;
uci1 56:0bba0ef15697 270 }
uci1 56:0bba0ef15697 271 #ifdef DEBUG
uci1 56:0bba0ef15697 272 printf("dseq=%hu, maxs=%hu\r\n",dseq,maxs);
uci1 56:0bba0ef15697 273 #endif
uci1 56:0bba0ef15697 274 if ( (dseq>=maxs) && (dseq<kMaxSeqNum)) {
uci1 56:0bba0ef15697 275 maxs=dseq+1;
uci1 56:0bba0ef15697 276 }
uci1 56:0bba0ef15697 277 if (maxs==__kMaxUShort) {
uci1 56:0bba0ef15697 278 break;
uci1 56:0bba0ef15697 279 }
uci1 25:57b2627fe756 280 }
uci1 25:57b2627fe756 281 }
uci1 25:57b2627fe756 282 }
uci1 25:57b2627fe756 283 }
uci1 56:0bba0ef15697 284 closedir(rd);
uci1 56:0bba0ef15697 285 } else {
uci1 56:0bba0ef15697 286 // no SD card
uci1 56:0bba0ef15697 287
uci1 25:57b2627fe756 288 }
uci1 21:ce51bb0ba4a5 289 #ifdef DEBUG
uci1 25:57b2627fe756 290 printf("return maxs=%hu\r\n",maxs);
uci1 21:ce51bb0ba4a5 291 #endif
uci1 25:57b2627fe756 292 return maxs;
uci1 0:664899e0b988 293 }
uci1 0:664899e0b988 294
uci1 25:57b2627fe756 295 FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent,
uci1 25:57b2627fe756 296 const bool redoDir) {
uci1 0:664899e0b988 297 FILE* f = 0;
uci1 56:0bba0ef15697 298 if (InitSDCard()) {
uci1 56:0bba0ef15697 299 //if ((name!=NULL) && ((*name)!=0) ) { // simple check if filename not set
uci1 56:0bba0ef15697 300 if (name!=NULL) { // simple check if filename not set
uci1 25:57b2627fe756 301 #ifdef DEBUG
uci1 56:0bba0ef15697 302 printf("opening SD file. name=[%s]\r\n",name);
uci1 25:57b2627fe756 303 #endif
uci1 56:0bba0ef15697 304 f = OpenSDFile(name, "rb", redoDir);
uci1 56:0bba0ef15697 305 /*
uci1 56:0bba0ef15697 306 if (setcurrent) {
uci1 56:0bba0ef15697 307 fgCurFile = f;
uci1 56:0bba0ef15697 308 strncpy(fgCurFileName, name, kFNBufSize-1);
uci1 56:0bba0ef15697 309 fgCurSeq = GetSeqNumFromFileName(fgCurFileName);
uci1 56:0bba0ef15697 310 }
uci1 56:0bba0ef15697 311 */
uci1 3:24c5f0f50bf1 312 }
uci1 0:664899e0b988 313 }
uci1 0:664899e0b988 314 return f;
uci1 0:664899e0b988 315 }
uci1 0:664899e0b988 316
uci1 25:57b2627fe756 317 bool SnSDUtils::GetFullFilename(const char* name, std::string& ffn) {
uci1 25:57b2627fe756 318 #ifdef DEBUG
uci1 25:57b2627fe756 319 printf("GetFullFilename (%s)\r\n",name);
uci1 25:57b2627fe756 320 #endif
uci1 25:57b2627fe756 321 bool ret = false;
uci1 25:57b2627fe756 322 uint32_t run(0);
uci1 25:57b2627fe756 323 uint16_t seq(0);
uci1 25:57b2627fe756 324 const char* fn = strrchr(name, '/');
uci1 25:57b2627fe756 325 #ifdef DEBUG
uci1 25:57b2627fe756 326 printf("w/o / : %s\r\n",fn);
uci1 25:57b2627fe756 327 #endif
uci1 25:57b2627fe756 328 if (fn!=NULL) {
uci1 25:57b2627fe756 329 ++fn; // remove the /
uci1 25:57b2627fe756 330 } else {
uci1 25:57b2627fe756 331 fn = name;
uci1 25:57b2627fe756 332 }
uci1 25:57b2627fe756 333 ffn = "";
uci1 25:57b2627fe756 334 if (GetRunSeqFromFilename(fn, run, seq)) {
uci1 25:57b2627fe756 335 #ifdef DEBUG
uci1 25:57b2627fe756 336 printf("got run=%d, seq=%hu\r\n",run,seq);
uci1 25:57b2627fe756 337 #endif
uci1 25:57b2627fe756 338 uint32_t sdlen(0);
uci1 27:efc4d654b139 339 std::string subds( GetSubDirFor(run,seq,sdlen, true) );
uci1 27:efc4d654b139 340 const char* subd = subds.c_str();
uci1 25:57b2627fe756 341 #ifdef DEBUG
uci1 25:57b2627fe756 342 printf("subd=%s\r\n",subd);
uci1 25:57b2627fe756 343 #endif
uci1 25:57b2627fe756 344 ffn = subd;
uci1 25:57b2627fe756 345 ffn += "/";
uci1 25:57b2627fe756 346 ret = true;
uci1 25:57b2627fe756 347 }
uci1 25:57b2627fe756 348 ffn += fn;
uci1 25:57b2627fe756 349 #ifdef DEBUG
uci1 25:57b2627fe756 350 printf("ffn=%s, ret=%d\r\n",ffn.c_str(),(int)ret);
uci1 25:57b2627fe756 351 #endif
uci1 25:57b2627fe756 352 return ret;
uci1 25:57b2627fe756 353 }
uci1 25:57b2627fe756 354
uci1 25:57b2627fe756 355 FILE* SnSDUtils::OpenSDFile(const char* name, const char* mode,
uci1 25:57b2627fe756 356 const bool redoDir) {
uci1 12:d472f9811262 357 // TODO: check if we have memory?
uci1 25:57b2627fe756 358 #ifdef DEBUG
uci1 25:57b2627fe756 359 printf("OpenSDFile: Trying to open %s.\r\n",name);
uci1 25:57b2627fe756 360 #endif
uci1 56:0bba0ef15697 361 FILE* f = 0;
uci1 56:0bba0ef15697 362 if (InitSDCard()) {
uci1 40:1324da35afd4 363
uci1 56:0bba0ef15697 364 std::string ffn;
uci1 56:0bba0ef15697 365 bool ok = true;
uci1 56:0bba0ef15697 366 #ifdef DEBUG
uci1 56:0bba0ef15697 367 printf("redoDir=%d\r\n",(int)redoDir);
uci1 56:0bba0ef15697 368 #endif
uci1 56:0bba0ef15697 369 if (redoDir) {
uci1 56:0bba0ef15697 370 #ifdef DEBUG
uci1 56:0bba0ef15697 371 printf("calling GetFullFilename\r\n");
uci1 56:0bba0ef15697 372 #endif
uci1 56:0bba0ef15697 373 ok = GetFullFilename(name, ffn);
uci1 56:0bba0ef15697 374 #ifdef DEBUG
uci1 56:0bba0ef15697 375 printf("ffn=%s\r\n",ffn.c_str());
uci1 56:0bba0ef15697 376 #endif
uci1 56:0bba0ef15697 377 } else {
uci1 56:0bba0ef15697 378 #ifdef DEBUG
uci1 56:0bba0ef15697 379 printf("looking for /\r\n");
uci1 56:0bba0ef15697 380 #endif
uci1 56:0bba0ef15697 381 // make sure the directory exists
uci1 56:0bba0ef15697 382 const char* ld = strrchr(name, '/');
uci1 25:57b2627fe756 383 #ifdef DEBUG
uci1 56:0bba0ef15697 384 printf("ld=%p, ld-name = %d\r\n",ld,(int)(ld-name));
uci1 25:57b2627fe756 385 #endif
uci1 56:0bba0ef15697 386 if ((ld!=0) && (ld>name)) {
uci1 56:0bba0ef15697 387 std::string dn(name, ld-name);
uci1 56:0bba0ef15697 388 DIR* d = OpenOrMakeAllDirs(dn.c_str());
uci1 25:57b2627fe756 389 #ifdef DEBUG
uci1 56:0bba0ef15697 390 printf("d=%p\r\n",d);
uci1 25:57b2627fe756 391 #endif
uci1 56:0bba0ef15697 392 if (d!=NULL) {
uci1 56:0bba0ef15697 393 closedir(d);
uci1 56:0bba0ef15697 394 }
uci1 56:0bba0ef15697 395 }
uci1 56:0bba0ef15697 396 // now just copy the (already-) full name
uci1 56:0bba0ef15697 397 ffn = name;
uci1 56:0bba0ef15697 398 }
uci1 56:0bba0ef15697 399 if ( ok && ffn.size()>0 ) {
uci1 56:0bba0ef15697 400 #ifdef DEBUG
uci1 56:0bba0ef15697 401 printf("OpenSDFile: %s, mode %s\r\n",ffn.c_str(),mode);
uci1 56:0bba0ef15697 402 #endif
uci1 56:0bba0ef15697 403 f = fopen(ffn.c_str(), mode);
uci1 56:0bba0ef15697 404 //setvbuf(f, 0, _IONBF, 0); // no buffering
uci1 56:0bba0ef15697 405 #ifdef DEBUG
uci1 56:0bba0ef15697 406 printf("OpenSDFile: f=%p\r\n",(void*)f);
uci1 56:0bba0ef15697 407 #endif
uci1 56:0bba0ef15697 408 }
uci1 25:57b2627fe756 409 #ifdef DEBUG
uci1 25:57b2627fe756 410 printf("ffn=%s\r\n",ffn.c_str());
uci1 25:57b2627fe756 411 #endif
uci1 25:57b2627fe756 412 }
uci1 1:e392595b4b76 413 return f;
uci1 1:e392595b4b76 414 }
uci1 1:e392595b4b76 415
uci1 0:664899e0b988 416 FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr,
uci1 40:1324da35afd4 417 const uint32_t run,
uci1 40:1324da35afd4 418 const uint16_t minseq) {
uci1 0:664899e0b988 419 // opens a new file in the specified directory and writes this
uci1 0:664899e0b988 420 // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes)
uci1 0:664899e0b988 421 //
uci1 22:f957c4f840ad 422 #ifdef DEBUG
uci1 40:1324da35afd4 423 printf("getting seq num for run %u, minseq %hu\r\n",
uci1 40:1324da35afd4 424 run, minseq);
uci1 22:f957c4f840ad 425 #endif
uci1 56:0bba0ef15697 426 fgCurFile = 0;
uci1 12:d472f9811262 427 fgCurSeq = GetSeqNum(macadr, run);
uci1 22:f957c4f840ad 428 #ifdef DEBUG
uci1 40:1324da35afd4 429 printf("fgCurSeq=%hu\r\n",fgCurSeq);
uci1 56:0bba0ef15697 430 #endif
uci1 56:0bba0ef15697 431 if (InitSDCard()) {
uci1 56:0bba0ef15697 432 if (fgCurSeq<minseq) {
uci1 56:0bba0ef15697 433 fgCurSeq=minseq;
uci1 56:0bba0ef15697 434 }
uci1 56:0bba0ef15697 435 #ifdef DEBUG
uci1 56:0bba0ef15697 436 printf("getting output file name\r\n");
uci1 22:f957c4f840ad 437 #endif
uci1 56:0bba0ef15697 438 memset(fgCurFileName, 0, sizeof(char)*kFNBufSize);
uci1 56:0bba0ef15697 439 strncpy(fgCurFileName,GetOutFileName(macadr, run, fgCurSeq),kFNBufSize-1);
uci1 56:0bba0ef15697 440 //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,fgCurSeq);
uci1 25:57b2627fe756 441 #ifdef DEBUG
uci1 56:0bba0ef15697 442 printf("fgCurFileName=%s\r\n",fgCurFileName);
uci1 25:57b2627fe756 443 #endif
uci1 56:0bba0ef15697 444 fgCurFile = 0;
uci1 56:0bba0ef15697 445 if (fgCurFileName!=NULL) {
uci1 22:f957c4f840ad 446 #ifdef DEBUG
uci1 56:0bba0ef15697 447 printf("opening SD file\r\n");
uci1 22:f957c4f840ad 448 #endif
uci1 56:0bba0ef15697 449 fgCurFile = OpenSDFile(fgCurFileName, "wb", false);
uci1 56:0bba0ef15697 450 if (fgCurFile!=NULL && ferror(fgCurFile)==0) {
uci1 19:74155d652c37 451 #ifdef DEBUG
uci1 56:0bba0ef15697 452 printf("Writing file header\r\n");
uci1 19:74155d652c37 453 #endif
uci1 56:0bba0ef15697 454 WriteFileHeader(fgCurFile, macadr, run, fgCurSeq);
uci1 56:0bba0ef15697 455
uci1 56:0bba0ef15697 456 AddToRunSeqList(run, fgCurSeq);
uci1 56:0bba0ef15697 457 }
uci1 2:e67f7c158087 458 }
uci1 56:0bba0ef15697 459 #ifdef DEBUG
uci1 56:0bba0ef15697 460 printf("fgCurFile=%p\r\n",(void*)fgCurFile);
uci1 56:0bba0ef15697 461 #endif
uci1 0:664899e0b988 462 }
uci1 1:e392595b4b76 463 return fgCurFile;
uci1 0:664899e0b988 464 }
uci1 0:664899e0b988 465
uci1 25:57b2627fe756 466 void SnSDUtils::PrintFilesInDirs(const char* dirname) {
uci1 56:0bba0ef15697 467 if (InitSDCard()) {
uci1 40:1324da35afd4 468
uci1 56:0bba0ef15697 469 DIR* d;
uci1 56:0bba0ef15697 470 struct dirent* dent;
uci1 56:0bba0ef15697 471 Watchdog::kick(); // don't reset
uci1 56:0bba0ef15697 472 if ( (d = opendir( dirname ))!=NULL ) {
uci1 56:0bba0ef15697 473 FATDirHandle* dir = static_cast<FATDirHandle*>(d);
uci1 56:0bba0ef15697 474 while ( (dent = readdir(d))!=NULL ) {
uci1 56:0bba0ef15697 475 printf("dn=%s. datr=%02x. dir=%d\r\n",
uci1 56:0bba0ef15697 476 dent->d_name,
uci1 56:0bba0ef15697 477 dir->filinfo()->fattrib,
uci1 56:0bba0ef15697 478 dir->filinfo()->fattrib & AM_DIR);
uci1 56:0bba0ef15697 479 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 56:0bba0ef15697 480 std::string dnm(dirname);
uci1 56:0bba0ef15697 481 dnm += "/";
uci1 56:0bba0ef15697 482 dnm += dent->d_name;
uci1 56:0bba0ef15697 483 PrintFilesInDirs(dnm.c_str());
uci1 56:0bba0ef15697 484 }
uci1 25:57b2627fe756 485 }
uci1 56:0bba0ef15697 486 closedir(d);
uci1 25:57b2627fe756 487 }
uci1 25:57b2627fe756 488 }
uci1 25:57b2627fe756 489 }
uci1 25:57b2627fe756 490
uci1 40:1324da35afd4 491 float SnSDUtils::GetFreeBytes() {
uci1 56:0bba0ef15697 492 float frs(0);
uci1 56:0bba0ef15697 493 if (InitSDCard()) {
uci1 40:1324da35afd4 494
uci1 56:0bba0ef15697 495 FATFS* fs;
uci1 56:0bba0ef15697 496 DWORD fre_clust;
uci1 56:0bba0ef15697 497 f_getfree("0:",&fre_clust,&fs);
uci1 56:0bba0ef15697 498 frs = static_cast<float>(fs->csize)
uci1 56:0bba0ef15697 499 *static_cast<float>(fs->free_clust)
uci1 40:1324da35afd4 500 #if _MAX_SS != 512
uci1 56:0bba0ef15697 501 *(fs->ssize);
uci1 40:1324da35afd4 502 #else
uci1 56:0bba0ef15697 503 *512;
uci1 40:1324da35afd4 504 #endif
uci1 40:1324da35afd4 505 #ifdef DEBUG
uci1 56:0bba0ef15697 506 printf("free space = %g b (%g GB, %g MB, %g KB)\r\n",
uci1 56:0bba0ef15697 507 frs, frs/1073741824.0, frs/1048576.0, frs/1024.0);
uci1 40:1324da35afd4 508 #endif
uci1 56:0bba0ef15697 509 }
uci1 40:1324da35afd4 510 return frs;
uci1 40:1324da35afd4 511 }
uci1 40:1324da35afd4 512
uci1 21:ce51bb0ba4a5 513 void SnSDUtils::GetDirProps(const char* dirname,
uci1 21:ce51bb0ba4a5 514 uint32_t& nfiles,
uci1 21:ce51bb0ba4a5 515 float& totbytes) {
uci1 21:ce51bb0ba4a5 516 nfiles = 0;
uci1 21:ce51bb0ba4a5 517 totbytes = 0;
uci1 56:0bba0ef15697 518 if (InitSDCard()) {
uci1 56:0bba0ef15697 519
uci1 56:0bba0ef15697 520 struct dirent* dent;
uci1 56:0bba0ef15697 521 FATDirHandle* d = static_cast<FATDirHandle*>( opendir(dirname) );
uci1 56:0bba0ef15697 522 if (d!=0) {
uci1 56:0bba0ef15697 523 while ( (dent = readdir(d))!=NULL ) {
uci1 56:0bba0ef15697 524 Watchdog::kick(); // don't reset
uci1 56:0bba0ef15697 525 if ( (d->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 56:0bba0ef15697 526 // a subdirectory
uci1 56:0bba0ef15697 527 std::string dnm(dirname);
uci1 56:0bba0ef15697 528 dnm += "/";
uci1 56:0bba0ef15697 529 dnm += dent->d_name;
uci1 56:0bba0ef15697 530 uint32_t sdnf;
uci1 56:0bba0ef15697 531 float sdtb;
uci1 56:0bba0ef15697 532 GetDirProps(dnm.c_str(), sdnf, sdtb);
uci1 56:0bba0ef15697 533 nfiles += sdnf;
uci1 56:0bba0ef15697 534 totbytes += sdtb;
uci1 56:0bba0ef15697 535 } else {
uci1 56:0bba0ef15697 536 // a file
uci1 56:0bba0ef15697 537 ++nfiles;
uci1 56:0bba0ef15697 538 totbytes += d->filinfo()->fsize;
uci1 56:0bba0ef15697 539 }
uci1 56:0bba0ef15697 540 }
uci1 56:0bba0ef15697 541 closedir(d);
uci1 21:ce51bb0ba4a5 542 }
uci1 21:ce51bb0ba4a5 543 }
uci1 21:ce51bb0ba4a5 544 #ifdef DEBUG
uci1 22:f957c4f840ad 545 printf("GetDirProps: %s :: nf=%u, tb=%g\r\n",
uci1 21:ce51bb0ba4a5 546 dirname, nfiles, totbytes);
uci1 21:ce51bb0ba4a5 547 #endif
uci1 21:ce51bb0ba4a5 548 }
uci1 21:ce51bb0ba4a5 549
uci1 22:f957c4f840ad 550 bool SnSDUtils::WriteHeartbeatTo(FILE* file,
uci1 22:f957c4f840ad 551 const uint32_t time,
uci1 22:f957c4f840ad 552 const uint32_t num) {
uci1 40:1324da35afd4 553 if (file!=0) {
uci1 56:0bba0ef15697 554 if (InitSDCard()) {
uci1 56:0bba0ef15697 555
uci1 56:0bba0ef15697 556 const bool r1 =
uci1 56:0bba0ef15697 557 SnHeaderFrame::WriteTo(file, SnHeaderFrame::kHeartbeatCode,
uci1 56:0bba0ef15697 558 SnHeartbeatFrame::SizeOf(SnHeartbeatFrame::kIOVers));
uci1 56:0bba0ef15697 559 const bool r2 =
uci1 56:0bba0ef15697 560 SnHeartbeatFrame::WriteTo(file, time, num);
uci1 56:0bba0ef15697 561 return (r1 && r2);
uci1 56:0bba0ef15697 562 }
uci1 40:1324da35afd4 563 }
uci1 56:0bba0ef15697 564 return false;
uci1 40:1324da35afd4 565 }
uci1 40:1324da35afd4 566
uci1 40:1324da35afd4 567 bool SnSDUtils::WriteTrigWaitWinTime(FILE* file,
uci1 40:1324da35afd4 568 SnClockSetFrame& clkset,
uci1 40:1324da35afd4 569 const bool isStart) {
uci1 40:1324da35afd4 570 if (file!=0) {
uci1 56:0bba0ef15697 571 if (InitSDCard()) {
uci1 56:0bba0ef15697 572
uci1 56:0bba0ef15697 573 bool ok = SnHeaderFrame::WriteTo(file,
uci1 56:0bba0ef15697 574 (isStart) ? (SnHeaderFrame::kFileTrgStrtCode)
uci1 56:0bba0ef15697 575 : (SnHeaderFrame::kFileTrgStopCode),
uci1 56:0bba0ef15697 576 clkset.SizeOf());
uci1 56:0bba0ef15697 577 ok &= (SnCommWin::kOkMsgSent == clkset.WriteTo(file));
uci1 56:0bba0ef15697 578 return ok;
uci1 56:0bba0ef15697 579 }
uci1 40:1324da35afd4 580 }
uci1 56:0bba0ef15697 581 return false;
uci1 22:f957c4f840ad 582 }
uci1 22:f957c4f840ad 583
uci1 0:664899e0b988 584 bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
uci1 0:664899e0b988 585 const SnEventFrame& evt,
uci1 0:664899e0b988 586 const SnConfigFrame& conf) {
uci1 0:664899e0b988 587 // write event to SD card
uci1 56:0bba0ef15697 588 bool ret = false;
uci1 40:1324da35afd4 589 if (efile!=0) {
uci1 56:0bba0ef15697 590 if (InitSDCard()) {
uci1 56:0bba0ef15697 591
uci1 56:0bba0ef15697 592 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 56:0bba0ef15697 593 uint16_t sWvBase=0;
uci1 56:0bba0ef15697 594 conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
uci1 56:0bba0ef15697 595 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode,
uci1 56:0bba0ef15697 596 evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB));
uci1 56:0bba0ef15697 597 ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
uci1 56:0bba0ef15697 598 fflush(efile);
uci1 56:0bba0ef15697 599 }
uci1 40:1324da35afd4 600 }
uci1 56:0bba0ef15697 601 return ret;
uci1 0:664899e0b988 602 }
uci1 0:664899e0b988 603
uci1 0:664899e0b988 604 bool SnSDUtils::WriteConfig(FILE* efile,
uci1 0:664899e0b988 605 const SnConfigFrame& conf) {
uci1 40:1324da35afd4 606 if (efile!=0) {
uci1 56:0bba0ef15697 607 if (InitSDCard()) {
uci1 40:1324da35afd4 608
uci1 56:0bba0ef15697 609 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode,
uci1 56:0bba0ef15697 610 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 56:0bba0ef15697 611 conf.WriteTo(efile);
uci1 56:0bba0ef15697 612 return true;
uci1 56:0bba0ef15697 613 }
uci1 40:1324da35afd4 614 }
uci1 56:0bba0ef15697 615 return false;
uci1 0:664899e0b988 616 }
uci1 0:664899e0b988 617
uci1 0:664899e0b988 618 void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
uci1 25:57b2627fe756 619 #ifdef DEBUG
uci1 25:57b2627fe756 620 printf("try to delete %s at %p\r\n",fname,f);
uci1 25:57b2627fe756 621 #endif
uci1 56:0bba0ef15697 622 if (InitSDCard()) {
uci1 40:1324da35afd4 623
uci1 56:0bba0ef15697 624 if (f!=0) {
uci1 56:0bba0ef15697 625 fclose(f);
uci1 56:0bba0ef15697 626 f=0;
uci1 56:0bba0ef15697 627 }
uci1 56:0bba0ef15697 628 std::string fn("");
uci1 56:0bba0ef15697 629 if (GetFullFilename(fname, fn)) {
uci1 25:57b2627fe756 630 #ifdef DEBUG
uci1 56:0bba0ef15697 631 printf("calling remove [%s]\r\n",fn.c_str());
uci1 25:57b2627fe756 632 #endif
uci1 56:0bba0ef15697 633 remove(fn.c_str());
uci1 56:0bba0ef15697 634 }
uci1 21:ce51bb0ba4a5 635 }
uci1 0:664899e0b988 636 }
uci1 0:664899e0b988 637
uci1 27:efc4d654b139 638 void SnSDUtils::DeleteFilesOfRun(const uint32_t run) {
uci1 27:efc4d654b139 639 #ifdef DEBUG
uci1 27:efc4d654b139 640 printf("deleteing files of run %lu\r\n",run);
uci1 27:efc4d654b139 641 #endif
uci1 27:efc4d654b139 642 uint32_t rdlen(0);
uci1 27:efc4d654b139 643 std::string rdnm( GetSubDirFor(run, 0, rdlen, false) );
uci1 27:efc4d654b139 644 DeleteAllFiles(rdnm.c_str());
uci1 27:efc4d654b139 645 }
uci1 27:efc4d654b139 646
uci1 27:efc4d654b139 647 void SnSDUtils::DeleteAllFiles(const char* dirname) {
uci1 27:efc4d654b139 648 #ifdef DEBUG
uci1 27:efc4d654b139 649 printf("deleting ALL files in %s\r\n",dirname);
uci1 27:efc4d654b139 650 #endif
uci1 56:0bba0ef15697 651 if (InitSDCard()) {
uci1 40:1324da35afd4 652
uci1 56:0bba0ef15697 653 DIR* d;
uci1 56:0bba0ef15697 654 struct dirent* dent;
uci1 56:0bba0ef15697 655 if ( (d = opendir( dirname ))!=NULL ) {
uci1 56:0bba0ef15697 656 FATDirHandle* dir = static_cast<FATDirHandle*>(d);
uci1 56:0bba0ef15697 657 while ( (dent = readdir(d))!=NULL ) {
uci1 56:0bba0ef15697 658 Watchdog::kick(); // don't reset
uci1 56:0bba0ef15697 659 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 56:0bba0ef15697 660 // a subdirectory
uci1 56:0bba0ef15697 661 std::string dnm(dirname);
uci1 56:0bba0ef15697 662 dnm += "/";
uci1 56:0bba0ef15697 663 dnm += dent->d_name;
uci1 56:0bba0ef15697 664 // delete all the files in this new subdir
uci1 27:efc4d654b139 665 #ifdef DEBUG
uci1 56:0bba0ef15697 666 printf("call DeleteAllFiles(%s)\r\n",dnm.c_str());
uci1 27:efc4d654b139 667 #endif
uci1 56:0bba0ef15697 668 DeleteAllFiles(dnm.c_str());
uci1 56:0bba0ef15697 669 } else if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 56:0bba0ef15697 670 // a data file (delete it)
uci1 56:0bba0ef15697 671 const bool isCurFile =
uci1 56:0bba0ef15697 672 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 56:0bba0ef15697 673 if (isCurFile==false) { // don't delete the current file
uci1 56:0bba0ef15697 674 FILE* f(0); // dummy
uci1 56:0bba0ef15697 675 DeleteFile(f, dent->d_name);
uci1 56:0bba0ef15697 676 }
uci1 27:efc4d654b139 677 }
uci1 56:0bba0ef15697 678 } // loop over stuff in this dir
uci1 56:0bba0ef15697 679 closedir(d);
uci1 56:0bba0ef15697 680 DeleteDirIfEmpty(dirname);
uci1 56:0bba0ef15697 681 }
uci1 27:efc4d654b139 682 }
uci1 27:efc4d654b139 683 }
uci1 27:efc4d654b139 684
uci1 56:0bba0ef15697 685 bool SnSDUtils::DeleteDirIfEmpty(const char* dirname) {
uci1 27:efc4d654b139 686 #ifdef DEBUG
uci1 27:efc4d654b139 687 printf("DeleteDirIfEmpty(%s)\r\n",dirname);
uci1 27:efc4d654b139 688 #endif
uci1 56:0bba0ef15697 689 bool doDel = false;
uci1 56:0bba0ef15697 690 if (InitSDCard()) {
uci1 40:1324da35afd4 691
uci1 56:0bba0ef15697 692 DIR* d;
uci1 56:0bba0ef15697 693 struct dirent* dent;
uci1 56:0bba0ef15697 694 if ( (d = opendir(dirname))!=NULL ) {
uci1 56:0bba0ef15697 695 dent = readdir(d);
uci1 56:0bba0ef15697 696 if ( dent==NULL ) {
uci1 56:0bba0ef15697 697 // then this directory is empty
uci1 56:0bba0ef15697 698 static const size_t subdsz = strlen(kSDsubDir);
uci1 56:0bba0ef15697 699 // just double check that this directory is
uci1 56:0bba0ef15697 700 // a subdirectory of the data dir
uci1 56:0bba0ef15697 701 if (strlen(dirname)>subdsz) {
uci1 56:0bba0ef15697 702 doDel = true;
uci1 56:0bba0ef15697 703 }
uci1 56:0bba0ef15697 704 } // else this dir isn't empty
uci1 56:0bba0ef15697 705 closedir(d);
uci1 56:0bba0ef15697 706 if (doDel) {
uci1 56:0bba0ef15697 707 #ifdef DEBUG
uci1 56:0bba0ef15697 708 printf("removing directory [%s]\r\n",dirname);
uci1 56:0bba0ef15697 709 #endif
uci1 56:0bba0ef15697 710 remove(dirname);
uci1 27:efc4d654b139 711 }
uci1 27:efc4d654b139 712 }
uci1 27:efc4d654b139 713 }
uci1 56:0bba0ef15697 714 return doDel;
uci1 27:efc4d654b139 715 }
uci1 27:efc4d654b139 716
uci1 56:0bba0ef15697 717 SnCommWin::ECommWinResult
uci1 56:0bba0ef15697 718 SnSDUtils::SendOneFile(const char* dfn,
uci1 56:0bba0ef15697 719 SnCommWin* comm,
uci1 56:0bba0ef15697 720 const uint32_t timeout,
uci1 56:0bba0ef15697 721 char* const buf,
uci1 56:0bba0ef15697 722 const uint32_t bsize,
uci1 56:0bba0ef15697 723 const SnConfigFrame& curConf,
uci1 56:0bba0ef15697 724 SnEventFrame& evt,
uci1 56:0bba0ef15697 725 SnPowerFrame& pow) {
uci1 56:0bba0ef15697 726
uci1 56:0bba0ef15697 727 #ifdef DEBUG
uci1 56:0bba0ef15697 728 printf("SendOneFile (%s)\r\n",dfn);
uci1 56:0bba0ef15697 729 #endif
uci1 56:0bba0ef15697 730
uci1 56:0bba0ef15697 731 SnCommWin::ECommWinResult res = SnCommWin::kOkMsgSent;
uci1 56:0bba0ef15697 732
uci1 56:0bba0ef15697 733 // open the file
uci1 56:0bba0ef15697 734 const bool isCurFile = (strcmp(dfn, GetCurFileName())==0);
uci1 56:0bba0ef15697 735 FILE* f(0);
uci1 56:0bba0ef15697 736 if (isCurFile) {
uci1 56:0bba0ef15697 737 // file must already be written out!
uci1 56:0bba0ef15697 738 f = GetCurFile();
uci1 56:0bba0ef15697 739 } else {
uci1 56:0bba0ef15697 740 f = OpenExistingFile(dfn, false, false);
uci1 56:0bba0ef15697 741 }
uci1 56:0bba0ef15697 742
uci1 56:0bba0ef15697 743 #ifdef DEBUG
uci1 56:0bba0ef15697 744 printf("SendOneFile: isCurFile=%d, f=%p, fn=%s\r\n",
uci1 56:0bba0ef15697 745 (int)isCurFile, (void*)f, dfn);
uci1 56:0bba0ef15697 746 #endif
uci1 56:0bba0ef15697 747
uci1 56:0bba0ef15697 748 uint8_t hndres = SnHeaderFrame::kHnShFailNonCode;
uci1 56:0bba0ef15697 749 if (f!=0) {
uci1 56:0bba0ef15697 750 #ifdef DEBUG
uci1 56:0bba0ef15697 751 printf("SendOneFile: calling SendDataFromFile\r\n");
uci1 56:0bba0ef15697 752 #endif
uci1 56:0bba0ef15697 753 res = comm->SendDataFromFile(f, dfn,
uci1 56:0bba0ef15697 754 curConf, evt, pow, buf, bsize,
uci1 56:0bba0ef15697 755 0, timeout,
uci1 56:0bba0ef15697 756 &hndres);
uci1 56:0bba0ef15697 757
uci1 56:0bba0ef15697 758 if (isCurFile) {
uci1 56:0bba0ef15697 759 // move (back) to the end of the file
uci1 56:0bba0ef15697 760 // altho hopefully no writing will happen after this
uci1 56:0bba0ef15697 761 fseek(fgCurFile, 0, SEEK_END);
uci1 56:0bba0ef15697 762 }
uci1 56:0bba0ef15697 763 }
uci1 56:0bba0ef15697 764 #ifdef DEBUG
uci1 56:0bba0ef15697 765 printf("isCurFile=%d, res=%d, deleting=%d, hndres=%02x\r\n",
uci1 56:0bba0ef15697 766 (int)isCurFile, (int)res, (int)(curConf.IsDeletingFiles()),
uci1 56:0bba0ef15697 767 hndres);
uci1 56:0bba0ef15697 768 #endif
uci1 56:0bba0ef15697 769
uci1 56:0bba0ef15697 770 return res;
uci1 56:0bba0ef15697 771 }
uci1 56:0bba0ef15697 772
uci1 56:0bba0ef15697 773 bool SnSDUtils::ClearRunSeqList() {
uci1 56:0bba0ef15697 774 if (InitSDCard()) {
uci1 56:0bba0ef15697 775 FILE* rslistf = fopen(kRunSeqListFilenm,"w");
uci1 56:0bba0ef15697 776 const bool ok = rslistf!=0;
uci1 56:0bba0ef15697 777 fclose(rslistf);
uci1 56:0bba0ef15697 778 #ifdef DEBUG
uci1 56:0bba0ef15697 779 printf("ClearRunSeqList. ok=%s\r\n",(ok?"true":"false"));
uci1 56:0bba0ef15697 780 #endif
uci1 56:0bba0ef15697 781 return ok;
uci1 56:0bba0ef15697 782 }
uci1 56:0bba0ef15697 783 return false;
uci1 56:0bba0ef15697 784 }
uci1 56:0bba0ef15697 785
uci1 56:0bba0ef15697 786 bool SnSDUtils::AddToRunSeqList(const uint32_t run,
uci1 56:0bba0ef15697 787 const uint16_t seq) {
uci1 56:0bba0ef15697 788 if (InitSDCard()) {
uci1 56:0bba0ef15697 789 FILE* rslistf = fopen(kRunSeqListFilenm,"a");
uci1 56:0bba0ef15697 790 bool ok = false;
uci1 56:0bba0ef15697 791 if (rslistf!=0) {
uci1 56:0bba0ef15697 792 ok = fprintf(rslistf, "%u %hu\n", run, seq) > 0;
uci1 56:0bba0ef15697 793 ok &= 0==ferror(rslistf);
uci1 56:0bba0ef15697 794 #ifdef DEBUG
uci1 56:0bba0ef15697 795 printf("AddToRunSeqList: run=%u, seq=%hu, ok=%s\r\n",
uci1 56:0bba0ef15697 796 run, seq, (ok?"true":"false"));
uci1 56:0bba0ef15697 797 #endif
uci1 56:0bba0ef15697 798 }
uci1 56:0bba0ef15697 799 fclose(rslistf);
uci1 56:0bba0ef15697 800 return ok;
uci1 56:0bba0ef15697 801 }
uci1 56:0bba0ef15697 802 return false;
uci1 56:0bba0ef15697 803 }
uci1 56:0bba0ef15697 804
uci1 56:0bba0ef15697 805 SnCommWin::ECommWinResult
uci1 56:0bba0ef15697 806 SnSDUtils::SendFileWithRunSeq(SnCommWin* comm,
uci1 56:0bba0ef15697 807 const uint32_t timeout,
uci1 56:0bba0ef15697 808 char* const buf,
uci1 56:0bba0ef15697 809 const uint32_t bsize,
uci1 56:0bba0ef15697 810 const SnConfigFrame& curConf,
uci1 56:0bba0ef15697 811 SnEventFrame& evt,
uci1 56:0bba0ef15697 812 SnPowerFrame& pow,
uci1 56:0bba0ef15697 813 const uint32_t run,
uci1 56:0bba0ef15697 814 const uint16_t seq) {
uci1 56:0bba0ef15697 815
uci1 56:0bba0ef15697 816 #ifdef DEBUG
uci1 56:0bba0ef15697 817 printf("SendFileWithRunSeq\r\n");
uci1 56:0bba0ef15697 818 #endif
uci1 56:0bba0ef15697 819
uci1 56:0bba0ef15697 820 // get the file name
uci1 56:0bba0ef15697 821 std::string dfn =
uci1 56:0bba0ef15697 822 GetOutFileName(SnConfigFrame::GetMacAddress(), run, seq);
uci1 56:0bba0ef15697 823
uci1 56:0bba0ef15697 824 // send it
uci1 56:0bba0ef15697 825 const SnCommWin::ECommWinResult res =
uci1 56:0bba0ef15697 826 SendOneFile(dfn.c_str(), comm, timeout, buf, bsize,
uci1 56:0bba0ef15697 827 curConf, evt, pow);
uci1 56:0bba0ef15697 828
uci1 56:0bba0ef15697 829 // see if we need to remove this directory now
uci1 56:0bba0ef15697 830 if (curConf.IsDeletingFiles()) {
uci1 56:0bba0ef15697 831 // get run/seq directory name
uci1 56:0bba0ef15697 832 uint32_t rdlen(0);
uci1 56:0bba0ef15697 833 std::string rdnm( GetSubDirFor(run, seq, rdlen, true) );
uci1 56:0bba0ef15697 834 #ifdef DEBUG
uci1 56:0bba0ef15697 835 printf("Checking removal of dir [%s]\r\n",rdnm.c_str());
uci1 56:0bba0ef15697 836 #endif
uci1 56:0bba0ef15697 837 if ( DeleteDirIfEmpty(rdnm.c_str()) ) {
uci1 56:0bba0ef15697 838 // removed the seq dir. do we need to remove
uci1 56:0bba0ef15697 839 // the run dir too?
uci1 56:0bba0ef15697 840 rdnm = GetSubDirFor(run, seq, rdlen, false);
uci1 56:0bba0ef15697 841 #ifdef DEBUG
uci1 56:0bba0ef15697 842 printf("Checking removal of dir [%s]\r\n",rdnm.c_str());
uci1 56:0bba0ef15697 843 #endif
uci1 56:0bba0ef15697 844 DeleteDirIfEmpty(rdnm.c_str());
uci1 56:0bba0ef15697 845 }
uci1 56:0bba0ef15697 846 }
uci1 56:0bba0ef15697 847
uci1 56:0bba0ef15697 848 return res;
uci1 56:0bba0ef15697 849 }
uci1 56:0bba0ef15697 850
uci1 56:0bba0ef15697 851 SnCommWin::ECommWinResult
uci1 56:0bba0ef15697 852 SnSDUtils::SendFilesInRunSeqList(SnCommWin* comm,
uci1 56:0bba0ef15697 853 const uint32_t timeout,
uci1 56:0bba0ef15697 854 char* const buf,
uci1 56:0bba0ef15697 855 const uint32_t bsize,
uci1 56:0bba0ef15697 856 const SnConfigFrame& curConf,
uci1 56:0bba0ef15697 857 SnEventFrame& evt,
uci1 56:0bba0ef15697 858 SnPowerFrame& pow) {
uci1 56:0bba0ef15697 859 #ifdef DEBUG
uci1 56:0bba0ef15697 860 printf("SendFilesInRunSeqList\r\n");
uci1 56:0bba0ef15697 861 #endif
uci1 56:0bba0ef15697 862
uci1 56:0bba0ef15697 863 SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent;
uci1 56:0bba0ef15697 864
uci1 56:0bba0ef15697 865 if (InitSDCard()) {
uci1 56:0bba0ef15697 866
uci1 56:0bba0ef15697 867 // open up the run/seq list file and send each corresponding file
uci1 56:0bba0ef15697 868 FILE* rslistf = fopen(kRunSeqListFilenm,"r");
uci1 56:0bba0ef15697 869 #ifdef DEBUG
uci1 56:0bba0ef15697 870 printf("fslistf=%p\r\n",(void*)rslistf);
uci1 56:0bba0ef15697 871 #endif
uci1 56:0bba0ef15697 872 if (rslistf!=0) {
uci1 56:0bba0ef15697 873 uint32_t run(0);
uci1 56:0bba0ef15697 874 uint16_t seq(0);
uci1 56:0bba0ef15697 875 while ( (feof(rslistf)==0)
uci1 56:0bba0ef15697 876 && (ferror(rslistf)==0) ) {
uci1 56:0bba0ef15697 877 #ifdef DEBUG
uci1 56:0bba0ef15697 878 printf("feof=%d, ferror=%d\r\n",
uci1 56:0bba0ef15697 879 (int)(feof(rslistf)), (int)(ferror(rslistf)));
uci1 56:0bba0ef15697 880 #endif
uci1 56:0bba0ef15697 881 const int nfilled = fscanf(rslistf, "%u %hu\n", &run ,&seq);
uci1 56:0bba0ef15697 882
uci1 56:0bba0ef15697 883 #ifdef DEBUG
uci1 56:0bba0ef15697 884 printf("nfilled=%d\r\n", nfilled);
uci1 56:0bba0ef15697 885 #endif
uci1 56:0bba0ef15697 886
uci1 56:0bba0ef15697 887 if ( 2==nfilled ) {
uci1 56:0bba0ef15697 888
uci1 56:0bba0ef15697 889 #ifdef DEBUG
uci1 56:0bba0ef15697 890 printf("run=%u, seq=%hu\r\n",run,seq);
uci1 56:0bba0ef15697 891 #endif
uci1 56:0bba0ef15697 892
uci1 56:0bba0ef15697 893 SnCommWin::ECommWinResult res =
uci1 56:0bba0ef15697 894 SendFileWithRunSeq(comm, timeout, buf, bsize,
uci1 56:0bba0ef15697 895 curConf, evt, pow,
uci1 56:0bba0ef15697 896 run, seq);
uci1 56:0bba0ef15697 897
uci1 56:0bba0ef15697 898 if ((res<rs) || (res==SnCommWin::kOkStopComm)) {
uci1 56:0bba0ef15697 899 rs = res;
uci1 56:0bba0ef15697 900 }
uci1 56:0bba0ef15697 901 // don't necessarily stop if rs is bad. don't want one bad file to
uci1 56:0bba0ef15697 902 // prevent sending the others
uci1 56:0bba0ef15697 903 if (rs<=SnCommWin::kFailTimeout) {
uci1 56:0bba0ef15697 904 break;
uci1 56:0bba0ef15697 905 } else if (rs==SnCommWin::kOkStopComm) {
uci1 56:0bba0ef15697 906 break;
uci1 56:0bba0ef15697 907 }
uci1 56:0bba0ef15697 908
uci1 56:0bba0ef15697 909 }
uci1 56:0bba0ef15697 910
uci1 56:0bba0ef15697 911 }
uci1 56:0bba0ef15697 912
uci1 56:0bba0ef15697 913 // do we need to clear the list?
uci1 56:0bba0ef15697 914 if (curConf.IsRunSeqListOneCommWinOnly()==false) {
uci1 56:0bba0ef15697 915 if (rs >= SnCommWin::kOkMsgSent) {
uci1 56:0bba0ef15697 916 // all sent ok
uci1 56:0bba0ef15697 917 ClearRunSeqList();
uci1 56:0bba0ef15697 918 }
uci1 56:0bba0ef15697 919 }
uci1 56:0bba0ef15697 920
uci1 56:0bba0ef15697 921 }
uci1 56:0bba0ef15697 922 fclose(rslistf);
uci1 56:0bba0ef15697 923 }
uci1 56:0bba0ef15697 924 return rs;
uci1 56:0bba0ef15697 925 }
uci1 56:0bba0ef15697 926
uci1 56:0bba0ef15697 927 SnCommWin::ECommWinResult
uci1 56:0bba0ef15697 928 SnSDUtils::SendPartOfRun(SnCommWin* comm,
uci1 56:0bba0ef15697 929 const uint32_t timeout,
uci1 56:0bba0ef15697 930 char* const buf,
uci1 56:0bba0ef15697 931 const uint32_t bsize,
uci1 56:0bba0ef15697 932 const SnConfigFrame& curConf,
uci1 56:0bba0ef15697 933 SnEventFrame& evt,
uci1 56:0bba0ef15697 934 SnPowerFrame& pow,
uci1 56:0bba0ef15697 935 const uint32_t run,
uci1 56:0bba0ef15697 936 const uint16_t minseq,
uci1 56:0bba0ef15697 937 const uint16_t maxseq) {
uci1 56:0bba0ef15697 938 // send files with run number 'run'
uci1 56:0bba0ef15697 939 // and seq number in [minseq,maxseq] (min/max inclusive)
uci1 56:0bba0ef15697 940
uci1 56:0bba0ef15697 941 #ifdef DEBUG
uci1 56:0bba0ef15697 942 printf("SendPartOfRun\r\n");
uci1 56:0bba0ef15697 943 #endif
uci1 56:0bba0ef15697 944
uci1 56:0bba0ef15697 945 SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent;
uci1 56:0bba0ef15697 946
uci1 56:0bba0ef15697 947 for (uint16_t seq=minseq; seq<=maxseq; ++seq) {
uci1 56:0bba0ef15697 948 SnCommWin::ECommWinResult res =
uci1 56:0bba0ef15697 949 SendFileWithRunSeq(comm,
uci1 56:0bba0ef15697 950 timeout, buf, bsize,
uci1 56:0bba0ef15697 951 curConf, evt, pow,
uci1 56:0bba0ef15697 952 run, seq);
uci1 56:0bba0ef15697 953
uci1 56:0bba0ef15697 954 if ((res<rs) || (res==SnCommWin::kOkStopComm)) {
uci1 56:0bba0ef15697 955 rs = res;
uci1 56:0bba0ef15697 956 }
uci1 56:0bba0ef15697 957 // don't necessarily stop if rs is bad. don't want one bad file to
uci1 56:0bba0ef15697 958 // prevent sending the others
uci1 56:0bba0ef15697 959 if (rs<=SnCommWin::kFailTimeout) {
uci1 56:0bba0ef15697 960 break;
uci1 56:0bba0ef15697 961 } else if (rs==SnCommWin::kOkStopComm) {
uci1 56:0bba0ef15697 962 break;
uci1 56:0bba0ef15697 963 }
uci1 56:0bba0ef15697 964
uci1 56:0bba0ef15697 965 }
uci1 56:0bba0ef15697 966
uci1 56:0bba0ef15697 967 return rs;
uci1 56:0bba0ef15697 968 }
uci1 56:0bba0ef15697 969
uci1 56:0bba0ef15697 970
uci1 40:1324da35afd4 971 SnCommWin::ECommWinResult SnSDUtils::SendAllOfRun(SnCommWin* comm,
uci1 40:1324da35afd4 972 const uint32_t timeout,
uci1 40:1324da35afd4 973 char* const buf,
uci1 40:1324da35afd4 974 const uint32_t bsize,
uci1 40:1324da35afd4 975 const SnConfigFrame& curConf,
uci1 40:1324da35afd4 976 SnEventFrame& evt,
uci1 40:1324da35afd4 977 SnPowerFrame& pow,
uci1 40:1324da35afd4 978 const uint32_t runnum) {
uci1 40:1324da35afd4 979 // send all files in a run
uci1 40:1324da35afd4 980
uci1 40:1324da35afd4 981 // get the run dir
uci1 40:1324da35afd4 982 uint32_t rdlen(0);
uci1 40:1324da35afd4 983 std::string rdnms ( GetSubDirFor(runnum, 0, rdlen, false) );
uci1 40:1324da35afd4 984 return SendAllFiles(comm, timeout, buf, bsize, curConf, evt, pow,
uci1 40:1324da35afd4 985 rdnms.c_str());
uci1 40:1324da35afd4 986 }
uci1 40:1324da35afd4 987
uci1 0:664899e0b988 988 SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
uci1 3:24c5f0f50bf1 989 const uint32_t timeout,
uci1 3:24c5f0f50bf1 990 char* const buf,
uci1 6:6f002d202f59 991 const uint32_t bsize,
uci1 6:6f002d202f59 992 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 993 SnEventFrame& evt,
uci1 12:d472f9811262 994 SnPowerFrame& pow,
uci1 25:57b2627fe756 995 const char* dirname) {
uci1 40:1324da35afd4 996 // send all files in the specified directory
uci1 56:0bba0ef15697 997
uci1 56:0bba0ef15697 998 SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail;
uci1 40:1324da35afd4 999
uci1 56:0bba0ef15697 1000 if (InitSDCard()) {
uci1 16:744ce85aede2 1001
uci1 56:0bba0ef15697 1002 rs = SnCommWin::kOkMsgSent;
uci1 56:0bba0ef15697 1003
uci1 56:0bba0ef15697 1004 DIR* d;
uci1 56:0bba0ef15697 1005 struct dirent* dent;
uci1 56:0bba0ef15697 1006 if ( (d = opendir( dirname ))!=NULL ) {
uci1 56:0bba0ef15697 1007 FATDirHandle* dir = static_cast<FATDirHandle*>(d);
uci1 56:0bba0ef15697 1008 while ( (dent = readdir(d))!=NULL ) {
uci1 56:0bba0ef15697 1009 Watchdog::kick(); // don't reset
uci1 56:0bba0ef15697 1010 SnCommWin::ECommWinResult res = rs;
uci1 56:0bba0ef15697 1011 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 56:0bba0ef15697 1012 // a subdirectory
uci1 56:0bba0ef15697 1013 std::string dnm(dirname);
uci1 56:0bba0ef15697 1014 dnm += "/";
uci1 56:0bba0ef15697 1015 dnm += dent->d_name;
uci1 56:0bba0ef15697 1016 // send all the files in this new subdir
uci1 56:0bba0ef15697 1017 res = SendAllFiles(comm, timeout, buf, bsize,
uci1 56:0bba0ef15697 1018 curConf, evt, pow,
uci1 56:0bba0ef15697 1019 dnm.c_str());
uci1 56:0bba0ef15697 1020 } else if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 56:0bba0ef15697 1021 // a data file (send it)
uci1 56:0bba0ef15697 1022 res = SendOneFile(dent->d_name, comm, timeout, buf, bsize,
uci1 56:0bba0ef15697 1023 curConf, evt, pow);
uci1 1:e392595b4b76 1024 }
uci1 56:0bba0ef15697 1025 if ((res<rs) || (res==SnCommWin::kOkStopComm)) {
uci1 56:0bba0ef15697 1026 rs = res;
uci1 56:0bba0ef15697 1027 }
uci1 56:0bba0ef15697 1028 // don't necessarily stop if rs is bad. don't want one bad file to
uci1 56:0bba0ef15697 1029 // prevent sending the others
uci1 56:0bba0ef15697 1030 if (rs<=SnCommWin::kFailTimeout) {
uci1 56:0bba0ef15697 1031 break;
uci1 56:0bba0ef15697 1032 } else if (rs==SnCommWin::kOkStopComm) {
uci1 56:0bba0ef15697 1033 break;
uci1 56:0bba0ef15697 1034 }
uci1 56:0bba0ef15697 1035 } // loop over stuff in this directory
uci1 56:0bba0ef15697 1036 closedir(d);
uci1 56:0bba0ef15697 1037 // see if we need to remove this directory now
uci1 56:0bba0ef15697 1038 if (curConf.IsDeletingFiles()) {
uci1 56:0bba0ef15697 1039 DeleteDirIfEmpty(dirname);
uci1 25:57b2627fe756 1040 }
uci1 0:664899e0b988 1041 }
uci1 0:664899e0b988 1042 }
uci1 0:664899e0b988 1043 return rs;
uci1 0:664899e0b988 1044 }
uci1 0:664899e0b988 1045