Update PRS1 ParseComplianceF0V23 to use the same event loop structure as ParseSummaryF0V23.

No change in functionality.
This commit is contained in:
sawinglogz 2019-10-24 11:44:47 -04:00
parent d6e4e42f2a
commit 8297760fa8
2 changed files with 64 additions and 60 deletions

View File

@ -3928,77 +3928,81 @@ bool PRS1DataChunk::ParseComplianceF0V23(void)
// We should flag an actual familyVersion 3 file if we ever encounter one! // We should flag an actual familyVersion 3 file if we ever encounter one!
CHECK_VALUE(this->familyVersion, 2); CHECK_VALUE(this->familyVersion, 2);
// TODO: hardcoding this is ugly, think of a better approach
if (this->m_data.size() < 0x13) {
qWarning() << this->sessionid << "compliance data too short:" << this->m_data.size();
return false;
}
const unsigned char * data = (unsigned char *)this->m_data.constData(); const unsigned char * data = (unsigned char *)this->m_data.constData();
int chunk_size = this->m_data.size();
static const int minimum_sizes[] = { 0xd, 5, 2, 2 };
static const int ncodes = sizeof(minimum_sizes) / sizeof(int);
// NOTE: These are fixed sizes, but are called minimum to more closely match the F0V6 parser.
CHECK_VALUE(data[0x00], 0); bool ok = true;
if (data[0x00] != 0) { int pos = 0;
if (data[0x00] != 5) { int code, size, delta;
qDebug() << this->sessionid << "compliance first byte" << data[0x00] <<" != 0, skipping"; int tt = 0;
}
return false;
}
CHECK_VALUES(data[0x01], 1, 0); // usually 1, occasionally 0, no visible difference in report
ParseSettingsF0V23(data, 0x0e);
// Note that reports don't show mask resist settings or hose diameter, even though the underlying
// settings have mask resist off and locked and hose diameter of 22mm.
// TODO: Where is "Altitude Compensation" set? (seems to be 1/Low), only seen on brick report
// TODO: Where is Mask Reminder Period set? (off)
// List of slices, really session-related events:
int start = 0;
int tt = start;
int len = this->size()-3;
int pos = 0x0e;
do { do {
quint8 c = data[pos++]; code = data[pos++];
// These aren't really slices as originally thought, they're events with a delta offset. // There is no hblock prior to F0V6.
// We'll convert them to slices in the importer. size = 0;
int delta = data[pos] | data[pos+1] << 8; if (code < ncodes) {
pos+=2; // make sure the handlers below don't go past the end of the buffer
SliceStatus status; size = minimum_sizes[code];
if (c == 0x02) { } // else if it's past ncodes, we'll log its information below (rather than handle it)
status = MaskOn; if (pos + size > chunk_size) {
qWarning() << this->sessionid << "slice" << code << "@" << pos << "longer than remaining chunk";
ok = false;
break;
}
switch (code) {
case 0: // Equipment On
CHECK_VALUE(pos, 1); // Always first
CHECK_VALUES(data[pos], 1, 0); // usually 1, occasionally 0, no visible difference in report
// F0V23 doesn't have a separate settings record like F0V6 does, the settings just follow the EquipmentOn data.
ok = ParseSettingsF0V23(data, 0x0e);
// Compliance doesn't have pressure set events following settings like summary does.
break;
case 2: // Mask On
delta = data[pos] | (data[pos+1] << 8);
if (tt == 0) { if (tt == 0) {
CHECK_VALUE(delta, 0); // we've never seen the initial MaskOn have any delta CHECK_VALUE(delta, 0); // we've never seen the initial MaskOn have any delta
} else { } else {
if (delta % 60) UNEXPECTED_VALUE(delta, "even minutes"); // mask-off events seem to be whole minutes? if (delta % 60) UNEXPECTED_VALUE(delta, "even minutes"); // mask-off events seem to be whole minutes?
} }
} else if (c == 0x03) { tt += data[pos] | (data[pos+1] << 8);
status = MaskOff; this->AddEvent(new PRS1ParsedSliceEvent(tt, MaskOn));
} else if (c == 0x01) { // no per-slice humidifer settings as in F0V6
status = EquipmentOff;
// This has a delta if the mask was removed before the machine was shut off.
} else {
qDebug() << this->sessionid << "unknown slice status" << c;
break; break;
} case 3: // Mask Off
tt += delta; tt += data[pos] | (data[pos+1] << 8);
this->AddEvent(new PRS1ParsedSliceEvent(tt, status)); this->AddEvent(new PRS1ParsedSliceEvent(tt, MaskOff));
} while (pos < len); // Compliance doesn't record any stats after mask-off like summary does.
break;
case 1: // Equipment Off
tt += data[pos] | (data[pos+1] << 8);
this->AddEvent(new PRS1ParsedSliceEvent(tt, EquipmentOff));
// also seems to be a trailing 01 00 81 after the slices? // also seems to be a trailing 01 00 81 after the slices?
if (pos == len) { CHECK_VALUES(data[pos+2], 1, 0); // usually 1, occasionally 0, no visible difference in report
CHECK_VALUES(data[pos], 1, 0); // usually 1, occasionally 0, no visible difference in report //CHECK_VALUE(data[pos+3], 0); // sometimes 1, 2, or 5, no visible difference in report
//CHECK_VALUE(data[pos+1], 0); // sometimes 1, 2, or 5, no visible difference in report //CHECK_VALUES(data[pos+4], 0x81, 0x80); // seems to be humidifier setting at end of session
//CHECK_VALUES(data[pos+2], 0x81, 0x80); // seems to be humidifier setting at end of session if (data[pos+4] && (((data[pos+4] & 0x80) == 0) || (data[pos+4] & 0x07) > 5)) {
if (data[pos+2] && (((data[pos+2] & 0x80) == 0) || (data[pos+2] & 0x07) > 5)) { UNEXPECTED_VALUE(data[pos+4], "valid humidifier setting");
UNEXPECTED_VALUE(data[pos+2], "valid humidifier setting");
} }
} else { break;
default:
UNEXPECTED_VALUE(code, "known slice code");
ok = false; // unlike F0V6, we don't know the size of unknown slices, so we can't recover
break;
}
pos += size;
} while (ok && pos < chunk_size);
if (ok && pos != chunk_size) {
qWarning() << this->sessionid << (this->size() - pos) << "trailing bytes"; qWarning() << this->sessionid << (this->size() - pos) << "trailing bytes";
} }
this->duration = tt; this->duration = tt;
return true; return ok;
} }

View File

@ -336,7 +336,7 @@ void parseAndEmitChunkYaml(const QString & path)
void PRS1Tests::testChunksToYaml() void PRS1Tests::testChunksToYaml()
{ {
//iterateTestCards(TESTDATA_PATH "prs1/input/", parseAndEmitChunkYaml); iterateTestCards(TESTDATA_PATH "prs1/input/", parseAndEmitChunkYaml);
} }