Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnSDUtils.cpp@63:4820a4460f00, 2014-11-28 (annotated)
- 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?
User | Revision | Line number | New 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 |