Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnCommWin.cpp@23:ccf39298f205, 2012-10-23 (annotated)
- Committer:
- uci1
- Date:
- Tue Oct 23 20:07:57 2012 +0000
- Revision:
- 23:ccf39298f205
- Parent:
- 21:ce51bb0ba4a5
- Child:
- 24:7d725fc8201e
SBD communication enabled. Fix bug in which the SBD message number would be repeatedly increased upon failed sending attempts. Add check in SBD recv in case message is longer than buffer. Add SendString to SnCommWin
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
uci1 | 2:e67f7c158087 | 1 | #include "SnCommWin.h" |
uci1 | 2:e67f7c158087 | 2 | |
uci1 | 6:6f002d202f59 | 3 | #include "SnHeaderFrame.h" |
uci1 | 2:e67f7c158087 | 4 | #include "SnConfigFrame.h" |
uci1 | 8:95a325df1f6b | 5 | #include "SnEventFrame.h" |
uci1 | 8:95a325df1f6b | 6 | #include "SnPowerFrame.h" |
uci1 | 8:95a325df1f6b | 7 | #include "SnStatusFrame.h" |
uci1 | 2:e67f7c158087 | 8 | #include "SnSDUtils.h" |
uci1 | 16:744ce85aede2 | 9 | #include "SnConstants.h" |
uci1 | 21:ce51bb0ba4a5 | 10 | #include "SnCRCUtils.h" |
uci1 | 21:ce51bb0ba4a5 | 11 | |
uci1 | 21:ce51bb0ba4a5 | 12 | #include <algorithm> |
uci1 | 21:ce51bb0ba4a5 | 13 | #include <ctype.h> |
uci1 | 21:ce51bb0ba4a5 | 14 | extern "C" void mbed_reset(); |
uci1 | 16:744ce85aede2 | 15 | |
uci1 | 16:744ce85aede2 | 16 | //#define DEBUG |
uci1 | 16:744ce85aede2 | 17 | |
uci1 | 16:744ce85aede2 | 18 | uint32_t SnCommWin::GetConnectTimeout() const { return kConnectTimeout; } |
uci1 | 16:744ce85aede2 | 19 | uint32_t SnCommWin::GetListenTimeout() const { return kListenTimeout; } |
uci1 | 2:e67f7c158087 | 20 | |
uci1 | 12:d472f9811262 | 21 | bool SnCommWin::IsTimedOut(const uint32_t timeout_clock) const { |
uci1 | 16:744ce85aede2 | 22 | if (timeout_clock==0) { |
uci1 | 16:744ce85aede2 | 23 | // for not obeying timeout option |
uci1 | 16:744ce85aede2 | 24 | return false; |
uci1 | 16:744ce85aede2 | 25 | } else { |
uci1 | 16:744ce85aede2 | 26 | const uint32_t ct = time(0); |
uci1 | 16:744ce85aede2 | 27 | if ( (ct==0) || |
uci1 | 16:744ce85aede2 | 28 | (abs(static_cast<double>(timeout_clock-ct))>kSecsPerDay) ) { |
uci1 | 16:744ce85aede2 | 29 | // clock problems! |
uci1 | 16:744ce85aede2 | 30 | // timeout now. hope the clock problems |
uci1 | 16:744ce85aede2 | 31 | // get fixed in the next comm window |
uci1 | 12:d472f9811262 | 32 | return true; |
uci1 | 16:744ce85aede2 | 33 | } else { |
uci1 | 16:744ce85aede2 | 34 | return (ct>timeout_clock); |
uci1 | 12:d472f9811262 | 35 | } |
uci1 | 12:d472f9811262 | 36 | } |
uci1 | 12:d472f9811262 | 37 | } |
uci1 | 12:d472f9811262 | 38 | |
uci1 | 2:e67f7c158087 | 39 | SnCommWin::ECommWinResult SnCommWin::SendData(SnConfigFrame& conf, |
uci1 | 2:e67f7c158087 | 40 | SnEventFrame& evt, |
uci1 | 8:95a325df1f6b | 41 | SnPowerFrame& pow, |
uci1 | 2:e67f7c158087 | 42 | char* const genBuf, |
uci1 | 3:24c5f0f50bf1 | 43 | const uint32_t bsize, |
uci1 | 12:d472f9811262 | 44 | const uint32_t timeout, |
uci1 | 12:d472f9811262 | 45 | const uint32_t handshakeTimeout) { |
uci1 | 12:d472f9811262 | 46 | #ifdef DEBUG |
uci1 | 3:24c5f0f50bf1 | 47 | printf("SnCommWin::SendData\r\n"); |
uci1 | 12:d472f9811262 | 48 | #endif |
uci1 | 2:e67f7c158087 | 49 | ECommWinResult res = kUndefFail; |
uci1 | 15:f2569d8e4176 | 50 | if ( (GetCommType() != SnConfigFrame::kIrid) || |
uci1 | 15:f2569d8e4176 | 51 | (conf.IsForcingSBDdata()) ) { |
uci1 | 15:f2569d8e4176 | 52 | // only send large amounts if we're not communicating by Iridum, |
uci1 | 15:f2569d8e4176 | 53 | // or if we are being forced to send the data over SBD |
uci1 | 15:f2569d8e4176 | 54 | if (conf.IsSendingAllFiles()) { |
uci1 | 12:d472f9811262 | 55 | #ifdef DEBUG |
uci1 | 15:f2569d8e4176 | 56 | printf("sending all files\r\n"); |
uci1 | 12:d472f9811262 | 57 | #endif |
uci1 | 15:f2569d8e4176 | 58 | res = SnSDUtils::SendAllFiles(this, timeout, |
uci1 | 15:f2569d8e4176 | 59 | genBuf, bsize, conf, evt, pow, |
uci1 | 15:f2569d8e4176 | 60 | handshakeTimeout); |
uci1 | 15:f2569d8e4176 | 61 | } else { |
uci1 | 15:f2569d8e4176 | 62 | if (conf.GetCommSendData()==0) { |
uci1 | 12:d472f9811262 | 63 | #ifdef DEBUG |
uci1 | 15:f2569d8e4176 | 64 | printf("no data to send\r\n"); |
uci1 | 12:d472f9811262 | 65 | #endif |
uci1 | 15:f2569d8e4176 | 66 | res = kOkNoMsg; |
uci1 | 15:f2569d8e4176 | 67 | } else { |
uci1 | 15:f2569d8e4176 | 68 | const uint32_t nev = (conf.GetCommSendData()>0) ? |
uci1 | 15:f2569d8e4176 | 69 | conf.GetCommSendData() // send N events |
uci1 | 15:f2569d8e4176 | 70 | : 0u; // send all events in last file |
uci1 | 12:d472f9811262 | 71 | #ifdef DEBUG |
uci1 | 16:744ce85aede2 | 72 | printf("calling SendData. f=%s, nev=%u\r\n",SnSDUtils::GetCurFileName(), nev); |
uci1 | 12:d472f9811262 | 73 | #endif |
uci1 | 15:f2569d8e4176 | 74 | res = SendData(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), |
uci1 | 15:f2569d8e4176 | 75 | conf, evt, pow, genBuf, bsize, nev, timeout, handshakeTimeout); |
uci1 | 12:d472f9811262 | 76 | #ifdef DEBUG |
uci1 | 15:f2569d8e4176 | 77 | printf("after send data cur file, res=%d\r\n",(int)res); |
uci1 | 12:d472f9811262 | 78 | #endif |
uci1 | 15:f2569d8e4176 | 79 | } |
uci1 | 2:e67f7c158087 | 80 | } |
uci1 | 15:f2569d8e4176 | 81 | } else { |
uci1 | 15:f2569d8e4176 | 82 | return kOkNoMsg; |
uci1 | 2:e67f7c158087 | 83 | } |
uci1 | 2:e67f7c158087 | 84 | return res; |
uci1 | 2:e67f7c158087 | 85 | } |
uci1 | 2:e67f7c158087 | 86 | |
uci1 | 2:e67f7c158087 | 87 | SnCommWin::ECommWinResult SnCommWin::SendData(FILE* inf, const char* infn, |
uci1 | 2:e67f7c158087 | 88 | const SnConfigFrame& curConf, |
uci1 | 2:e67f7c158087 | 89 | SnEventFrame& evt, |
uci1 | 8:95a325df1f6b | 90 | SnPowerFrame& pow, |
uci1 | 2:e67f7c158087 | 91 | char* const genBuf, |
uci1 | 6:6f002d202f59 | 92 | const uint32_t bsize, |
uci1 | 2:e67f7c158087 | 93 | const uint32_t nevts, |
uci1 | 6:6f002d202f59 | 94 | const uint32_t timeout_clock, |
uci1 | 12:d472f9811262 | 95 | const uint32_t handshakeTimeout) { |
uci1 | 2:e67f7c158087 | 96 | // nevts==0 ==> send all events |
uci1 | 21:ce51bb0ba4a5 | 97 | // handshakeTimeout is never a clock time -- always a delta(t) |
uci1 | 2:e67f7c158087 | 98 | |
uci1 | 12:d472f9811262 | 99 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 100 | printf("SnCommWin::SendData file (%p), fn=%s\r\n",inf,infn); |
uci1 | 12:d472f9811262 | 101 | #endif |
uci1 | 2:e67f7c158087 | 102 | ECommWinResult res = kUndefFail; |
uci1 | 12:d472f9811262 | 103 | bool didDel = false; |
uci1 | 2:e67f7c158087 | 104 | if (inf!=0) { |
uci1 | 12:d472f9811262 | 105 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 106 | printf("sending file name %s\r\n",infn); |
uci1 | 12:d472f9811262 | 107 | #endif |
uci1 | 16:744ce85aede2 | 108 | |
uci1 | 6:6f002d202f59 | 109 | // send the file name |
uci1 | 6:6f002d202f59 | 110 | res = SendFilename(infn, genBuf, timeout_clock); |
uci1 | 3:24c5f0f50bf1 | 111 | if (res>kAllFails) { |
uci1 | 6:6f002d202f59 | 112 | if (genBuf!=0) { |
uci1 | 12:d472f9811262 | 113 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 114 | printf("calling send file contents\r\n"); |
uci1 | 12:d472f9811262 | 115 | #endif |
uci1 | 16:744ce85aede2 | 116 | |
uci1 | 6:6f002d202f59 | 117 | // send the contents |
uci1 | 8:95a325df1f6b | 118 | res = SendFileContents(inf, curConf, evt, pow, genBuf, |
uci1 | 12:d472f9811262 | 119 | nevts, timeout_clock); |
uci1 | 12:d472f9811262 | 120 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 121 | printf("res=%d (fails=%d)\r\n",(int)res,(int)kAllFails); |
uci1 | 12:d472f9811262 | 122 | #endif |
uci1 | 12:d472f9811262 | 123 | if (res>kAllFails) { |
uci1 | 12:d472f9811262 | 124 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 125 | printf("calling wait handshake\r\n"); |
uci1 | 12:d472f9811262 | 126 | #endif |
uci1 | 6:6f002d202f59 | 127 | // wait for handshake |
uci1 | 6:6f002d202f59 | 128 | uint8_t hndshk=0; |
uci1 | 21:ce51bb0ba4a5 | 129 | res = WaitHandshake(curConf, handshakeTimeout, genBuf, bsize, hndshk); |
uci1 | 21:ce51bb0ba4a5 | 130 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 131 | printf("res=%d, nevts=%u, isdel=%d, inf=%p, curfile=%p, hndshk=%02x\r\n", |
uci1 | 21:ce51bb0ba4a5 | 132 | res, nevts, curConf.IsDeletingFiles(), inf, |
uci1 | 21:ce51bb0ba4a5 | 133 | SnSDUtils::GetCurFile(), hndshk); |
uci1 | 21:ce51bb0ba4a5 | 134 | #endif |
uci1 | 6:6f002d202f59 | 135 | if ( (res==SnCommWin::kOkWithMsg) // got handshake |
uci1 | 6:6f002d202f59 | 136 | && (nevts==0) // sent whole file |
uci1 | 6:6f002d202f59 | 137 | && curConf.IsDeletingFiles() // want to delete |
uci1 | 12:d472f9811262 | 138 | && (inf!=SnSDUtils::GetCurFile()) // not current file |
uci1 | 6:6f002d202f59 | 139 | && (hndshk==SnHeaderFrame::kHnShOkComplCode)) { // whole file received |
uci1 | 6:6f002d202f59 | 140 | // delete it |
uci1 | 21:ce51bb0ba4a5 | 141 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 142 | printf("deleting file %p, %s\r\n",inf,infn); |
uci1 | 21:ce51bb0ba4a5 | 143 | #endif |
uci1 | 6:6f002d202f59 | 144 | SnSDUtilsWhisperer::DeleteFile(inf, infn); |
uci1 | 12:d472f9811262 | 145 | didDel=true; |
uci1 | 6:6f002d202f59 | 146 | } |
uci1 | 3:24c5f0f50bf1 | 147 | } |
uci1 | 2:e67f7c158087 | 148 | } |
uci1 | 2:e67f7c158087 | 149 | } |
uci1 | 12:d472f9811262 | 150 | } else { |
uci1 | 12:d472f9811262 | 151 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 152 | printf("inf=0!\r\n"); |
uci1 | 12:d472f9811262 | 153 | #endif |
uci1 | 12:d472f9811262 | 154 | } |
uci1 | 12:d472f9811262 | 155 | if ( (inf!=SnSDUtils::GetCurFile()) && (didDel==false) ) { |
uci1 | 12:d472f9811262 | 156 | SnSDUtils::CloseOutputFile(inf); |
uci1 | 2:e67f7c158087 | 157 | } |
uci1 | 2:e67f7c158087 | 158 | return res; |
uci1 | 2:e67f7c158087 | 159 | } |
uci1 | 8:95a325df1f6b | 160 | |
uci1 | 21:ce51bb0ba4a5 | 161 | SnCommWin::ECommWinResult SnCommWin::WaitHandshake(const SnConfigFrame& conf, |
uci1 | 21:ce51bb0ba4a5 | 162 | const uint32_t timeout, |
uci1 | 8:95a325df1f6b | 163 | char* const buf, |
uci1 | 8:95a325df1f6b | 164 | const uint32_t bsize, |
uci1 | 8:95a325df1f6b | 165 | uint8_t& hndShkCode) { |
uci1 | 12:d472f9811262 | 166 | // ensure we don't wait forever |
uci1 | 21:ce51bb0ba4a5 | 167 | const uint32_t to = ((timeout>0) && (timeout<kAbsMaxTimer)) |
uci1 | 21:ce51bb0ba4a5 | 168 | ? conf.GetTimeoutTime(time(0), timeout) |
uci1 | 21:ce51bb0ba4a5 | 169 | : conf.GetTimeoutTime(time(0), kListenTimeout); |
uci1 | 12:d472f9811262 | 170 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 171 | printf("WaitHandshake, to=%u\r\n",to); |
uci1 | 12:d472f9811262 | 172 | #endif |
uci1 | 8:95a325df1f6b | 173 | |
uci1 | 12:d472f9811262 | 174 | const int mlen = ReceiveAll(buf, SnHeaderFrame::SizeOf(), to); |
uci1 | 8:95a325df1f6b | 175 | if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) { |
uci1 | 8:95a325df1f6b | 176 | uint32_t msgLen=0; |
uci1 | 8:95a325df1f6b | 177 | const char* b = buf; |
uci1 | 8:95a325df1f6b | 178 | SnHeaderFrame::ReadFrom(b, hndShkCode, msgLen); |
uci1 | 12:d472f9811262 | 179 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 180 | printf("got handshake code=%02x, len=%u\r\n",hndShkCode,msgLen); |
uci1 | 12:d472f9811262 | 181 | #endif |
uci1 | 8:95a325df1f6b | 182 | if ((hndShkCode & SnHeaderFrame::kHndShkBits)!=0) { |
uci1 | 8:95a325df1f6b | 183 | return SnCommWin::kOkWithMsg; |
uci1 | 8:95a325df1f6b | 184 | } else { |
uci1 | 8:95a325df1f6b | 185 | // TODO: somehow handle unexpected message? |
uci1 | 8:95a325df1f6b | 186 | return SnCommWin::kUnexpectedRec; |
uci1 | 8:95a325df1f6b | 187 | } |
uci1 | 8:95a325df1f6b | 188 | } |
uci1 | 8:95a325df1f6b | 189 | return SnCommWin::kOkNoMsg; |
uci1 | 8:95a325df1f6b | 190 | } |
uci1 | 8:95a325df1f6b | 191 | |
uci1 | 21:ce51bb0ba4a5 | 192 | SnCommWin::ECommWinResult SnCommWin::GetFilename(const uint32_t timeout, |
uci1 | 21:ce51bb0ba4a5 | 193 | char* const buf, |
uci1 | 21:ce51bb0ba4a5 | 194 | const uint32_t namelen) { |
uci1 | 21:ce51bb0ba4a5 | 195 | // called by GetConfig upon receipt of a kMbedFilenameCode |
uci1 | 21:ce51bb0ba4a5 | 196 | |
uci1 | 21:ce51bb0ba4a5 | 197 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 198 | printf("GetMbedFile, to=%u\r\n",timeout); |
uci1 | 21:ce51bb0ba4a5 | 199 | #endif |
uci1 | 21:ce51bb0ba4a5 | 200 | const int mlen = ReceiveAll(buf, namelen, timeout); |
uci1 | 21:ce51bb0ba4a5 | 201 | if (mlen>0 && static_cast<uint32_t>(mlen) == namelen) { |
uci1 | 21:ce51bb0ba4a5 | 202 | return SnCommWin::kOkWithMsg; |
uci1 | 21:ce51bb0ba4a5 | 203 | } |
uci1 | 21:ce51bb0ba4a5 | 204 | return SnCommWin::kUnexpectedRec; |
uci1 | 21:ce51bb0ba4a5 | 205 | } |
uci1 | 21:ce51bb0ba4a5 | 206 | |
uci1 | 21:ce51bb0ba4a5 | 207 | SnCommWin::ECommWinResult SnCommWin::GetLocalFile(std::string fname, |
uci1 | 21:ce51bb0ba4a5 | 208 | char* const buf, |
uci1 | 21:ce51bb0ba4a5 | 209 | const uint32_t bsize, |
uci1 | 21:ce51bb0ba4a5 | 210 | const uint32_t timeout) { |
uci1 | 21:ce51bb0ba4a5 | 211 | // get a file and save it locally with the specified name |
uci1 | 21:ce51bb0ba4a5 | 212 | |
uci1 | 21:ce51bb0ba4a5 | 213 | // get the header for the file |
uci1 | 21:ce51bb0ba4a5 | 214 | uint8_t mcode=0; uint32_t mlen=0; |
uci1 | 21:ce51bb0ba4a5 | 215 | SnCommWin::ECommWinResult res = |
uci1 | 21:ce51bb0ba4a5 | 216 | GetHeader(timeout, buf, bsize, mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 217 | if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileCode) ) { |
uci1 | 21:ce51bb0ba4a5 | 218 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 219 | printf("Got mbed file header. File length = %u\r\n",mlen); |
uci1 | 21:ce51bb0ba4a5 | 220 | #endif |
uci1 | 21:ce51bb0ba4a5 | 221 | // got the header.. make the file.. |
uci1 | 21:ce51bb0ba4a5 | 222 | // make the file name ALLCAPS, since LocalFileSystem will do it anyway |
uci1 | 21:ce51bb0ba4a5 | 223 | std::transform(fname.begin(), fname.end(), fname.begin(), toupper); |
uci1 | 21:ce51bb0ba4a5 | 224 | // now ensure the file name is 8.3 only -- for LocalFileSystem |
uci1 | 21:ce51bb0ba4a5 | 225 | const size_t ldlen = strlen(kLocalDir); |
uci1 | 21:ce51bb0ba4a5 | 226 | // 12 = 8.3 filename format, 1 for / and 1 for \0 |
uci1 | 21:ce51bb0ba4a5 | 227 | const uint32_t fbs = ldlen+1+12+1; |
uci1 | 21:ce51bb0ba4a5 | 228 | char fnb[fbs]; |
uci1 | 21:ce51bb0ba4a5 | 229 | char* fb = fnb; |
uci1 | 21:ce51bb0ba4a5 | 230 | memcpy(fb, kLocalDir, ldlen); fb+=ldlen; // /local |
uci1 | 21:ce51bb0ba4a5 | 231 | memset(fb, '/', 1); fb+=1; // / |
uci1 | 21:ce51bb0ba4a5 | 232 | strncpy(fb, fname.c_str(), 8); fb+=8; // FILENAME |
uci1 | 21:ce51bb0ba4a5 | 233 | *fb = '.'; ++fb; // . |
uci1 | 21:ce51bb0ba4a5 | 234 | strncpy(fb, fname.c_str()+fname.size()-3, 3); // EXT |
uci1 | 21:ce51bb0ba4a5 | 235 | // all that just for the file name! |
uci1 | 21:ce51bb0ba4a5 | 236 | FILE* lf = fopen(fnb,"wb"); |
uci1 | 21:ce51bb0ba4a5 | 237 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 238 | printf("tried to open file [%s]. lf=%p\r\n",fnb,(void*)lf); |
uci1 | 21:ce51bb0ba4a5 | 239 | #endif |
uci1 | 21:ce51bb0ba4a5 | 240 | // get all the data and dump it into the file |
uci1 | 21:ce51bb0ba4a5 | 241 | int b = 0, toget = 0; |
uci1 | 21:ce51bb0ba4a5 | 242 | while ( mlen>b ) { |
uci1 | 21:ce51bb0ba4a5 | 243 | if (IsTimedOut(timeout)) { |
uci1 | 21:ce51bb0ba4a5 | 244 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 245 | printf("timeout while getting file\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 246 | #endif |
uci1 | 21:ce51bb0ba4a5 | 247 | res = kFailTimeout; |
uci1 | 21:ce51bb0ba4a5 | 248 | break; |
uci1 | 21:ce51bb0ba4a5 | 249 | } |
uci1 | 21:ce51bb0ba4a5 | 250 | toget = mlen - b; |
uci1 | 21:ce51bb0ba4a5 | 251 | if (toget>bsize) { |
uci1 | 21:ce51bb0ba4a5 | 252 | toget = bsize; |
uci1 | 21:ce51bb0ba4a5 | 253 | } |
uci1 | 21:ce51bb0ba4a5 | 254 | const int got = ReceiveAll(buf, toget, timeout); |
uci1 | 21:ce51bb0ba4a5 | 255 | if (lf!=NULL) { |
uci1 | 21:ce51bb0ba4a5 | 256 | SnBitUtils::WriteTo(lf, buf, got); |
uci1 | 21:ce51bb0ba4a5 | 257 | } |
uci1 | 21:ce51bb0ba4a5 | 258 | b += got; |
uci1 | 21:ce51bb0ba4a5 | 259 | } |
uci1 | 21:ce51bb0ba4a5 | 260 | uint32_t crc=0; |
uci1 | 21:ce51bb0ba4a5 | 261 | if (lf!=NULL) { |
uci1 | 21:ce51bb0ba4a5 | 262 | // calculate the crc from what's actually in the file |
uci1 | 21:ce51bb0ba4a5 | 263 | fclose(lf); // to flush it |
uci1 | 21:ce51bb0ba4a5 | 264 | lf = fopen(fnb,"rb"); |
uci1 | 21:ce51bb0ba4a5 | 265 | fseek(lf, 0, SEEK_END); |
uci1 | 21:ce51bb0ba4a5 | 266 | int32_t fend = ftell(lf); |
uci1 | 21:ce51bb0ba4a5 | 267 | fseek(lf, 0, SEEK_SET); |
uci1 | 21:ce51bb0ba4a5 | 268 | char c; |
uci1 | 21:ce51bb0ba4a5 | 269 | for (int32_t i=0; i<fend; ++i) { |
uci1 | 21:ce51bb0ba4a5 | 270 | SnBitUtils::ReadFrom(lf, c); |
uci1 | 21:ce51bb0ba4a5 | 271 | if (feof(lf)==0 && ferror(lf)==0) { |
uci1 | 21:ce51bb0ba4a5 | 272 | crc = update_crc32_xfer(crc, c); |
uci1 | 21:ce51bb0ba4a5 | 273 | } else { |
uci1 | 21:ce51bb0ba4a5 | 274 | break; |
uci1 | 21:ce51bb0ba4a5 | 275 | } |
uci1 | 21:ce51bb0ba4a5 | 276 | } |
uci1 | 21:ce51bb0ba4a5 | 277 | fclose(lf); |
uci1 | 21:ce51bb0ba4a5 | 278 | } |
uci1 | 21:ce51bb0ba4a5 | 279 | if ( mlen!=b ) { |
uci1 | 21:ce51bb0ba4a5 | 280 | if (res > kUnexpectedRec) { |
uci1 | 21:ce51bb0ba4a5 | 281 | res = kUnexpectedRec; |
uci1 | 21:ce51bb0ba4a5 | 282 | } // otherwise it's already worse |
uci1 | 21:ce51bb0ba4a5 | 283 | } else { |
uci1 | 21:ce51bb0ba4a5 | 284 | // check that the file is ok |
uci1 | 21:ce51bb0ba4a5 | 285 | // get the checksum |
uci1 | 21:ce51bb0ba4a5 | 286 | res = GetHeader(timeout, buf, bsize, mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 287 | if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileChksCode) ) { |
uci1 | 21:ce51bb0ba4a5 | 288 | if (crc != mlen) { |
uci1 | 21:ce51bb0ba4a5 | 289 | res = kUnexpectedRec; // important! |
uci1 | 21:ce51bb0ba4a5 | 290 | } |
uci1 | 21:ce51bb0ba4a5 | 291 | } |
uci1 | 21:ce51bb0ba4a5 | 292 | } |
uci1 | 21:ce51bb0ba4a5 | 293 | //TODO: REMOVE |
uci1 | 21:ce51bb0ba4a5 | 294 | /* |
uci1 | 21:ce51bb0ba4a5 | 295 | char dbg[250]; memset(dbg, 0, 250); |
uci1 | 21:ce51bb0ba4a5 | 296 | char* dd = buf; |
uci1 | 21:ce51bb0ba4a5 | 297 | sprintf(dbg,"lf=%s (%p), my crc=%d, b=%d, mlen=%d\r\n",fnb,(void*)lf,crc,crc,b,mlen); |
uci1 | 21:ce51bb0ba4a5 | 298 | SnHeaderFrame::WriteTo(dd, SnHeaderFrame::kStringCode, strlen(dbg)); |
uci1 | 21:ce51bb0ba4a5 | 299 | strcpy(buf+SnHeaderFrame::SizeOf(),dbg); |
uci1 | 21:ce51bb0ba4a5 | 300 | SendAll(buf, SnHeaderFrame::SizeOf() + strlen(dbg), timeout); |
uci1 | 21:ce51bb0ba4a5 | 301 | */ |
uci1 | 21:ce51bb0ba4a5 | 302 | /////////// |
uci1 | 21:ce51bb0ba4a5 | 303 | if (lf!=NULL) { |
uci1 | 21:ce51bb0ba4a5 | 304 | if ( res<kOkWithMsg ) { |
uci1 | 21:ce51bb0ba4a5 | 305 | // timeout, bad checksum, something else bad? |
uci1 | 21:ce51bb0ba4a5 | 306 | remove(fnb); // delete the file |
uci1 | 21:ce51bb0ba4a5 | 307 | } else { |
uci1 | 21:ce51bb0ba4a5 | 308 | // if we got a new program, remove the old ones. |
uci1 | 21:ce51bb0ba4a5 | 309 | // (schedule myself for immediate de-resolution) |
uci1 | 21:ce51bb0ba4a5 | 310 | // |
uci1 | 21:ce51bb0ba4a5 | 311 | // first just count how many we would save |
uci1 | 21:ce51bb0ba4a5 | 312 | const uint16_t nSavedBins = LoopLocalDirBinFiles(false, fname); |
uci1 | 21:ce51bb0ba4a5 | 313 | if (nSavedBins==1) { |
uci1 | 21:ce51bb0ba4a5 | 314 | // ok. new program will be the only one. remove the others |
uci1 | 21:ce51bb0ba4a5 | 315 | // hope the new program works! |
uci1 | 21:ce51bb0ba4a5 | 316 | LoopLocalDirBinFiles(true, fname); |
uci1 | 21:ce51bb0ba4a5 | 317 | |
uci1 | 21:ce51bb0ba4a5 | 318 | // goodbye cruel world, it's over. walk on by... |
uci1 | 21:ce51bb0ba4a5 | 319 | mbed_reset(); |
uci1 | 21:ce51bb0ba4a5 | 320 | } |
uci1 | 21:ce51bb0ba4a5 | 321 | } |
uci1 | 21:ce51bb0ba4a5 | 322 | } |
uci1 | 21:ce51bb0ba4a5 | 323 | } |
uci1 | 21:ce51bb0ba4a5 | 324 | |
uci1 | 21:ce51bb0ba4a5 | 325 | return res; |
uci1 | 21:ce51bb0ba4a5 | 326 | } |
uci1 | 21:ce51bb0ba4a5 | 327 | |
uci1 | 21:ce51bb0ba4a5 | 328 | int16_t SnCommWin::LoopLocalDirBinFiles(const bool doRemove, |
uci1 | 21:ce51bb0ba4a5 | 329 | const std::string& fname) { |
uci1 | 21:ce51bb0ba4a5 | 330 | // loop over the local directory, count the BIN files that match 'fname' |
uci1 | 21:ce51bb0ba4a5 | 331 | // |
uci1 | 21:ce51bb0ba4a5 | 332 | // fname is assumed to be all caps already! |
uci1 | 21:ce51bb0ba4a5 | 333 | // |
uci1 | 21:ce51bb0ba4a5 | 334 | // if doRemove==true, will actually delete non-matching files |
uci1 | 21:ce51bb0ba4a5 | 335 | // |
uci1 | 21:ce51bb0ba4a5 | 336 | // return number of non-matching files |
uci1 | 21:ce51bb0ba4a5 | 337 | uint16_t nSavedBins = 0; |
uci1 | 21:ce51bb0ba4a5 | 338 | DIR* d( opendir(kLocalDir) ); |
uci1 | 21:ce51bb0ba4a5 | 339 | struct dirent* dent; |
uci1 | 21:ce51bb0ba4a5 | 340 | if ( d!=NULL ) { |
uci1 | 21:ce51bb0ba4a5 | 341 | while ( (dent = readdir(d))!=NULL ) { |
uci1 | 21:ce51bb0ba4a5 | 342 | const size_t flen = strlen(dent->d_name); |
uci1 | 21:ce51bb0ba4a5 | 343 | const char* dext = dent->d_name + flen - 4; |
uci1 | 21:ce51bb0ba4a5 | 344 | if ( strncmp(dext,".BIN",4)==0 || strncmp(dext,".bin",4)==0 ) { |
uci1 | 21:ce51bb0ba4a5 | 345 | // ends with .BIN |
uci1 | 21:ce51bb0ba4a5 | 346 | if (strncmp(dent->d_name, fname.c_str(), fname.size())!=0) { |
uci1 | 21:ce51bb0ba4a5 | 347 | // some other mbed program than our new one |
uci1 | 21:ce51bb0ba4a5 | 348 | std::string dfn(kLocalDir); |
uci1 | 21:ce51bb0ba4a5 | 349 | dfn += "/"; |
uci1 | 21:ce51bb0ba4a5 | 350 | dfn += dent->d_name; |
uci1 | 21:ce51bb0ba4a5 | 351 | if (doRemove) { |
uci1 | 21:ce51bb0ba4a5 | 352 | remove(dfn.c_str()); |
uci1 | 21:ce51bb0ba4a5 | 353 | } |
uci1 | 21:ce51bb0ba4a5 | 354 | } else { |
uci1 | 21:ce51bb0ba4a5 | 355 | ++nSavedBins; |
uci1 | 21:ce51bb0ba4a5 | 356 | } |
uci1 | 21:ce51bb0ba4a5 | 357 | } // else not an mbed program |
uci1 | 21:ce51bb0ba4a5 | 358 | } |
uci1 | 21:ce51bb0ba4a5 | 359 | closedir(d); |
uci1 | 21:ce51bb0ba4a5 | 360 | } |
uci1 | 21:ce51bb0ba4a5 | 361 | return nSavedBins; |
uci1 | 21:ce51bb0ba4a5 | 362 | } |
uci1 | 21:ce51bb0ba4a5 | 363 | |
uci1 | 21:ce51bb0ba4a5 | 364 | SnCommWin::ECommWinResult SnCommWin::GetHeader(const uint32_t timeOut, |
uci1 | 21:ce51bb0ba4a5 | 365 | char* const buf, |
uci1 | 21:ce51bb0ba4a5 | 366 | const uint32_t bsize, |
uci1 | 21:ce51bb0ba4a5 | 367 | uint8_t& mcode, |
uci1 | 21:ce51bb0ba4a5 | 368 | uint32_t& mlen) { |
uci1 | 21:ce51bb0ba4a5 | 369 | SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; |
uci1 | 21:ce51bb0ba4a5 | 370 | if (bsize>=SnHeaderFrame::kMaxSizeOf) { |
uci1 | 21:ce51bb0ba4a5 | 371 | // get header |
uci1 | 21:ce51bb0ba4a5 | 372 | const int hlen = ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeOut); |
uci1 | 21:ce51bb0ba4a5 | 373 | if (hlen>0 && static_cast<uint32_t>(hlen)==SnHeaderFrame::SizeOf()) { |
uci1 | 21:ce51bb0ba4a5 | 374 | mcode=0; |
uci1 | 21:ce51bb0ba4a5 | 375 | mlen=0; |
uci1 | 21:ce51bb0ba4a5 | 376 | const char* b = buf; |
uci1 | 21:ce51bb0ba4a5 | 377 | SnHeaderFrame::ReadFrom(b, mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 378 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 379 | printf("mcode=%02x, mlen=%u\r\n", mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 380 | #endif |
uci1 | 21:ce51bb0ba4a5 | 381 | res = SnCommWin::kOkWithMsg; |
uci1 | 21:ce51bb0ba4a5 | 382 | } |
uci1 | 21:ce51bb0ba4a5 | 383 | } |
uci1 | 21:ce51bb0ba4a5 | 384 | return res; |
uci1 | 21:ce51bb0ba4a5 | 385 | } |
uci1 | 21:ce51bb0ba4a5 | 386 | |
uci1 | 8:95a325df1f6b | 387 | SnCommWin::ECommWinResult SnCommWin::GetConfig(SnConfigFrame& conf, |
uci1 | 8:95a325df1f6b | 388 | const uint32_t timeOut, |
uci1 | 8:95a325df1f6b | 389 | char* const confBuf, |
uci1 | 8:95a325df1f6b | 390 | const uint32_t bsize) { |
uci1 | 8:95a325df1f6b | 391 | // confBuf assumed to alread be of allocated size |
uci1 | 8:95a325df1f6b | 392 | |
uci1 | 12:d472f9811262 | 393 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 394 | printf("GetConfig, to=%u\r\n",timeOut); |
uci1 | 12:d472f9811262 | 395 | #endif |
uci1 | 8:95a325df1f6b | 396 | |
uci1 | 8:95a325df1f6b | 397 | SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; |
uci1 | 21:ce51bb0ba4a5 | 398 | if (bsize>=SnConfigFrame::kMaxSizeOf) { |
uci1 | 8:95a325df1f6b | 399 | // get header |
uci1 | 21:ce51bb0ba4a5 | 400 | uint8_t mcode=0; uint32_t mlen=0; |
uci1 | 21:ce51bb0ba4a5 | 401 | res = GetHeader(timeOut, confBuf, bsize, mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 402 | if (res>=SnCommWin::kOkWithMsg) { |
uci1 | 12:d472f9811262 | 403 | if (mcode==SnHeaderFrame::kNoConfigCode) { |
uci1 | 12:d472f9811262 | 404 | // no config to get |
uci1 | 16:744ce85aede2 | 405 | res = SnCommWin::kOkWthMsgNoConf; |
uci1 | 21:ce51bb0ba4a5 | 406 | } else if (mcode==SnHeaderFrame::kMbedFilenameCode) { |
uci1 | 21:ce51bb0ba4a5 | 407 | res = GetFilename(timeOut, confBuf, mlen); |
uci1 | 21:ce51bb0ba4a5 | 408 | if (res>kAllFails) { |
uci1 | 21:ce51bb0ba4a5 | 409 | std::string fname(confBuf, mlen); // the filename |
uci1 | 21:ce51bb0ba4a5 | 410 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 411 | printf("got filename = [%s]\r\n", fname.c_str()); |
uci1 | 21:ce51bb0ba4a5 | 412 | #endif |
uci1 | 21:ce51bb0ba4a5 | 413 | res = GetLocalFile(fname, confBuf, bsize, timeOut); |
uci1 | 21:ce51bb0ba4a5 | 414 | } |
uci1 | 12:d472f9811262 | 415 | } else if (mcode!=SnHeaderFrame::kConfigCode) { |
uci1 | 8:95a325df1f6b | 416 | res = SnCommWin::kUnexpectedRec; |
uci1 | 8:95a325df1f6b | 417 | } else { |
uci1 | 8:95a325df1f6b | 418 | // get config |
uci1 | 8:95a325df1f6b | 419 | const int clen = ReceiveAll(confBuf, mlen, timeOut); |
uci1 | 8:95a325df1f6b | 420 | if (clen>0 && static_cast<uint32_t>(clen)==mlen) { |
uci1 | 21:ce51bb0ba4a5 | 421 | const char* b = confBuf; |
uci1 | 8:95a325df1f6b | 422 | conf.ReadFrom(b); |
uci1 | 16:744ce85aede2 | 423 | res = SnCommWin::kOkWithMsg; |
uci1 | 8:95a325df1f6b | 424 | } else { |
uci1 | 8:95a325df1f6b | 425 | res = SnCommWin::kUnexpectedRec; |
uci1 | 8:95a325df1f6b | 426 | } |
uci1 | 8:95a325df1f6b | 427 | } |
uci1 | 8:95a325df1f6b | 428 | } else { |
uci1 | 21:ce51bb0ba4a5 | 429 | // not a problem if we get nothing (or no config) |
uci1 | 16:744ce85aede2 | 430 | res = SnCommWin::kOkNoMsg; |
uci1 | 8:95a325df1f6b | 431 | } |
uci1 | 8:95a325df1f6b | 432 | } |
uci1 | 8:95a325df1f6b | 433 | return res; |
uci1 | 8:95a325df1f6b | 434 | } |
uci1 | 8:95a325df1f6b | 435 | |
uci1 | 8:95a325df1f6b | 436 | SnCommWin::ECommWinResult SnCommWin::SendStatus(const SnConfigFrame& conf, |
uci1 | 8:95a325df1f6b | 437 | const SnEventFrame& evt, |
uci1 | 8:95a325df1f6b | 438 | const SnPowerFrame& pow, |
uci1 | 10:3c93db1cfb12 | 439 | const uint16_t seq, |
uci1 | 10:3c93db1cfb12 | 440 | const float thmrate, |
uci1 | 10:3c93db1cfb12 | 441 | const float evtrate, |
uci1 | 8:95a325df1f6b | 442 | char* const genBuf, |
uci1 | 8:95a325df1f6b | 443 | const uint32_t timeout_clock) { |
uci1 | 8:95a325df1f6b | 444 | // TODO: check if connected? |
uci1 | 12:d472f9811262 | 445 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 446 | printf("########### Send Status\r\n"); |
uci1 | 12:d472f9811262 | 447 | #endif |
uci1 | 21:ce51bb0ba4a5 | 448 | uint8_t loseLSB=0, loseMSB=0; |
uci1 | 21:ce51bb0ba4a5 | 449 | uint16_t wvBase=0; |
uci1 | 21:ce51bb0ba4a5 | 450 | conf.GetPackParsFor(GetCommType(), loseLSB, loseMSB, wvBase); |
uci1 | 8:95a325df1f6b | 451 | const uint32_t ssize = SnStatusFrame::SizeOf(SnStatusFrame::kIOVers, conf); |
uci1 | 8:95a325df1f6b | 452 | char* b = genBuf; |
uci1 | 8:95a325df1f6b | 453 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kStatusCode, ssize); |
uci1 | 21:ce51bb0ba4a5 | 454 | SnStatusFrame::WriteTo(b, conf, evt, genBuf, seq, thmrate, evtrate, |
uci1 | 21:ce51bb0ba4a5 | 455 | loseLSB, loseMSB, wvBase); |
uci1 | 10:3c93db1cfb12 | 456 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, |
uci1 | 10:3c93db1cfb12 | 457 | pow.SizeOf(SnPowerFrame::kIOvers)); |
uci1 | 10:3c93db1cfb12 | 458 | pow.WriteTo(b); |
uci1 | 10:3c93db1cfb12 | 459 | int msiz = b-genBuf; |
uci1 | 18:55f1581f2ee4 | 460 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 461 | printf("calling SendAll (status)\r\n"); |
uci1 | 18:55f1581f2ee4 | 462 | #endif |
uci1 | 10:3c93db1cfb12 | 463 | int mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 8:95a325df1f6b | 464 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 465 | printf("status frame:\r\n"); |
uci1 | 15:f2569d8e4176 | 466 | for (uint32_t i=0; i<msiz; i++) { |
uci1 | 8:95a325df1f6b | 467 | printf("%02X ",genBuf[i]); |
uci1 | 8:95a325df1f6b | 468 | } |
uci1 | 8:95a325df1f6b | 469 | printf("\r\n"); |
uci1 | 8:95a325df1f6b | 470 | #endif |
uci1 | 8:95a325df1f6b | 471 | if (mlen==msiz) { |
uci1 | 12:d472f9811262 | 472 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 473 | printf("status+power sent\r\n"); |
uci1 | 12:d472f9811262 | 474 | #endif |
uci1 | 21:ce51bb0ba4a5 | 475 | // event compression parameters must be the same |
uci1 | 21:ce51bb0ba4a5 | 476 | // as those sent in the status update |
uci1 | 8:95a325df1f6b | 477 | b = genBuf; |
uci1 | 10:3c93db1cfb12 | 478 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode, |
uci1 | 21:ce51bb0ba4a5 | 479 | evt.SizeOf(SnEventFrame::kIOVers, loseLSB, loseMSB)); |
uci1 | 21:ce51bb0ba4a5 | 480 | b = evt.WriteTo(b, loseLSB, loseMSB, wvBase); |
uci1 | 21:ce51bb0ba4a5 | 481 | msiz = b-genBuf; |
uci1 | 16:744ce85aede2 | 482 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 483 | printf("calling SendAll (event) %d:\r\n",msiz); |
uci1 | 21:ce51bb0ba4a5 | 484 | for (uint32_t i=0; i<msiz; i++) { |
uci1 | 21:ce51bb0ba4a5 | 485 | printf("%02X ",genBuf[i]); |
uci1 | 21:ce51bb0ba4a5 | 486 | } |
uci1 | 21:ce51bb0ba4a5 | 487 | printf("\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 488 | #endif |
uci1 | 21:ce51bb0ba4a5 | 489 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 21:ce51bb0ba4a5 | 490 | if (mlen==msiz) { |
uci1 | 21:ce51bb0ba4a5 | 491 | return SnCommWin::kOkMsgSent; |
uci1 | 21:ce51bb0ba4a5 | 492 | } |
uci1 | 8:95a325df1f6b | 493 | } |
uci1 | 8:95a325df1f6b | 494 | return SnCommWin::kFailPartSent; |
uci1 | 8:95a325df1f6b | 495 | } |
uci1 | 8:95a325df1f6b | 496 | |
uci1 | 23:ccf39298f205 | 497 | SnCommWin::ECommWinResult SnCommWin::SendString(const char* str, |
uci1 | 23:ccf39298f205 | 498 | const uint32_t timeout) { |
uci1 | 23:ccf39298f205 | 499 | #ifdef DEBUG |
uci1 | 23:ccf39298f205 | 500 | printf("SnCommWin::SendString %s\r\n",str); |
uci1 | 23:ccf39298f205 | 501 | #endif |
uci1 | 23:ccf39298f205 | 502 | const size_t rlen = strlen(str); |
uci1 | 23:ccf39298f205 | 503 | const size_t slen = rlen > kMaxStrLen ? kMaxStrLen : rlen; |
uci1 | 23:ccf39298f205 | 504 | const int msiz = slen+SnHeaderFrame::SizeOf(); |
uci1 | 23:ccf39298f205 | 505 | char* const ts = new char[msiz]; |
uci1 | 23:ccf39298f205 | 506 | char* t = ts; |
uci1 | 23:ccf39298f205 | 507 | SnHeaderFrame::WriteTo(t, SnHeaderFrame::kStringCode, slen); |
uci1 | 23:ccf39298f205 | 508 | const int mlen = SendAll(ts, msiz, timeout); |
uci1 | 23:ccf39298f205 | 509 | delete[] ts; |
uci1 | 23:ccf39298f205 | 510 | return (msiz==mlen) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
uci1 | 23:ccf39298f205 | 511 | } |
uci1 | 23:ccf39298f205 | 512 | |
uci1 | 12:d472f9811262 | 513 | SnCommWin::ECommWinResult SnCommWin::SendFilename(const char* inf, |
uci1 | 8:95a325df1f6b | 514 | char* const genBuf, |
uci1 | 8:95a325df1f6b | 515 | const uint32_t timeout_clock) { |
uci1 | 12:d472f9811262 | 516 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 517 | printf("SnCommWin::SendFilename %s\r\n",inf); |
uci1 | 12:d472f9811262 | 518 | #endif |
uci1 | 16:744ce85aede2 | 519 | |
uci1 | 12:d472f9811262 | 520 | // remove the directory |
uci1 | 12:d472f9811262 | 521 | const char* fn = strrchr(inf, '/'); |
uci1 | 12:d472f9811262 | 522 | if (fn==0) { |
uci1 | 12:d472f9811262 | 523 | // no directory |
uci1 | 12:d472f9811262 | 524 | fn = inf; |
uci1 | 12:d472f9811262 | 525 | } else if (fn!=inf) { |
uci1 | 12:d472f9811262 | 526 | ++fn; // move past the '/' if it was found |
uci1 | 12:d472f9811262 | 527 | } |
uci1 | 12:d472f9811262 | 528 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 529 | printf("send %s\r\n",fn); |
uci1 | 12:d472f9811262 | 530 | #endif |
uci1 | 8:95a325df1f6b | 531 | const size_t flen = strlen(fn); |
uci1 | 8:95a325df1f6b | 532 | char* b = genBuf; |
uci1 | 8:95a325df1f6b | 533 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFilenameCode, flen); |
uci1 | 12:d472f9811262 | 534 | b = SnBitUtils::WriteTo(b, fn, flen); |
uci1 | 12:d472f9811262 | 535 | const int msiz = b-genBuf; |
uci1 | 8:95a325df1f6b | 536 | const int mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 12:d472f9811262 | 537 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 538 | printf("time = %u, timeout = %u\r\n",time(0), timeout_clock); |
uci1 | 12:d472f9811262 | 539 | #endif |
uci1 | 8:95a325df1f6b | 540 | return (msiz==mlen) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
uci1 | 8:95a325df1f6b | 541 | } |
uci1 | 8:95a325df1f6b | 542 | |
uci1 | 12:d472f9811262 | 543 | int SnCommWin::SendFileBlock(FILE* inf, |
uci1 | 12:d472f9811262 | 544 | const uint8_t blockHeaderCode, |
uci1 | 12:d472f9811262 | 545 | const uint32_t blockSize, |
uci1 | 12:d472f9811262 | 546 | char* const genBuf, |
uci1 | 12:d472f9811262 | 547 | const uint32_t timeout) { |
uci1 | 12:d472f9811262 | 548 | // sends the block from the file. does not check if the file has sufficient bytes |
uci1 | 12:d472f9811262 | 549 | // this should be done before calling this function |
uci1 | 12:d472f9811262 | 550 | // (where the number of bytes in the file can be cached) |
uci1 | 12:d472f9811262 | 551 | char* b = genBuf; |
uci1 | 12:d472f9811262 | 552 | SnHeaderFrame::WriteTo(b, blockHeaderCode, blockSize); |
uci1 | 12:d472f9811262 | 553 | SnBitUtils::ReadFrom(inf, b, blockSize); |
uci1 | 12:d472f9811262 | 554 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 555 | printf("Sending block hc %02x, len=%u\r\n",blockHeaderCode,blockSize+SnHeaderFrame::SizeOf()); |
uci1 | 12:d472f9811262 | 556 | #endif |
uci1 | 12:d472f9811262 | 557 | return SendAll(genBuf, blockSize+SnHeaderFrame::SizeOf(), timeout); |
uci1 | 12:d472f9811262 | 558 | } |
uci1 | 12:d472f9811262 | 559 | |
uci1 | 12:d472f9811262 | 560 | SnCommWin::ECommWinResult SnCommWin::SendFileContents(FILE* inf, |
uci1 | 12:d472f9811262 | 561 | const SnConfigFrame& curConf, |
uci1 | 12:d472f9811262 | 562 | SnEventFrame& evt, |
uci1 | 12:d472f9811262 | 563 | SnPowerFrame& pow, |
uci1 | 12:d472f9811262 | 564 | char* const genBuf, |
uci1 | 12:d472f9811262 | 565 | uint32_t nevts, |
uci1 | 12:d472f9811262 | 566 | const uint32_t timeout_clock) { |
uci1 | 12:d472f9811262 | 567 | // firstEvt==0 ==> start at beginning |
uci1 | 12:d472f9811262 | 568 | // nevts==0 ==> all events |
uci1 | 12:d472f9811262 | 569 | |
uci1 | 12:d472f9811262 | 570 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 571 | printf("SendFileContents (byte streaming)\r\n"); |
uci1 | 12:d472f9811262 | 572 | #endif |
uci1 | 12:d472f9811262 | 573 | |
uci1 | 12:d472f9811262 | 574 | // store position in file so we can go back to it afterwards |
uci1 | 12:d472f9811262 | 575 | // this is probably not necessary, because if this file is open |
uci1 | 12:d472f9811262 | 576 | // in write-only mode, we're screwed.. |
uci1 | 12:d472f9811262 | 577 | const int fpos = ftell(inf); |
uci1 | 12:d472f9811262 | 578 | if (fpos>0) { |
uci1 | 12:d472f9811262 | 579 | fseek(inf, 0, SEEK_SET); |
uci1 | 12:d472f9811262 | 580 | } |
uci1 | 12:d472f9811262 | 581 | // how many bytes? |
uci1 | 12:d472f9811262 | 582 | fseek(inf, 0, SEEK_END); // go to end |
uci1 | 12:d472f9811262 | 583 | const int fend = ftell(inf); |
uci1 | 12:d472f9811262 | 584 | fseek(inf, 0, SEEK_SET); // go to start |
uci1 | 12:d472f9811262 | 585 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 586 | printf("fend=%d\r\n",fend); |
uci1 | 12:d472f9811262 | 587 | printf("fpos=%d\r\n",fpos); |
uci1 | 12:d472f9811262 | 588 | #endif |
uci1 | 12:d472f9811262 | 589 | |
uci1 | 12:d472f9811262 | 590 | // variables used when sending data |
uci1 | 12:d472f9811262 | 591 | char* b = genBuf; |
uci1 | 12:d472f9811262 | 592 | int msiz, mlen; |
uci1 | 21:ce51bb0ba4a5 | 593 | // count number of events / power readings sent |
uci1 | 21:ce51bb0ba4a5 | 594 | uint32_t evtsSent=0, powsSent=0; |
uci1 | 12:d472f9811262 | 595 | |
uci1 | 12:d472f9811262 | 596 | // first is the file header, which has no SnHeaderFrame |
uci1 | 12:d472f9811262 | 597 | msiz = SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers); |
uci1 | 12:d472f9811262 | 598 | bool ok = (ftell(inf)+msiz)<=fend; |
uci1 | 12:d472f9811262 | 599 | if (ok) { |
uci1 | 12:d472f9811262 | 600 | mlen = SendFileBlock(inf, SnHeaderFrame::kFileHeadrCode, |
uci1 | 12:d472f9811262 | 601 | msiz, genBuf, timeout_clock); |
uci1 | 12:d472f9811262 | 602 | ok &= (msiz+SnHeaderFrame::SizeOf())==mlen; |
uci1 | 12:d472f9811262 | 603 | |
uci1 | 12:d472f9811262 | 604 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 605 | printf("sent file header. ok=%d\r\n",(int)ok); |
uci1 | 12:d472f9811262 | 606 | #endif |
uci1 | 12:d472f9811262 | 607 | |
uci1 | 12:d472f9811262 | 608 | // the header info for each block |
uci1 | 12:d472f9811262 | 609 | uint8_t hcode; |
uci1 | 12:d472f9811262 | 610 | uint32_t hlen; |
uci1 | 12:d472f9811262 | 611 | |
uci1 | 12:d472f9811262 | 612 | // now just loop through file and send each block |
uci1 | 18:55f1581f2ee4 | 613 | bool fok = true; |
uci1 | 18:55f1581f2ee4 | 614 | while ( fok |
uci1 | 12:d472f9811262 | 615 | && (feof(inf)==0) |
uci1 | 12:d472f9811262 | 616 | && (ferror(inf)==0) |
uci1 | 12:d472f9811262 | 617 | && ((ftell(inf)+SnHeaderFrame::SizeOf())<=fend) ) { |
uci1 | 12:d472f9811262 | 618 | // read the header for the block |
uci1 | 12:d472f9811262 | 619 | SnSDUtils::ReadBlockHeader(inf, hcode, hlen); |
uci1 | 18:55f1581f2ee4 | 620 | fok &= (ftell(inf)+hlen)<=fend; |
uci1 | 12:d472f9811262 | 621 | #ifdef DEBUG |
uci1 | 18:55f1581f2ee4 | 622 | printf("new block: hc=%02x, hl=%u, ftell=%d, fend=%d, " |
uci1 | 18:55f1581f2ee4 | 623 | "ok=%d, fok=%d\r\n", |
uci1 | 18:55f1581f2ee4 | 624 | hcode, hlen, ftell(inf), fend, (int)ok, (int)fok); |
uci1 | 12:d472f9811262 | 625 | #endif |
uci1 | 12:d472f9811262 | 626 | if (ok) { |
uci1 | 12:d472f9811262 | 627 | // send the block |
uci1 | 12:d472f9811262 | 628 | // TODO: repack events? |
uci1 | 12:d472f9811262 | 629 | msiz = hlen + SnHeaderFrame::SizeOf(); |
uci1 | 12:d472f9811262 | 630 | mlen = SendFileBlock(inf, hcode, hlen, genBuf, timeout_clock); |
uci1 | 12:d472f9811262 | 631 | ok &= msiz==mlen; |
uci1 | 12:d472f9811262 | 632 | if (ok) { |
uci1 | 12:d472f9811262 | 633 | if (hcode==SnHeaderFrame::kEventCode) { |
uci1 | 12:d472f9811262 | 634 | ++evtsSent; |
uci1 | 12:d472f9811262 | 635 | if (nevts>0) { |
uci1 | 12:d472f9811262 | 636 | if (evtsSent>=nevts) { |
uci1 | 12:d472f9811262 | 637 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 638 | printf("send %u events. stop\r\n",evtsSent); |
uci1 | 12:d472f9811262 | 639 | #endif |
uci1 | 12:d472f9811262 | 640 | break; |
uci1 | 12:d472f9811262 | 641 | } |
uci1 | 12:d472f9811262 | 642 | } |
uci1 | 12:d472f9811262 | 643 | } else if (hcode==SnHeaderFrame::kPowerCode) { |
uci1 | 12:d472f9811262 | 644 | ++powsSent; |
uci1 | 12:d472f9811262 | 645 | } |
uci1 | 12:d472f9811262 | 646 | } else { |
uci1 | 12:d472f9811262 | 647 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 648 | printf("not ok when sending hcode=%02x\r\n",hcode); |
uci1 | 12:d472f9811262 | 649 | #endif |
uci1 | 21:ce51bb0ba4a5 | 650 | } // if ok after sending block |
uci1 | 21:ce51bb0ba4a5 | 651 | } // if ok after sending block header |
uci1 | 21:ce51bb0ba4a5 | 652 | } // loop over file contents |
uci1 | 21:ce51bb0ba4a5 | 653 | } else { |
uci1 | 21:ce51bb0ba4a5 | 654 | // otherwise file size not sufficient for file header |
uci1 | 21:ce51bb0ba4a5 | 655 | // so it's either 0 or corrupted. |
uci1 | 21:ce51bb0ba4a5 | 656 | // proceed as normal even tho no contents were sent. |
uci1 | 21:ce51bb0ba4a5 | 657 | // if we're deleting files, this one will be deleted. |
uci1 | 21:ce51bb0ba4a5 | 658 | ok = true; |
uci1 | 21:ce51bb0ba4a5 | 659 | } |
uci1 | 12:d472f9811262 | 660 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 661 | printf("loop done. ok=%d\r\n",(int)ok); |
uci1 | 12:d472f9811262 | 662 | #endif |
uci1 | 21:ce51bb0ba4a5 | 663 | |
uci1 | 21:ce51bb0ba4a5 | 664 | // send number of events sent |
uci1 | 12:d472f9811262 | 665 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 666 | printf("sending evtsSent (%u)\r\n",evtsSent); |
uci1 | 12:d472f9811262 | 667 | #endif |
uci1 | 21:ce51bb0ba4a5 | 668 | b = genBuf; |
uci1 | 21:ce51bb0ba4a5 | 669 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t)); |
uci1 | 21:ce51bb0ba4a5 | 670 | b = SnBitUtils::WriteTo(b, evtsSent); |
uci1 | 21:ce51bb0ba4a5 | 671 | msiz = b - genBuf; |
uci1 | 21:ce51bb0ba4a5 | 672 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 21:ce51bb0ba4a5 | 673 | ok &= msiz==mlen; |
uci1 | 18:55f1581f2ee4 | 674 | |
uci1 | 18:55f1581f2ee4 | 675 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 676 | printf("ok=%d (msiz=%d, mlen=%d)\r\n", (int)ok, msiz, mlen); |
uci1 | 18:55f1581f2ee4 | 677 | #endif |
uci1 | 21:ce51bb0ba4a5 | 678 | |
uci1 | 21:ce51bb0ba4a5 | 679 | // send number of power readings sent |
uci1 | 12:d472f9811262 | 680 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 681 | printf("sending powsSent (%u)\r\n",powsSent); |
uci1 | 12:d472f9811262 | 682 | #endif |
uci1 | 21:ce51bb0ba4a5 | 683 | b = genBuf; |
uci1 | 21:ce51bb0ba4a5 | 684 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t)); |
uci1 | 21:ce51bb0ba4a5 | 685 | b = SnBitUtils::WriteTo(b, powsSent); |
uci1 | 21:ce51bb0ba4a5 | 686 | msiz = b - genBuf; |
uci1 | 21:ce51bb0ba4a5 | 687 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 21:ce51bb0ba4a5 | 688 | ok &= msiz==mlen; |
uci1 | 21:ce51bb0ba4a5 | 689 | |
uci1 | 18:55f1581f2ee4 | 690 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 691 | printf("ok=%d (msiz=%d, mlen=%d)\r\n", (int)ok, msiz, mlen); |
uci1 | 18:55f1581f2ee4 | 692 | #endif |
uci1 | 12:d472f9811262 | 693 | |
uci1 | 12:d472f9811262 | 694 | |
uci1 | 12:d472f9811262 | 695 | // put file position back |
uci1 | 12:d472f9811262 | 696 | fseek(inf, fpos, SEEK_SET); |
uci1 | 12:d472f9811262 | 697 | |
uci1 | 12:d472f9811262 | 698 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 699 | printf("end contents: ok=%d\r\n",(int)ok); |
uci1 | 12:d472f9811262 | 700 | #endif |
uci1 | 12:d472f9811262 | 701 | |
uci1 | 12:d472f9811262 | 702 | return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
uci1 | 12:d472f9811262 | 703 | } |
uci1 | 12:d472f9811262 | 704 | |
uci1 | 12:d472f9811262 | 705 | /* |
uci1 | 8:95a325df1f6b | 706 | SnCommWin::ECommWinResult SnCommWin::SendFileContents(FILE* inf, |
uci1 | 8:95a325df1f6b | 707 | const SnConfigFrame& curConf, |
uci1 | 8:95a325df1f6b | 708 | SnEventFrame& evt, |
uci1 | 8:95a325df1f6b | 709 | SnPowerFrame& pow, |
uci1 | 8:95a325df1f6b | 710 | char* const genBuf, |
uci1 | 8:95a325df1f6b | 711 | uint32_t nevts, |
uci1 | 8:95a325df1f6b | 712 | const uint32_t timeout_clock, |
uci1 | 8:95a325df1f6b | 713 | const uint32_t firstEvt) { |
uci1 | 12:d472f9811262 | 714 | printf("comm win send file contents\r\n"); |
uci1 | 8:95a325df1f6b | 715 | // firstEvt==0 ==> start at beginning |
uci1 | 8:95a325df1f6b | 716 | // nevts==0 ==> all events |
uci1 | 8:95a325df1f6b | 717 | |
uci1 | 8:95a325df1f6b | 718 | const int fpos = ftell(inf); |
uci1 | 8:95a325df1f6b | 719 | if (fpos>0) { |
uci1 | 8:95a325df1f6b | 720 | fseek(inf, 0, SEEK_SET); |
uci1 | 8:95a325df1f6b | 721 | } |
uci1 | 12:d472f9811262 | 722 | // how many bytes? |
uci1 | 12:d472f9811262 | 723 | fseek(inf, 0, SEEK_END); // go to end |
uci1 | 12:d472f9811262 | 724 | const int fend = ftell(inf); |
uci1 | 12:d472f9811262 | 725 | fseek(inf, 0, SEEK_SET); // go to start |
uci1 | 12:d472f9811262 | 726 | printf("fend=%d\r\n",fend); |
uci1 | 8:95a325df1f6b | 727 | printf("fpos=%d\r\n",fpos); |
uci1 | 8:95a325df1f6b | 728 | // get file header |
uci1 | 8:95a325df1f6b | 729 | uint64_t macadr; |
uci1 | 8:95a325df1f6b | 730 | uint32_t run; |
uci1 | 8:95a325df1f6b | 731 | uint16_t seq; |
uci1 | 12:d472f9811262 | 732 | bool ok = (ftell(inf)+SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers))<=fend; |
uci1 | 12:d472f9811262 | 733 | if (ok) { |
uci1 | 12:d472f9811262 | 734 | SnSDUtils::ReadFileHeader(inf, macadr, run, seq, &pow); |
uci1 | 12:d472f9811262 | 735 | printf("read file header: run %u, seq %hu\r\n",run,seq); |
uci1 | 12:d472f9811262 | 736 | } |
uci1 | 12:d472f9811262 | 737 | |
uci1 | 12:d472f9811262 | 738 | printf(">>> file hdr read ftell(inf)=%d\r\n",ftell(inf)); |
uci1 | 8:95a325df1f6b | 739 | |
uci1 | 8:95a325df1f6b | 740 | // check block |
uci1 | 8:95a325df1f6b | 741 | uint8_t hcode; |
uci1 | 8:95a325df1f6b | 742 | uint32_t hlen; |
uci1 | 12:d472f9811262 | 743 | ok &= (ftell(inf)+SnHeaderFrame::SizeOf())<=fend; |
uci1 | 12:d472f9811262 | 744 | if (ok) { |
uci1 | 12:d472f9811262 | 745 | SnSDUtils::ReadBlockHeader(inf, hcode, hlen); |
uci1 | 12:d472f9811262 | 746 | printf("read block hd %02x, len %u\r\n",hcode,hlen); |
uci1 | 12:d472f9811262 | 747 | if (hcode==SnHeaderFrame::kPowerCode) { |
uci1 | 12:d472f9811262 | 748 | ok &= (ftell(inf)+SnPowerFrame::SizeOf(SnPowerFrame::kIOvers))<=fend; |
uci1 | 12:d472f9811262 | 749 | if (ok) { |
uci1 | 12:d472f9811262 | 750 | pow.ReadFrom(inf); |
uci1 | 12:d472f9811262 | 751 | printf("read power: v1=%g, v2=%g\r\n",pow.GetAveV1(), pow.GetAveV2()); |
uci1 | 12:d472f9811262 | 752 | // now read the next header |
uci1 | 12:d472f9811262 | 753 | ok &= (ftell(inf)+SnHeaderFrame::SizeOf())<=fend; |
uci1 | 12:d472f9811262 | 754 | if (ok) { |
uci1 | 12:d472f9811262 | 755 | SnSDUtils::ReadBlockHeader(inf, hcode, hlen); |
uci1 | 12:d472f9811262 | 756 | printf("read new header: hc %02x, hlen=%u\r\n",hcode,hlen); |
uci1 | 12:d472f9811262 | 757 | } |
uci1 | 12:d472f9811262 | 758 | } |
uci1 | 12:d472f9811262 | 759 | } |
uci1 | 8:95a325df1f6b | 760 | } |
uci1 | 8:95a325df1f6b | 761 | |
uci1 | 12:d472f9811262 | 762 | printf(">>> power tried ftell(inf)=%d\r\n",ftell(inf)); |
uci1 | 12:d472f9811262 | 763 | |
uci1 | 12:d472f9811262 | 764 | printf("hcode=%02x\r\n",hcode); |
uci1 | 12:d472f9811262 | 765 | printf("ok=%d\r\n",(int)ok); |
uci1 | 12:d472f9811262 | 766 | printf("feof=%d\r\n",feof(inf)); |
uci1 | 12:d472f9811262 | 767 | printf("ferror=%d\r\n",ferror(inf)); |
uci1 | 12:d472f9811262 | 768 | printf("%d+%u <= %d ? %d\r\n",ftell(inf),hlen,fend, |
uci1 | 12:d472f9811262 | 769 | (int)((ftell(inf)+hlen)<=fend)); |
uci1 | 12:d472f9811262 | 770 | |
uci1 | 8:95a325df1f6b | 771 | // TODO: check memory for temporary config/event frames? |
uci1 | 8:95a325df1f6b | 772 | // get config |
uci1 | 8:95a325df1f6b | 773 | while ((hcode!=SnHeaderFrame::kConfigCode) |
uci1 | 12:d472f9811262 | 774 | && ok |
uci1 | 8:95a325df1f6b | 775 | && (feof(inf)==0) |
uci1 | 12:d472f9811262 | 776 | && (ferror(inf)==0) |
uci1 | 12:d472f9811262 | 777 | && ((ftell(inf)+hlen) <= fend) ) { |
uci1 | 12:d472f9811262 | 778 | printf("skip: ftell=%d, hlen=%u\r\n",ftell(inf),hlen); |
uci1 | 8:95a325df1f6b | 779 | fseek(inf, hlen, SEEK_CUR); // skip this block |
uci1 | 12:d472f9811262 | 780 | ok = (ftell(inf)+SnHeaderFrame::SizeOf())<=fend; |
uci1 | 12:d472f9811262 | 781 | if (ok) { |
uci1 | 12:d472f9811262 | 782 | SnSDUtils::ReadBlockHeader(inf, hcode, hlen); |
uci1 | 12:d472f9811262 | 783 | printf("hcs >>> ftell(inf)=%d, hcode=%02x, hlen=%u\r\n",ftell(inf),hcode,hlen); |
uci1 | 12:d472f9811262 | 784 | printf("feof=%d, ferror=%d\r\n",feof(inf),ferror(inf)); |
uci1 | 12:d472f9811262 | 785 | } |
uci1 | 8:95a325df1f6b | 786 | } |
uci1 | 8:95a325df1f6b | 787 | |
uci1 | 12:d472f9811262 | 788 | printf("checking ftell\r\n"); |
uci1 | 12:d472f9811262 | 789 | bool gotConf = false; |
uci1 | 12:d472f9811262 | 790 | ok = (ftell(inf)+hlen) <= fend; |
uci1 | 12:d472f9811262 | 791 | printf("making temp config\r\n"); |
uci1 | 12:d472f9811262 | 792 | SnConfigFrame conf; // TODO: SOMETIMES STALLS HERE! |
uci1 | 12:d472f9811262 | 793 | printf("trying to read\r\n"); |
uci1 | 12:d472f9811262 | 794 | if (ok && (hcode==SnHeaderFrame::kConfigCode)) { |
uci1 | 12:d472f9811262 | 795 | printf("reading config from ftell=%d, hcode=%02x, hlen=%u, ok=%d\r\n", |
uci1 | 12:d472f9811262 | 796 | ftell(inf), hcode, hlen, (int)ok); |
uci1 | 12:d472f9811262 | 797 | conf.ReadFrom(inf); |
uci1 | 12:d472f9811262 | 798 | gotConf = (ftell(inf) <= fend) && (feof(inf)==0) && (ferror(inf)==0); |
uci1 | 12:d472f9811262 | 799 | } |
uci1 | 12:d472f9811262 | 800 | printf(">>> conf. ftell(inf)=%d, gotconf=%d\r\n",ftell(inf),(int)gotConf); |
uci1 | 8:95a325df1f6b | 801 | |
uci1 | 8:95a325df1f6b | 802 | char* b = genBuf; |
uci1 | 12:d472f9811262 | 803 | int msiz, mlen; |
uci1 | 12:d472f9811262 | 804 | if (ok && gotConf) { |
uci1 | 12:d472f9811262 | 805 | // get event size |
uci1 | 12:d472f9811262 | 806 | uint8_t sLoseLSB=0, sLoseMSB=0; |
uci1 | 12:d472f9811262 | 807 | uint16_t sWvBase=0; |
uci1 | 12:d472f9811262 | 808 | curConf.GetPackParsFor(GetCommType(), sLoseLSB, sLoseMSB, sWvBase); |
uci1 | 12:d472f9811262 | 809 | |
uci1 | 12:d472f9811262 | 810 | // size of event in file |
uci1 | 12:d472f9811262 | 811 | const uint32_t esize = SnEventFrame::SizeOf(SnEventFrame::kIOVers, |
uci1 | 12:d472f9811262 | 812 | conf.GetWvLoseLSB(), |
uci1 | 12:d472f9811262 | 813 | conf.GetWvLoseMSB()); |
uci1 | 12:d472f9811262 | 814 | |
uci1 | 12:d472f9811262 | 815 | printf("esize=%u\r\n",esize); |
uci1 | 12:d472f9811262 | 816 | |
uci1 | 12:d472f9811262 | 817 | // number of events / power readings we will send |
uci1 | 12:d472f9811262 | 818 | uint32_t evtsSent=0, powsSent=0; |
uci1 | 8:95a325df1f6b | 819 | b = genBuf; |
uci1 | 12:d472f9811262 | 820 | // send the file header |
uci1 | 12:d472f9811262 | 821 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileHeadrCode, |
uci1 | 12:d472f9811262 | 822 | SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers)); |
uci1 | 12:d472f9811262 | 823 | SnSDUtils::WriteFileHeader(b, macadr, run, seq); |
uci1 | 8:95a325df1f6b | 824 | msiz = b-genBuf; |
uci1 | 8:95a325df1f6b | 825 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 8:95a325df1f6b | 826 | if (mlen==msiz) { |
uci1 | 12:d472f9811262 | 827 | // send power header |
uci1 | 8:95a325df1f6b | 828 | b = genBuf; |
uci1 | 12:d472f9811262 | 829 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, |
uci1 | 12:d472f9811262 | 830 | pow.SizeOf(SnPowerFrame::kIOvers)); |
uci1 | 12:d472f9811262 | 831 | pow.WriteTo(b); |
uci1 | 8:95a325df1f6b | 832 | msiz = b-genBuf; |
uci1 | 8:95a325df1f6b | 833 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 12:d472f9811262 | 834 | ++powsSent; |
uci1 | 8:95a325df1f6b | 835 | if (mlen==msiz) { |
uci1 | 12:d472f9811262 | 836 | // send the config |
uci1 | 12:d472f9811262 | 837 | b = genBuf; |
uci1 | 12:d472f9811262 | 838 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kConfigCode, |
uci1 | 12:d472f9811262 | 839 | conf.SizeOf(SnConfigFrame::kIOVers)); |
uci1 | 12:d472f9811262 | 840 | conf.WriteTo(b); |
uci1 | 12:d472f9811262 | 841 | msiz = b-genBuf; |
uci1 | 12:d472f9811262 | 842 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 12:d472f9811262 | 843 | if (mlen==msiz) { |
uci1 | 12:d472f9811262 | 844 | ok = true; |
uci1 | 12:d472f9811262 | 845 | } |
uci1 | 8:95a325df1f6b | 846 | } |
uci1 | 8:95a325df1f6b | 847 | } |
uci1 | 12:d472f9811262 | 848 | |
uci1 | 12:d472f9811262 | 849 | printf("ok=%d, nevts=%u\r\n",(int)ok,nevts); |
uci1 | 8:95a325df1f6b | 850 | |
uci1 | 12:d472f9811262 | 851 | if (ok) { |
uci1 | 12:d472f9811262 | 852 | // size of event sent over afar |
uci1 | 12:d472f9811262 | 853 | const uint32_t ssize = SnEventFrame::SizeOf(SnEventFrame::kIOVers, |
uci1 | 12:d472f9811262 | 854 | sLoseLSB, sLoseMSB); |
uci1 | 12:d472f9811262 | 855 | |
uci1 | 12:d472f9811262 | 856 | // loop over blocks. send event & power frames |
uci1 | 12:d472f9811262 | 857 | // until EOF or nevets have been sent |
uci1 | 12:d472f9811262 | 858 | uint8_t hc; uint32_t hl; |
uci1 | 12:d472f9811262 | 859 | while (ok && (feof(inf)==0) |
uci1 | 12:d472f9811262 | 860 | && (ferror(inf)==0) |
uci1 | 12:d472f9811262 | 861 | && (ftell(inf)<fend) ) { // feof doesn't seem to work |
uci1 | 12:d472f9811262 | 862 | printf(">>> ftell(inf)=%d\r\n",ftell(inf)); |
uci1 | 12:d472f9811262 | 863 | if ((ftell(inf)+SnHeaderFrame::SizeOf())<=fend) { |
uci1 | 12:d472f9811262 | 864 | SnSDUtils::ReadBlockHeader(inf, hc, hl); |
uci1 | 12:d472f9811262 | 865 | if (hc==SnHeaderFrame::kEventCode) { |
uci1 | 12:d472f9811262 | 866 | if ((ftell(inf)+ssize)<=fend) { |
uci1 | 12:d472f9811262 | 867 | evt.ReadFrom(inf, genBuf, |
uci1 | 12:d472f9811262 | 868 | conf.GetWvLoseLSB(), conf.GetWvLoseMSB(), |
uci1 | 12:d472f9811262 | 869 | conf.GetWvBaseline()); |
uci1 | 12:d472f9811262 | 870 | if (evt.GetEvtNum()>=firstEvt) { |
uci1 | 12:d472f9811262 | 871 | ++evtsSent; |
uci1 | 12:d472f9811262 | 872 | printf("sending evt %u\r\n",evtsSent); |
uci1 | 12:d472f9811262 | 873 | // must be after evt.Read, since that uses the buffer |
uci1 | 12:d472f9811262 | 874 | b = genBuf; |
uci1 | 12:d472f9811262 | 875 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode, ssize); |
uci1 | 12:d472f9811262 | 876 | evt.WriteTo(b, sLoseLSB, sLoseMSB, sWvBase); // will repack if necessary |
uci1 | 12:d472f9811262 | 877 | msiz = b-genBuf; //SnHeaderFrame::SizeOf()+ssize; |
uci1 | 12:d472f9811262 | 878 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 12:d472f9811262 | 879 | ok &= mlen==msiz; |
uci1 | 12:d472f9811262 | 880 | } |
uci1 | 12:d472f9811262 | 881 | } else { |
uci1 | 12:d472f9811262 | 882 | printf("event header, but not enough bytes in file\r\n"); |
uci1 | 12:d472f9811262 | 883 | ok = false; |
uci1 | 12:d472f9811262 | 884 | } |
uci1 | 12:d472f9811262 | 885 | } else if (hc==SnHeaderFrame::kPowerCode) { |
uci1 | 12:d472f9811262 | 886 | if ((ftell(inf)+SnPowerFrame::SizeOf(SnPowerFrame::kIOvers))<=fend) { |
uci1 | 12:d472f9811262 | 887 | ++powsSent; |
uci1 | 12:d472f9811262 | 888 | pow.ReadFrom(inf); |
uci1 | 12:d472f9811262 | 889 | printf("sending power frame %u, v1=%g, v2=%g, t=%u\r\n", |
uci1 | 12:d472f9811262 | 890 | powsSent, pow.GetAveV1(), pow.GetAveV2(), pow.GetTime()); |
uci1 | 12:d472f9811262 | 891 | b = genBuf; |
uci1 | 12:d472f9811262 | 892 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, |
uci1 | 12:d472f9811262 | 893 | SnPowerFrame::SizeOf(SnPowerFrame::kIOvers)); |
uci1 | 12:d472f9811262 | 894 | pow.WriteTo(b); |
uci1 | 12:d472f9811262 | 895 | msiz = b-genBuf; |
uci1 | 12:d472f9811262 | 896 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 12:d472f9811262 | 897 | ok &= mlen==msiz; |
uci1 | 12:d472f9811262 | 898 | } else { |
uci1 | 12:d472f9811262 | 899 | printf("power header, but not enough bytes in file\r\n"); |
uci1 | 12:d472f9811262 | 900 | ok = false; |
uci1 | 12:d472f9811262 | 901 | } |
uci1 | 12:d472f9811262 | 902 | } else { |
uci1 | 12:d472f9811262 | 903 | printf("unhandled block. hc=%hhu, hl=%u\r\n", |
uci1 | 12:d472f9811262 | 904 | hc, hl); |
uci1 | 12:d472f9811262 | 905 | if ((ftell(inf)+hl)<=fend) { |
uci1 | 12:d472f9811262 | 906 | fseek(inf, hl, SEEK_CUR); // skip this block |
uci1 | 12:d472f9811262 | 907 | } else { |
uci1 | 12:d472f9811262 | 908 | printf("not enough bytes in file to skip block\r\n"); |
uci1 | 12:d472f9811262 | 909 | ok = false; |
uci1 | 12:d472f9811262 | 910 | } |
uci1 | 8:95a325df1f6b | 911 | } |
uci1 | 8:95a325df1f6b | 912 | } else { |
uci1 | 12:d472f9811262 | 913 | printf("not enough bytes in file to read header\r\n"); |
uci1 | 12:d472f9811262 | 914 | printf("feof=%d\r\n",feof(inf)); |
uci1 | 12:d472f9811262 | 915 | printf("ftell(inf)=%d, hdr size=%u, fend=%u\r\n", |
uci1 | 12:d472f9811262 | 916 | (ftell(inf)), SnHeaderFrame::SizeOf(), fend); |
uci1 | 8:95a325df1f6b | 917 | ok = false; |
uci1 | 8:95a325df1f6b | 918 | } |
uci1 | 8:95a325df1f6b | 919 | } |
uci1 | 12:d472f9811262 | 920 | // send number of events sent |
uci1 | 12:d472f9811262 | 921 | b = genBuf; |
uci1 | 12:d472f9811262 | 922 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t)); |
uci1 | 12:d472f9811262 | 923 | b = SnBitUtils::WriteTo(b, evtsSent); |
uci1 | 12:d472f9811262 | 924 | msiz = b - genBuf; |
uci1 | 12:d472f9811262 | 925 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 12:d472f9811262 | 926 | ok &= msiz==mlen; |
uci1 | 12:d472f9811262 | 927 | // send number of power readings sent |
uci1 | 12:d472f9811262 | 928 | b = genBuf; |
uci1 | 12:d472f9811262 | 929 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t)); |
uci1 | 12:d472f9811262 | 930 | b = SnBitUtils::WriteTo(b, powsSent); |
uci1 | 12:d472f9811262 | 931 | msiz = b - genBuf; |
uci1 | 12:d472f9811262 | 932 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 12:d472f9811262 | 933 | ok &= msiz==mlen; |
uci1 | 8:95a325df1f6b | 934 | } |
uci1 | 12:d472f9811262 | 935 | } else { |
uci1 | 12:d472f9811262 | 936 | printf("failed to get config from file\r\n"); |
uci1 | 12:d472f9811262 | 937 | // send corrupted file handshake |
uci1 | 8:95a325df1f6b | 938 | b = genBuf; |
uci1 | 12:d472f9811262 | 939 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileReadFailCode, 0u); |
uci1 | 12:d472f9811262 | 940 | msiz = b-genBuf; |
uci1 | 8:95a325df1f6b | 941 | mlen = SendAll(genBuf, msiz, timeout_clock); |
uci1 | 8:95a325df1f6b | 942 | ok &= msiz==mlen; |
uci1 | 8:95a325df1f6b | 943 | } |
uci1 | 12:d472f9811262 | 944 | |
uci1 | 8:95a325df1f6b | 945 | // put file position back |
uci1 | 8:95a325df1f6b | 946 | fseek(inf, fpos, SEEK_SET); |
uci1 | 8:95a325df1f6b | 947 | |
uci1 | 8:95a325df1f6b | 948 | return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
uci1 | 8:95a325df1f6b | 949 | } |
uci1 | 12:d472f9811262 | 950 | */ |