Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Jan 23 19:29:01 2013 +0000
Revision:
31:b5bd3b189150
Parent:
28:484943132bb0
Child:
39:2f17131d22a5
Added option in SnConstants to allow for proper switching of peripheral power in stations that have the Afar and Iridium power lines spliced together. Afar, SBD and Twitter comms enabled. Afar and Iridium powered together.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "SnConfigFrame.h"
uci1 0:664899e0b988 2
uci1 0:664899e0b988 3 #include "mbed.h"
uci1 0:664899e0b988 4
uci1 0:664899e0b988 5 #include "SnBitUtils.h"
uci1 16:744ce85aede2 6 #include "SnHeaderFrame.h"
uci1 22:f957c4f840ad 7 #include "Watchdog.h"
uci1 0:664899e0b988 8
uci1 0:664899e0b988 9 extern "C" void mbed_mac_address(char *);
uci1 0:664899e0b988 10
uci1 31:b5bd3b189150 11 bool SnConfigFrame::fgApplySafetyNets = true;
uci1 18:55f1581f2ee4 12 const uint8_t SnConfigFrame::kIOVers = 4;
uci1 3:24c5f0f50bf1 13 const char* const SnConfigFrame::kDefConfFile = "/local/DEFCONF.DAT";
uci1 28:484943132bb0 14 const char* const SnConfigFrame::kDefIPflag = "DEF";
uci1 1:e392595b4b76 15 const uint32_t SnConfigFrame::kMinCommWinPrdLowPwr = 14400; // exclusive min low power comm win period (s)
uci1 1:e392595b4b76 16 const uint32_t SnConfigFrame::kMaxCommWinPrdLowPwr = 259200; // exclusive max low power comm win period (s)
uci1 1:e392595b4b76 17 const uint32_t SnConfigFrame::kMinCommWinDurLowPwr = 300; // exclusive min low power comm win duration (s)
uci1 1:e392595b4b76 18 const uint32_t SnConfigFrame::kMaxCommWinDurLowPwr = 3600; // exclusive max low power comm win duration (s)
uci1 1:e392595b4b76 19 const uint8_t SnConfigFrame::kConfLblLen;
uci1 0:664899e0b988 20
uci1 0:664899e0b988 21 uint64_t SnConfigFrame::fgMacAdr = 0;
uci1 0:664899e0b988 22
uci1 0:664899e0b988 23 void SnConfigFrame::SetMacAddress() {
uci1 0:664899e0b988 24 static const uint8_t b64 = sizeof(uint64_t);
uci1 0:664899e0b988 25 static char c[b64];
uci1 0:664899e0b988 26 mbed_mac_address(&(c[0]));
uci1 0:664899e0b988 27 // like a big endian union
uci1 0:664899e0b988 28 fgMacAdr = 0;
uci1 0:664899e0b988 29 const char* a = c+(b64-1);
uci1 0:664899e0b988 30 for (uint8_t i=0; i<b64; i++, a--) {
uci1 0:664899e0b988 31 fgMacAdr |= static_cast<uint64_t>(*a) << (i<<3);
uci1 0:664899e0b988 32 }
uci1 0:664899e0b988 33 }
uci1 0:664899e0b988 34
uci1 0:664899e0b988 35 void SnConfigFrame::SetHardDefaults() {
uci1 0:664899e0b988 36 sprintf(fLabel,"HardDefaults");
uci1 0:664899e0b988 37 fConfTime = 1338854400u; // Tue, 05 Jun 2012 00:00:00 GMT
uci1 0:664899e0b988 38 fRun = 0;
uci1 0:664899e0b988 39 fFirstEvt = 0;
uci1 8:95a325df1f6b 40 fEvtsPerSeq = 1000;
uci1 8:95a325df1f6b 41 fRunMode = 0;
uci1 1:e392595b4b76 42 fStreamHiLoPlas = 0;
uci1 0:664899e0b988 43 fWvLoseLSB = 0;
uci1 1:e392595b4b76 44 fWvLoseMSB = 4;
uci1 0:664899e0b988 45 fWvBaseline = 0;
uci1 0:664899e0b988 46 fDatPackType = ~0;
uci1 0:664899e0b988 47 uint16_t* dc = &(fDAC[0][0]);
uci1 0:664899e0b988 48 for (uint16_t i=0; i<kTotDacs; i++, dc++) {
uci1 0:664899e0b988 49 *dc = 3072u;
uci1 0:664899e0b988 50 }
uci1 0:664899e0b988 51 fNumPlas = 1;
uci1 0:664899e0b988 52 uint16_t* pl = &(fPLA[0]);
uci1 0:664899e0b988 53 for (uint8_t j=0; j<kNplas; j++, pl++) {
uci1 0:664899e0b988 54 *pl = 0x7FFFu;
uci1 0:664899e0b988 55 }
uci1 28:484943132bb0 56 fNumCardsMajLog = 2;
uci1 0:664899e0b988 57 fEnableThermTrig = 1;
uci1 1:e392595b4b76 58 fForceTrigPeriod = 67u;
uci1 0:664899e0b988 59 fHeartBeatPeriod = 0;
uci1 0:664899e0b988 60 fAmpsOn = 0x0Fu;
uci1 0:664899e0b988 61 fEvtThrtlPeriodMs = 50u;
uci1 28:484943132bb0 62 fPowerMode = kAmpsDatTak|kCardDatTak|kAmpsComWin|kCardComWin|kIridComWin|kAfarComWin;
uci1 0:664899e0b988 63 fBatVoltLowPwr = 0;
uci1 28:484943132bb0 64 fVoltCheckPeriod = 600u;
uci1 28:484943132bb0 65 fCommWinPeriod = 3600u;
uci1 1:e392595b4b76 66 fCommWinDuration = 600u;
uci1 28:484943132bb0 67 fCommSendData = static_cast<int16_t>(kUseBits);
uci1 0:664899e0b988 68 fCommWinPrdLowPwr = 86100u;
uci1 0:664899e0b988 69 fCommWinDurLowPwr = 300u;
uci1 22:f957c4f840ad 70 fWatchDogPeriod = WDFAILSAFE;
uci1 28:484943132bb0 71 SetDefaultIPs();
uci1 8:95a325df1f6b 72 fIsLowPower = false;
uci1 8:95a325df1f6b 73 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 74 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 75
uci1 8:95a325df1f6b 76
uci1 8:95a325df1f6b 77 }
uci1 8:95a325df1f6b 78
uci1 28:484943132bb0 79 void SnConfigFrame::SetDefaultRemoteServ() {
uci1 28:484943132bb0 80 sprintf(fRemoteServer,"%s","128.195.204.151");
uci1 28:484943132bb0 81 }
uci1 28:484943132bb0 82
uci1 28:484943132bb0 83 void SnConfigFrame::SetDefaultRemotePort() {
uci1 28:484943132bb0 84 fRemotePort = 6655;
uci1 28:484943132bb0 85 }
uci1 28:484943132bb0 86
uci1 28:484943132bb0 87 void SnConfigFrame::SetDefaultMbedIP() {
uci1 28:484943132bb0 88 const uint64_t ip = GetMacAddress();
uci1 28:484943132bb0 89 switch (ip) {
uci1 28:484943132bb0 90 case 0x0002F7F0C3B60000: // station 3
uci1 28:484943132bb0 91 sprintf(fMbedIP,"%s","157.132.94.35");
uci1 28:484943132bb0 92 break;
uci1 28:484943132bb0 93 case 0x0002F7F0C41C0000: // station 4
uci1 28:484943132bb0 94 sprintf(fMbedIP,"%s","157.132.94.37");
uci1 28:484943132bb0 95 break;
uci1 28:484943132bb0 96 case 0x0002F7F0AEE00000: // station 5
uci1 28:484943132bb0 97 sprintf(fMbedIP,"%s","157.132.94.39");
uci1 28:484943132bb0 98 break;
uci1 28:484943132bb0 99 case 0x0002F7F0C4450000: // station 6
uci1 28:484943132bb0 100 sprintf(fMbedIP,"%s","157.132.94.41");
uci1 28:484943132bb0 101 break;
uci1 28:484943132bb0 102 case 0x0002F7F0D2880000: // station 7
uci1 28:484943132bb0 103 sprintf(fMbedIP,"%s","157.132.94.43");
uci1 28:484943132bb0 104 break;
uci1 28:484943132bb0 105 case 0x0002F7F0C0F80000: // station 8
uci1 28:484943132bb0 106 sprintf(fMbedIP,"%s","157.132.94.45");
uci1 28:484943132bb0 107 break;
uci1 28:484943132bb0 108 default: // what??
uci1 28:484943132bb0 109 sprintf(fMbedIP,"%s","157.132.94.30"); // anciet station
uci1 28:484943132bb0 110 break;
uci1 28:484943132bb0 111 };
uci1 28:484943132bb0 112 }
uci1 28:484943132bb0 113 // brian dornick 3107
uci1 28:484943132bb0 114 void SnConfigFrame::SetDefaultMaskIP() {
uci1 28:484943132bb0 115 sprintf(fMbedMask,"%s","255.255.255.0");
uci1 28:484943132bb0 116 }
uci1 28:484943132bb0 117
uci1 28:484943132bb0 118 void SnConfigFrame::SetDefaultGateIP() {
uci1 28:484943132bb0 119 sprintf(fMbedGate,"%s","157.132.94.1");
uci1 28:484943132bb0 120 }
uci1 28:484943132bb0 121
uci1 28:484943132bb0 122 void SnConfigFrame::SetDefaultIPs() {
uci1 28:484943132bb0 123 SetDefaultRemoteServ();
uci1 28:484943132bb0 124 SetDefaultRemotePort();
uci1 28:484943132bb0 125 SetDefaultMbedIP();
uci1 28:484943132bb0 126 SetDefaultMaskIP();
uci1 28:484943132bb0 127 SetDefaultGateIP();
uci1 28:484943132bb0 128 }
uci1 28:484943132bb0 129
uci1 28:484943132bb0 130 void SnConfigFrame::ApplySafetyNets() {
uci1 28:484943132bb0 131 if (fNumPlas>kNplas) {
uci1 28:484943132bb0 132 fNumPlas=kNplas;
uci1 28:484943132bb0 133 }
uci1 28:484943132bb0 134 if (fNumCardsMajLog>kNchans) {
uci1 28:484943132bb0 135 fNumCardsMajLog=kNchans;
uci1 28:484943132bb0 136 }
uci1 28:484943132bb0 137 if (fNumCardsMajLog<1u) {
uci1 28:484943132bb0 138 fNumCardsMajLog=1u;
uci1 28:484943132bb0 139 }
uci1 28:484943132bb0 140 if ( (fForceTrigPeriod>0) &&
uci1 28:484943132bb0 141 (fForceTrigPeriod<kMinForcePer) ) {
uci1 28:484943132bb0 142 fForceTrigPeriod = kMinForcePer;
uci1 28:484943132bb0 143 }
uci1 28:484943132bb0 144 if (fEvtThrtlPeriodMs>kMaxThrottlePerMs) {
uci1 28:484943132bb0 145 fEvtThrtlPeriodMs=kMaxThrottlePerMs;
uci1 28:484943132bb0 146 }
uci1 28:484943132bb0 147 if ( (IsPoweredFor(kIridComWin)==false) &&
uci1 28:484943132bb0 148 (IsPoweredFor(kAfarComWin)==false) ) {
uci1 28:484943132bb0 149 EnablePowerFor(kIridComWin);
uci1 28:484943132bb0 150 EnablePowerFor(kAfarComWin);
uci1 28:484943132bb0 151 }
uci1 28:484943132bb0 152 if (fBatVoltLowPwr>kMaxBatVoltLowPwr) {
uci1 28:484943132bb0 153 fBatVoltLowPwr=kMaxBatVoltLowPwr;
uci1 28:484943132bb0 154 }
uci1 28:484943132bb0 155 if (fCommWinPeriod>kMaxCommWinPeriod) {
uci1 28:484943132bb0 156 fCommWinPeriod=kMaxCommWinPeriod;
uci1 28:484943132bb0 157 }
uci1 28:484943132bb0 158 if (fCommWinDuration<kMinCommWinDur) {
uci1 28:484943132bb0 159 fCommWinDuration=kMinCommWinDur;
uci1 28:484943132bb0 160 }
uci1 28:484943132bb0 161 if (fCommWinPrdLowPwr>kMaxCommWinPeriod) {
uci1 28:484943132bb0 162 fCommWinPrdLowPwr=kMaxCommWinPeriod;
uci1 28:484943132bb0 163 }
uci1 28:484943132bb0 164 if (fCommWinDurLowPwr<kMinCommWinDur) {
uci1 28:484943132bb0 165 fCommWinDurLowPwr=kMinCommWinDur;
uci1 28:484943132bb0 166 }
uci1 28:484943132bb0 167 if (fWatchDogPeriod>kMaxWatchDogPer) {
uci1 28:484943132bb0 168 fWatchDogPeriod=kMaxWatchDogPer;
uci1 28:484943132bb0 169 }
uci1 28:484943132bb0 170 if (fWatchDogPeriod<kMinWatchDogPer) {
uci1 28:484943132bb0 171 fWatchDogPeriod=kMinWatchDogPer;
uci1 28:484943132bb0 172 }
uci1 28:484943132bb0 173 }
uci1 28:484943132bb0 174
uci1 21:ce51bb0ba4a5 175 uint32_t SnConfigFrame::GetTimeoutTime(const uint32_t startTime,
uci1 21:ce51bb0ba4a5 176 const uint32_t delta) const {
uci1 21:ce51bb0ba4a5 177 const uint32_t ct = time(0);
uci1 21:ce51bb0ba4a5 178 uint32_t lst = time(0)-startTime;
uci1 21:ce51bb0ba4a5 179 if ( (ct<startTime) || (ct==0) ||
uci1 21:ce51bb0ba4a5 180 (lst>kSecsPerDay) ) {
uci1 21:ce51bb0ba4a5 181 // possible clock problems
uci1 21:ce51bb0ba4a5 182 lst = kDefTimeout;
uci1 21:ce51bb0ba4a5 183 }
uci1 21:ce51bb0ba4a5 184 const uint32_t lio =
uci1 21:ce51bb0ba4a5 185 ((lst+delta) < GetCommWinDuration()) ?
uci1 21:ce51bb0ba4a5 186 lst+delta : GetCommWinDuration();
uci1 21:ce51bb0ba4a5 187 return lio+startTime;
uci1 21:ce51bb0ba4a5 188 }
uci1 21:ce51bb0ba4a5 189
uci1 8:95a325df1f6b 190 void SnConfigFrame::ChangeToLowPower() {
uci1 8:95a325df1f6b 191
uci1 8:95a325df1f6b 192 // save old label
uci1 8:95a325df1f6b 193 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 194
uci1 8:95a325df1f6b 195 // append label
uci1 8:95a325df1f6b 196 // this will allow the new config to be put in the DB
uci1 8:95a325df1f6b 197 int slen = strlen(fLabel);
uci1 8:95a325df1f6b 198 static const char* tag = "_LOWPOW";
uci1 8:95a325df1f6b 199 const int ml = strlen(tag)+1;
uci1 8:95a325df1f6b 200 if (slen > (kConfLblLen-ml) ) {
uci1 8:95a325df1f6b 201 memset(fLabel+kConfLblLen-ml, '\0', ml);
uci1 8:95a325df1f6b 202 }
uci1 8:95a325df1f6b 203 strncat(fLabel, tag, ml-1);
uci1 8:95a325df1f6b 204
uci1 8:95a325df1f6b 205 // save power settings
uci1 8:95a325df1f6b 206 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 207
uci1 8:95a325df1f6b 208 // change power settings
uci1 8:95a325df1f6b 209 DisablePowerFor(kAmpsDatTak);
uci1 8:95a325df1f6b 210 DisablePowerFor(kCardDatTak);
uci1 8:95a325df1f6b 211 DisablePowerFor(kIridDatTak);
uci1 8:95a325df1f6b 212 DisablePowerFor(kAfarDatTak);
uci1 8:95a325df1f6b 213 DisablePowerFor(kAmpsComWin);
uci1 8:95a325df1f6b 214 DisablePowerFor(kCardComWin);
uci1 8:95a325df1f6b 215 if ( (IsPoweredFor(kIridComWin)==false) &&
uci1 8:95a325df1f6b 216 (IsPoweredFor(kAfarComWin)==false) ) {
uci1 8:95a325df1f6b 217 // TODO: turn on only iridum maybe?
uci1 8:95a325df1f6b 218 EnablePowerFor(kIridComWin);
uci1 8:95a325df1f6b 219 EnablePowerFor(kAfarComWin);
uci1 8:95a325df1f6b 220 }
uci1 8:95a325df1f6b 221 // set mode to low power
uci1 8:95a325df1f6b 222 fIsLowPower = true;
uci1 8:95a325df1f6b 223 }
uci1 8:95a325df1f6b 224
uci1 8:95a325df1f6b 225 void SnConfigFrame::ChangeToNormPower() {
uci1 8:95a325df1f6b 226 // put label back
uci1 8:95a325df1f6b 227 memcpy(fLabel, fNormLabel, kConfLblLen);
uci1 8:95a325df1f6b 228 // put power settings back
uci1 8:95a325df1f6b 229 fPowerMode = fNormPowerMode;
uci1 8:95a325df1f6b 230 // set mode to normal
uci1 8:95a325df1f6b 231 fIsLowPower = false;
uci1 0:664899e0b988 232 }
uci1 0:664899e0b988 233
uci1 0:664899e0b988 234 void SnConfigFrame::GetPackParsFor(const EDatPackBit d,
uci1 0:664899e0b988 235 uint8_t& loseLSB, uint8_t& loseMSB,
uci1 0:664899e0b988 236 uint16_t& wvBase) const {
uci1 0:664899e0b988 237 const bool pack = IsDatPackedFor(d);
uci1 0:664899e0b988 238 loseLSB = pack ? GetWvLoseLSB() : 0u;
uci1 0:664899e0b988 239 loseMSB = pack ? GetWvLoseMSB() : 0u;
uci1 0:664899e0b988 240 wvBase = pack ? GetWvBaseline() : 0u;
uci1 0:664899e0b988 241 }
uci1 0:664899e0b988 242
uci1 0:664899e0b988 243 void SnConfigFrame::GetHiLoPlas(const uint16_t pla,
uci1 0:664899e0b988 244 uint16_t& hiPla,
uci1 0:664899e0b988 245 uint16_t& loPla,
uci1 0:664899e0b988 246 const bool r2l) {
uci1 0:664899e0b988 247 // split the PLA bitword into 2: one for the high threshold
uci1 0:664899e0b988 248 // and one for the low threshold. "lows" in the string will become
uci1 0:664899e0b988 249 // "highs" in the low threshold PLA.
uci1 0:664899e0b988 250 //
uci1 0:664899e0b988 251 // example 1)
uci1 0:664899e0b988 252 // PLA string = HLHL....
uci1 0:664899e0b988 253 // hi thresh = H.H.....
uci1 0:664899e0b988 254 // lo thresh = .H.H....
uci1 0:664899e0b988 255 //
uci1 0:664899e0b988 256 // example 2)
uci1 0:664899e0b988 257 // PLA string = HBL.....
uci1 0:664899e0b988 258 // hi thresh = HL......
uci1 0:664899e0b988 259 // lo thresh = .LH.....
uci1 0:664899e0b988 260 //
uci1 0:664899e0b988 261 // (with . = A here, to make the example more readable)
uci1 0:664899e0b988 262 //
uci1 0:664899e0b988 263 // A = 11, B = 00
uci1 0:664899e0b988 264 // H = 01 or 10, alternating
uci1 0:664899e0b988 265 // L = 10 or 01, alternating
uci1 0:664899e0b988 266 // 01 at leftmost bits is H
uci1 0:664899e0b988 267 // for example:
uci1 0:664899e0b988 268 // 0x7FFF = 01 11 11 11 11 11 11 11
uci1 0:664899e0b988 269 // => HAAAAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 270 // => AAAAAAAH for RIGHT TO LEFT
uci1 0:664899e0b988 271 // 0x56FF = 01 01 01 10 11 11 11 11
uci1 0:664899e0b988 272 // => HLHHAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 273 // => AAAAHHLH for RIGHT TO LEFT
uci1 0:664899e0b988 274 //
uci1 0:664899e0b988 275 // so HHHHHHHH is
uci1 0:664899e0b988 276 // 01 10 01 10 01 10 01 10 always (r2l or l2r)
uci1 0:664899e0b988 277 //
uci1 0:664899e0b988 278 // r2l = whether to read bits right to left (true) or not (false)
uci1 0:664899e0b988 279 // Mahshid liked right to left
uci1 0:664899e0b988 280 // Liang liked left to right
uci1 0:664899e0b988 281 // so we allow for either
uci1 0:664899e0b988 282
uci1 0:664899e0b988 283 const int8_t start = (r2l) ? 0 : BITS_IN_SHORT-2;
uci1 0:664899e0b988 284 const int8_t end = (r2l) ? BITS_IN_SHORT : -2;
uci1 0:664899e0b988 285 const int8_t step = (r2l) ? 2 : -2;
uci1 0:664899e0b988 286
uci1 0:664899e0b988 287 uint8_t hi= (r2l) ? 0x2 : 0x1;
uci1 0:664899e0b988 288 uint8_t lo= (r2l) ? 0x1 : 0x2;
uci1 0:664899e0b988 289
uci1 0:664899e0b988 290 // set all bits to 0
uci1 0:664899e0b988 291 hiPla = 0;
uci1 0:664899e0b988 292 loPla = 0;
uci1 0:664899e0b988 293
uci1 0:664899e0b988 294 for (int8_t i=start; i!=end; i+=step, hi^=0x3, lo^=0x3) {
uci1 0:664899e0b988 295 const uint8_t b = (pla & (0x3<<i)) >> i;
uci1 0:664899e0b988 296 if (b==hi) {
uci1 0:664899e0b988 297 hiPla |= hi << i;
uci1 0:664899e0b988 298 loPla |= 0x3 << i;
uci1 0:664899e0b988 299 } else if (b==lo) {
uci1 0:664899e0b988 300 hiPla |= 0x3 << i;
uci1 0:664899e0b988 301 loPla |= hi << i;
uci1 0:664899e0b988 302 } else if (b==0x3) {
uci1 0:664899e0b988 303 // any
uci1 0:664899e0b988 304 hiPla |= 0x3 << i;
uci1 0:664899e0b988 305 loPla |= 0x3 << i;
uci1 0:664899e0b988 306 } else {
uci1 0:664899e0b988 307 // no check that b is something else.. should be impossible.
uci1 0:664899e0b988 308 // between
uci1 0:664899e0b988 309 hiPla |= lo << i;
uci1 0:664899e0b988 310 loPla |= lo << i;
uci1 0:664899e0b988 311 }
uci1 0:664899e0b988 312 }
uci1 0:664899e0b988 313
uci1 0:664899e0b988 314 }
uci1 0:664899e0b988 315
uci1 0:664899e0b988 316 bool SnConfigFrame::ReadFromFile(const char* cfile) {
uci1 0:664899e0b988 317 // intended only for reading default config file
uci1 0:664899e0b988 318
uci1 3:24c5f0f50bf1 319 /*
uci1 3:24c5f0f50bf1 320 DIR* d;
uci1 3:24c5f0f50bf1 321 struct dirent* dent;
uci1 3:24c5f0f50bf1 322 printf("files in /local:\r\n");
uci1 3:24c5f0f50bf1 323 if ( (d = opendir( "/local" ))!=NULL ) {
uci1 3:24c5f0f50bf1 324 while ( (dent = readdir(d))!=NULL ) {
uci1 3:24c5f0f50bf1 325 printf("%s\r\n",dent->d_name);
uci1 3:24c5f0f50bf1 326 }
uci1 3:24c5f0f50bf1 327 closedir(d);
uci1 3:24c5f0f50bf1 328 }
uci1 3:24c5f0f50bf1 329 */
uci1 0:664899e0b988 330 bool ret = false;
uci1 0:664899e0b988 331 FILE* cf = fopen(cfile,"rb");
uci1 0:664899e0b988 332 if (cf!=0) {
uci1 16:744ce85aede2 333 // check the header and file size to be
uci1 16:744ce85aede2 334 // protect a bit against corruption
uci1 16:744ce85aede2 335 uint8_t hc; uint32_t hl;
uci1 16:744ce85aede2 336 SnHeaderFrame::ReadFrom(cf, hc, hl);
uci1 16:744ce85aede2 337 if (hc==SnHeaderFrame::kConfigCode) {
uci1 16:744ce85aede2 338 const int fpos = ftell(cf);
uci1 16:744ce85aede2 339 // how many bytes?
uci1 16:744ce85aede2 340 fseek(cf, 0, SEEK_END); // go to end
uci1 16:744ce85aede2 341 const int fend = ftell(cf);
uci1 16:744ce85aede2 342 fseek(cf, fpos, SEEK_SET); // go back
uci1 16:744ce85aede2 343
uci1 16:744ce85aede2 344 if (hl == fend-fpos) {
uci1 16:744ce85aede2 345 ReadFrom(cf);
uci1 16:744ce85aede2 346 ret = (ferror(cf)==0);
uci1 16:744ce85aede2 347 }
uci1 16:744ce85aede2 348 }
uci1 0:664899e0b988 349 fclose(cf);
uci1 0:664899e0b988 350 }
uci1 0:664899e0b988 351 return ret;
uci1 0:664899e0b988 352 }
uci1 0:664899e0b988 353
uci1 0:664899e0b988 354 bool SnConfigFrame::WriteToFile(const char* cfile) const {
uci1 0:664899e0b988 355 // intended only for writing default config file
uci1 0:664899e0b988 356
uci1 0:664899e0b988 357 bool ret = false;
uci1 0:664899e0b988 358 FILE* cf = fopen(cfile,"wb");
uci1 0:664899e0b988 359 if (cf!=0) {
uci1 0:664899e0b988 360 WriteTo(cf);
uci1 0:664899e0b988 361 ret = (ferror(cf)==0);
uci1 0:664899e0b988 362 fclose(cf);
uci1 0:664899e0b988 363 }
uci1 0:664899e0b988 364 return ret;
uci1 0:664899e0b988 365 }