Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnCommWin.cpp@63:4820a4460f00, 2014-11-28 (annotated)
- Committer:
- uci1
- Date:
- Fri Nov 28 05:41:42 2014 +0000
- Revision:
- 63:4820a4460f00
- Parent:
- 56:0bba0ef15697
- Child:
- 64:6c7a316eafad
Revert to SDFileSystemFilInfo with no-stall changes to SDFileSystem.cpp . change watchdog to internal RC clock. move check power to after startup LED sequence. make InitSDCard try up to 26 init's. DEBUG ENABLED, NO SAFETY NETS
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 | 41:d6f5e2f09e07 | 8 | #include "SnSignalStrengthFrame.h" |
uci1 | 2:e67f7c158087 | 9 | #include "SnSDUtils.h" |
uci1 | 16:744ce85aede2 | 10 | #include "SnConstants.h" |
uci1 | 21:ce51bb0ba4a5 | 11 | #include "SnCRCUtils.h" |
uci1 | 37:ff95e7070f26 | 12 | #include "SnCommPeripheral.h" |
uci1 | 21:ce51bb0ba4a5 | 13 | |
uci1 | 21:ce51bb0ba4a5 | 14 | #include <algorithm> |
uci1 | 21:ce51bb0ba4a5 | 15 | #include <ctype.h> |
uci1 | 21:ce51bb0ba4a5 | 16 | extern "C" void mbed_reset(); |
uci1 | 16:744ce85aede2 | 17 | |
uci1 | 63:4820a4460f00 | 18 | #define DEBUG |
uci1 | 16:744ce85aede2 | 19 | |
uci1 | 27:efc4d654b139 | 20 | const char* SnCommWin::kLocalDir = "/local"; |
uci1 | 27:efc4d654b139 | 21 | const char* SnCommWin::kDelAllConfCodeStr = "fj2io32FIJ(#jd;;.O@++/]ewavk2[49ojv"; |
uci1 | 27:efc4d654b139 | 22 | const uint8_t SnCommWin::kDelAllConfCodeLen = 35; // length of the above string |
uci1 | 25:57b2627fe756 | 23 | |
uci1 | 37:ff95e7070f26 | 24 | SnCommWin::SnCommWin(SnCommPeripheral* p) : |
uci1 | 56:0bba0ef15697 | 25 | fSendingInHandshake(false), fComm(p) { |
uci1 | 37:ff95e7070f26 | 26 | if (p==0) { |
uci1 | 37:ff95e7070f26 | 27 | error("SnCommWin - must have peripheral! Received 0.\r\n"); |
uci1 | 37:ff95e7070f26 | 28 | } |
uci1 | 37:ff95e7070f26 | 29 | } |
uci1 | 37:ff95e7070f26 | 30 | |
uci1 | 37:ff95e7070f26 | 31 | SnCommWin::~SnCommWin() { |
uci1 | 37:ff95e7070f26 | 32 | delete fComm; |
uci1 | 37:ff95e7070f26 | 33 | } |
uci1 | 37:ff95e7070f26 | 34 | |
uci1 | 40:1324da35afd4 | 35 | bool SnCommWin::TrySetSysTimeUnix(const uint32_t timeout, |
uci1 | 40:1324da35afd4 | 36 | uint32_t& prvTime, |
uci1 | 40:1324da35afd4 | 37 | uint32_t& setTime) { |
uci1 | 40:1324da35afd4 | 38 | return (fComm!=0) ? (fComm->TrySetSysTimeUnix(timeout,prvTime,setTime)) |
uci1 | 40:1324da35afd4 | 39 | : false; |
uci1 | 37:ff95e7070f26 | 40 | } |
uci1 | 37:ff95e7070f26 | 41 | |
uci1 | 37:ff95e7070f26 | 42 | bool SnCommWin::Connect(const uint32_t timeout) { |
uci1 | 37:ff95e7070f26 | 43 | return (fComm!=0) ? (fComm->Connect(timeout)) : false; |
uci1 | 37:ff95e7070f26 | 44 | } |
uci1 | 37:ff95e7070f26 | 45 | |
uci1 | 37:ff95e7070f26 | 46 | bool SnCommWin::CloseConn(const uint32_t timeout) { |
uci1 | 37:ff95e7070f26 | 47 | return (fComm!=0) ? (fComm->CloseConn(timeout)) : false; |
uci1 | 12:d472f9811262 | 48 | } |
uci1 | 12:d472f9811262 | 49 | |
uci1 | 40:1324da35afd4 | 50 | bool SnCommWin::PowerDown(const uint32_t timeout) { |
uci1 | 40:1324da35afd4 | 51 | return (fComm!=0) ? (fComm->PowerDown(timeout)) : false; |
uci1 | 40:1324da35afd4 | 52 | } |
uci1 | 40:1324da35afd4 | 53 | |
uci1 | 2:e67f7c158087 | 54 | SnCommWin::ECommWinResult SnCommWin::SendData(SnConfigFrame& conf, |
uci1 | 2:e67f7c158087 | 55 | SnEventFrame& evt, |
uci1 | 8:95a325df1f6b | 56 | SnPowerFrame& pow, |
uci1 | 2:e67f7c158087 | 57 | char* const genBuf, |
uci1 | 3:24c5f0f50bf1 | 58 | const uint32_t bsize, |
uci1 | 40:1324da35afd4 | 59 | const uint32_t timeout) { |
uci1 | 12:d472f9811262 | 60 | #ifdef DEBUG |
uci1 | 3:24c5f0f50bf1 | 61 | printf("SnCommWin::SendData\r\n"); |
uci1 | 12:d472f9811262 | 62 | #endif |
uci1 | 2:e67f7c158087 | 63 | ECommWinResult res = kUndefFail; |
uci1 | 15:f2569d8e4176 | 64 | if ( (GetCommType() != SnConfigFrame::kIrid) || |
uci1 | 15:f2569d8e4176 | 65 | (conf.IsForcingSBDdata()) ) { |
uci1 | 15:f2569d8e4176 | 66 | // only send large amounts if we're not communicating by Iridum, |
uci1 | 15:f2569d8e4176 | 67 | // or if we are being forced to send the data over SBD |
uci1 | 15:f2569d8e4176 | 68 | if (conf.IsSendingAllFiles()) { |
uci1 | 12:d472f9811262 | 69 | #ifdef DEBUG |
uci1 | 15:f2569d8e4176 | 70 | printf("sending all files\r\n"); |
uci1 | 12:d472f9811262 | 71 | #endif |
uci1 | 15:f2569d8e4176 | 72 | res = SnSDUtils::SendAllFiles(this, timeout, |
uci1 | 40:1324da35afd4 | 73 | genBuf, bsize, conf, evt, pow); |
uci1 | 40:1324da35afd4 | 74 | // handshakes handled after each file, in SendDataFromFile |
uci1 | 15:f2569d8e4176 | 75 | } else { |
uci1 | 15:f2569d8e4176 | 76 | if (conf.GetCommSendData()==0) { |
uci1 | 12:d472f9811262 | 77 | #ifdef DEBUG |
uci1 | 15:f2569d8e4176 | 78 | printf("no data to send\r\n"); |
uci1 | 12:d472f9811262 | 79 | #endif |
uci1 | 15:f2569d8e4176 | 80 | res = kOkNoMsg; |
uci1 | 56:0bba0ef15697 | 81 | } else if (conf.IsSendingFilesRunSeqList()) { |
uci1 | 56:0bba0ef15697 | 82 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 83 | printf ("calling SendFilesInRunSeqList\r\n"); |
uci1 | 56:0bba0ef15697 | 84 | #endif |
uci1 | 56:0bba0ef15697 | 85 | res = SnSDUtils::SendFilesInRunSeqList( |
uci1 | 56:0bba0ef15697 | 86 | this, timeout, |
uci1 | 56:0bba0ef15697 | 87 | genBuf, bsize, conf, evt, pow); |
uci1 | 56:0bba0ef15697 | 88 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 89 | printf ("res = %d after SendFilesInRunSeqList\r\n", |
uci1 | 56:0bba0ef15697 | 90 | static_cast<int>(res)); |
uci1 | 56:0bba0ef15697 | 91 | #endif |
uci1 | 15:f2569d8e4176 | 92 | } else { |
uci1 | 56:0bba0ef15697 | 93 | // send most recent file or a few events from that file |
uci1 | 15:f2569d8e4176 | 94 | const uint32_t nev = (conf.GetCommSendData()>0) ? |
uci1 | 15:f2569d8e4176 | 95 | conf.GetCommSendData() // send N events |
uci1 | 15:f2569d8e4176 | 96 | : 0u; // send all events in last file |
uci1 | 12:d472f9811262 | 97 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 98 | printf("calling SendDataFromFile. f=%s, nev=%u\r\n", |
uci1 | 40:1324da35afd4 | 99 | SnSDUtils::GetCurFileName(), nev); |
uci1 | 12:d472f9811262 | 100 | #endif |
uci1 | 40:1324da35afd4 | 101 | uint8_t hndcode(0); |
uci1 | 40:1324da35afd4 | 102 | uint32_t hndlen(0); |
uci1 | 40:1324da35afd4 | 103 | res = SendDataFromFile(SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), |
uci1 | 40:1324da35afd4 | 104 | conf, evt, pow, genBuf, bsize, nev, timeout, |
uci1 | 40:1324da35afd4 | 105 | &hndcode, &hndlen); |
uci1 | 40:1324da35afd4 | 106 | // handshake handled in SendData |
uci1 | 12:d472f9811262 | 107 | #ifdef DEBUG |
uci1 | 15:f2569d8e4176 | 108 | printf("after send data cur file, res=%d\r\n",(int)res); |
uci1 | 12:d472f9811262 | 109 | #endif |
uci1 | 15:f2569d8e4176 | 110 | } |
uci1 | 2:e67f7c158087 | 111 | } |
uci1 | 15:f2569d8e4176 | 112 | } else { |
uci1 | 15:f2569d8e4176 | 113 | return kOkNoMsg; |
uci1 | 2:e67f7c158087 | 114 | } |
uci1 | 2:e67f7c158087 | 115 | return res; |
uci1 | 2:e67f7c158087 | 116 | } |
uci1 | 2:e67f7c158087 | 117 | |
uci1 | 40:1324da35afd4 | 118 | SnCommWin::ECommWinResult SnCommWin::SendDataFromFile(FILE* inf, const char* infn, |
uci1 | 2:e67f7c158087 | 119 | const SnConfigFrame& curConf, |
uci1 | 2:e67f7c158087 | 120 | SnEventFrame& evt, |
uci1 | 8:95a325df1f6b | 121 | SnPowerFrame& pow, |
uci1 | 2:e67f7c158087 | 122 | char* const genBuf, |
uci1 | 6:6f002d202f59 | 123 | const uint32_t bsize, |
uci1 | 2:e67f7c158087 | 124 | const uint32_t nevts, |
uci1 | 40:1324da35afd4 | 125 | const uint32_t timeout, |
uci1 | 40:1324da35afd4 | 126 | uint8_t* hndcode, |
uci1 | 40:1324da35afd4 | 127 | uint32_t* hndlen) { |
uci1 | 2:e67f7c158087 | 128 | // nevts==0 ==> send all events |
uci1 | 21:ce51bb0ba4a5 | 129 | // handshakeTimeout is never a clock time -- always a delta(t) |
uci1 | 2:e67f7c158087 | 130 | |
uci1 | 12:d472f9811262 | 131 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 132 | printf("SnCommWin::SendDataFromFile file (%p), fn=%s\r\n",inf,infn); |
uci1 | 12:d472f9811262 | 133 | #endif |
uci1 | 2:e67f7c158087 | 134 | ECommWinResult res = kUndefFail; |
uci1 | 12:d472f9811262 | 135 | bool didDel = false; |
uci1 | 40:1324da35afd4 | 136 | |
uci1 | 40:1324da35afd4 | 137 | // allow up to the full window if we're not obeying timeout |
uci1 | 40:1324da35afd4 | 138 | const uint32_t timeout_clock = curConf.IsObeyingTimeout() ? |
uci1 | 40:1324da35afd4 | 139 | timeout : |
uci1 | 40:1324da35afd4 | 140 | curConf.GetTimeoutTime(time(0), |
uci1 | 40:1324da35afd4 | 141 | curConf.GetCommWinDuration()); |
uci1 | 40:1324da35afd4 | 142 | |
uci1 | 40:1324da35afd4 | 143 | |
uci1 | 2:e67f7c158087 | 144 | if (inf!=0) { |
uci1 | 12:d472f9811262 | 145 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 146 | printf("sending file name %s\r\n",infn); |
uci1 | 12:d472f9811262 | 147 | #endif |
uci1 | 40:1324da35afd4 | 148 | |
uci1 | 6:6f002d202f59 | 149 | // send the file name |
uci1 | 40:1324da35afd4 | 150 | int32_t btogo(0), ttogo(0); |
uci1 | 40:1324da35afd4 | 151 | int32_t bsent = SendFilename(infn, genBuf, btogo, timeout_clock); |
uci1 | 40:1324da35afd4 | 152 | if (genBuf!=0) { |
uci1 | 12:d472f9811262 | 153 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 154 | printf("calling send file contents\r\n"); |
uci1 | 12:d472f9811262 | 155 | #endif |
uci1 | 16:744ce85aede2 | 156 | |
uci1 | 40:1324da35afd4 | 157 | // send the contents |
uci1 | 40:1324da35afd4 | 158 | bsent += SendFileContents(inf, curConf, evt, pow, genBuf, |
uci1 | 40:1324da35afd4 | 159 | nevts, ttogo, timeout_clock); |
uci1 | 40:1324da35afd4 | 160 | btogo += ttogo; |
uci1 | 40:1324da35afd4 | 161 | bsent += fComm->FinishSending(timeout_clock); |
uci1 | 40:1324da35afd4 | 162 | res = (bsent==btogo) ? SnCommWin::kOkMsgSent |
uci1 | 40:1324da35afd4 | 163 | : SnCommWin::kFailPartSent; |
uci1 | 12:d472f9811262 | 164 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 165 | printf("res=%d (fails=%d)\r\n",(int)res,(int)kAllFails); |
uci1 | 12:d472f9811262 | 166 | #endif |
uci1 | 40:1324da35afd4 | 167 | if (res>kAllFails) { |
uci1 | 12:d472f9811262 | 168 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 169 | printf("calling wait handshake\r\n"); |
uci1 | 12:d472f9811262 | 170 | #endif |
uci1 | 40:1324da35afd4 | 171 | // wait for handshake |
uci1 | 40:1324da35afd4 | 172 | uint8_t hndshk(0); uint32_t hndshkLen(0); |
uci1 | 40:1324da35afd4 | 173 | res = WaitHandshake(curConf, timeout_clock, genBuf, bsize, hndshk, |
uci1 | 40:1324da35afd4 | 174 | &hndshkLen); |
uci1 | 40:1324da35afd4 | 175 | if (hndcode!=0) { |
uci1 | 40:1324da35afd4 | 176 | *hndcode = hndshk; |
uci1 | 40:1324da35afd4 | 177 | } |
uci1 | 40:1324da35afd4 | 178 | if (hndlen!=0) { |
uci1 | 40:1324da35afd4 | 179 | *hndlen = hndshkLen; |
uci1 | 40:1324da35afd4 | 180 | } |
uci1 | 26:b3180073c8ec | 181 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 182 | printf("res=%d, nevts=%u, isdel=%d, inf=%p, curfile=%p, hndshk=%02x\r\n", |
uci1 | 40:1324da35afd4 | 183 | res, nevts, curConf.IsDeletingFiles(), inf, |
uci1 | 40:1324da35afd4 | 184 | SnSDUtils::GetCurFile(), hndshk); |
uci1 | 21:ce51bb0ba4a5 | 185 | #endif |
uci1 | 40:1324da35afd4 | 186 | if (SnCommWin::kOkWithMsg==res) { |
uci1 | 56:0bba0ef15697 | 187 | res = HandleHandshake( |
uci1 | 56:0bba0ef15697 | 188 | //SnSDUtils::GetCurFile(), SnSDUtils::GetCurFileName(), |
uci1 | 56:0bba0ef15697 | 189 | inf, infn, |
uci1 | 40:1324da35afd4 | 190 | curConf, evt, pow, genBuf, bsize, timeout_clock, |
uci1 | 40:1324da35afd4 | 191 | hndshk, hndshkLen, &nevts); |
uci1 | 40:1324da35afd4 | 192 | didDel = (SnCommWin::kOkWthMsgDidDel==res); |
uci1 | 40:1324da35afd4 | 193 | } |
uci1 | 2:e67f7c158087 | 194 | } |
uci1 | 40:1324da35afd4 | 195 | } // if genBuf!=0 |
uci1 | 12:d472f9811262 | 196 | } else { |
uci1 | 12:d472f9811262 | 197 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 198 | printf("inf=0!\r\n"); |
uci1 | 12:d472f9811262 | 199 | #endif |
uci1 | 56:0bba0ef15697 | 200 | res = kOkNoMsg; |
uci1 | 12:d472f9811262 | 201 | } |
uci1 | 12:d472f9811262 | 202 | if ( (inf!=SnSDUtils::GetCurFile()) && (didDel==false) ) { |
uci1 | 12:d472f9811262 | 203 | SnSDUtils::CloseOutputFile(inf); |
uci1 | 2:e67f7c158087 | 204 | } |
uci1 | 37:ff95e7070f26 | 205 | if ( fComm->IsTimedOut(timeout_clock) ) { |
uci1 | 25:57b2627fe756 | 206 | if ( kFailTimeout < res ) { |
uci1 | 25:57b2627fe756 | 207 | res = kFailTimeout; |
uci1 | 25:57b2627fe756 | 208 | } |
uci1 | 25:57b2627fe756 | 209 | } |
uci1 | 2:e67f7c158087 | 210 | return res; |
uci1 | 2:e67f7c158087 | 211 | } |
uci1 | 8:95a325df1f6b | 212 | |
uci1 | 40:1324da35afd4 | 213 | SnCommWin::ECommWinResult SnCommWin::HandleHandshake(FILE* inf, const char* infn, |
uci1 | 40:1324da35afd4 | 214 | const SnConfigFrame& curConf, |
uci1 | 40:1324da35afd4 | 215 | SnEventFrame& evt, |
uci1 | 40:1324da35afd4 | 216 | SnPowerFrame& pow, |
uci1 | 40:1324da35afd4 | 217 | char* const genBuf, |
uci1 | 40:1324da35afd4 | 218 | const uint32_t bsize, |
uci1 | 40:1324da35afd4 | 219 | const uint32_t handshakeTimeout, |
uci1 | 40:1324da35afd4 | 220 | const uint8_t hndshk, |
uci1 | 40:1324da35afd4 | 221 | const uint32_t hndlen, |
uci1 | 40:1324da35afd4 | 222 | const uint32_t* nevts) { |
uci1 | 40:1324da35afd4 | 223 | |
uci1 | 40:1324da35afd4 | 224 | SnCommWin::ECommWinResult res = SnCommWin::kUnexpectedRec; |
uci1 | 40:1324da35afd4 | 225 | |
uci1 | 40:1324da35afd4 | 226 | if ( (hndshk==SnHeaderFrame::kHnShNoReplyCode) |
uci1 | 40:1324da35afd4 | 227 | || (hndshk==SnHeaderFrame::kHnShOkPartlCode) ) { |
uci1 | 40:1324da35afd4 | 228 | // nothing to do |
uci1 | 40:1324da35afd4 | 229 | res = SnCommWin::kOkWithMsg; |
uci1 | 40:1324da35afd4 | 230 | } else if (hndshk==SnHeaderFrame::kHnShFailNonCode) { |
uci1 | 40:1324da35afd4 | 231 | res = SnCommWin::kFailNoneSent; |
uci1 | 40:1324da35afd4 | 232 | } else if (hndshk==SnHeaderFrame::kHnShFailPrtCode) { |
uci1 | 40:1324da35afd4 | 233 | res = SnCommWin::kFailPartSent; |
uci1 | 40:1324da35afd4 | 234 | } else if (hndshk==SnHeaderFrame::kHnShOkComplCode) { |
uci1 | 40:1324da35afd4 | 235 | // file received |
uci1 | 56:0bba0ef15697 | 236 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 237 | printf("HnShOkCompl: isdel=%d, isCurFil=%d (%p,%p), nevts_ptr=%p\r\n", |
uci1 | 56:0bba0ef15697 | 238 | (int)(curConf.IsDeletingFiles()), |
uci1 | 56:0bba0ef15697 | 239 | (int)(inf==SnSDUtils::GetCurFile()), |
uci1 | 56:0bba0ef15697 | 240 | (void*)inf, (void*)(SnSDUtils::GetCurFile()), |
uci1 | 56:0bba0ef15697 | 241 | (void*)(nevts)); |
uci1 | 56:0bba0ef15697 | 242 | if (nevts!=0) { |
uci1 | 56:0bba0ef15697 | 243 | printf("*nevts=%u\r\n",*nevts); |
uci1 | 56:0bba0ef15697 | 244 | } |
uci1 | 56:0bba0ef15697 | 245 | #endif |
uci1 | 40:1324da35afd4 | 246 | if ( (curConf.IsDeletingFiles()) |
uci1 | 40:1324da35afd4 | 247 | && (inf!=SnSDUtils::GetCurFile()) |
uci1 | 40:1324da35afd4 | 248 | && ((nevts!=0) && (*nevts==0)) ) { // whole file was received |
uci1 | 40:1324da35afd4 | 249 | // delete this file |
uci1 | 40:1324da35afd4 | 250 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 251 | printf("deleting file %p, %s\r\n",inf,infn); |
uci1 | 40:1324da35afd4 | 252 | #endif |
uci1 | 40:1324da35afd4 | 253 | SnSDUtilsWhisperer::DeleteFile(inf, infn); |
uci1 | 40:1324da35afd4 | 254 | res = SnCommWin::kOkWthMsgDidDel; |
uci1 | 40:1324da35afd4 | 255 | } else { |
uci1 | 40:1324da35afd4 | 256 | res = SnCommWin::kOkWithMsg; |
uci1 | 40:1324da35afd4 | 257 | } |
uci1 | 40:1324da35afd4 | 258 | } else if ( hndshk==SnHeaderFrame::kHnShOkStopCode ) { |
uci1 | 40:1324da35afd4 | 259 | res = SnCommWin::kOkStopComm; |
uci1 | 40:1324da35afd4 | 260 | } else if ( (hndshk==SnHeaderFrame::kHnShOkDelAlCode) || |
uci1 | 40:1324da35afd4 | 261 | (hndshk==SnHeaderFrame::kHnShOkDelRnCode) ) { |
uci1 | 40:1324da35afd4 | 262 | if ( GetDeleteAllConfirmCode(curConf, |
uci1 | 40:1324da35afd4 | 263 | kDelAllConfCodeLen, |
uci1 | 40:1324da35afd4 | 264 | handshakeTimeout, |
uci1 | 40:1324da35afd4 | 265 | genBuf, bsize) ) { |
uci1 | 40:1324da35afd4 | 266 | if (hndshk==SnHeaderFrame::kHnShOkDelAlCode) { |
uci1 | 40:1324da35afd4 | 267 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 268 | printf("delete all\r\n"); |
uci1 | 40:1324da35afd4 | 269 | #endif |
uci1 | 40:1324da35afd4 | 270 | SnSDUtilsWhisperer::DeleteAllFiles(); |
uci1 | 40:1324da35afd4 | 271 | } else if (hndshk==SnHeaderFrame::kHnShOkDelRnCode) { |
uci1 | 40:1324da35afd4 | 272 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 273 | printf("delete run %u\r\n",hndlen); |
uci1 | 40:1324da35afd4 | 274 | #endif |
uci1 | 40:1324da35afd4 | 275 | SnSDUtilsWhisperer::DeleteFilesOfRun(hndlen); |
uci1 | 40:1324da35afd4 | 276 | } |
uci1 | 40:1324da35afd4 | 277 | res = SnCommWin::kOkStopComm; |
uci1 | 40:1324da35afd4 | 278 | } |
uci1 | 56:0bba0ef15697 | 279 | } else if ( hndshk==SnHeaderFrame::kHnShOkClRSLCode ) { |
uci1 | 56:0bba0ef15697 | 280 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 281 | printf("clear run seq list requested\r\n"); |
uci1 | 56:0bba0ef15697 | 282 | #endif |
uci1 | 56:0bba0ef15697 | 283 | SnSDUtils::ClearRunSeqList(); |
uci1 | 40:1324da35afd4 | 284 | } else if ( hndshk==SnHeaderFrame::kHnShOkReqRnCode ) { |
uci1 | 40:1324da35afd4 | 285 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 286 | printf("run %u requested\r\n",hndlen); |
uci1 | 40:1324da35afd4 | 287 | #endif |
uci1 | 56:0bba0ef15697 | 288 | if (fSendingInHandshake==false) { |
uci1 | 56:0bba0ef15697 | 289 | // prevent another SendAllOfRun handshake request until we're done |
uci1 | 56:0bba0ef15697 | 290 | // (allowing it could lead to a stack overflow) |
uci1 | 56:0bba0ef15697 | 291 | fSendingInHandshake = true; |
uci1 | 56:0bba0ef15697 | 292 | SnSDUtils::SendAllOfRun(this, handshakeTimeout, |
uci1 | 56:0bba0ef15697 | 293 | genBuf, bsize, curConf, evt, pow, |
uci1 | 56:0bba0ef15697 | 294 | hndlen); |
uci1 | 56:0bba0ef15697 | 295 | fSendingInHandshake = false; |
uci1 | 56:0bba0ef15697 | 296 | res = SnCommWin::kOkStopComm; |
uci1 | 56:0bba0ef15697 | 297 | } |
uci1 | 56:0bba0ef15697 | 298 | } else if ( hndshk==SnHeaderFrame::kHnShOkRqPtRnCode ) { |
uci1 | 56:0bba0ef15697 | 299 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 300 | printf("part of run %u requested\r\n",hndlen); |
uci1 | 56:0bba0ef15697 | 301 | #endif |
uci1 | 56:0bba0ef15697 | 302 | // need the seq limits -- another handshake message |
uci1 | 56:0bba0ef15697 | 303 | SendHndshkReq(genBuf, handshakeTimeout); |
uci1 | 56:0bba0ef15697 | 304 | uint8_t shndshk(0); uint32_t shndshkLen(0); |
uci1 | 56:0bba0ef15697 | 305 | res = WaitHandshake(curConf, handshakeTimeout, genBuf, bsize, shndshk, |
uci1 | 56:0bba0ef15697 | 306 | &shndshkLen); |
uci1 | 56:0bba0ef15697 | 307 | if (SnCommWin::kOkWithMsg==res) { |
uci1 | 56:0bba0ef15697 | 308 | if ( shndshk==SnHeaderFrame::kHnShOkRqPtSqCode ) { |
uci1 | 56:0bba0ef15697 | 309 | // ok got the min/max seq's as expected |
uci1 | 56:0bba0ef15697 | 310 | const uint16_t minseq = GetMinSeqFrom(shndshkLen); |
uci1 | 56:0bba0ef15697 | 311 | const uint16_t maxseq = GetMaxSeqFrom(shndshkLen); |
uci1 | 56:0bba0ef15697 | 312 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 313 | printf("[minseq=%hu, maxseq=%hu]\r\n",minseq,maxseq); |
uci1 | 56:0bba0ef15697 | 314 | #endif |
uci1 | 56:0bba0ef15697 | 315 | if (fSendingInHandshake==false) { |
uci1 | 56:0bba0ef15697 | 316 | // prevent another SendAllOfRun handshake request |
uci1 | 56:0bba0ef15697 | 317 | // until we're done |
uci1 | 56:0bba0ef15697 | 318 | // (allowing it could lead to a stack overflow) |
uci1 | 56:0bba0ef15697 | 319 | fSendingInHandshake = true; |
uci1 | 56:0bba0ef15697 | 320 | SnSDUtils::SendPartOfRun(this, handshakeTimeout, |
uci1 | 56:0bba0ef15697 | 321 | genBuf, bsize, curConf, evt, pow, |
uci1 | 56:0bba0ef15697 | 322 | hndlen, // the run num |
uci1 | 56:0bba0ef15697 | 323 | minseq, maxseq); |
uci1 | 56:0bba0ef15697 | 324 | fSendingInHandshake = false; |
uci1 | 56:0bba0ef15697 | 325 | } |
uci1 | 56:0bba0ef15697 | 326 | } |
uci1 | 56:0bba0ef15697 | 327 | } |
uci1 | 40:1324da35afd4 | 328 | res = SnCommWin::kOkStopComm; |
uci1 | 40:1324da35afd4 | 329 | } |
uci1 | 40:1324da35afd4 | 330 | |
uci1 | 40:1324da35afd4 | 331 | return res; |
uci1 | 40:1324da35afd4 | 332 | } |
uci1 | 40:1324da35afd4 | 333 | |
uci1 | 40:1324da35afd4 | 334 | |
uci1 | 27:efc4d654b139 | 335 | bool SnCommWin::GetDeleteAllConfirmCode(const SnConfigFrame& conf, |
uci1 | 27:efc4d654b139 | 336 | const uint32_t length, |
uci1 | 27:efc4d654b139 | 337 | const uint32_t timeout, |
uci1 | 27:efc4d654b139 | 338 | char* const buf, |
uci1 | 27:efc4d654b139 | 339 | const uint32_t bsize) { |
uci1 | 27:efc4d654b139 | 340 | bool ret = false; |
uci1 | 27:efc4d654b139 | 341 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 342 | printf("GetDeleteAllConfirmCode, timeout=%u\r\n",timeout); |
uci1 | 27:efc4d654b139 | 343 | #endif |
uci1 | 27:efc4d654b139 | 344 | // better pull all the bytes no matter the buffer size |
uci1 | 27:efc4d654b139 | 345 | const uint32_t ll = (bsize<length) ? bsize : length; |
uci1 | 27:efc4d654b139 | 346 | int mlen = 0; |
uci1 | 27:efc4d654b139 | 347 | while ( mlen<length ) { |
uci1 | 40:1324da35afd4 | 348 | mlen += fComm->ReceiveAll(buf, ll, timeout); |
uci1 | 40:1324da35afd4 | 349 | if (fComm->IsTimedOut(timeout)) { |
uci1 | 27:efc4d654b139 | 350 | break; |
uci1 | 27:efc4d654b139 | 351 | } |
uci1 | 27:efc4d654b139 | 352 | } |
uci1 | 27:efc4d654b139 | 353 | if (mlen==length) { |
uci1 | 27:efc4d654b139 | 354 | const char* b = buf; |
uci1 | 27:efc4d654b139 | 355 | const char* c = kDelAllConfCodeStr; |
uci1 | 27:efc4d654b139 | 356 | bool match = true; |
uci1 | 27:efc4d654b139 | 357 | for (uint8_t i=0; (i<kDelAllConfCodeLen) && match; ++i, ++b, ++c) { |
uci1 | 27:efc4d654b139 | 358 | match = ((*b)==(*c)); |
uci1 | 27:efc4d654b139 | 359 | } |
uci1 | 27:efc4d654b139 | 360 | ret = match; |
uci1 | 27:efc4d654b139 | 361 | } |
uci1 | 27:efc4d654b139 | 362 | return ret; |
uci1 | 27:efc4d654b139 | 363 | } |
uci1 | 27:efc4d654b139 | 364 | |
uci1 | 21:ce51bb0ba4a5 | 365 | SnCommWin::ECommWinResult SnCommWin::WaitHandshake(const SnConfigFrame& conf, |
uci1 | 21:ce51bb0ba4a5 | 366 | const uint32_t timeout, |
uci1 | 8:95a325df1f6b | 367 | char* const buf, |
uci1 | 8:95a325df1f6b | 368 | const uint32_t bsize, |
uci1 | 27:efc4d654b139 | 369 | uint8_t& hndShkCode, |
uci1 | 27:efc4d654b139 | 370 | uint32_t* hndShkLen) { |
uci1 | 12:d472f9811262 | 371 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 372 | printf("WaitHandshake, timeout=%u\r\n",timeout); |
uci1 | 12:d472f9811262 | 373 | #endif |
uci1 | 8:95a325df1f6b | 374 | |
uci1 | 40:1324da35afd4 | 375 | const int mlen = fComm->ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeout); |
uci1 | 8:95a325df1f6b | 376 | if (mlen>0 && static_cast<uint32_t>(mlen) == SnHeaderFrame::SizeOf()) { |
uci1 | 8:95a325df1f6b | 377 | uint32_t msgLen=0; |
uci1 | 8:95a325df1f6b | 378 | const char* b = buf; |
uci1 | 8:95a325df1f6b | 379 | SnHeaderFrame::ReadFrom(b, hndShkCode, msgLen); |
uci1 | 12:d472f9811262 | 380 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 381 | printf("got handshake code=%02x, len=%u\r\n",hndShkCode,msgLen); |
uci1 | 12:d472f9811262 | 382 | #endif |
uci1 | 8:95a325df1f6b | 383 | if ((hndShkCode & SnHeaderFrame::kHndShkBits)!=0) { |
uci1 | 27:efc4d654b139 | 384 | if (hndShkLen!=0) { |
uci1 | 27:efc4d654b139 | 385 | *hndShkLen = msgLen; |
uci1 | 27:efc4d654b139 | 386 | } |
uci1 | 8:95a325df1f6b | 387 | return SnCommWin::kOkWithMsg; |
uci1 | 8:95a325df1f6b | 388 | } else { |
uci1 | 8:95a325df1f6b | 389 | // TODO: somehow handle unexpected message? |
uci1 | 8:95a325df1f6b | 390 | return SnCommWin::kUnexpectedRec; |
uci1 | 8:95a325df1f6b | 391 | } |
uci1 | 8:95a325df1f6b | 392 | } |
uci1 | 8:95a325df1f6b | 393 | return SnCommWin::kOkNoMsg; |
uci1 | 8:95a325df1f6b | 394 | } |
uci1 | 8:95a325df1f6b | 395 | |
uci1 | 21:ce51bb0ba4a5 | 396 | SnCommWin::ECommWinResult SnCommWin::GetFilename(const uint32_t timeout, |
uci1 | 21:ce51bb0ba4a5 | 397 | char* const buf, |
uci1 | 21:ce51bb0ba4a5 | 398 | const uint32_t namelen) { |
uci1 | 21:ce51bb0ba4a5 | 399 | // called by GetConfig upon receipt of a kMbedFilenameCode |
uci1 | 21:ce51bb0ba4a5 | 400 | |
uci1 | 21:ce51bb0ba4a5 | 401 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 402 | printf("GetMbedFile, to=%u\r\n",timeout); |
uci1 | 21:ce51bb0ba4a5 | 403 | #endif |
uci1 | 37:ff95e7070f26 | 404 | const int mlen = fComm->ReceiveAll(buf, namelen, timeout); |
uci1 | 21:ce51bb0ba4a5 | 405 | if (mlen>0 && static_cast<uint32_t>(mlen) == namelen) { |
uci1 | 21:ce51bb0ba4a5 | 406 | return SnCommWin::kOkWithMsg; |
uci1 | 21:ce51bb0ba4a5 | 407 | } |
uci1 | 21:ce51bb0ba4a5 | 408 | return SnCommWin::kUnexpectedRec; |
uci1 | 21:ce51bb0ba4a5 | 409 | } |
uci1 | 21:ce51bb0ba4a5 | 410 | |
uci1 | 21:ce51bb0ba4a5 | 411 | SnCommWin::ECommWinResult SnCommWin::GetLocalFile(std::string fname, |
uci1 | 21:ce51bb0ba4a5 | 412 | char* const buf, |
uci1 | 21:ce51bb0ba4a5 | 413 | const uint32_t bsize, |
uci1 | 21:ce51bb0ba4a5 | 414 | const uint32_t timeout) { |
uci1 | 21:ce51bb0ba4a5 | 415 | // get a file and save it locally with the specified name |
uci1 | 21:ce51bb0ba4a5 | 416 | |
uci1 | 21:ce51bb0ba4a5 | 417 | // get the header for the file |
uci1 | 21:ce51bb0ba4a5 | 418 | uint8_t mcode=0; uint32_t mlen=0; |
uci1 | 21:ce51bb0ba4a5 | 419 | SnCommWin::ECommWinResult res = |
uci1 | 21:ce51bb0ba4a5 | 420 | GetHeader(timeout, buf, bsize, mcode, mlen); |
uci1 | 54:ea1234a44fe8 | 421 | #ifdef DEBUG |
uci1 | 54:ea1234a44fe8 | 422 | printf("Got header code %x, len %u\r\n",mcode,mlen); |
uci1 | 54:ea1234a44fe8 | 423 | #endif |
uci1 | 54:ea1234a44fe8 | 424 | |
uci1 | 21:ce51bb0ba4a5 | 425 | if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileCode) ) { |
uci1 | 21:ce51bb0ba4a5 | 426 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 427 | printf("Got mbed file header. File length = %u\r\n",mlen); |
uci1 | 21:ce51bb0ba4a5 | 428 | #endif |
uci1 | 21:ce51bb0ba4a5 | 429 | // got the header.. make the file.. |
uci1 | 21:ce51bb0ba4a5 | 430 | // make the file name ALLCAPS, since LocalFileSystem will do it anyway |
uci1 | 37:ff95e7070f26 | 431 | SnCommPeripheral::CapitalizeInPlace(fname.begin(), fname.end()); |
uci1 | 21:ce51bb0ba4a5 | 432 | // now ensure the file name is 8.3 only -- for LocalFileSystem |
uci1 | 21:ce51bb0ba4a5 | 433 | const size_t ldlen = strlen(kLocalDir); |
uci1 | 21:ce51bb0ba4a5 | 434 | // 12 = 8.3 filename format, 1 for / and 1 for \0 |
uci1 | 21:ce51bb0ba4a5 | 435 | const uint32_t fbs = ldlen+1+12+1; |
uci1 | 21:ce51bb0ba4a5 | 436 | char fnb[fbs]; |
uci1 | 36:87865913ae6f | 437 | memset(fnb, 0, sizeof(char)*fbs); |
uci1 | 40:1324da35afd4 | 438 | // find the extension |
uci1 | 40:1324da35afd4 | 439 | const size_t xdot = fname.rfind('.'); |
uci1 | 40:1324da35afd4 | 440 | if (xdot!=string::npos && (fname.size()==(4+xdot))) { |
uci1 | 40:1324da35afd4 | 441 | const size_t fnpl = (xdot>8) ? 8 : xdot; |
uci1 | 40:1324da35afd4 | 442 | char* fb = fnb; |
uci1 | 40:1324da35afd4 | 443 | memcpy(fb, kLocalDir, ldlen); fb+=ldlen; // /local |
uci1 | 40:1324da35afd4 | 444 | *fb = '/'; ++fb; // / |
uci1 | 40:1324da35afd4 | 445 | strncpy(fb, fname.c_str(), fnpl); fb+=fnpl; // FILENAME |
uci1 | 40:1324da35afd4 | 446 | *fb = '.'; ++fb; // . |
uci1 | 40:1324da35afd4 | 447 | strncpy(fb, fname.c_str()+xdot+1, 3); // EXT |
uci1 | 40:1324da35afd4 | 448 | // all that just for the file name! |
uci1 | 40:1324da35afd4 | 449 | FILE* lf = fopen(fnb,"wb"); |
uci1 | 21:ce51bb0ba4a5 | 450 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 451 | printf("tried to open file [%s]. lf=%p\r\n",fnb,(void*)lf); |
uci1 | 21:ce51bb0ba4a5 | 452 | #endif |
uci1 | 40:1324da35afd4 | 453 | // get all the data and dump it into the file |
uci1 | 40:1324da35afd4 | 454 | int b = 0, toget = 0; |
uci1 | 40:1324da35afd4 | 455 | while ( mlen>b ) { |
uci1 | 40:1324da35afd4 | 456 | if (fComm->IsTimedOut(timeout)) { |
uci1 | 36:87865913ae6f | 457 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 458 | printf("timeout while getting file\r\n"); |
uci1 | 36:87865913ae6f | 459 | #endif |
uci1 | 40:1324da35afd4 | 460 | res = kFailTimeout; |
uci1 | 21:ce51bb0ba4a5 | 461 | break; |
uci1 | 21:ce51bb0ba4a5 | 462 | } |
uci1 | 40:1324da35afd4 | 463 | toget = mlen - b; |
uci1 | 40:1324da35afd4 | 464 | if (toget>bsize) { |
uci1 | 40:1324da35afd4 | 465 | toget = bsize; |
uci1 | 40:1324da35afd4 | 466 | } |
uci1 | 40:1324da35afd4 | 467 | const int got = fComm->ReceiveAll(buf, toget, timeout); |
uci1 | 40:1324da35afd4 | 468 | if (lf!=NULL) { |
uci1 | 36:87865913ae6f | 469 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 470 | printf("writing %d bytes to file\r\n", got); |
uci1 | 36:87865913ae6f | 471 | #endif |
uci1 | 40:1324da35afd4 | 472 | SnBitUtils::WriteTo(lf, buf, got); |
uci1 | 40:1324da35afd4 | 473 | } |
uci1 | 40:1324da35afd4 | 474 | b += got; |
uci1 | 40:1324da35afd4 | 475 | } // file data receive loop |
uci1 | 40:1324da35afd4 | 476 | uint32_t crc=0; |
uci1 | 40:1324da35afd4 | 477 | if (lf!=NULL) { |
uci1 | 40:1324da35afd4 | 478 | // calculate the crc from what's actually in the file |
uci1 | 40:1324da35afd4 | 479 | fclose(lf); // to flush it |
uci1 | 36:87865913ae6f | 480 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 481 | printf("fopen: %s\r\n",fnb); |
uci1 | 36:87865913ae6f | 482 | #endif |
uci1 | 40:1324da35afd4 | 483 | lf = fopen(fnb,"rb"); |
uci1 | 40:1324da35afd4 | 484 | fseek(lf, 0, SEEK_END); |
uci1 | 40:1324da35afd4 | 485 | int32_t fend = ftell(lf); |
uci1 | 40:1324da35afd4 | 486 | fseek(lf, 0, SEEK_SET); |
uci1 | 40:1324da35afd4 | 487 | char c; |
uci1 | 40:1324da35afd4 | 488 | for (int32_t i=0; i<fend; ++i) { |
uci1 | 40:1324da35afd4 | 489 | SnBitUtils::ReadFrom(lf, c); |
uci1 | 40:1324da35afd4 | 490 | if (feof(lf)==0 && ferror(lf)==0) { |
uci1 | 40:1324da35afd4 | 491 | crc = SnCRCUtils::update_crc32_xfer(crc, c); |
uci1 | 40:1324da35afd4 | 492 | } else { |
uci1 | 40:1324da35afd4 | 493 | break; |
uci1 | 40:1324da35afd4 | 494 | } |
uci1 | 21:ce51bb0ba4a5 | 495 | } |
uci1 | 40:1324da35afd4 | 496 | fclose(lf); |
uci1 | 40:1324da35afd4 | 497 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 498 | printf("closed file. crc = %u\r\n", crc); |
uci1 | 40:1324da35afd4 | 499 | #endif |
uci1 | 40:1324da35afd4 | 500 | } // if output file not 0 |
uci1 | 40:1324da35afd4 | 501 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 502 | printf("mlen=%u, b=%d, eq=%s\r\n",mlen,b, |
uci1 | 40:1324da35afd4 | 503 | (mlen==b)?"true":"false"); |
uci1 | 40:1324da35afd4 | 504 | #endif |
uci1 | 40:1324da35afd4 | 505 | if ( mlen!=b ) { |
uci1 | 40:1324da35afd4 | 506 | if (res > kUnexpectedRec) { |
uci1 | 40:1324da35afd4 | 507 | res = kUnexpectedRec; |
uci1 | 40:1324da35afd4 | 508 | } // otherwise it's already worse |
uci1 | 40:1324da35afd4 | 509 | } else { |
uci1 | 40:1324da35afd4 | 510 | // check that the file is ok |
uci1 | 40:1324da35afd4 | 511 | // get the checksum |
uci1 | 40:1324da35afd4 | 512 | res = GetHeader(timeout, buf, bsize, mcode, mlen); |
uci1 | 40:1324da35afd4 | 513 | if ( (res>=kOkWithMsg) && (mcode==SnHeaderFrame::kMbedFileChksCode) ) { |
uci1 | 40:1324da35afd4 | 514 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 515 | printf("received chksum=%u, crc=%u, eq=%s\r\n", |
uci1 | 40:1324da35afd4 | 516 | mlen,crc,(crc==mlen)?"true":"false"); |
uci1 | 40:1324da35afd4 | 517 | #endif |
uci1 | 40:1324da35afd4 | 518 | if (crc != mlen) { |
uci1 | 36:87865913ae6f | 519 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 520 | printf("checksums differ! unexpected.\r\n"); |
uci1 | 40:1324da35afd4 | 521 | #endif |
uci1 | 40:1324da35afd4 | 522 | res = kUnexpectedRec; // important! |
uci1 | 40:1324da35afd4 | 523 | } |
uci1 | 40:1324da35afd4 | 524 | } |
uci1 | 40:1324da35afd4 | 525 | } // end get remote file checksum |
uci1 | 40:1324da35afd4 | 526 | |
uci1 | 40:1324da35afd4 | 527 | if (lf!=NULL) { |
uci1 | 40:1324da35afd4 | 528 | if ( res<kOkWithMsg ) { |
uci1 | 40:1324da35afd4 | 529 | // timeout, bad checksum, something else bad? |
uci1 | 40:1324da35afd4 | 530 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 531 | printf("removing %s\r\n",fnb); |
uci1 | 36:87865913ae6f | 532 | #endif |
uci1 | 40:1324da35afd4 | 533 | remove(fnb); // delete the file |
uci1 | 40:1324da35afd4 | 534 | } else { |
uci1 | 40:1324da35afd4 | 535 | // if we got a new program, remove the old ones. |
uci1 | 40:1324da35afd4 | 536 | // (schedule myself for immediate de-resolution) |
uci1 | 40:1324da35afd4 | 537 | // |
uci1 | 40:1324da35afd4 | 538 | // first just count how many we would save |
uci1 | 40:1324da35afd4 | 539 | const uint16_t nSavedBins = LoopLocalDirBinFiles(false, fname); |
uci1 | 36:87865913ae6f | 540 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 541 | printf("nSavedBins=%hu",nSavedBins); |
uci1 | 36:87865913ae6f | 542 | #endif |
uci1 | 40:1324da35afd4 | 543 | if (nSavedBins==1) { |
uci1 | 40:1324da35afd4 | 544 | // ok. new program will be the only one. remove the others |
uci1 | 40:1324da35afd4 | 545 | // hope the new program works! |
uci1 | 40:1324da35afd4 | 546 | LoopLocalDirBinFiles(true, fname); |
uci1 | 36:87865913ae6f | 547 | |
uci1 | 36:87865913ae6f | 548 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 549 | printf("rebooting\r\n"); |
uci1 | 36:87865913ae6f | 550 | #endif |
uci1 | 40:1324da35afd4 | 551 | // goodbye cruel world, it's over. walk on by... |
uci1 | 40:1324da35afd4 | 552 | mbed_reset(); |
uci1 | 40:1324da35afd4 | 553 | } |
uci1 | 40:1324da35afd4 | 554 | } // end check new program block |
uci1 | 40:1324da35afd4 | 555 | } // if output file not 0 |
uci1 | 40:1324da35afd4 | 556 | } else { |
uci1 | 40:1324da35afd4 | 557 | // filename mangled. either doesn't contain a '.' |
uci1 | 40:1324da35afd4 | 558 | // or the extension is longer than 3 letters |
uci1 | 54:ea1234a44fe8 | 559 | #ifdef DEBUG |
uci1 | 54:ea1234a44fe8 | 560 | printf("filname mangled. (%s) size=%u, xdot=%u", |
uci1 | 54:ea1234a44fe8 | 561 | fname.c_str(), fname.size(), xdot); |
uci1 | 54:ea1234a44fe8 | 562 | #endif |
uci1 | 40:1324da35afd4 | 563 | res = SnCommWin::kUnexpectedRec; |
uci1 | 21:ce51bb0ba4a5 | 564 | } |
uci1 | 40:1324da35afd4 | 565 | } // if header ok |
uci1 | 54:ea1234a44fe8 | 566 | |
uci1 | 21:ce51bb0ba4a5 | 567 | return res; |
uci1 | 21:ce51bb0ba4a5 | 568 | } |
uci1 | 21:ce51bb0ba4a5 | 569 | |
uci1 | 21:ce51bb0ba4a5 | 570 | int16_t SnCommWin::LoopLocalDirBinFiles(const bool doRemove, |
uci1 | 21:ce51bb0ba4a5 | 571 | const std::string& fname) { |
uci1 | 21:ce51bb0ba4a5 | 572 | // loop over the local directory, count the BIN files that match 'fname' |
uci1 | 21:ce51bb0ba4a5 | 573 | // |
uci1 | 21:ce51bb0ba4a5 | 574 | // fname is assumed to be all caps already! |
uci1 | 21:ce51bb0ba4a5 | 575 | // |
uci1 | 21:ce51bb0ba4a5 | 576 | // if doRemove==true, will actually delete non-matching files |
uci1 | 21:ce51bb0ba4a5 | 577 | // |
uci1 | 21:ce51bb0ba4a5 | 578 | // return number of non-matching files |
uci1 | 21:ce51bb0ba4a5 | 579 | uint16_t nSavedBins = 0; |
uci1 | 21:ce51bb0ba4a5 | 580 | DIR* d( opendir(kLocalDir) ); |
uci1 | 21:ce51bb0ba4a5 | 581 | struct dirent* dent; |
uci1 | 21:ce51bb0ba4a5 | 582 | if ( d!=NULL ) { |
uci1 | 21:ce51bb0ba4a5 | 583 | while ( (dent = readdir(d))!=NULL ) { |
uci1 | 21:ce51bb0ba4a5 | 584 | const size_t flen = strlen(dent->d_name); |
uci1 | 21:ce51bb0ba4a5 | 585 | const char* dext = dent->d_name + flen - 4; |
uci1 | 21:ce51bb0ba4a5 | 586 | if ( strncmp(dext,".BIN",4)==0 || strncmp(dext,".bin",4)==0 ) { |
uci1 | 21:ce51bb0ba4a5 | 587 | // ends with .BIN |
uci1 | 21:ce51bb0ba4a5 | 588 | if (strncmp(dent->d_name, fname.c_str(), fname.size())!=0) { |
uci1 | 21:ce51bb0ba4a5 | 589 | // some other mbed program than our new one |
uci1 | 21:ce51bb0ba4a5 | 590 | std::string dfn(kLocalDir); |
uci1 | 21:ce51bb0ba4a5 | 591 | dfn += "/"; |
uci1 | 21:ce51bb0ba4a5 | 592 | dfn += dent->d_name; |
uci1 | 21:ce51bb0ba4a5 | 593 | if (doRemove) { |
uci1 | 21:ce51bb0ba4a5 | 594 | remove(dfn.c_str()); |
uci1 | 21:ce51bb0ba4a5 | 595 | } |
uci1 | 21:ce51bb0ba4a5 | 596 | } else { |
uci1 | 21:ce51bb0ba4a5 | 597 | ++nSavedBins; |
uci1 | 21:ce51bb0ba4a5 | 598 | } |
uci1 | 21:ce51bb0ba4a5 | 599 | } // else not an mbed program |
uci1 | 21:ce51bb0ba4a5 | 600 | } |
uci1 | 21:ce51bb0ba4a5 | 601 | closedir(d); |
uci1 | 21:ce51bb0ba4a5 | 602 | } |
uci1 | 21:ce51bb0ba4a5 | 603 | return nSavedBins; |
uci1 | 21:ce51bb0ba4a5 | 604 | } |
uci1 | 21:ce51bb0ba4a5 | 605 | |
uci1 | 21:ce51bb0ba4a5 | 606 | SnCommWin::ECommWinResult SnCommWin::GetHeader(const uint32_t timeOut, |
uci1 | 21:ce51bb0ba4a5 | 607 | char* const buf, |
uci1 | 21:ce51bb0ba4a5 | 608 | const uint32_t bsize, |
uci1 | 21:ce51bb0ba4a5 | 609 | uint8_t& mcode, |
uci1 | 21:ce51bb0ba4a5 | 610 | uint32_t& mlen) { |
uci1 | 21:ce51bb0ba4a5 | 611 | SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; |
uci1 | 21:ce51bb0ba4a5 | 612 | if (bsize>=SnHeaderFrame::kMaxSizeOf) { |
uci1 | 21:ce51bb0ba4a5 | 613 | // get header |
uci1 | 37:ff95e7070f26 | 614 | const int hlen = fComm->ReceiveAll(buf, SnHeaderFrame::SizeOf(), timeOut); |
uci1 | 21:ce51bb0ba4a5 | 615 | if (hlen>0 && static_cast<uint32_t>(hlen)==SnHeaderFrame::SizeOf()) { |
uci1 | 21:ce51bb0ba4a5 | 616 | mcode=0; |
uci1 | 21:ce51bb0ba4a5 | 617 | mlen=0; |
uci1 | 21:ce51bb0ba4a5 | 618 | const char* b = buf; |
uci1 | 21:ce51bb0ba4a5 | 619 | SnHeaderFrame::ReadFrom(b, mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 620 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 621 | printf("mcode=%02x, mlen=%u\r\n", mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 622 | #endif |
uci1 | 21:ce51bb0ba4a5 | 623 | res = SnCommWin::kOkWithMsg; |
uci1 | 21:ce51bb0ba4a5 | 624 | } |
uci1 | 21:ce51bb0ba4a5 | 625 | } |
uci1 | 21:ce51bb0ba4a5 | 626 | return res; |
uci1 | 21:ce51bb0ba4a5 | 627 | } |
uci1 | 21:ce51bb0ba4a5 | 628 | |
uci1 | 8:95a325df1f6b | 629 | SnCommWin::ECommWinResult SnCommWin::GetConfig(SnConfigFrame& conf, |
uci1 | 8:95a325df1f6b | 630 | const uint32_t timeOut, |
uci1 | 8:95a325df1f6b | 631 | char* const confBuf, |
uci1 | 8:95a325df1f6b | 632 | const uint32_t bsize) { |
uci1 | 8:95a325df1f6b | 633 | // confBuf assumed to alread be of allocated size |
uci1 | 8:95a325df1f6b | 634 | |
uci1 | 12:d472f9811262 | 635 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 636 | printf("GetConfig, to=%u\r\n",timeOut); |
uci1 | 12:d472f9811262 | 637 | #endif |
uci1 | 8:95a325df1f6b | 638 | |
uci1 | 8:95a325df1f6b | 639 | SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; |
uci1 | 21:ce51bb0ba4a5 | 640 | if (bsize>=SnConfigFrame::kMaxSizeOf) { |
uci1 | 8:95a325df1f6b | 641 | // get header |
uci1 | 21:ce51bb0ba4a5 | 642 | uint8_t mcode=0; uint32_t mlen=0; |
uci1 | 21:ce51bb0ba4a5 | 643 | res = GetHeader(timeOut, confBuf, bsize, mcode, mlen); |
uci1 | 21:ce51bb0ba4a5 | 644 | if (res>=SnCommWin::kOkWithMsg) { |
uci1 | 12:d472f9811262 | 645 | if (mcode==SnHeaderFrame::kNoConfigCode) { |
uci1 | 12:d472f9811262 | 646 | // no config to get |
uci1 | 16:744ce85aede2 | 647 | res = SnCommWin::kOkWthMsgNoConf; |
uci1 | 21:ce51bb0ba4a5 | 648 | } else if (mcode==SnHeaderFrame::kMbedFilenameCode) { |
uci1 | 21:ce51bb0ba4a5 | 649 | res = GetFilename(timeOut, confBuf, mlen); |
uci1 | 21:ce51bb0ba4a5 | 650 | if (res>kAllFails) { |
uci1 | 54:ea1234a44fe8 | 651 | std::string fnameb(confBuf, mlen); // the filename |
uci1 | 54:ea1234a44fe8 | 652 | std::string fname(fnameb.c_str()); // mlen may include the \0 which would be counted in size() |
uci1 | 21:ce51bb0ba4a5 | 653 | #ifdef DEBUG |
uci1 | 54:ea1234a44fe8 | 654 | printf("got filename = [%s] (%u)\r\n", fname.c_str(), fname.size()); |
uci1 | 21:ce51bb0ba4a5 | 655 | #endif |
uci1 | 21:ce51bb0ba4a5 | 656 | res = GetLocalFile(fname, confBuf, bsize, timeOut); |
uci1 | 21:ce51bb0ba4a5 | 657 | } |
uci1 | 12:d472f9811262 | 658 | } else if (mcode!=SnHeaderFrame::kConfigCode) { |
uci1 | 8:95a325df1f6b | 659 | res = SnCommWin::kUnexpectedRec; |
uci1 | 8:95a325df1f6b | 660 | } else { |
uci1 | 8:95a325df1f6b | 661 | // get config |
uci1 | 37:ff95e7070f26 | 662 | const int clen = fComm->ReceiveAll(confBuf, mlen, timeOut); |
uci1 | 8:95a325df1f6b | 663 | if (clen>0 && static_cast<uint32_t>(clen)==mlen) { |
uci1 | 40:1324da35afd4 | 664 | const uint8_t Rv = SnConfigFrame::PeekIOversion(confBuf); |
uci1 | 40:1324da35afd4 | 665 | if (SnConfigFrame::IsIOversionOk(Rv)) { |
uci1 | 40:1324da35afd4 | 666 | const char* b = confBuf; |
uci1 | 40:1324da35afd4 | 667 | conf.ReadFrom(b); |
uci1 | 40:1324da35afd4 | 668 | res = SnCommWin::kOkWithMsg; |
uci1 | 40:1324da35afd4 | 669 | } else { |
uci1 | 40:1324da35afd4 | 670 | res = SnCommWin::kUnexpectedRec; |
uci1 | 40:1324da35afd4 | 671 | char s[256]; |
uci1 | 40:1324da35afd4 | 672 | sprintf(s,"Cannot accept config version [%hhu]. " |
uci1 | 40:1324da35afd4 | 673 | "Expect [%hhu].",Rv,SnConfigFrame::kIOVers); |
uci1 | 40:1324da35afd4 | 674 | SendString(s, timeOut); |
uci1 | 40:1324da35afd4 | 675 | } |
uci1 | 8:95a325df1f6b | 676 | } else { |
uci1 | 8:95a325df1f6b | 677 | res = SnCommWin::kUnexpectedRec; |
uci1 | 8:95a325df1f6b | 678 | } |
uci1 | 8:95a325df1f6b | 679 | } |
uci1 | 8:95a325df1f6b | 680 | } else { |
uci1 | 21:ce51bb0ba4a5 | 681 | // not a problem if we get nothing (or no config) |
uci1 | 16:744ce85aede2 | 682 | res = SnCommWin::kOkNoMsg; |
uci1 | 8:95a325df1f6b | 683 | } |
uci1 | 8:95a325df1f6b | 684 | } |
uci1 | 8:95a325df1f6b | 685 | return res; |
uci1 | 8:95a325df1f6b | 686 | } |
uci1 | 8:95a325df1f6b | 687 | |
uci1 | 40:1324da35afd4 | 688 | int32_t SnCommWin::SendHndshkReq(char* const genBuf, |
uci1 | 40:1324da35afd4 | 689 | const uint32_t timeout_clock) { |
uci1 | 40:1324da35afd4 | 690 | // send a request demanding a handshake |
uci1 | 40:1324da35afd4 | 691 | // as we will be waiting for a response after this, |
uci1 | 40:1324da35afd4 | 692 | // FinishSending is also called |
uci1 | 40:1324da35afd4 | 693 | char* b = genBuf; |
uci1 | 40:1324da35afd4 | 694 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kHnShDemandCode, 0); |
uci1 | 40:1324da35afd4 | 695 | const uint32_t bytesToBeSent = b-genBuf; |
uci1 | 40:1324da35afd4 | 696 | const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock); |
uci1 | 40:1324da35afd4 | 697 | const int32_t flen = fComm->FinishSending(timeout_clock); |
uci1 | 40:1324da35afd4 | 698 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 699 | printf("SendHndshkReq: time = %u, timeout = %u, mlen=%d, flen=%d\r\n", |
uci1 | 40:1324da35afd4 | 700 | time(0), timeout_clock, mlen, flen); |
uci1 | 40:1324da35afd4 | 701 | #endif |
uci1 | 40:1324da35afd4 | 702 | return mlen+flen; |
uci1 | 40:1324da35afd4 | 703 | } |
uci1 | 40:1324da35afd4 | 704 | |
uci1 | 41:d6f5e2f09e07 | 705 | SnCommWin::ECommWinResult SnCommWin::SendSignalStrength(char* const genBuf, |
uci1 | 41:d6f5e2f09e07 | 706 | SnSignalStrengthFrame& sigstr, |
uci1 | 41:d6f5e2f09e07 | 707 | const uint32_t timeout_clock) { |
uci1 | 41:d6f5e2f09e07 | 708 | // try to get the signal strength and send it if possible |
uci1 | 41:d6f5e2f09e07 | 709 | float ss; |
uci1 | 41:d6f5e2f09e07 | 710 | if ( fComm->CheckSignalStrength(timeout_clock, ss) ) { |
uci1 | 41:d6f5e2f09e07 | 711 | char* b = genBuf; |
uci1 | 41:d6f5e2f09e07 | 712 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kSignalStrCode, sigstr.SizeOf()); |
uci1 | 41:d6f5e2f09e07 | 713 | sigstr.SetSigStr(ss, time(0)); |
uci1 | 41:d6f5e2f09e07 | 714 | sigstr.SetCommType( static_cast<uint8_t>(GetCommType()) ); |
uci1 | 41:d6f5e2f09e07 | 715 | sigstr.WriteTo(b); |
uci1 | 41:d6f5e2f09e07 | 716 | const uint32_t bytesToBeSent = b - genBuf; |
uci1 | 41:d6f5e2f09e07 | 717 | const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock); |
uci1 | 41:d6f5e2f09e07 | 718 | const int32_t flen = fComm->FinishSending(timeout_clock); |
uci1 | 41:d6f5e2f09e07 | 719 | if (bytesToBeSent==(mlen+flen)) { |
uci1 | 41:d6f5e2f09e07 | 720 | return SnCommWin::kOkMsgSent; |
uci1 | 41:d6f5e2f09e07 | 721 | } else { |
uci1 | 41:d6f5e2f09e07 | 722 | return SnCommWin::kFailPartSent; |
uci1 | 41:d6f5e2f09e07 | 723 | } |
uci1 | 41:d6f5e2f09e07 | 724 | } |
uci1 | 41:d6f5e2f09e07 | 725 | return SnCommWin::kFailNoneSent; |
uci1 | 41:d6f5e2f09e07 | 726 | } |
uci1 | 41:d6f5e2f09e07 | 727 | |
uci1 | 8:95a325df1f6b | 728 | SnCommWin::ECommWinResult SnCommWin::SendStatus(const SnConfigFrame& conf, |
uci1 | 8:95a325df1f6b | 729 | const SnEventFrame& evt, |
uci1 | 8:95a325df1f6b | 730 | const SnPowerFrame& pow, |
uci1 | 10:3c93db1cfb12 | 731 | const uint16_t seq, |
uci1 | 10:3c93db1cfb12 | 732 | const float thmrate, |
uci1 | 10:3c93db1cfb12 | 733 | const float evtrate, |
uci1 | 56:0bba0ef15697 | 734 | const uint32_t powerOnTime, |
uci1 | 56:0bba0ef15697 | 735 | const SnTempFrame& temper, |
uci1 | 8:95a325df1f6b | 736 | char* const genBuf, |
uci1 | 8:95a325df1f6b | 737 | const uint32_t timeout_clock) { |
uci1 | 8:95a325df1f6b | 738 | // TODO: check if connected? |
uci1 | 12:d472f9811262 | 739 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 740 | printf("########### Send Status\r\n"); |
uci1 | 12:d472f9811262 | 741 | #endif |
uci1 | 21:ce51bb0ba4a5 | 742 | uint8_t loseLSB=0, loseMSB=0; |
uci1 | 21:ce51bb0ba4a5 | 743 | uint16_t wvBase=0; |
uci1 | 21:ce51bb0ba4a5 | 744 | conf.GetPackParsFor(GetCommType(), loseLSB, loseMSB, wvBase); |
uci1 | 8:95a325df1f6b | 745 | const uint32_t ssize = SnStatusFrame::SizeOf(SnStatusFrame::kIOVers, conf); |
uci1 | 8:95a325df1f6b | 746 | char* b = genBuf; |
uci1 | 8:95a325df1f6b | 747 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kStatusCode, ssize); |
uci1 | 56:0bba0ef15697 | 748 | SnStatusFrame::WriteTo(b, conf, evt, genBuf, seq, thmrate, evtrate, |
uci1 | 56:0bba0ef15697 | 749 | powerOnTime, temper, |
uci1 | 21:ce51bb0ba4a5 | 750 | loseLSB, loseMSB, wvBase); |
uci1 | 10:3c93db1cfb12 | 751 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kPowerCode, |
uci1 | 10:3c93db1cfb12 | 752 | pow.SizeOf(SnPowerFrame::kIOvers)); |
uci1 | 10:3c93db1cfb12 | 753 | pow.WriteTo(b); |
uci1 | 40:1324da35afd4 | 754 | int32_t msiz = b-genBuf; |
uci1 | 18:55f1581f2ee4 | 755 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 756 | printf("calling SendAll (status)\r\n"); |
uci1 | 18:55f1581f2ee4 | 757 | #endif |
uci1 | 40:1324da35afd4 | 758 | int32_t mlen = fComm->SendAll(genBuf, msiz, timeout_clock); |
uci1 | 41:d6f5e2f09e07 | 759 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 760 | printf("SendAll returned %d\r\n",mlen); |
uci1 | 41:d6f5e2f09e07 | 761 | #endif |
uci1 | 40:1324da35afd4 | 762 | mlen += fComm->FinishSending(timeout_clock); |
uci1 | 8:95a325df1f6b | 763 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 764 | printf("mlen=%d after FinishSending. msiz=%d\r\n",mlen,msiz); |
uci1 | 8:95a325df1f6b | 765 | printf("status frame:\r\n"); |
uci1 | 15:f2569d8e4176 | 766 | for (uint32_t i=0; i<msiz; i++) { |
uci1 | 8:95a325df1f6b | 767 | printf("%02X ",genBuf[i]); |
uci1 | 8:95a325df1f6b | 768 | } |
uci1 | 8:95a325df1f6b | 769 | printf("\r\n"); |
uci1 | 8:95a325df1f6b | 770 | #endif |
uci1 | 8:95a325df1f6b | 771 | if (mlen==msiz) { |
uci1 | 12:d472f9811262 | 772 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 773 | printf("status+power sent\r\n"); |
uci1 | 12:d472f9811262 | 774 | #endif |
uci1 | 21:ce51bb0ba4a5 | 775 | // event compression parameters must be the same |
uci1 | 21:ce51bb0ba4a5 | 776 | // as those sent in the status update |
uci1 | 8:95a325df1f6b | 777 | b = genBuf; |
uci1 | 10:3c93db1cfb12 | 778 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kEventCode, |
uci1 | 21:ce51bb0ba4a5 | 779 | evt.SizeOf(SnEventFrame::kIOVers, loseLSB, loseMSB)); |
uci1 | 21:ce51bb0ba4a5 | 780 | b = evt.WriteTo(b, loseLSB, loseMSB, wvBase); |
uci1 | 21:ce51bb0ba4a5 | 781 | msiz = b-genBuf; |
uci1 | 16:744ce85aede2 | 782 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 783 | printf("calling SendAll (event) %d:\r\n",msiz); |
uci1 | 21:ce51bb0ba4a5 | 784 | for (uint32_t i=0; i<msiz; i++) { |
uci1 | 21:ce51bb0ba4a5 | 785 | printf("%02X ",genBuf[i]); |
uci1 | 21:ce51bb0ba4a5 | 786 | } |
uci1 | 21:ce51bb0ba4a5 | 787 | printf("\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 788 | #endif |
uci1 | 37:ff95e7070f26 | 789 | mlen = fComm->SendAll(genBuf, msiz, timeout_clock); |
uci1 | 40:1324da35afd4 | 790 | mlen += fComm->FinishSending(timeout_clock); |
uci1 | 21:ce51bb0ba4a5 | 791 | if (mlen==msiz) { |
uci1 | 21:ce51bb0ba4a5 | 792 | return SnCommWin::kOkMsgSent; |
uci1 | 21:ce51bb0ba4a5 | 793 | } |
uci1 | 8:95a325df1f6b | 794 | } |
uci1 | 8:95a325df1f6b | 795 | return SnCommWin::kFailPartSent; |
uci1 | 8:95a325df1f6b | 796 | } |
uci1 | 8:95a325df1f6b | 797 | |
uci1 | 27:efc4d654b139 | 798 | |
uci1 | 23:ccf39298f205 | 799 | SnCommWin::ECommWinResult SnCommWin::SendString(const char* str, |
uci1 | 23:ccf39298f205 | 800 | const uint32_t timeout) { |
uci1 | 23:ccf39298f205 | 801 | #ifdef DEBUG |
uci1 | 23:ccf39298f205 | 802 | printf("SnCommWin::SendString %s\r\n",str); |
uci1 | 23:ccf39298f205 | 803 | #endif |
uci1 | 37:ff95e7070f26 | 804 | const bool ok = fComm->SendString(str, timeout); |
uci1 | 37:ff95e7070f26 | 805 | return (ok) ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
uci1 | 23:ccf39298f205 | 806 | } |
uci1 | 23:ccf39298f205 | 807 | |
uci1 | 40:1324da35afd4 | 808 | int32_t SnCommWin::SendFilename(const char* inf, |
uci1 | 40:1324da35afd4 | 809 | char* const genBuf, |
uci1 | 40:1324da35afd4 | 810 | int32_t& bytesToBeSent, |
uci1 | 40:1324da35afd4 | 811 | const uint32_t timeout_clock) { |
uci1 | 12:d472f9811262 | 812 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 813 | printf("SnCommWin::SendFilename %s\r\n",inf); |
uci1 | 12:d472f9811262 | 814 | #endif |
uci1 | 16:744ce85aede2 | 815 | |
uci1 | 12:d472f9811262 | 816 | // remove the directory |
uci1 | 12:d472f9811262 | 817 | const char* fn = strrchr(inf, '/'); |
uci1 | 12:d472f9811262 | 818 | if (fn==0) { |
uci1 | 12:d472f9811262 | 819 | // no directory |
uci1 | 12:d472f9811262 | 820 | fn = inf; |
uci1 | 12:d472f9811262 | 821 | } else if (fn!=inf) { |
uci1 | 12:d472f9811262 | 822 | ++fn; // move past the '/' if it was found |
uci1 | 12:d472f9811262 | 823 | } |
uci1 | 12:d472f9811262 | 824 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 825 | printf("send %s\r\n",fn); |
uci1 | 12:d472f9811262 | 826 | #endif |
uci1 | 8:95a325df1f6b | 827 | const size_t flen = strlen(fn); |
uci1 | 8:95a325df1f6b | 828 | char* b = genBuf; |
uci1 | 8:95a325df1f6b | 829 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFilenameCode, flen); |
uci1 | 12:d472f9811262 | 830 | b = SnBitUtils::WriteTo(b, fn, flen); |
uci1 | 40:1324da35afd4 | 831 | bytesToBeSent = b-genBuf; |
uci1 | 40:1324da35afd4 | 832 | const int32_t mlen = fComm->SendAll(genBuf, bytesToBeSent, timeout_clock); |
uci1 | 12:d472f9811262 | 833 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 834 | printf("time = %u, timeout = %u\r\n",time(0), timeout_clock); |
uci1 | 12:d472f9811262 | 835 | #endif |
uci1 | 40:1324da35afd4 | 836 | return mlen; |
uci1 | 8:95a325df1f6b | 837 | } |
uci1 | 8:95a325df1f6b | 838 | |
uci1 | 40:1324da35afd4 | 839 | int32_t SnCommWin::SendFileBlock(FILE* inf, |
uci1 | 40:1324da35afd4 | 840 | const uint8_t blockHeaderCode, |
uci1 | 40:1324da35afd4 | 841 | const uint32_t blockSize, |
uci1 | 40:1324da35afd4 | 842 | char* const genBuf, |
uci1 | 40:1324da35afd4 | 843 | int32_t& bytesToSend, |
uci1 | 40:1324da35afd4 | 844 | const uint32_t timeout) { |
uci1 | 12:d472f9811262 | 845 | // sends the block from the file. does not check if the file has sufficient bytes |
uci1 | 12:d472f9811262 | 846 | // this should be done before calling this function |
uci1 | 12:d472f9811262 | 847 | // (where the number of bytes in the file can be cached) |
uci1 | 40:1324da35afd4 | 848 | // |
uci1 | 40:1324da35afd4 | 849 | // bytesToSend will be set to the total bytes that should be delivered eventually |
uci1 | 40:1324da35afd4 | 850 | // the number of bytes actually shipped out by SendAll is returned |
uci1 | 12:d472f9811262 | 851 | char* b = genBuf; |
uci1 | 12:d472f9811262 | 852 | SnHeaderFrame::WriteTo(b, blockHeaderCode, blockSize); |
uci1 | 12:d472f9811262 | 853 | SnBitUtils::ReadFrom(inf, b, blockSize); |
uci1 | 12:d472f9811262 | 854 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 855 | printf("Sending block hc %02x, len=%u\r\n",blockHeaderCode,blockSize+SnHeaderFrame::SizeOf()); |
uci1 | 12:d472f9811262 | 856 | #endif |
uci1 | 40:1324da35afd4 | 857 | bytesToSend = blockSize+SnHeaderFrame::SizeOf(); |
uci1 | 40:1324da35afd4 | 858 | return fComm->SendAll(genBuf, bytesToSend, timeout); |
uci1 | 12:d472f9811262 | 859 | } |
uci1 | 12:d472f9811262 | 860 | |
uci1 | 40:1324da35afd4 | 861 | int32_t SnCommWin::SendFileContents(FILE* inf, |
uci1 | 40:1324da35afd4 | 862 | const SnConfigFrame& curConf, |
uci1 | 40:1324da35afd4 | 863 | SnEventFrame& evt, |
uci1 | 40:1324da35afd4 | 864 | SnPowerFrame& pow, |
uci1 | 40:1324da35afd4 | 865 | char* const genBuf, |
uci1 | 40:1324da35afd4 | 866 | uint32_t nevts, |
uci1 | 40:1324da35afd4 | 867 | int32_t& bytesToBeSent, |
uci1 | 40:1324da35afd4 | 868 | const uint32_t timeout_clock) { |
uci1 | 12:d472f9811262 | 869 | // firstEvt==0 ==> start at beginning |
uci1 | 12:d472f9811262 | 870 | // nevts==0 ==> all events |
uci1 | 40:1324da35afd4 | 871 | // |
uci1 | 40:1324da35afd4 | 872 | // bytesToSend will be set to the total bytes that should be delivered eventually |
uci1 | 40:1324da35afd4 | 873 | // the number of bytes actually shipped out by SendAll is returned |
uci1 | 12:d472f9811262 | 874 | |
uci1 | 12:d472f9811262 | 875 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 876 | printf("SendFileContents (byte streaming)\r\n"); |
uci1 | 12:d472f9811262 | 877 | #endif |
uci1 | 12:d472f9811262 | 878 | |
uci1 | 12:d472f9811262 | 879 | // store position in file so we can go back to it afterwards |
uci1 | 12:d472f9811262 | 880 | // this is probably not necessary, because if this file is open |
uci1 | 12:d472f9811262 | 881 | // in write-only mode, we're screwed.. |
uci1 | 12:d472f9811262 | 882 | const int fpos = ftell(inf); |
uci1 | 12:d472f9811262 | 883 | if (fpos>0) { |
uci1 | 12:d472f9811262 | 884 | fseek(inf, 0, SEEK_SET); |
uci1 | 12:d472f9811262 | 885 | } |
uci1 | 12:d472f9811262 | 886 | // how many bytes? |
uci1 | 12:d472f9811262 | 887 | fseek(inf, 0, SEEK_END); // go to end |
uci1 | 12:d472f9811262 | 888 | const int fend = ftell(inf); |
uci1 | 12:d472f9811262 | 889 | fseek(inf, 0, SEEK_SET); // go to start |
uci1 | 12:d472f9811262 | 890 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 891 | printf("fend=%d\r\n",fend); |
uci1 | 12:d472f9811262 | 892 | printf("fpos=%d\r\n",fpos); |
uci1 | 12:d472f9811262 | 893 | #endif |
uci1 | 12:d472f9811262 | 894 | |
uci1 | 12:d472f9811262 | 895 | // variables used when sending data |
uci1 | 12:d472f9811262 | 896 | char* b = genBuf; |
uci1 | 40:1324da35afd4 | 897 | int32_t msiz(0), mlen(0), mtogo(0), tsent(0); |
uci1 | 21:ce51bb0ba4a5 | 898 | // count number of events / power readings sent |
uci1 | 40:1324da35afd4 | 899 | uint32_t evtsSent=0, powsSent=0, crc=0; |
uci1 | 12:d472f9811262 | 900 | |
uci1 | 12:d472f9811262 | 901 | // first is the file header, which has no SnHeaderFrame |
uci1 | 12:d472f9811262 | 902 | msiz = SnSDUtils::SizeOfFileHeader(SnSDUtils::kIOvers); |
uci1 | 12:d472f9811262 | 903 | bool ok = (ftell(inf)+msiz)<=fend; |
uci1 | 12:d472f9811262 | 904 | if (ok) { |
uci1 | 12:d472f9811262 | 905 | mlen = SendFileBlock(inf, SnHeaderFrame::kFileHeadrCode, |
uci1 | 40:1324da35afd4 | 906 | msiz, genBuf, mtogo, timeout_clock); |
uci1 | 40:1324da35afd4 | 907 | //ok &= (msiz+SnHeaderFrame::SizeOf())==mlen; |
uci1 | 40:1324da35afd4 | 908 | bytesToBeSent += mtogo; |
uci1 | 40:1324da35afd4 | 909 | tsent += mlen; |
uci1 | 12:d472f9811262 | 910 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 911 | printf("sent file header. ok=%d\r\n",(int)ok); |
uci1 | 12:d472f9811262 | 912 | #endif |
uci1 | 40:1324da35afd4 | 913 | // calc crc w/o the header block of the file header, as |
uci1 | 40:1324da35afd4 | 914 | // this does not get stored in the file |
uci1 | 40:1324da35afd4 | 915 | crc = SnCRCUtils::GetUpdatedCRC32for(crc, genBuf+SnHeaderFrame::SizeOf(), |
uci1 | 40:1324da35afd4 | 916 | mtogo-SnHeaderFrame::SizeOf()); |
uci1 | 40:1324da35afd4 | 917 | |
uci1 | 12:d472f9811262 | 918 | // the header info for each block |
uci1 | 40:1324da35afd4 | 919 | uint8_t hcode(0); |
uci1 | 40:1324da35afd4 | 920 | uint32_t hlen(0); |
uci1 | 12:d472f9811262 | 921 | |
uci1 | 12:d472f9811262 | 922 | // now just loop through file and send each block |
uci1 | 18:55f1581f2ee4 | 923 | bool fok = true; |
uci1 | 18:55f1581f2ee4 | 924 | while ( fok |
uci1 | 12:d472f9811262 | 925 | && (feof(inf)==0) |
uci1 | 12:d472f9811262 | 926 | && (ferror(inf)==0) |
uci1 | 12:d472f9811262 | 927 | && ((ftell(inf)+SnHeaderFrame::SizeOf())<=fend) ) { |
uci1 | 12:d472f9811262 | 928 | // read the header for the block |
uci1 | 12:d472f9811262 | 929 | SnSDUtils::ReadBlockHeader(inf, hcode, hlen); |
uci1 | 18:55f1581f2ee4 | 930 | fok &= (ftell(inf)+hlen)<=fend; |
uci1 | 12:d472f9811262 | 931 | #ifdef DEBUG |
uci1 | 18:55f1581f2ee4 | 932 | printf("new block: hc=%02x, hl=%u, ftell=%d, fend=%d, " |
uci1 | 18:55f1581f2ee4 | 933 | "ok=%d, fok=%d\r\n", |
uci1 | 18:55f1581f2ee4 | 934 | hcode, hlen, ftell(inf), fend, (int)ok, (int)fok); |
uci1 | 12:d472f9811262 | 935 | #endif |
uci1 | 40:1324da35afd4 | 936 | if (fok) { |
uci1 | 12:d472f9811262 | 937 | // send the block |
uci1 | 12:d472f9811262 | 938 | // TODO: repack events? |
uci1 | 40:1324da35afd4 | 939 | mlen = SendFileBlock(inf, hcode, hlen, genBuf, |
uci1 | 40:1324da35afd4 | 940 | mtogo, timeout_clock); |
uci1 | 40:1324da35afd4 | 941 | bytesToBeSent += mtogo; |
uci1 | 40:1324da35afd4 | 942 | tsent += mlen; |
uci1 | 40:1324da35afd4 | 943 | crc = SnCRCUtils::GetUpdatedCRC32for(crc, genBuf, mtogo); |
uci1 | 40:1324da35afd4 | 944 | |
uci1 | 40:1324da35afd4 | 945 | if (hcode==SnHeaderFrame::kEventCode) { |
uci1 | 40:1324da35afd4 | 946 | ++evtsSent; |
uci1 | 40:1324da35afd4 | 947 | if (nevts>0) { |
uci1 | 40:1324da35afd4 | 948 | if (evtsSent>=nevts) { |
uci1 | 12:d472f9811262 | 949 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 950 | printf("sent %u events. stop\r\n",evtsSent); |
uci1 | 12:d472f9811262 | 951 | #endif |
uci1 | 40:1324da35afd4 | 952 | break; |
uci1 | 12:d472f9811262 | 953 | } |
uci1 | 12:d472f9811262 | 954 | } |
uci1 | 40:1324da35afd4 | 955 | } else if (hcode==SnHeaderFrame::kPowerCode) { |
uci1 | 40:1324da35afd4 | 956 | ++powsSent; |
uci1 | 40:1324da35afd4 | 957 | } |
uci1 | 40:1324da35afd4 | 958 | } // otherwise file size not sufficient for this block |
uci1 | 21:ce51bb0ba4a5 | 959 | } // loop over file contents |
uci1 | 21:ce51bb0ba4a5 | 960 | } else { |
uci1 | 21:ce51bb0ba4a5 | 961 | // otherwise file size not sufficient for file header |
uci1 | 21:ce51bb0ba4a5 | 962 | // so it's either 0 or corrupted. |
uci1 | 21:ce51bb0ba4a5 | 963 | // proceed as normal even tho no contents were sent. |
uci1 | 21:ce51bb0ba4a5 | 964 | // if we're deleting files, this one will be deleted. |
uci1 | 21:ce51bb0ba4a5 | 965 | ok = true; |
uci1 | 21:ce51bb0ba4a5 | 966 | } |
uci1 | 12:d472f9811262 | 967 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 968 | printf("loop done. ok=%d\r\n",(int)ok); |
uci1 | 12:d472f9811262 | 969 | #endif |
uci1 | 40:1324da35afd4 | 970 | |
uci1 | 40:1324da35afd4 | 971 | // send the crc |
uci1 | 40:1324da35afd4 | 972 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 973 | printf("sending crc (%u)\r\n",crc); |
uci1 | 40:1324da35afd4 | 974 | #endif |
uci1 | 40:1324da35afd4 | 975 | b = genBuf; |
uci1 | 40:1324da35afd4 | 976 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kMbedFileChksCode, sizeof(uint32_t)); |
uci1 | 40:1324da35afd4 | 977 | b = SnBitUtils::WriteTo(b, crc); |
uci1 | 40:1324da35afd4 | 978 | msiz = b - genBuf; |
uci1 | 40:1324da35afd4 | 979 | mlen = fComm->SendAll(genBuf, msiz, timeout_clock); |
uci1 | 40:1324da35afd4 | 980 | bytesToBeSent += msiz; |
uci1 | 40:1324da35afd4 | 981 | tsent += mlen; |
uci1 | 40:1324da35afd4 | 982 | |
uci1 | 40:1324da35afd4 | 983 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 984 | printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen); |
uci1 | 40:1324da35afd4 | 985 | #endif |
uci1 | 40:1324da35afd4 | 986 | |
uci1 | 21:ce51bb0ba4a5 | 987 | |
uci1 | 21:ce51bb0ba4a5 | 988 | // send number of events sent |
uci1 | 12:d472f9811262 | 989 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 990 | printf("sending evtsSent (%u)\r\n",evtsSent); |
uci1 | 12:d472f9811262 | 991 | #endif |
uci1 | 21:ce51bb0ba4a5 | 992 | b = genBuf; |
uci1 | 21:ce51bb0ba4a5 | 993 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNevtsCode, sizeof(uint32_t)); |
uci1 | 21:ce51bb0ba4a5 | 994 | b = SnBitUtils::WriteTo(b, evtsSent); |
uci1 | 21:ce51bb0ba4a5 | 995 | msiz = b - genBuf; |
uci1 | 37:ff95e7070f26 | 996 | mlen = fComm->SendAll(genBuf, msiz, timeout_clock); |
uci1 | 40:1324da35afd4 | 997 | bytesToBeSent += msiz; |
uci1 | 40:1324da35afd4 | 998 | tsent += mlen; |
uci1 | 40:1324da35afd4 | 999 | |
uci1 | 18:55f1581f2ee4 | 1000 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 1001 | printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen); |
uci1 | 18:55f1581f2ee4 | 1002 | #endif |
uci1 | 21:ce51bb0ba4a5 | 1003 | |
uci1 | 21:ce51bb0ba4a5 | 1004 | // send number of power readings sent |
uci1 | 12:d472f9811262 | 1005 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1006 | printf("sending powsSent (%u)\r\n",powsSent); |
uci1 | 12:d472f9811262 | 1007 | #endif |
uci1 | 21:ce51bb0ba4a5 | 1008 | b = genBuf; |
uci1 | 21:ce51bb0ba4a5 | 1009 | SnHeaderFrame::WriteTo(b, SnHeaderFrame::kFileNpwrsCode, sizeof(uint32_t)); |
uci1 | 21:ce51bb0ba4a5 | 1010 | b = SnBitUtils::WriteTo(b, powsSent); |
uci1 | 21:ce51bb0ba4a5 | 1011 | msiz = b - genBuf; |
uci1 | 37:ff95e7070f26 | 1012 | mlen = fComm->SendAll(genBuf, msiz, timeout_clock); |
uci1 | 40:1324da35afd4 | 1013 | bytesToBeSent += msiz; |
uci1 | 40:1324da35afd4 | 1014 | tsent += mlen; |
uci1 | 21:ce51bb0ba4a5 | 1015 | |
uci1 | 18:55f1581f2ee4 | 1016 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 1017 | printf("(msiz=%d, mlen=%d)\r\n", msiz, mlen); |
uci1 | 18:55f1581f2ee4 | 1018 | #endif |
uci1 | 12:d472f9811262 | 1019 | |
uci1 | 12:d472f9811262 | 1020 | // put file position back |
uci1 | 12:d472f9811262 | 1021 | fseek(inf, fpos, SEEK_SET); |
uci1 | 12:d472f9811262 | 1022 | |
uci1 | 12:d472f9811262 | 1023 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 1024 | printf("end contents: ok=%d\r\n",(int)ok); |
uci1 | 12:d472f9811262 | 1025 | #endif |
uci1 | 12:d472f9811262 | 1026 | |
uci1 | 40:1324da35afd4 | 1027 | return tsent; |
uci1 | 8:95a325df1f6b | 1028 | |
uci1 | 40:1324da35afd4 | 1029 | //return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
uci1 | 8:95a325df1f6b | 1030 | } |