Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Nov 28 01:24:23 2012 +0000
Revision:
30:f869ed4bcc08
Parent:
27:efc4d654b139
Child:
31:b5bd3b189150
Change power so to account for the Iridium being on the same relay as afar. Afar, SBD, Twitter enabled. No Debugging.

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