Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Jul 30 02:03:21 2013 +0000
Revision:
39:2f17131d22a5
Parent:
38:9070c17536cd
Child:
40:1324da35afd4
Temp commit so we can revert to other revisions. Changed some dynamic_casts to static_casts. Added NULL char to config label writing and updated io versions. Added battery hysteresis.

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