Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu Nov 01 07:00:17 2012 +0000
Revision:
27:efc4d654b139
Parent:
25:57b2627fe756
Child:
30:f869ed4bcc08
Afar comms enabled. Bug fixes: comm win opens with high rate now and no power to afar with afar comm enabled will not stall MBED. Features: stop file transfer, delete a specified run or delete all files on the SD card (file trans handshakes).

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