Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Oct 30 05:23:57 2012 +0000
Revision:
25:57b2627fe756
Parent:
22:f957c4f840ad
Child:
27:efc4d654b139
AFAR comms. Upped baud to 921600. Store data in run-seq subdirs, max of 100 files per dir, to prevent station grinding to a halt due when 800 files are in one directory. Cache file size count. Stagger tickers. Fixed some gcc warnings.

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