Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu May 23 22:26:39 2013 +0000
Revision:
36:87865913ae6f
Parent:
31:b5bd3b189150
Child:
38:9070c17536cd
this will not compile. just starting to modularize the comms and essential packages for extraction (to use in both the DAQ and monitoring station)

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 22:f957c4f840ad 430 const SnCommWin::ECommWinResult r1 =
uci1 22:f957c4f840ad 431 SnHeaderFrame::WriteTo(file, SnHeaderFrame::kHeartbeatCode,
uci1 22:f957c4f840ad 432 SnHeartbeatFrame::SizeOf(SnHeartbeatFrame::kIOVers));
uci1 22:f957c4f840ad 433 const SnCommWin::ECommWinResult r2 =
uci1 22:f957c4f840ad 434 SnHeartbeatFrame::WriteTo(file, time, num);
uci1 22:f957c4f840ad 435 return ((r1==SnCommWin::kOkMsgSent)
uci1 22:f957c4f840ad 436 && (r2==SnCommWin::kOkMsgSent));
uci1 22:f957c4f840ad 437 }
uci1 22:f957c4f840ad 438
uci1 0:664899e0b988 439 bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
uci1 0:664899e0b988 440 const SnEventFrame& evt,
uci1 0:664899e0b988 441 const SnConfigFrame& conf) {
uci1 0:664899e0b988 442 // write event to SD card
uci1 0:664899e0b988 443
uci1 0:664899e0b988 444 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 0:664899e0b988 445 uint16_t sWvBase=0;
uci1 0:664899e0b988 446 conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
uci1 8:95a325df1f6b 447 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode,
uci1 8:95a325df1f6b 448 evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB));
uci1 0:664899e0b988 449 const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
uci1 0:664899e0b988 450 fflush(efile);
uci1 0:664899e0b988 451 return ret;
uci1 0:664899e0b988 452 }
uci1 0:664899e0b988 453
uci1 0:664899e0b988 454 bool SnSDUtils::WriteConfig(FILE* efile,
uci1 0:664899e0b988 455 const SnConfigFrame& conf) {
uci1 8:95a325df1f6b 456 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode,
uci1 8:95a325df1f6b 457 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 0:664899e0b988 458 conf.WriteTo(efile);
uci1 0:664899e0b988 459 return true;
uci1 0:664899e0b988 460 }
uci1 0:664899e0b988 461
uci1 0:664899e0b988 462 void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
uci1 25:57b2627fe756 463 #ifdef DEBUG
uci1 25:57b2627fe756 464 printf("try to delete %s at %p\r\n",fname,f);
uci1 25:57b2627fe756 465 #endif
uci1 27:efc4d654b139 466 if (f!=0) {
uci1 27:efc4d654b139 467 fclose(f);
uci1 27:efc4d654b139 468 f=0;
uci1 27:efc4d654b139 469 }
uci1 25:57b2627fe756 470 std::string fn("");
uci1 25:57b2627fe756 471 if (GetFullFilename(fname, fn)) {
uci1 25:57b2627fe756 472 #ifdef DEBUG
uci1 25:57b2627fe756 473 printf("calling remove [%s]\r\n",fn.c_str());
uci1 25:57b2627fe756 474 #endif
uci1 25:57b2627fe756 475 remove(fn.c_str());
uci1 21:ce51bb0ba4a5 476 }
uci1 0:664899e0b988 477 }
uci1 0:664899e0b988 478
uci1 27:efc4d654b139 479 void SnSDUtils::DeleteFilesOfRun(const uint32_t run) {
uci1 27:efc4d654b139 480 #ifdef DEBUG
uci1 27:efc4d654b139 481 printf("deleteing files of run %lu\r\n",run);
uci1 27:efc4d654b139 482 #endif
uci1 27:efc4d654b139 483 uint32_t rdlen(0);
uci1 27:efc4d654b139 484 std::string rdnm( GetSubDirFor(run, 0, rdlen, false) );
uci1 27:efc4d654b139 485 DeleteAllFiles(rdnm.c_str());
uci1 27:efc4d654b139 486 }
uci1 27:efc4d654b139 487
uci1 27:efc4d654b139 488 void SnSDUtils::DeleteAllFiles(const char* dirname) {
uci1 27:efc4d654b139 489 #ifdef DEBUG
uci1 27:efc4d654b139 490 printf("deleting ALL files in %s\r\n",dirname);
uci1 27:efc4d654b139 491 #endif
uci1 27:efc4d654b139 492 DIR* d;
uci1 27:efc4d654b139 493 struct dirent* dent;
uci1 27:efc4d654b139 494 if ( (d = opendir( dirname ))!=NULL ) {
uci1 27:efc4d654b139 495 FATDirHandle* dir = dynamic_cast<FATDirHandle*>(d);
uci1 27:efc4d654b139 496 while ( (dent = readdir(d))!=NULL ) {
uci1 27:efc4d654b139 497 Watchdog::kick(); // don't reset
uci1 27:efc4d654b139 498 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 27:efc4d654b139 499 // a subdirectory
uci1 27:efc4d654b139 500 std::string dnm(dirname);
uci1 27:efc4d654b139 501 dnm += "/";
uci1 27:efc4d654b139 502 dnm += dent->d_name;
uci1 27:efc4d654b139 503 // delete all the files in this new subdir
uci1 27:efc4d654b139 504 #ifdef DEBUG
uci1 27:efc4d654b139 505 printf("call DeleteAllFiles(%s)\r\n",dnm.c_str());
uci1 27:efc4d654b139 506 #endif
uci1 27:efc4d654b139 507 DeleteAllFiles(dnm.c_str());
uci1 27:efc4d654b139 508 } else if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 27:efc4d654b139 509 // a data file (delete it)
uci1 27:efc4d654b139 510 const bool isCurFile =
uci1 27:efc4d654b139 511 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 27:efc4d654b139 512 if (isCurFile==false) { // don't delete the current file
uci1 27:efc4d654b139 513 FILE* f(0); // dummy
uci1 27:efc4d654b139 514 DeleteFile(f, dent->d_name);
uci1 27:efc4d654b139 515 }
uci1 27:efc4d654b139 516 }
uci1 27:efc4d654b139 517 } // loop over stuff in this dir
uci1 27:efc4d654b139 518 closedir(d);
uci1 27:efc4d654b139 519 DeleteDirIfEmpty(dirname);
uci1 27:efc4d654b139 520 }
uci1 27:efc4d654b139 521 }
uci1 27:efc4d654b139 522
uci1 27:efc4d654b139 523 void SnSDUtils::DeleteDirIfEmpty(const char* dirname) {
uci1 27:efc4d654b139 524 #ifdef DEBUG
uci1 27:efc4d654b139 525 printf("DeleteDirIfEmpty(%s)\r\n",dirname);
uci1 27:efc4d654b139 526 #endif
uci1 27:efc4d654b139 527 DIR* d;
uci1 27:efc4d654b139 528 struct dirent* dent;
uci1 27:efc4d654b139 529 if ( (d = opendir(dirname))!=NULL ) {
uci1 27:efc4d654b139 530 dent = readdir(d);
uci1 27:efc4d654b139 531 bool doDel = false;
uci1 27:efc4d654b139 532 if ( dent==NULL ) {
uci1 27:efc4d654b139 533 // then this directory is empty
uci1 27:efc4d654b139 534 static const size_t subdsz = strlen(kSDsubDir);
uci1 27:efc4d654b139 535 // just double check that this directory is
uci1 27:efc4d654b139 536 // a subdirectory of the data dir
uci1 27:efc4d654b139 537 if (strlen(dirname)>subdsz) {
uci1 27:efc4d654b139 538 doDel = true;
uci1 27:efc4d654b139 539 }
uci1 27:efc4d654b139 540 } // else this dir isn't empty
uci1 27:efc4d654b139 541 closedir(d);
uci1 27:efc4d654b139 542 if (doDel) {
uci1 27:efc4d654b139 543 #ifdef DEBUG
uci1 27:efc4d654b139 544 printf("removing directory [%s]\r\n",dirname);
uci1 27:efc4d654b139 545 #endif
uci1 27:efc4d654b139 546 remove(dirname);
uci1 27:efc4d654b139 547 }
uci1 27:efc4d654b139 548 }
uci1 27:efc4d654b139 549 }
uci1 27:efc4d654b139 550
uci1 0:664899e0b988 551 SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
uci1 3:24c5f0f50bf1 552 const uint32_t timeout,
uci1 3:24c5f0f50bf1 553 char* const buf,
uci1 6:6f002d202f59 554 const uint32_t bsize,
uci1 6:6f002d202f59 555 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 556 SnEventFrame& evt,
uci1 12:d472f9811262 557 SnPowerFrame& pow,
uci1 25:57b2627fe756 558 const uint32_t handshakeTimeout,
uci1 25:57b2627fe756 559 const char* dirname) {
uci1 25:57b2627fe756 560
uci1 25:57b2627fe756 561 SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent;
uci1 16:744ce85aede2 562
uci1 0:664899e0b988 563 DIR* d;
uci1 0:664899e0b988 564 struct dirent* dent;
uci1 25:57b2627fe756 565 if ( (d = opendir( dirname ))!=NULL ) {
uci1 25:57b2627fe756 566 FATDirHandle* dir = dynamic_cast<FATDirHandle*>(d);
uci1 0:664899e0b988 567 while ( (dent = readdir(d))!=NULL ) {
uci1 25:57b2627fe756 568 Watchdog::kick(); // don't reset
uci1 27:efc4d654b139 569 SnCommWin::ECommWinResult res = rs;
uci1 25:57b2627fe756 570 if ( (dir->filinfo()->fattrib & AM_DIR)!=0 ) {
uci1 25:57b2627fe756 571 // a subdirectory
uci1 25:57b2627fe756 572 std::string dnm(dirname);
uci1 25:57b2627fe756 573 dnm += "/";
uci1 25:57b2627fe756 574 dnm += dent->d_name;
uci1 25:57b2627fe756 575 // send all the files in this new subdir
uci1 27:efc4d654b139 576 res = SendAllFiles(comm, timeout, buf, bsize,
uci1 27:efc4d654b139 577 curConf, evt, pow,
uci1 25:57b2627fe756 578 handshakeTimeout, dnm.c_str());
uci1 25:57b2627fe756 579 } else if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 25:57b2627fe756 580 // a data file (send it)
uci1 1:e392595b4b76 581 const bool isCurFile =
uci1 1:e392595b4b76 582 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 25:57b2627fe756 583 FILE* f(0);
uci1 1:e392595b4b76 584 if (isCurFile) {
uci1 3:24c5f0f50bf1 585 // file must already be written out!
uci1 1:e392595b4b76 586 f = GetCurFile();
uci1 1:e392595b4b76 587 } else {
uci1 25:57b2627fe756 588 std::string ffn(dirname);
uci1 25:57b2627fe756 589 ffn += "/";
uci1 25:57b2627fe756 590 ffn += dent->d_name;
uci1 25:57b2627fe756 591 f = OpenExistingFile(ffn.c_str(), false, false);
uci1 1:e392595b4b76 592 }
uci1 12:d472f9811262 593 #ifdef DEBUG
uci1 12:d472f9811262 594 printf("calling senddata: f=%p (cur %p), fn=%s\r\n",
uci1 12:d472f9811262 595 f, GetCurFile(), dent->d_name);
uci1 12:d472f9811262 596 #endif
uci1 25:57b2627fe756 597 uint8_t hndres = SnHeaderFrame::kHnShFailNonCode;
uci1 27:efc4d654b139 598 res = comm->SendData(f, dent->d_name,
uci1 27:efc4d654b139 599 curConf, evt, pow, buf, bsize,
uci1 27:efc4d654b139 600 0, timeout, handshakeTimeout,
uci1 27:efc4d654b139 601 &hndres);
uci1 16:744ce85aede2 602
uci1 25:57b2627fe756 603 #ifdef DEBUG
uci1 25:57b2627fe756 604 printf("isCurFile=%d, res=%d, deleting=%d, hndres=%02x\r\n",
uci1 25:57b2627fe756 605 (int)isCurFile, (int)res, (int)(curConf.IsDeletingFiles()),
uci1 25:57b2627fe756 606 hndres);
uci1 25:57b2627fe756 607 #endif
uci1 3:24c5f0f50bf1 608 if (isCurFile) {
uci1 3:24c5f0f50bf1 609 // move (back) to the end of the file
uci1 3:24c5f0f50bf1 610 // altho hopefully no writing will happen after this
uci1 3:24c5f0f50bf1 611 fseek(fgCurFile, 0, SEEK_END);
uci1 25:57b2627fe756 612 }
uci1 27:efc4d654b139 613
uci1 25:57b2627fe756 614 }
uci1 27:efc4d654b139 615 if ((res<rs) || (res==SnCommWin::kOkStopComm)) {
uci1 27:efc4d654b139 616 rs = res;
uci1 27:efc4d654b139 617 }
uci1 27:efc4d654b139 618 // don't necessarily stop if rs is bad. don't want one bad file to
uci1 27:efc4d654b139 619 // prevent sending the others
uci1 25:57b2627fe756 620 if (rs<=SnCommWin::kFailTimeout) {
uci1 25:57b2627fe756 621 break;
uci1 27:efc4d654b139 622 } else if (rs==SnCommWin::kOkStopComm) {
uci1 27:efc4d654b139 623 break;
uci1 25:57b2627fe756 624 }
uci1 27:efc4d654b139 625 } // loop over stuff in this directory
uci1 25:57b2627fe756 626 closedir(d);
uci1 25:57b2627fe756 627 // see if we need to remove this directory now
uci1 25:57b2627fe756 628 if (curConf.IsDeletingFiles()) {
uci1 27:efc4d654b139 629 DeleteDirIfEmpty(dirname);
uci1 0:664899e0b988 630 }
uci1 0:664899e0b988 631 }
uci1 0:664899e0b988 632
uci1 0:664899e0b988 633 return rs;
uci1 0:664899e0b988 634 }
uci1 0:664899e0b988 635