Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Jan 23 19:29:01 2013 +0000
Revision:
31:b5bd3b189150
Parent:
30:f869ed4bcc08
Child:
36:87865913ae6f
Added option in SnConstants to allow for proper switching of peripheral power in stations that have the Afar and Iridium power lines spliced together. Afar, SBD and Twitter comms enabled. Afar and Iridium powered together.

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 30:f869ed4bcc08 295 if ( ok && ffn.size()>0 ) {
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