Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed May 29 18:54:19 2013 +0000
Revision:
38:9070c17536cd
Parent:
36:87865913ae6f
Child:
39:2f17131d22a5
Update SnCRCUtils to use templated function. Add MODSERIAL include to SnCommWinUsb when enabled. Move iridium constants to SnCommConstants.

Who changed what in which revision?

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