...
 
Commits (8)
......@@ -7,6 +7,17 @@
<meta content="The OSCAR Team" name="author" >
</head>
<body>
<p>
<b>Changes and fixes in OSCAR v1.X.Y</b>
<br>Portions of OSCAR are © 2019-2020 by
<i>The OSCAR Team</i></p>
<ul>
<li>[new] Additional Philips Respironics devices tested and fully supported:
<ul>
<li>DreamStation BiPAP autoSV (900X150)</li>
</ul>
<li>[fix] Improve support for rare events in 50-series Philips Respironics devices.</li>
</ul>
<p>
<b>Changes and fixes in OSCAR v1.1.1</b>
<br>Portions of OSCAR are © 2019-2020 by
......
......@@ -19,10 +19,10 @@ All systems need a C++ compiler and linker and the QT platform download.
Windows Building: See Building/Windows/BUILD-WIN.md
-----------------
MacOS Building: See Building/Windows/BUILD-mac.md
MacOS Building: See Building/MacOS/BUILD-mac.md
---------------
Linux Building: See Building/Windows/BUILD-Linux-md
Linux Building: See Building/Linux/BUILD-Linux.md
---------------
Software Licensing Information
......@@ -30,9 +30,9 @@ Software Licensing Information
OSCAR is released under the GNU GPL v3 License. Please see below for a note on giving correct attribution
in redistribution of derivatives.
It is built using Qt SDK (Open Source Edition), available from http://qt.io.
It is built using Qt SDK (Open Source Edition), available from https://qt.io.
Redistribution of derivatives ( a note added by Mark Watins )
Redistribution of derivatives ( a note added by Mark Watkins )
-----------------------------
Mark Watkins created this software to help lessen the exploitation of others. Seeing his work being used to exploit others
is incredibly un-motivational, and incredibly disrespectful of all the work he put into this project.
......
......@@ -295,6 +295,7 @@ static const PRS1TestedModel s_PRS1TestedModels[] = {
{ "960T", 5, 2, "BiPAP autoSV Advanced 30 (System One 60 Series)" }, // omits "(System One 60 Series)" on official reports
{ "900X110", 5, 3, "DreamStation BiPAP autoSV" },
{ "900X120", 5, 3, "DreamStation BiPAP autoSV" },
{ "900X150", 5, 3, "DreamStation BiPAP autoSV" },
{ "1061401", 3, 0, "BiPAP S/T (C Series)" },
{ "1061T", 3, 3, "BiPAP S/T 30 (System One 60 Series)" },
......@@ -3602,23 +3603,33 @@ bool PRS1DataChunk::ParseEventsF0V23()
break;
}
startpos = pos;
if (code != 0x12) { // This one event has no timestamp in F0V6
t += data[pos] | (data[pos+1] << 8);
if (code != 0x12 && code != 0x01) { // This one event has no timestamp in F0V6
elapsed = data[pos] | (data[pos+1] << 8);
if (elapsed > 0x7FFF) UNEXPECTED_VALUE(elapsed, "<32768s"); // check whether this is generally unsigned, since 0x01 isn't
t += elapsed;
pos += 2;
}
switch (code) {
case 0x00: // ??? So far only seen on 451P and 551P occasionally, usually no more than once per session
// A nonzero delta corresponds to an N-second gap in data (value was 0x85, only seen once). Look for more.
if (sessionid != 122) CHECK_VALUE(data[startpos], 0); // skip the onc occurrence already seen
CHECK_VALUE(data[startpos+1], 0);
if (data[pos] < 0x80 || data[pos] > 0x85) {
UNEXPECTED_VALUE(data[pos], "0x80-0x85");
DUMP_EVENT();
}
case 0x00: // Humidifier setting change (logged in summary in 60 series)
ParseHumidifierSetting50Series(data[pos]);
if (this->familyVersion == 3) DUMP_EVENT();
break;
//case 0x01: // never seen
case 0x01: // Time elapsed?
// Only seen once, on a 550P.
// It looks almost like a time-elapsed event 4 found in F0V4 summaries, but
// 0xFFCC looks like it represents a time adjustment of -52 seconds,
// since the subsequent 0x11 statistics event has a time offset of 172 seconds,
// and counting this as -52 seconds results in a total session time that
// matches the summary and waveform data. Very weird.
CHECK_VALUE(data[pos], 0xCC);
CHECK_VALUE(data[pos+1], 0xFF);
elapsed = data[pos] | (data[pos+1] << 8);
if (elapsed & 0x8000) {
elapsed = (~0xFFFF | elapsed); // sign extend 16-bit number to native int
}
t += elapsed;
break;
case 0x02: // Pressure adjustment
// See notes in ParseEventsF0V6.
this->AddEvent(new PRS1PressureSetEvent(t, data[pos]));
......@@ -5083,7 +5094,7 @@ bool PRS1DataChunk::ParseSummaryF0V4(void)
CHECK_VALUE(chunk_size, 1); // and the only record in the session.
if (this->sessionid == 1) UNEXPECTED_VALUE(this->sessionid, ">1");
break;
case 7: // Humidifier setting change
case 7: // Humidifier setting change (logged in events in 50 series)
tt += data[pos] | (data[pos+1] << 8); // This adds to the total duration (otherwise it won't match report)
this->ParseHumidifierSetting60Series(data[pos+2], data[pos+3]);
break;
......@@ -6783,8 +6794,7 @@ void PRS1DataChunk::ParseHumidifierSettingV3(unsigned char byte1, unsigned char
// All variations seen.
} else if (family == 5) {
if (tubepresent) {
if (tubetemp != 0 && tubetemp > 4) UNEXPECTED_VALUE(tubetemp, "<= 4");
// All humidity levels seen.
// All tube temperature and humidity levels seen.
} else if (humidadaptive) {
// All humidity levels seen.
} else if (humidfixed) {
......@@ -8689,7 +8699,7 @@ bool PRS1DataChunk::ReadHeader(QFile & f)
// Do a few early sanity checks before any variable-length header data.
if (this->blockSize == 0) {
qWarning() << this->m_path << "blocksize 0?";
qWarning() << this->m_path << "@" << hex << this->m_filepos << "blocksize 0, skipping remainder of file";
break;
}
if (this->fileVersion < 2 || this->fileVersion > 3) {
......
......@@ -824,57 +824,6 @@ QStringList getDriveList()
}
}
}
#elif defined(Q_OS_MAC) || defined(Q_OS_BSD4)
struct statfs *mounts;
int num_mounts = getmntinfo(&mounts, MNT_WAIT);
if (num_mounts >= 0) {
for (int i = 0; i < num_mounts; i++) {
QString name = mounts[i].f_mntonname;
// Only interested in drives mounted under /Volumes
if (name.toLower().startsWith("/volumes/")) {
drivelist.push_back(name);
// qDebug() << QString("Disk type '%1' mounted at: %2").arg(mounts[i].f_fstypename).arg(mounts[i].f_mntonname);
}
}
}
#elif defined(Q_OS_UNIX) && !defined(Q_OS_HAIKU)
// Unix / Linux (except BSD)
FILE *mtab = setmntent("/etc/mtab", "r");
struct mntent *m;
struct mntent mnt;
char strings[4096];
// NOTE: getmntent_r is a GNU extension, requiring glibc.
while ((m = getmntent_r(mtab, &mnt, strings, sizeof(strings)))) {
struct statfs fs;
if ((mnt.mnt_dir != NULL) && (statfs(mnt.mnt_dir, &fs) == 0)) {
QString name = mnt.mnt_dir;
quint64 size = fs.f_blocks * fs.f_bsize;
if (size > 0) { // this should theoretically ignore /dev, /proc, /sys etc..
drivelist.push_back(name);
}
// quint64 free = fs.f_bfree * fs.f_bsize;
// quint64 avail = fs.f_bavail * fs.f_bsize;
}
}
endmntent(mtab);
#elif defined(Q_OS_WIN) || defined(Q_OS_HAIKU)
QFileInfoList list = QDir::drives();
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
QString name = fileInfo.filePath();
if (name.at(0).toUpper() != QChar('C')) { // Ignore the C drive
drivelist.push_back(name);
}
}
#endif
return drivelist;
}
......
This diff is collapsed.