Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Nov 06 00:04:30 2013 +0000
Revision:
47:fbe956b10a91
Parent:
40:1324da35afd4
Child:
56:0bba0ef15697
afar and sbd on. debug ON. recursively make directories on the SD card so blank cards can be used. move debug block in procForce to before pin high so forced trigs work in debug mode

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 15:f2569d8e4176 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 2:e67f7c158087 22 char SnSDUtils::fgCurFileName[kFNBufSize]={0};
uci1 1:e392595b4b76 23 FILE* SnSDUtils::fgCurFile = 0;
uci1 12:d472f9811262 24 uint16_t SnSDUtils::fgCurSeq = 0;
uci1 40:1324da35afd4 25 bool SnSDUtils::fgNeedToInit = true;
uci1 40:1324da35afd4 26 const uint8_t SnSDUtils::kIOvers = 4;
uci1 5:9cea89700c66 27 const uint32_t SnSDUtils::kMaxSizeOfFileHdr =
uci1 5:9cea89700c66 28 sizeof(uint8_t)+sizeof(uint64_t)+sizeof(uint32_t)+sizeof(uint16_t)
uci1 8:95a325df1f6b 29 +(sizeof(uint8_t)+(2u*sizeof(uint16_t))); // power frame v1
uci1 4:a91682e19d6b 30
uci1 40:1324da35afd4 31 SnSDUtils::InitSDFcn SnSDUtils::fgDoInit = 0;
uci1 40:1324da35afd4 32
uci1 4:a91682e19d6b 33 static const uint16_t __kMaxUShort = ~0;
uci1 0:664899e0b988 34
uci1 40:1324da35afd4 35 void SnSDUtils::InitSDCard(const bool force) {
uci1 40:1324da35afd4 36 if ((fgNeedToInit || force) && (fgDoInit!=0)) {
uci1 40:1324da35afd4 37 (*fgDoInit)();
uci1 40:1324da35afd4 38 fgNeedToInit = false;
uci1 40:1324da35afd4 39 }
uci1 40:1324da35afd4 40 }
uci1 40:1324da35afd4 41
uci1 25:57b2627fe756 42 const char* SnSDUtils::GetSubDirFor(const uint32_t run, const uint16_t seq,
uci1 25:57b2627fe756 43 uint32_t& slen, const bool useSeq) {
uci1 40:1324da35afd4 44 // returns a STATIC string! (so make a copy of it before use)
uci1 25:57b2627fe756 45 // sets slen to the length of this string (same as strlen)
uci1 40:1324da35afd4 46 static const uint16_t tmplen = strlen(kSDsubDir)+50;
uci1 40:1324da35afd4 47 static char* tmpsd = new char[tmplen];
uci1 40:1324da35afd4 48 slen = snprintf(tmpsd, tmplen, "%s/r%05ld", kSDsubDir, run);
uci1 25:57b2627fe756 49 if (useSeq) {
uci1 40:1324da35afd4 50 slen += snprintf(tmpsd+slen, tmplen-slen, "/s%05d", (seq/SUBDIRSEQ)*SUBDIRSEQ);
uci1 40:1324da35afd4 51 }
uci1 40:1324da35afd4 52 if (slen > tmplen) {
uci1 40:1324da35afd4 53 slen = tmplen;
uci1 25:57b2627fe756 54 }
uci1 25:57b2627fe756 55 return tmpsd;
uci1 25:57b2627fe756 56 }
uci1 25:57b2627fe756 57
uci1 0:664899e0b988 58 const char* SnSDUtils::GetOutFileName(const uint64_t macadr,
uci1 0:664899e0b988 59 const uint32_t run,
uci1 0:664899e0b988 60 const uint16_t seq) {
uci1 0:664899e0b988 61 // returns the formatted file name, or NULL if the directory is too long
uci1 0:664899e0b988 62 // and the full name cannot fit in the buffer
uci1 0:664899e0b988 63 // NOTE: this fcn uses a static buffer, and so should not be called
uci1 0:664899e0b988 64 // multiple times in the same line (that includes the calling of functions
uci1 0:664899e0b988 65 // that call this function!)
uci1 0:664899e0b988 66 //
uci1 0:664899e0b988 67 // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat
uci1 0:664899e0b988 68 // 35 chars 7 + 12 +1+ 5 +1+ 5 + 4
uci1 25:57b2627fe756 69 uint32_t sdlen(0);
uci1 27:efc4d654b139 70 std::string subdirs( GetSubDirFor(run, seq, sdlen, true) );
uci1 27:efc4d654b139 71 const char* subdir = subdirs.c_str();
uci1 25:57b2627fe756 72 if (sdlen<(kFNBufSize-37)) {
uci1 0:664899e0b988 73 static char tbuf[kFNBufSize];
uci1 0:664899e0b988 74 memset(tbuf, 0, sizeof(char)*kFNBufSize);
uci1 0:664899e0b988 75 // if file name format changes, GetSeqNum must be changed too
uci1 25:57b2627fe756 76 sprintf(tbuf, "%s/SnEvtsM%012llXr%05lds%05d.dat",
uci1 25:57b2627fe756 77 subdir,
uci1 0:664899e0b988 78 macadr>>16, // 64 -> 48 bits
uci1 0:664899e0b988 79 run, seq);
uci1 0:664899e0b988 80 return tbuf;
uci1 0:664899e0b988 81 } else {
uci1 0:664899e0b988 82 return NULL;
uci1 0:664899e0b988 83 }
uci1 0:664899e0b988 84 }
uci1 25:57b2627fe756 85
uci1 25:57b2627fe756 86 bool SnSDUtils::GetRunSeqFromFilename(const char* fn,
uci1 25:57b2627fe756 87 uint32_t& run,
uci1 25:57b2627fe756 88 uint16_t& seq) {
uci1 25:57b2627fe756 89 bool ret = false;
uci1 25:57b2627fe756 90 const int32_t ncomp = strrchr(fn, 'r') - fn;
uci1 25:57b2627fe756 91 #ifdef DEBUG
uci1 25:57b2627fe756 92 printf("fn=%s, ncomp=%d\r\n",fn,ncomp);
uci1 25:57b2627fe756 93 #endif
uci1 25:57b2627fe756 94 if ((ncomp<strlen(fn)) && (ncomp>0)) {
uci1 25:57b2627fe756 95 if (sscanf(fn+ncomp,"r%lus%hu.dat",&run,&seq)==2) {
uci1 25:57b2627fe756 96 #ifdef DEBUG
uci1 25:57b2627fe756 97 printf("run=%u, seq=%hu\r\n",run,seq);
uci1 25:57b2627fe756 98 #endif
uci1 25:57b2627fe756 99 ret = true;
uci1 25:57b2627fe756 100 }
uci1 25:57b2627fe756 101 }
uci1 25:57b2627fe756 102 return ret;
uci1 25:57b2627fe756 103 }
uci1 25:57b2627fe756 104 /*
uci1 10:3c93db1cfb12 105 uint16_t SnSDUtils::GetSeqNumFromFileName(const char* fn) {
uci1 10:3c93db1cfb12 106 uint16_t seq=0;
uci1 10:3c93db1cfb12 107 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 10:3c93db1cfb12 108 if (ncomp<strlen(fn)) {
uci1 10:3c93db1cfb12 109 sscanf(fn+ncomp,"s%hu.dat",&seq);
uci1 10:3c93db1cfb12 110 }
uci1 10:3c93db1cfb12 111 return seq;
uci1 10:3c93db1cfb12 112 }
uci1 25:57b2627fe756 113 */
uci1 47:fbe956b10a91 114
uci1 47:fbe956b10a91 115 DIR* SnSDUtils::OpenOrMakeAllDirs(const char* dirname) {
uci1 47:fbe956b10a91 116 #ifdef DEBUG
uci1 47:fbe956b10a91 117 printf("OpenOrMakeAllDirs: [%s]\r\n",dirname);
uci1 47:fbe956b10a91 118 #endif
uci1 47:fbe956b10a91 119 // try making the subdir
uci1 47:fbe956b10a91 120 DIR* sd(0);
uci1 47:fbe956b10a91 121 std::string dn(dirname);
uci1 47:fbe956b10a91 122 std::size_t slash(0);
uci1 47:fbe956b10a91 123 std::string sdr;
uci1 47:fbe956b10a91 124 bool ok=true;
uci1 47:fbe956b10a91 125 while (ok) {
uci1 47:fbe956b10a91 126 slash=dn.find_first_of('/',slash+1);
uci1 47:fbe956b10a91 127 if (slash==std::string::npos) {
uci1 47:fbe956b10a91 128 sdr = dn; // no more slashes
uci1 47:fbe956b10a91 129 ok=false;
uci1 47:fbe956b10a91 130 } else {
uci1 47:fbe956b10a91 131 sdr = dn.substr(0, slash);
uci1 47:fbe956b10a91 132 }
uci1 47:fbe956b10a91 133 #ifdef DEBUG
uci1 47:fbe956b10a91 134 printf("slash=%d, sdr=[%s] (%d), ok=%s\r\n",
uci1 47:fbe956b10a91 135 (int)slash, sdr.c_str(), (int)sdr.size(),
uci1 47:fbe956b10a91 136 ok ? "true" : "false");
uci1 47:fbe956b10a91 137 #endif
uci1 47:fbe956b10a91 138 if (sd!=0) {
uci1 47:fbe956b10a91 139 // close the one from last time
uci1 47:fbe956b10a91 140 closedir(sd);
uci1 47:fbe956b10a91 141 }
uci1 47:fbe956b10a91 142 // skip the /sd, as it's not a real directory
uci1 47:fbe956b10a91 143 // should be skipped anyway, but..
uci1 47:fbe956b10a91 144 if (sdr.compare(kSDdir)!=0) {
uci1 47:fbe956b10a91 145 #ifdef DEBUG
uci1 47:fbe956b10a91 146 printf("calling OpenOrMakeDir [%s]\r\n",sdr.c_str());
uci1 47:fbe956b10a91 147 #endif
uci1 47:fbe956b10a91 148 sd = OpenOrMakeDir(sdr.c_str());
uci1 47:fbe956b10a91 149 }
uci1 47:fbe956b10a91 150 }
uci1 47:fbe956b10a91 151 return sd;
uci1 47:fbe956b10a91 152 }
uci1 47:fbe956b10a91 153
uci1 25:57b2627fe756 154 DIR* SnSDUtils::OpenOrMakeDir(const char* dirname) {
uci1 25:57b2627fe756 155 #ifdef DEBUG
uci1 25:57b2627fe756 156 printf("open dir %s\r\n",dirname);
uci1 25:57b2627fe756 157 #endif
uci1 40:1324da35afd4 158 InitSDCard();
uci1 40:1324da35afd4 159
uci1 25:57b2627fe756 160 DIR* rd( opendir(dirname) );
uci1 25:57b2627fe756 161 if (rd==NULL) {
uci1 25:57b2627fe756 162 // try making the directory
uci1 25:57b2627fe756 163 #ifdef DEBUG
uci1 25:57b2627fe756 164 printf("making dir %s\r\n",dirname);
uci1 25:57b2627fe756 165 #endif
uci1 25:57b2627fe756 166 mkdir(dirname, 0777);
uci1 36:87865913ae6f 167 #ifdef DEBUG
uci1 36:87865913ae6f 168 printf("opening dir %s\r\n",dirname);
uci1 36:87865913ae6f 169 #endif
uci1 25:57b2627fe756 170 rd = opendir(dirname);
uci1 25:57b2627fe756 171 }
uci1 36:87865913ae6f 172 #ifdef DEBUG
uci1 36:87865913ae6f 173 printf("returning rd=%p\r\n",(void*)rd);
uci1 36:87865913ae6f 174 #endif
uci1 25:57b2627fe756 175 return rd;
uci1 25:57b2627fe756 176 }
uci1 10:3c93db1cfb12 177
uci1 0:664899e0b988 178 uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr,
uci1 0:664899e0b988 179 const uint32_t run) {
uci1 0:664899e0b988 180 // count the files having expected filename format
uci1 40:1324da35afd4 181 InitSDCard();
uci1 0:664899e0b988 182
uci1 25:57b2627fe756 183 // get the run dir
uci1 25:57b2627fe756 184 uint32_t rdlen(0);
uci1 27:efc4d654b139 185 std::string rdnms ( GetSubDirFor(run, 0, rdlen, false) );
uci1 27:efc4d654b139 186 const char* rdnm = rdnms.c_str();
uci1 25:57b2627fe756 187 // open/make the run directory
uci1 47:fbe956b10a91 188 FATDirHandle* rd(static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) ));
uci1 25:57b2627fe756 189 struct dirent* rdent;
uci1 25:57b2627fe756 190 uint16_t dseq(0), maxs(0);
uci1 36:87865913ae6f 191 #ifdef DEBUG
uci1 36:87865913ae6f 192 printf("starting readdir loop over %p\r\n",(void*)rd);
uci1 36:87865913ae6f 193 #endif
uci1 25:57b2627fe756 194 while ( (rdent = readdir(rd))!=NULL ) {
uci1 36:87865913ae6f 195 #ifdef DEBUG
uci1 36:87865913ae6f 196 printf("rdent = %p\r\n",(void*)rdent);
uci1 36:87865913ae6f 197 #endif
uci1 25:57b2627fe756 198 if ((rd->filinfo()->fattrib & AM_DIR)!=0) {
uci1 36:87865913ae6f 199 #ifdef DEBUG
uci1 36:87865913ae6f 200 printf("is a dir\r\n");
uci1 36:87865913ae6f 201 #endif
uci1 25:57b2627fe756 202 // is a directory
uci1 25:57b2627fe756 203 const int ncm = sscanf(rdent->d_name, "s%hu", &dseq);
uci1 25:57b2627fe756 204 if (ncm==1) {
uci1 25:57b2627fe756 205 if (dseq>maxs) {
uci1 25:57b2627fe756 206 maxs = dseq;
uci1 4:a91682e19d6b 207 }
uci1 0:664899e0b988 208 }
uci1 0:664899e0b988 209 }
uci1 36:87865913ae6f 210 #ifdef DEBUG
uci1 36:87865913ae6f 211 else {
uci1 36:87865913ae6f 212 printf("not a dir\r\n");
uci1 36:87865913ae6f 213 }
uci1 36:87865913ae6f 214 #endif
uci1 0:664899e0b988 215 }
uci1 36:87865913ae6f 216 #ifdef DEBUG
uci1 36:87865913ae6f 217 printf("closing directory %p\r\n",(void*)rd);
uci1 36:87865913ae6f 218 #endif
uci1 25:57b2627fe756 219 closedir(rd);
uci1 25:57b2627fe756 220 #ifdef DEBUG
uci1 40:1324da35afd4 221 printf("Found max seq dir num %hu for run %u\r\n",maxs,run);
uci1 25:57b2627fe756 222 #endif
uci1 25:57b2627fe756 223 // open up the seq dir
uci1 27:efc4d654b139 224 rdnms = GetSubDirFor(run, maxs, rdlen, true);
uci1 27:efc4d654b139 225 rdnm = rdnms.c_str();
uci1 25:57b2627fe756 226 // runXseq0 filename (fn points to a static buffer)
uci1 25:57b2627fe756 227 const char* fn = GetOutFileName(macadr, run, maxs)
uci1 25:57b2627fe756 228 + rdlen + 1; // take out dir and '/'s
uci1 25:57b2627fe756 229 // don't compare seq#. don't use num of chars in case seq is >999
uci1 25:57b2627fe756 230 const int32_t ncomp = strrchr(fn, 's') - fn;
uci1 25:57b2627fe756 231 // open (or make) the run/seq dir
uci1 47:fbe956b10a91 232 rd = static_cast<FATDirHandle*>( OpenOrMakeAllDirs(rdnm) );
uci1 25:57b2627fe756 233 // get the new sequence number (ok if it overflows this seq "bin")
uci1 25:57b2627fe756 234 maxs=0;
uci1 25:57b2627fe756 235 while ( (rdent = readdir(rd))!=NULL ) {
uci1 25:57b2627fe756 236 Watchdog::kick(); // don't reset
uci1 25:57b2627fe756 237 if ((rd->filinfo()->fattrib & AM_DIR)==0) {
uci1 25:57b2627fe756 238 // is a file.
uci1 25:57b2627fe756 239 // don't just count files, in case one seq was
uci1 25:57b2627fe756 240 // transferred and erased in the middle of a run
uci1 25:57b2627fe756 241 if (strncmp(rdent->d_name, fn, ncomp)==0) {
uci1 25:57b2627fe756 242 // allow for deleted files to make gaps.
uci1 25:57b2627fe756 243 // search for highest seq number and increase that
uci1 25:57b2627fe756 244 if (sscanf((rdent->d_name)+ncomp,"s%hu.dat",&dseq)==1) {
uci1 25:57b2627fe756 245 #ifdef DEBUG
uci1 25:57b2627fe756 246 printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n",
uci1 25:57b2627fe756 247 rdent->d_name, dseq, __kMaxUShort);
uci1 25:57b2627fe756 248 #endif
uci1 25:57b2627fe756 249 if (dseq==__kMaxUShort) {
uci1 25:57b2627fe756 250 maxs = dseq;
uci1 25:57b2627fe756 251 break;
uci1 25:57b2627fe756 252 }
uci1 25:57b2627fe756 253 if (dseq>=maxs) {
uci1 25:57b2627fe756 254 maxs=dseq+1;
uci1 25:57b2627fe756 255 }
uci1 25:57b2627fe756 256 if (maxs==__kMaxUShort) {
uci1 25:57b2627fe756 257 break;
uci1 25:57b2627fe756 258 }
uci1 25:57b2627fe756 259 }
uci1 25:57b2627fe756 260 }
uci1 25:57b2627fe756 261 }
uci1 25:57b2627fe756 262 }
uci1 25:57b2627fe756 263 closedir(rd);
uci1 7:079617408fec 264
uci1 21:ce51bb0ba4a5 265 #ifdef DEBUG
uci1 25:57b2627fe756 266 printf("return maxs=%hu\r\n",maxs);
uci1 21:ce51bb0ba4a5 267 #endif
uci1 25:57b2627fe756 268 return maxs;
uci1 0:664899e0b988 269 }
uci1 0:664899e0b988 270
uci1 25:57b2627fe756 271 FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent,
uci1 25:57b2627fe756 272 const bool redoDir) {
uci1 40:1324da35afd4 273 InitSDCard();
uci1 0:664899e0b988 274 FILE* f = 0;
uci1 25:57b2627fe756 275 //if ((name!=NULL) && ((*name)!=0) ) { // simple check if filename not set
uci1 25:57b2627fe756 276 if (name!=NULL) { // simple check if filename not set
uci1 25:57b2627fe756 277 #ifdef DEBUG
uci1 25:57b2627fe756 278 printf("opening SD file. name=[%s]\r\n",name);
uci1 25:57b2627fe756 279 #endif
uci1 25:57b2627fe756 280 f = OpenSDFile(name, "rb", redoDir);
uci1 12:d472f9811262 281 /*
uci1 3:24c5f0f50bf1 282 if (setcurrent) {
uci1 3:24c5f0f50bf1 283 fgCurFile = f;
uci1 12:d472f9811262 284 strncpy(fgCurFileName, name, kFNBufSize-1);
uci1 12:d472f9811262 285 fgCurSeq = GetSeqNumFromFileName(fgCurFileName);
uci1 3:24c5f0f50bf1 286 }
uci1 12:d472f9811262 287 */
uci1 0:664899e0b988 288 }
uci1 0:664899e0b988 289 return f;
uci1 0:664899e0b988 290 }
uci1 0:664899e0b988 291
uci1 25:57b2627fe756 292 bool SnSDUtils::GetFullFilename(const char* name, std::string& ffn) {
uci1 25:57b2627fe756 293 #ifdef DEBUG
uci1 25:57b2627fe756 294 printf("GetFullFilename (%s)\r\n",name);
uci1 25:57b2627fe756 295 #endif
uci1 25:57b2627fe756 296 bool ret = false;
uci1 25:57b2627fe756 297 uint32_t run(0);
uci1 25:57b2627fe756 298 uint16_t seq(0);
uci1 25:57b2627fe756 299 const char* fn = strrchr(name, '/');
uci1 25:57b2627fe756 300 #ifdef DEBUG
uci1 25:57b2627fe756 301 printf("w/o / : %s\r\n",fn);
uci1 25:57b2627fe756 302 #endif
uci1 25:57b2627fe756 303 if (fn!=NULL) {
uci1 25:57b2627fe756 304 ++fn; // remove the /
uci1 25:57b2627fe756 305 } else {
uci1 25:57b2627fe756 306 fn = name;
uci1 25:57b2627fe756 307 }
uci1 25:57b2627fe756 308 ffn = "";
uci1 25:57b2627fe756 309 if (GetRunSeqFromFilename(fn, run, seq)) {
uci1 25:57b2627fe756 310 #ifdef DEBUG
uci1 25:57b2627fe756 311 printf("got run=%d, seq=%hu\r\n",run,seq);
uci1 25:57b2627fe756 312 #endif
uci1 25:57b2627fe756 313 uint32_t sdlen(0);
uci1 27:efc4d654b139 314 std::string subds( GetSubDirFor(run,seq,sdlen, true) );
uci1 27:efc4d654b139 315 const char* subd = subds.c_str();
uci1 25:57b2627fe756 316 #ifdef DEBUG
uci1 25:57b2627fe756 317 printf("subd=%s\r\n",subd);
uci1 25:57b2627fe756 318 #endif
uci1 25:57b2627fe756 319 ffn = subd;
uci1 25:57b2627fe756 320 ffn += "/";
uci1 25:57b2627fe756 321 ret = true;
uci1 25:57b2627fe756 322 }
uci1 25:57b2627fe756 323 ffn += fn;
uci1 25:57b2627fe756 324 #ifdef DEBUG
uci1 25:57b2627fe756 325 printf("ffn=%s, ret=%d\r\n",ffn.c_str(),(int)ret);
uci1 25:57b2627fe756 326 #endif
uci1 25:57b2627fe756 327 return ret;
uci1 25:57b2627fe756 328 }
uci1 25:57b2627fe756 329
uci1 25:57b2627fe756 330 FILE* SnSDUtils::OpenSDFile(const char* name, const char* mode,
uci1 25:57b2627fe756 331 const bool redoDir) {
uci1 12:d472f9811262 332 // TODO: check if we have memory?
uci1 25:57b2627fe756 333 #ifdef DEBUG
uci1 25:57b2627fe756 334 printf("OpenSDFile: Trying to open %s.\r\n",name);
uci1 25:57b2627fe756 335 #endif
uci1 40:1324da35afd4 336 InitSDCard();
uci1 40:1324da35afd4 337
uci1 25:57b2627fe756 338 std::string ffn;
uci1 25:57b2627fe756 339 FILE* f = 0;
uci1 25:57b2627fe756 340 bool ok = true;
uci1 25:57b2627fe756 341 #ifdef DEBUG
uci1 25:57b2627fe756 342 printf("redoDir=%d\r\n",(int)redoDir);
uci1 25:57b2627fe756 343 #endif
uci1 25:57b2627fe756 344 if (redoDir) {
uci1 25:57b2627fe756 345 #ifdef DEBUG
uci1 25:57b2627fe756 346 printf("calling GetFullFilename\r\n");
uci1 25:57b2627fe756 347 #endif
uci1 25:57b2627fe756 348 ok = GetFullFilename(name, ffn);
uci1 25:57b2627fe756 349 #ifdef DEBUG
uci1 25:57b2627fe756 350 printf("ffn=%s\r\n",ffn.c_str());
uci1 25:57b2627fe756 351 #endif
uci1 25:57b2627fe756 352 } else {
uci1 25:57b2627fe756 353 #ifdef DEBUG
uci1 25:57b2627fe756 354 printf("looking for /\r\n");
uci1 25:57b2627fe756 355 #endif
uci1 25:57b2627fe756 356 // make sure the directory exists
uci1 25:57b2627fe756 357 const char* ld = strrchr(name, '/');
uci1 25:57b2627fe756 358 #ifdef DEBUG
uci1 25:57b2627fe756 359 printf("ld=%p, ld-name = %d\r\n",ld,(int)(ld-name));
uci1 25:57b2627fe756 360 #endif
uci1 25:57b2627fe756 361 if ((ld!=0) && (ld>name)) {
uci1 25:57b2627fe756 362 std::string dn(name, ld-name);
uci1 47:fbe956b10a91 363 DIR* d = OpenOrMakeAllDirs(dn.c_str());
uci1 25:57b2627fe756 364 #ifdef DEBUG
uci1 25:57b2627fe756 365 printf("d=%p\r\n",d);
uci1 25:57b2627fe756 366 #endif
uci1 25:57b2627fe756 367 if (d!=NULL) {
uci1 25:57b2627fe756 368 closedir(d);
uci1 25:57b2627fe756 369 }
uci1 25:57b2627fe756 370 }
uci1 25:57b2627fe756 371 // now just copy the (already-) full name
uci1 25:57b2627fe756 372 ffn = name;
uci1 25:57b2627fe756 373 }
uci1 30:f869ed4bcc08 374 if ( ok && ffn.size()>0 ) {
uci1 25:57b2627fe756 375 #ifdef DEBUG
uci1 25:57b2627fe756 376 printf("OpenSDFile: %s, mode %s\r\n",ffn.c_str(),mode);
uci1 25:57b2627fe756 377 #endif
uci1 25:57b2627fe756 378 f = fopen(ffn.c_str(), mode);
uci1 25:57b2627fe756 379 //setvbuf(f, 0, _IONBF, 0); // no buffering
uci1 25:57b2627fe756 380 #ifdef DEBUG
uci1 25:57b2627fe756 381 printf("OpenSDFile: f=%p\r\n",(void*)f);
uci1 25:57b2627fe756 382 #endif
uci1 12:d472f9811262 383 }
uci1 12:d472f9811262 384 #ifdef DEBUG
uci1 25:57b2627fe756 385 printf("ffn=%s\r\n",ffn.c_str());
uci1 19:74155d652c37 386 #endif
uci1 1:e392595b4b76 387 return f;
uci1 1:e392595b4b76 388 }
uci1 1:e392595b4b76 389
uci1 0:664899e0b988 390 FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr,
uci1 40:1324da35afd4 391 const uint32_t run,
uci1 40:1324da35afd4 392 const uint16_t minseq) {
uci1 0:664899e0b988 393 // opens a new file in the specified directory and writes this
uci1 0:664899e0b988 394 // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes)
uci1 0:664899e0b988 395 //
uci1 22:f957c4f840ad 396 #ifdef DEBUG
uci1 40:1324da35afd4 397 printf("getting seq num for run %u, minseq %hu\r\n",
uci1 40:1324da35afd4 398 run, minseq);
uci1 22:f957c4f840ad 399 #endif
uci1 40:1324da35afd4 400 InitSDCard();
uci1 40:1324da35afd4 401
uci1 12:d472f9811262 402 fgCurSeq = GetSeqNum(macadr, run);
uci1 40:1324da35afd4 403 if (fgCurSeq<minseq) {
uci1 40:1324da35afd4 404 fgCurSeq=minseq;
uci1 40:1324da35afd4 405 }
uci1 22:f957c4f840ad 406 #ifdef DEBUG
uci1 40:1324da35afd4 407 printf("fgCurSeq=%hu\r\n",fgCurSeq);
uci1 22:f957c4f840ad 408 printf("getting output file name\r\n");
uci1 22:f957c4f840ad 409 #endif
uci1 0:664899e0b988 410 memset(fgCurFileName, 0, sizeof(char)*kFNBufSize);
uci1 12:d472f9811262 411 strncpy(fgCurFileName,GetOutFileName(macadr, run, fgCurSeq),kFNBufSize-1);
uci1 12:d472f9811262 412 //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,fgCurSeq);
uci1 25:57b2627fe756 413 #ifdef DEBUG
uci1 25:57b2627fe756 414 printf("fgCurFileName=%s\r\n",fgCurFileName);
uci1 25:57b2627fe756 415 #endif
uci1 1:e392595b4b76 416 fgCurFile = 0;
uci1 0:664899e0b988 417 if (fgCurFileName!=NULL) {
uci1 22:f957c4f840ad 418 #ifdef DEBUG
uci1 22:f957c4f840ad 419 printf("opening SD file\r\n");
uci1 22:f957c4f840ad 420 #endif
uci1 25:57b2627fe756 421 fgCurFile = OpenSDFile(fgCurFileName, "wb", false);
uci1 2:e67f7c158087 422 if (fgCurFile!=NULL && ferror(fgCurFile)==0) {
uci1 19:74155d652c37 423 #ifdef DEBUG
uci1 19:74155d652c37 424 printf("Writing file header\r\n");
uci1 19:74155d652c37 425 #endif
uci1 12:d472f9811262 426 WriteFileHeader(fgCurFile, macadr, run, fgCurSeq);
uci1 2:e67f7c158087 427 }
uci1 0:664899e0b988 428 }
uci1 19:74155d652c37 429 #ifdef DEBUG
uci1 19:74155d652c37 430 printf("fgCurFile=%p\r\n",(void*)fgCurFile);
uci1 19:74155d652c37 431 #endif
uci1 1:e392595b4b76 432 return fgCurFile;
uci1 0:664899e0b988 433 }
uci1 0:664899e0b988 434
uci1 25:57b2627fe756 435 void SnSDUtils::PrintFilesInDirs(const char* dirname) {
uci1 40:1324da35afd4 436 InitSDCard();
uci1 40:1324da35afd4 437
uci1 25:57b2627fe756 438 DIR* d;
uci1 25:57b2627fe756 439 struct dirent* dent;
uci1 25:57b2627fe756 440 Watchdog::kick(); // don't reset
uci1 25:57b2627fe756 441 if ( (d = opendir( dirname ))!=NULL ) {
uci1 39:2f17131d22a5 442 FATDirHandle* dir = static_cast<FATDirHandle*>(d);
uci1 25:57b2627fe756 443 while ( (dent = readdir(d))!=NULL ) {
uci1 25:57b2627fe756 444 printf("dn=%s. datr=%02x. dir=%d\r\n",
uci1 25:57b2627fe756 445 dent->d_name,
uci1 25:57b2627fe756 446 dir->filinfo()->fattrib,
uci1 25:57b2627fe756 447 dir->filinfo()->fattrib & AM_DIR);
uci1 25:57b2627fe756 448 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 25:57b2627fe756 449 std::string dnm(dirname);
uci1 25:57b2627fe756 450 dnm += "/";
uci1 25:57b2627fe756 451 dnm += dent->d_name;
uci1 25:57b2627fe756 452 PrintFilesInDirs(dnm.c_str());
uci1 25:57b2627fe756 453 }
uci1 25:57b2627fe756 454 }
uci1 47:fbe956b10a91 455 closedir(d);
uci1 25:57b2627fe756 456 }
uci1 25:57b2627fe756 457
uci1 25:57b2627fe756 458 }
uci1 25:57b2627fe756 459
uci1 40:1324da35afd4 460 float SnSDUtils::GetFreeBytes() {
uci1 40:1324da35afd4 461 InitSDCard();
uci1 40:1324da35afd4 462
uci1 40:1324da35afd4 463 FATFS* fs;
uci1 40:1324da35afd4 464 DWORD fre_clust;
uci1 40:1324da35afd4 465 f_getfree("0:",&fre_clust,&fs);
uci1 40:1324da35afd4 466 const float frs = static_cast<float>(fs->csize)
uci1 40:1324da35afd4 467 *static_cast<float>(fs->free_clust)
uci1 40:1324da35afd4 468 #if _MAX_SS != 512
uci1 40:1324da35afd4 469 *(fs->ssize);
uci1 40:1324da35afd4 470 #else
uci1 40:1324da35afd4 471 *512;
uci1 40:1324da35afd4 472 #endif
uci1 40:1324da35afd4 473 #ifdef DEBUG
uci1 40:1324da35afd4 474 printf("free space = %g b (%g GB, %g MB, %g KB)\r\n",
uci1 40:1324da35afd4 475 frs, frs/1073741824.0, frs/1048576.0, frs/1024.0);
uci1 40:1324da35afd4 476 #endif
uci1 40:1324da35afd4 477 return frs;
uci1 40:1324da35afd4 478 }
uci1 40:1324da35afd4 479
uci1 21:ce51bb0ba4a5 480 void SnSDUtils::GetDirProps(const char* dirname,
uci1 21:ce51bb0ba4a5 481 uint32_t& nfiles,
uci1 21:ce51bb0ba4a5 482 float& totbytes) {
uci1 40:1324da35afd4 483 InitSDCard();
uci1 40:1324da35afd4 484
uci1 21:ce51bb0ba4a5 485 nfiles = 0;
uci1 21:ce51bb0ba4a5 486 totbytes = 0;
uci1 25:57b2627fe756 487 struct dirent* dent;
uci1 39:2f17131d22a5 488 FATDirHandle* d = static_cast<FATDirHandle*>( opendir(dirname) );
uci1 21:ce51bb0ba4a5 489 if (d!=0) {
uci1 25:57b2627fe756 490 while ( (dent = readdir(d))!=NULL ) {
uci1 25:57b2627fe756 491 Watchdog::kick(); // don't reset
uci1 25:57b2627fe756 492 if ( (d->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 25:57b2627fe756 493 // a subdirectory
uci1 25:57b2627fe756 494 std::string dnm(dirname);
uci1 25:57b2627fe756 495 dnm += "/";
uci1 25:57b2627fe756 496 dnm += dent->d_name;
uci1 25:57b2627fe756 497 uint32_t sdnf;
uci1 25:57b2627fe756 498 float sdtb;
uci1 25:57b2627fe756 499 GetDirProps(dnm.c_str(), sdnf, sdtb);
uci1 25:57b2627fe756 500 nfiles += sdnf;
uci1 25:57b2627fe756 501 totbytes += sdtb;
uci1 25:57b2627fe756 502 } else {
uci1 25:57b2627fe756 503 // a file
uci1 25:57b2627fe756 504 ++nfiles;
uci1 25:57b2627fe756 505 totbytes += d->filinfo()->fsize;
uci1 25:57b2627fe756 506 }
uci1 21:ce51bb0ba4a5 507 }
uci1 21:ce51bb0ba4a5 508 closedir(d);
uci1 21:ce51bb0ba4a5 509 }
uci1 21:ce51bb0ba4a5 510 #ifdef DEBUG
uci1 22:f957c4f840ad 511 printf("GetDirProps: %s :: nf=%u, tb=%g\r\n",
uci1 21:ce51bb0ba4a5 512 dirname, nfiles, totbytes);
uci1 21:ce51bb0ba4a5 513 #endif
uci1 21:ce51bb0ba4a5 514 }
uci1 21:ce51bb0ba4a5 515
uci1 22:f957c4f840ad 516 bool SnSDUtils::WriteHeartbeatTo(FILE* file,
uci1 22:f957c4f840ad 517 const uint32_t time,
uci1 22:f957c4f840ad 518 const uint32_t num) {
uci1 40:1324da35afd4 519 if (file!=0) {
uci1 40:1324da35afd4 520 InitSDCard();
uci1 40:1324da35afd4 521
uci1 40:1324da35afd4 522 const bool r1 =
uci1 40:1324da35afd4 523 SnHeaderFrame::WriteTo(file, SnHeaderFrame::kHeartbeatCode,
uci1 40:1324da35afd4 524 SnHeartbeatFrame::SizeOf(SnHeartbeatFrame::kIOVers));
uci1 40:1324da35afd4 525 const bool r2 =
uci1 40:1324da35afd4 526 SnHeartbeatFrame::WriteTo(file, time, num);
uci1 40:1324da35afd4 527 return (r1 && r2);
uci1 40:1324da35afd4 528 } else {
uci1 40:1324da35afd4 529 return false;
uci1 40:1324da35afd4 530 }
uci1 40:1324da35afd4 531 }
uci1 40:1324da35afd4 532
uci1 40:1324da35afd4 533 bool SnSDUtils::WriteTrigWaitWinTime(FILE* file,
uci1 40:1324da35afd4 534 SnClockSetFrame& clkset,
uci1 40:1324da35afd4 535 const bool isStart) {
uci1 40:1324da35afd4 536 if (file!=0) {
uci1 40:1324da35afd4 537 InitSDCard();
uci1 40:1324da35afd4 538
uci1 40:1324da35afd4 539 bool ok = SnHeaderFrame::WriteTo(file,
uci1 40:1324da35afd4 540 (isStart) ? (SnHeaderFrame::kFileTrgStrtCode)
uci1 40:1324da35afd4 541 : (SnHeaderFrame::kFileTrgStopCode),
uci1 40:1324da35afd4 542 clkset.SizeOf());
uci1 40:1324da35afd4 543 ok &= (SnCommWin::kOkMsgSent == clkset.WriteTo(file));
uci1 40:1324da35afd4 544 return ok;
uci1 40:1324da35afd4 545 } else {
uci1 40:1324da35afd4 546 return false;
uci1 40:1324da35afd4 547 }
uci1 22:f957c4f840ad 548 }
uci1 22:f957c4f840ad 549
uci1 0:664899e0b988 550 bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
uci1 0:664899e0b988 551 const SnEventFrame& evt,
uci1 0:664899e0b988 552 const SnConfigFrame& conf) {
uci1 0:664899e0b988 553 // write event to SD card
uci1 0:664899e0b988 554
uci1 40:1324da35afd4 555 if (efile!=0) {
uci1 40:1324da35afd4 556 InitSDCard();
uci1 40:1324da35afd4 557
uci1 40:1324da35afd4 558 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 40:1324da35afd4 559 uint16_t sWvBase=0;
uci1 40:1324da35afd4 560 conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
uci1 40:1324da35afd4 561 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode,
uci1 40:1324da35afd4 562 evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB));
uci1 40:1324da35afd4 563 const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
uci1 40:1324da35afd4 564 fflush(efile);
uci1 40:1324da35afd4 565 return ret;
uci1 40:1324da35afd4 566 } else {
uci1 40:1324da35afd4 567 return false;
uci1 40:1324da35afd4 568 }
uci1 0:664899e0b988 569 }
uci1 0:664899e0b988 570
uci1 0:664899e0b988 571 bool SnSDUtils::WriteConfig(FILE* efile,
uci1 0:664899e0b988 572 const SnConfigFrame& conf) {
uci1 40:1324da35afd4 573 if (efile!=0) {
uci1 40:1324da35afd4 574 InitSDCard();
uci1 40:1324da35afd4 575
uci1 40:1324da35afd4 576 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode,
uci1 8:95a325df1f6b 577 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 40:1324da35afd4 578 conf.WriteTo(efile);
uci1 40:1324da35afd4 579 return true;
uci1 40:1324da35afd4 580 } else {
uci1 40:1324da35afd4 581 return false;
uci1 40:1324da35afd4 582 }
uci1 0:664899e0b988 583 }
uci1 0:664899e0b988 584
uci1 0:664899e0b988 585 void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
uci1 25:57b2627fe756 586 #ifdef DEBUG
uci1 25:57b2627fe756 587 printf("try to delete %s at %p\r\n",fname,f);
uci1 25:57b2627fe756 588 #endif
uci1 40:1324da35afd4 589 InitSDCard();
uci1 40:1324da35afd4 590
uci1 27:efc4d654b139 591 if (f!=0) {
uci1 27:efc4d654b139 592 fclose(f);
uci1 27:efc4d654b139 593 f=0;
uci1 27:efc4d654b139 594 }
uci1 25:57b2627fe756 595 std::string fn("");
uci1 25:57b2627fe756 596 if (GetFullFilename(fname, fn)) {
uci1 25:57b2627fe756 597 #ifdef DEBUG
uci1 25:57b2627fe756 598 printf("calling remove [%s]\r\n",fn.c_str());
uci1 25:57b2627fe756 599 #endif
uci1 25:57b2627fe756 600 remove(fn.c_str());
uci1 21:ce51bb0ba4a5 601 }
uci1 0:664899e0b988 602 }
uci1 0:664899e0b988 603
uci1 27:efc4d654b139 604 void SnSDUtils::DeleteFilesOfRun(const uint32_t run) {
uci1 27:efc4d654b139 605 #ifdef DEBUG
uci1 27:efc4d654b139 606 printf("deleteing files of run %lu\r\n",run);
uci1 27:efc4d654b139 607 #endif
uci1 27:efc4d654b139 608 uint32_t rdlen(0);
uci1 27:efc4d654b139 609 std::string rdnm( GetSubDirFor(run, 0, rdlen, false) );
uci1 27:efc4d654b139 610 DeleteAllFiles(rdnm.c_str());
uci1 27:efc4d654b139 611 }
uci1 27:efc4d654b139 612
uci1 27:efc4d654b139 613 void SnSDUtils::DeleteAllFiles(const char* dirname) {
uci1 27:efc4d654b139 614 #ifdef DEBUG
uci1 27:efc4d654b139 615 printf("deleting ALL files in %s\r\n",dirname);
uci1 27:efc4d654b139 616 #endif
uci1 40:1324da35afd4 617 InitSDCard();
uci1 40:1324da35afd4 618
uci1 27:efc4d654b139 619 DIR* d;
uci1 27:efc4d654b139 620 struct dirent* dent;
uci1 27:efc4d654b139 621 if ( (d = opendir( dirname ))!=NULL ) {
uci1 39:2f17131d22a5 622 FATDirHandle* dir = static_cast<FATDirHandle*>(d);
uci1 27:efc4d654b139 623 while ( (dent = readdir(d))!=NULL ) {
uci1 27:efc4d654b139 624 Watchdog::kick(); // don't reset
uci1 27:efc4d654b139 625 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 27:efc4d654b139 626 // a subdirectory
uci1 27:efc4d654b139 627 std::string dnm(dirname);
uci1 27:efc4d654b139 628 dnm += "/";
uci1 27:efc4d654b139 629 dnm += dent->d_name;
uci1 27:efc4d654b139 630 // delete all the files in this new subdir
uci1 27:efc4d654b139 631 #ifdef DEBUG
uci1 27:efc4d654b139 632 printf("call DeleteAllFiles(%s)\r\n",dnm.c_str());
uci1 27:efc4d654b139 633 #endif
uci1 27:efc4d654b139 634 DeleteAllFiles(dnm.c_str());
uci1 27:efc4d654b139 635 } else if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 27:efc4d654b139 636 // a data file (delete it)
uci1 27:efc4d654b139 637 const bool isCurFile =
uci1 27:efc4d654b139 638 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 27:efc4d654b139 639 if (isCurFile==false) { // don't delete the current file
uci1 27:efc4d654b139 640 FILE* f(0); // dummy
uci1 27:efc4d654b139 641 DeleteFile(f, dent->d_name);
uci1 27:efc4d654b139 642 }
uci1 27:efc4d654b139 643 }
uci1 27:efc4d654b139 644 } // loop over stuff in this dir
uci1 27:efc4d654b139 645 closedir(d);
uci1 27:efc4d654b139 646 DeleteDirIfEmpty(dirname);
uci1 27:efc4d654b139 647 }
uci1 27:efc4d654b139 648 }
uci1 27:efc4d654b139 649
uci1 27:efc4d654b139 650 void SnSDUtils::DeleteDirIfEmpty(const char* dirname) {
uci1 27:efc4d654b139 651 #ifdef DEBUG
uci1 27:efc4d654b139 652 printf("DeleteDirIfEmpty(%s)\r\n",dirname);
uci1 27:efc4d654b139 653 #endif
uci1 40:1324da35afd4 654 InitSDCard();
uci1 40:1324da35afd4 655
uci1 27:efc4d654b139 656 DIR* d;
uci1 27:efc4d654b139 657 struct dirent* dent;
uci1 27:efc4d654b139 658 if ( (d = opendir(dirname))!=NULL ) {
uci1 27:efc4d654b139 659 dent = readdir(d);
uci1 27:efc4d654b139 660 bool doDel = false;
uci1 27:efc4d654b139 661 if ( dent==NULL ) {
uci1 27:efc4d654b139 662 // then this directory is empty
uci1 27:efc4d654b139 663 static const size_t subdsz = strlen(kSDsubDir);
uci1 27:efc4d654b139 664 // just double check that this directory is
uci1 27:efc4d654b139 665 // a subdirectory of the data dir
uci1 27:efc4d654b139 666 if (strlen(dirname)>subdsz) {
uci1 27:efc4d654b139 667 doDel = true;
uci1 27:efc4d654b139 668 }
uci1 27:efc4d654b139 669 } // else this dir isn't empty
uci1 27:efc4d654b139 670 closedir(d);
uci1 27:efc4d654b139 671 if (doDel) {
uci1 27:efc4d654b139 672 #ifdef DEBUG
uci1 27:efc4d654b139 673 printf("removing directory [%s]\r\n",dirname);
uci1 27:efc4d654b139 674 #endif
uci1 27:efc4d654b139 675 remove(dirname);
uci1 27:efc4d654b139 676 }
uci1 27:efc4d654b139 677 }
uci1 27:efc4d654b139 678 }
uci1 27:efc4d654b139 679
uci1 40:1324da35afd4 680 SnCommWin::ECommWinResult SnSDUtils::SendAllOfRun(SnCommWin* comm,
uci1 40:1324da35afd4 681 const uint32_t timeout,
uci1 40:1324da35afd4 682 char* const buf,
uci1 40:1324da35afd4 683 const uint32_t bsize,
uci1 40:1324da35afd4 684 const SnConfigFrame& curConf,
uci1 40:1324da35afd4 685 SnEventFrame& evt,
uci1 40:1324da35afd4 686 SnPowerFrame& pow,
uci1 40:1324da35afd4 687 const uint32_t runnum) {
uci1 40:1324da35afd4 688 // send all files in a run
uci1 40:1324da35afd4 689
uci1 40:1324da35afd4 690 // get the run dir
uci1 40:1324da35afd4 691 uint32_t rdlen(0);
uci1 40:1324da35afd4 692 std::string rdnms ( GetSubDirFor(runnum, 0, rdlen, false) );
uci1 40:1324da35afd4 693 return SendAllFiles(comm, timeout, buf, bsize, curConf, evt, pow,
uci1 40:1324da35afd4 694 rdnms.c_str());
uci1 40:1324da35afd4 695 }
uci1 40:1324da35afd4 696
uci1 0:664899e0b988 697 SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
uci1 3:24c5f0f50bf1 698 const uint32_t timeout,
uci1 3:24c5f0f50bf1 699 char* const buf,
uci1 6:6f002d202f59 700 const uint32_t bsize,
uci1 6:6f002d202f59 701 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 702 SnEventFrame& evt,
uci1 12:d472f9811262 703 SnPowerFrame& pow,
uci1 25:57b2627fe756 704 const char* dirname) {
uci1 40:1324da35afd4 705 // send all files in the specified directory
uci1 40:1324da35afd4 706
uci1 40:1324da35afd4 707 InitSDCard();
uci1 25:57b2627fe756 708
uci1 25:57b2627fe756 709 SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent;
uci1 16:744ce85aede2 710
uci1 0:664899e0b988 711 DIR* d;
uci1 0:664899e0b988 712 struct dirent* dent;
uci1 25:57b2627fe756 713 if ( (d = opendir( dirname ))!=NULL ) {
uci1 39:2f17131d22a5 714 FATDirHandle* dir = static_cast<FATDirHandle*>(d);
uci1 0:664899e0b988 715 while ( (dent = readdir(d))!=NULL ) {
uci1 25:57b2627fe756 716 Watchdog::kick(); // don't reset
uci1 27:efc4d654b139 717 SnCommWin::ECommWinResult res = rs;
uci1 25:57b2627fe756 718 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 25:57b2627fe756 719 // a subdirectory
uci1 25:57b2627fe756 720 std::string dnm(dirname);
uci1 25:57b2627fe756 721 dnm += "/";
uci1 25:57b2627fe756 722 dnm += dent->d_name;
uci1 25:57b2627fe756 723 // send all the files in this new subdir
uci1 27:efc4d654b139 724 res = SendAllFiles(comm, timeout, buf, bsize,
uci1 27:efc4d654b139 725 curConf, evt, pow,
uci1 40:1324da35afd4 726 dnm.c_str());
uci1 25:57b2627fe756 727 } else if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 25:57b2627fe756 728 // a data file (send it)
uci1 1:e392595b4b76 729 const bool isCurFile =
uci1 1:e392595b4b76 730 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 25:57b2627fe756 731 FILE* f(0);
uci1 1:e392595b4b76 732 if (isCurFile) {
uci1 3:24c5f0f50bf1 733 // file must already be written out!
uci1 1:e392595b4b76 734 f = GetCurFile();
uci1 1:e392595b4b76 735 } else {
uci1 25:57b2627fe756 736 std::string ffn(dirname);
uci1 25:57b2627fe756 737 ffn += "/";
uci1 25:57b2627fe756 738 ffn += dent->d_name;
uci1 25:57b2627fe756 739 f = OpenExistingFile(ffn.c_str(), false, false);
uci1 1:e392595b4b76 740 }
uci1 12:d472f9811262 741 #ifdef DEBUG
uci1 12:d472f9811262 742 printf("calling senddata: f=%p (cur %p), fn=%s\r\n",
uci1 12:d472f9811262 743 f, GetCurFile(), dent->d_name);
uci1 12:d472f9811262 744 #endif
uci1 25:57b2627fe756 745 uint8_t hndres = SnHeaderFrame::kHnShFailNonCode;
uci1 40:1324da35afd4 746 if (f!=0) {
uci1 40:1324da35afd4 747 res = comm->SendDataFromFile(f, dent->d_name,
uci1 40:1324da35afd4 748 curConf, evt, pow, buf, bsize,
uci1 40:1324da35afd4 749 0, timeout,
uci1 40:1324da35afd4 750 &hndres);
uci1 40:1324da35afd4 751
uci1 40:1324da35afd4 752 if (isCurFile) {
uci1 40:1324da35afd4 753 // move (back) to the end of the file
uci1 40:1324da35afd4 754 // altho hopefully no writing will happen after this
uci1 40:1324da35afd4 755 fseek(fgCurFile, 0, SEEK_END);
uci1 40:1324da35afd4 756 }
uci1 40:1324da35afd4 757 }
uci1 25:57b2627fe756 758 #ifdef DEBUG
uci1 25:57b2627fe756 759 printf("isCurFile=%d, res=%d, deleting=%d, hndres=%02x\r\n",
uci1 25:57b2627fe756 760 (int)isCurFile, (int)res, (int)(curConf.IsDeletingFiles()),
uci1 25:57b2627fe756 761 hndres);
uci1 25:57b2627fe756 762 #endif
uci1 27:efc4d654b139 763
uci1 25:57b2627fe756 764 }
uci1 27:efc4d654b139 765 if ((res<rs) || (res==SnCommWin::kOkStopComm)) {
uci1 27:efc4d654b139 766 rs = res;
uci1 27:efc4d654b139 767 }
uci1 27:efc4d654b139 768 // don't necessarily stop if rs is bad. don't want one bad file to
uci1 27:efc4d654b139 769 // prevent sending the others
uci1 25:57b2627fe756 770 if (rs<=SnCommWin::kFailTimeout) {
uci1 25:57b2627fe756 771 break;
uci1 27:efc4d654b139 772 } else if (rs==SnCommWin::kOkStopComm) {
uci1 27:efc4d654b139 773 break;
uci1 25:57b2627fe756 774 }
uci1 27:efc4d654b139 775 } // loop over stuff in this directory
uci1 25:57b2627fe756 776 closedir(d);
uci1 25:57b2627fe756 777 // see if we need to remove this directory now
uci1 25:57b2627fe756 778 if (curConf.IsDeletingFiles()) {
uci1 27:efc4d654b139 779 DeleteDirIfEmpty(dirname);
uci1 0:664899e0b988 780 }
uci1 0:664899e0b988 781 }
uci1 0:664899e0b988 782
uci1 0:664899e0b988 783 return rs;
uci1 0:664899e0b988 784 }
uci1 0:664899e0b988 785