-
{updateText.NEEDS_UPDATED}
-
{updateText.IMPROVEMENTS}
-
- Follow these instructions to do so.
-
+
+
+
+
{updateText.NEEDS_UPDATED}
+
{updateText.IMPROVEMENTS}
+
+ Follow these instructions to do so.
+
+
);
diff --git a/app/containers/App.js b/app/containers/App.js
index ab8c3014e5..25a91091a7 100644
--- a/app/containers/App.js
+++ b/app/containers/App.js
@@ -123,16 +123,33 @@ export class App extends Component {
log: this.log
});
+ const addServers = (servers) => {
+ if (servers && servers.length && servers.length > 0) {
+ for (let server of servers) {
+ const protocol = server.name === 'localhost' ? 'http://' : 'https://';
+ const url = protocol + server.name + ':' + server.port;
+ serverdata[server.name] = {
+ API_URL: url,
+ UPLOAD_URL: url,
+ DATA_URL: url + '/dataservices',
+ BLIP_URL: url,
+ };
+ }
+ } else {
+ this.log('No servers found');
+ }
+ };
+
dns.resolveSrv('environments-srv.tidepool.org', (err, servers) => {
- for (let server of servers) {
- const protocol = server.name === 'localhost' ? 'http://' : 'https://';
- const url = protocol + server.name + ':' + server.port;
- serverdata[server.name] = {
- API_URL: url,
- UPLOAD_URL: url,
- DATA_URL: url + '/dataservices',
- BLIP_URL: url,
- };
+ if (err) {
+ this.log(`DNS resolver error: ${err}. Retrying...`);
+ dns.resolveSrv('environments-srv.tidepool.org', (err2, servers2) => {
+ if (!err2) {
+ addServers(servers2);
+ }
+ });
+ } else {
+ addServers(servers);
}
});
diff --git a/app/main.dev.js b/app/main.dev.js
index 163d427669..b141dcb472 100755
--- a/app/main.dev.js
+++ b/app/main.dev.js
@@ -1,7 +1,8 @@
/* global __ROLLBAR_POST_TOKEN__ */
import _ from 'lodash';
-import { app, BrowserWindow, Menu, shell, ipcMain, crashReporter } from 'electron';
+import { app, BrowserWindow, Menu, shell, ipcMain, crashReporter, dialog } from 'electron';
import os from 'os';
+import osName from 'os-name';
import open from 'open';
import { autoUpdater } from 'electron-updater';
import * as chromeFinder from 'chrome-launcher/dist/chrome-finder';
@@ -106,7 +107,23 @@ app.on('ready', async () => {
mainWindow.loadURL(`file://${__dirname}/app.html`);
- mainWindow.webContents.on('did-finish-load', () => {
+ mainWindow.webContents.on('did-finish-load', async () => {
+ if (osName() === 'Windows 7') {
+ const options = {
+ type: 'info',
+ title: 'Please update to a modern operating system',
+ message:
+ `Windows 7 won't be patched for any new viruses or security problems
+going forward.
+
+While Windows 7 will continue to work, Microsoft recommends you
+start planning to upgrade to Windows 10, or an alternative
+operating system, as soon as possible.`,
+ buttons: ['Continue']
+ };
+ await dialog.showMessageBox(options);
+ }
+
mainWindow.show();
mainWindow.focus();
checkUpdates();
diff --git a/app/package.json b/app/package.json
index d5f73399c1..710245d98c 100644
--- a/app/package.json
+++ b/app/package.json
@@ -1,7 +1,7 @@
{
"name": "tidepool-uploader",
"productName": "tidepool-uploader",
- "version": "2.27.0",
+ "version": "2.28.0",
"description": "Tidepool Project Universal Uploader",
"main": "./main.prod.js",
"author": {
diff --git a/app/reducers/devices.js b/app/reducers/devices.js
index ad2eee240d..2a438052b5 100644
--- a/app/reducers/devices.js
+++ b/app/reducers/devices.js
@@ -111,6 +111,13 @@ const devices = {
source: {type: 'device', driverId: 'BayerContourNext'},
enabled: {mac: true, win: true, linux: true}
},
+ bayercontour: {
+ instructions: 'Plug in meter with cable and make sure meter is switched on',
+ key: 'bayercontour',
+ name: 'Ascensia (Bayer) Contour Next EZ, Contour or Contour Link',
+ source: {type: 'device', driverId: 'BayerContour'},
+ enabled: {mac: true, win: true, linux: true}
+ },
animas: {
instructions: 'Suspend and align back of pump with IR dongle front',
key: 'animas',
diff --git a/docs/checklists/bayerContour.md b/docs/checklists/bayerContour.md
new file mode 100644
index 0000000000..e6b1d82ef2
--- /dev/null
+++ b/docs/checklists/bayerContour.md
@@ -0,0 +1,39 @@
+## Checklist for Blood Glucose Meter Implementation
+
+(Key:
+
+ - `[x]` available in data protocol/documented in spec and implemented
+ - `[-]` available in data protocol/documented in spec but *not* yet implemented
+ - `[?]` unknown whether available in data protocol/documented in spec; *not* yet implemented
+ - `*[ ]` TODO: needs implementation!
+ - `[ ]` unavailable in data protocol and/or not documented in spec and not yet implemented)
+
+### Required if Present
+
+- `[x]` smbg values
+- `[x]` units of smbg values (read from device, not hard-coded)
+- `[x]` out-of-range values (LO or HI)
+- `[x]` out-of-range value thresholds (e.g., often 20 for low and 600 for high on BGMs)
+- `[ ]` date & time settings changes
+- `[ ]` blood ketone values
+- `[ ]` units of blood ketone values (read from device, not hard-coded)
+- `[ ]` ketone out-of-range values
+- `[ ]` ketone out-of-range value thresholds
+- `[x]` use `common.checkDeviceTime(currentDeviceTime, timezone, cb)` to check against server time
+
+### No Tidepool Data Model Yet
+
+- `[x]` control (solution) tests (whether marked in UI or auto-detected) - until we have a data model, these should be discarded
+- `[ ]` device settings, other than date & time (e.g., target blood glucose range)
+- `[-]` tag/note (e.g., pre- vs. post-meal)
+
+### Tidepool ingestion API
+
+Choose one of the following:
+
+ - `[ ]` legacy "jellyfish" ingestion API
+ - `[x]` platform ingestion API
+
+### Known implementation issues/TODOs
+
+*Use this space to describe device-specific known issues or implementation TODOs **not** contained in the above datatype-specific sections.*
diff --git a/docs/checklists/caresensNPremierBluetooth.md b/docs/checklists/caresensNPremierBluetooth.md
index 96d92a46f9..69d577b9ad 100644
--- a/docs/checklists/caresensNPremierBluetooth.md
+++ b/docs/checklists/caresensNPremierBluetooth.md
@@ -37,3 +37,5 @@ Choose one of the following:
### Known implementation issues/TODOs
*Use this space to describe device-specific known issues or implementation TODOs **not** contained in the above datatype-specific sections.*
+
+It is not possible to distinguish between CareSens models when uploading via Bluetooth, as the Bluetooth advertising name for Premier and Dual meters uses the same format ("CareSens + 4 digits")
diff --git a/lib/core/device.js b/lib/core/device.js
index 2c5ba8abff..cd5973d503 100644
--- a/lib/core/device.js
+++ b/lib/core/device.js
@@ -46,6 +46,7 @@ import abbottFreeStyleLite from '../drivers/abbott/abbottFreeStyleLite';
import abbottFreeStyleLibre from '../drivers/abbott/abbottFreeStyleLibre';
import abbottFreeStyleNeo from '../drivers/abbott/abbottFreeStyleNeo';
import bayerContourNext from '../drivers/bayer/bayerContourNext';
+import bayerContour from '../drivers/bayer/bayerContour';
import animasDriver from '../drivers/animas/animasDriver';
import medtronicDriver from '../drivers/medtronic/medtronicDriver';
import medtronic600Driver from '../drivers/medtronic600/medtronic600Driver';
@@ -76,6 +77,7 @@ device.deviceDrivers = {
AbbottFreeStyleLibre: abbottFreeStyleLibre,
AbbottFreeStyleNeo: abbottFreeStyleNeo,
BayerContourNext: bayerContourNext,
+ BayerContour: bayerContour,
Animas: animasDriver,
Medtronic: medtronicDriver,
Medtronic600: medtronic600Driver,
@@ -96,6 +98,7 @@ device.deviceComms = {
AbbottFreeStyleNeo: hidDevice,
Tandem: serialDevice,
BayerContourNext: hidDevice,
+ BayerContour: serialDevice,
Animas: serialDevice,
Medtronic: hidDevice,
Medtronic600: hidDevice,
@@ -180,6 +183,13 @@ device.driverManifests = {
{ vendorId: 6777, productId: 30720 }, // Bayer Contour Next One
],
},
+ BayerContour: {
+ mode: 'serial',
+ usb: [
+ { vendorId: 6777, productId: 24577, driver: 'ftdi' }, // Official Bayer cable
+ { vendorId: 1027, productId: 24577, driver: 'ftdi' }, // FTDI cable
+ ],
+ },
Animas: {
mode: 'serial',
bitrate: 9600,
@@ -393,12 +403,21 @@ device.detectUsbSerial = (driverId, cb) => {
const getDevice = (results) => {
const devices = _.map(results, (result) => {
+ let userSpaceDriver = null;
+ for (let i = 0; i < driverManifest.usb.length; i++) {
+ if (driverManifest.usb[i].vendorId === parseInt(result.vendorId, 16)
+ && driverManifest.usb[i].productId === parseInt(result.productId, 16)) {
+ userSpaceDriver = driverManifest.usb[i].driver;
+ }
+ }
+
const retval = {
driverId,
vendorId: result.vendorId,
productId: result.productId,
usbDevice: result.device,
- path: result.comName,
+ userSpaceDriver,
+ path: result.path,
};
if (driverManifest.bitrate) {
retval.bitrate = driverManifest.bitrate;
@@ -437,7 +456,7 @@ device.detectUsbSerial = (driverId, cb) => {
if (driverManifest.usb[i].vendorId === vendorId
&& driverManifest.usb[i].productId === productId) {
if (device.os === 'mac') {
- if (matching.comName.match('/dev/tty.+')) {
+ if (matching.path.match('/dev/tty.+')) {
return true;
}
} else {
diff --git a/lib/drivers/bayer/.eslintrc b/lib/drivers/bayer/.eslintrc
new file mode 100644
index 0000000000..a129ab0552
--- /dev/null
+++ b/lib/drivers/bayer/.eslintrc
@@ -0,0 +1,74 @@
+{
+ "extends": "airbnb",
+ "parser": "babel-eslint",
+ "plugins": ["lodash"],
+ "parserOptions": {
+ "ecmaVersion": 6
+ },
+ "rules": {
+ "max-len": "warn",
+ "import/order": "warn",
+ "no-plusplus": [
+ "error",
+ {
+ "allowForLoopAfterthoughts": true
+ }
+ ],
+ "lodash/prefer-lodash-method": "off",
+ "arrow-parens": "warn",
+ "operator-linebreak": "warn",
+ "no-else-return": "warn",
+ "object-curly-newline": "warn",
+ "implicit-arrow-linebreak": "warn"
+ },
+ "overrides": [
+ {
+ "files": [
+ "bayerContourNext.js",
+ ],
+ "rules": {
+ "func-names": "warn",
+ "no-var": "warn",
+ "vars-on-top": "warn",
+ "no-unused-vars": "warn",
+ "object-shorthand": "warn",
+ "comma-dangle": "warn",
+ "space-before-function-paren": "warn",
+ "no-param-reassign": "warn",
+ "prefer-template": "warn",
+ "no-useless-escape": "warn",
+ "keyword-spacing": "warn",
+ "indent": "warn",
+ "spaced-comment": "warn",
+ "eqeqeq": "warn",
+ "space-infix-ops": "warn",
+ "prefer-arrow-callback": "warn",
+ "no-shadow": "warn",
+ "array-bracket-spacing": "warn",
+ "no-use-before-define": "warn",
+ "no-else-return": "warn",
+ "no-bitwise": "warn",
+ "consistent-return": "warn",
+ "no-plusplus": "warn",
+ "no-continue": "warn",
+ "no-loop-func": "warn",
+ "object-curly-spacing": "warn",
+ "key-spacing": "warn",
+ "padded-blocks": "warn",
+ "no-console": "warn",
+ "no-multi-spaces": "warn",
+ "no-mixed-operators": "warn",
+ "max-len": "warn",
+ "prefer-destructuring": "warn",
+ "no-buffer-constructor": "warn",
+ "no-restricted-syntax": "warn",
+ "camelcase": "warn",
+ "no-underscore-dangle": "warn"
+ }
+ }
+ ],
+ "settings": {
+ "lodash": 3,
+ "import/resolver": node
+ }
+}
diff --git a/lib/drivers/bayer/bayerConstants.js b/lib/drivers/bayer/bayerConstants.js
new file mode 100644
index 0000000000..d2fc9f539e
--- /dev/null
+++ b/lib/drivers/bayer/bayerConstants.js
@@ -0,0 +1,62 @@
+/*
+ * == BSD2 LICENSE ==
+ * Copyright (c) 2020, Tidepool Project
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the associated License, which is identical to the BSD 2-Clause
+ * License as published by the Open Source Initiative at opensource.org.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the License for more details.
+ *
+ * You should have received a copy of the License along with this program; if
+ * not, you can obtain one from Tidepool Project at tidepool.org.
+ * == BSD2 LICENSE ==
+ */
+
+export const ASCII_CONTROL = {
+ ACK: 0x06,
+ CR: 0x0D,
+ ENQ: 0x05,
+ EOT: 0x04,
+ ETB: 0x17,
+ ETX: 0x03,
+ LF: 0x0A,
+ NAK: 0x15,
+ STX: 0x02,
+ CAN: 0x18,
+};
+
+export const MODELS = {
+ Bayer6200: 'Contour Next Link', // mg/dL
+ Bayer6210: 'Contour Next Link 2.4', // mg/dL
+ Bayer6300: 'Contour Next Link', // mmol/L
+ Bayer7350: 'Contour Next', // mg/dL & mmol/L
+ Bayer7390: 'Contour USB', // mg/dL
+ Bayer7410: 'Contour Next USB', // mg/dL & mmol/L
+ Contour7800: 'Contour Next One', // mg/dL & mmol/L
+ Bayer7150: 'Contour',
+ Bayer7160: 'Contour Next EZ',
+ Bayer7220: 'Contour',
+ Bayer7600: 'Contour Plus',
+};
+
+export const COMMANDS = {
+ READ: [0x52, 0x7c], // R|
+ WRITE: [0x57, 0x7c], // W|
+ DATE: [0x44, 0x7c], // D|
+ TIME: [0x54, 0x7c], // T|
+};
+
+export const METHODS = {
+ B: 'whole blood',
+ P: 'plasma',
+ C: 'capillary',
+};
+
+export const MARKS = {
+ B: 'pre-meal',
+ A: 'post-meal',
+ D: 'logbook',
+};
diff --git a/lib/drivers/bayer/bayerContour.js b/lib/drivers/bayer/bayerContour.js
new file mode 100644
index 0000000000..2d187f3f50
--- /dev/null
+++ b/lib/drivers/bayer/bayerContour.js
@@ -0,0 +1,585 @@
+/*
+ * == BSD2 LICENSE ==
+ * Copyright (c) 2020, Tidepool Project
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the associated License, which is identical to the BSD 2-Clause
+ * License as published by the Open Source Initiative at opensource.org.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the License for more details.
+ *
+ * You should have received a copy of the License along with this program; if
+ * not, you can obtain one from Tidepool Project at tidepool.org.
+ * == BSD2 LICENSE ==
+ */
+
+/* eslint-disable no-param-reassign */
+
+import _ from 'lodash';
+import async from 'async';
+import sundial from 'sundial';
+
+import structJs from '../../struct';
+import annotate from '../../eventAnnotations';
+import TZOUtil from '../../TimezoneOffsetUtil';
+import common from '../../commonFunctions';
+import {
+ MODELS, ASCII_CONTROL, COMMANDS, METHODS, MARKS,
+} from './bayerConstants';
+
+const isBrowser = typeof window !== 'undefined';
+// eslint-disable-next-line no-console
+const debug = isBrowser ? require('bows')('BCDriver') : console.log;
+
+const struct = structJs();
+
+module.exports = (config) => {
+ const cfg = _.clone(config);
+ const serialDevice = config.deviceComms;
+ let retries = 0;
+
+ cfg.tzoUtil = new TZOUtil(cfg.timezone, new Date().toISOString(), []);
+ _.assign(cfg.deviceInfo, {
+ tags: ['bgm'],
+ manufacturers: ['Bayer'],
+ });
+
+ const extractPacket = (bytes) => {
+ // all packets passed the bcnPacketHandler validation are valid, the checksum is verified later
+ const packet = {
+ bytes,
+ valid: false,
+ packet_len: 0,
+ payload: null,
+ };
+
+ const packetLength = bytes.length;
+ packet.packet_len = packetLength;
+ packet.valid = true;
+
+ return packet;
+ };
+
+ const bcnPacketHandler = (buffer) => {
+ if (buffer.len() < 1) { // only empty buffer is no valid packet
+ return false;
+ }
+
+ const packet = extractPacket(buffer.bytes());
+ if (packet.packet_len !== 0) {
+ // cleanup the buffer data
+ buffer.discard(packet.packet_len);
+ }
+
+ if (packet.valid) {
+ return packet;
+ }
+ return null;
+ };
+
+ const buildPacket = (command, cmdlength) => {
+ const datalen = cmdlength;
+ const buf = new ArrayBuffer(datalen);
+ const bytes = new Uint8Array(buf);
+
+ if (cmdlength === 1) {
+ struct.storeByte(command, bytes, 0);
+ } else {
+ const ctr = struct.copyBytes(bytes, 0, command, cmdlength);
+ struct.storeByte(0x0D, bytes, ctr); // add carriage return
+ }
+ debug('Sending byte(s):', common.bytes2hex(bytes));
+ return buf;
+ };
+
+ const packetParser = (result) => {
+ if (result != null) {
+ const tostr = _.map(result,
+ (e) => String.fromCharCode(e)).join('');
+ result.payload = tostr;
+ return result;
+ }
+ return null;
+ };
+
+ const buildCmdWithParser = (cmd, length) => ({
+ packet: buildPacket(cmd, length),
+ parser: packetParser,
+ });
+
+ const buildCmd = (cmd, length) => ({
+ packet: buildPacket(cmd, length),
+ parser: (result) => result,
+ });
+
+ const verifyChecksum = (record) => {
+ const str = record.trim();
+ const data = str.split(String.fromCharCode(ASCII_CONTROL.ETB));
+ const check = data[1];
+ let sum = 0;
+ const n = record.slice(0, record.length - 3);
+
+ _.map(n, (e) => {
+ if (e.charCodeAt(0) !== ASCII_CONTROL.STX) {
+ sum += e.charCodeAt(0);
+ }
+ });
+
+ if ((sum % 256) !== parseInt(check, 16)) {
+ return null;
+ }
+ return data[0];
+ };
+
+ const parseHeader = (s) => {
+ const data = s.split('\n').filter((e) => e.length > 1);
+ const header = data.shift();
+
+ if (verifyChecksum(header)) {
+ data.shift(); // patient not used
+ data.pop(); // remove linefeed
+ const pString = header.split('|');
+ const pInfo = pString[4].split('^');
+ const sNum = pInfo[2];
+ const records = data.filter((e) => e[2] === 'R');
+ const recordAverage = records.shift(); // the first record means the average
+ const ordRecords = data.filter((e) => e[2] === 'O');
+
+ const devInfo = {
+ model: pInfo[0],
+ serialNumber: sNum,
+ nrecs: records.length,
+ recordA: recordAverage,
+ rawrecords: records,
+ ordRecords,
+ };
+
+ return devInfo;
+ }
+ return null;
+ };
+
+ const parseDataRecord = (str, callback) => {
+ const data = verifyChecksum(str);
+ if (data) {
+ debug('Record:', data);
+ const result = data.trim().match(/^.*\d+R\|(\d+).*Glucose\|(\d+\.?\d*)\|(\w+\/\w+)\^(\w*)\|\d*\|(>|<|T|>\\T|<\\T|)\|(\w*)\|(\w*)\|{3}(\d{12})$/);
+ if (result != null) {
+ return callback(null, result.slice(1, 10));
+ }
+ }
+ return callback(new Error('Invalid record data'));
+ };
+
+ const getAnnotations = (annotation, value, units) => {
+ if (annotation.indexOf('>') !== -1) {
+ return [{
+ code: 'bg/out-of-range',
+ threshold: units === 'mg/dL' ? value - 1 : _.round(18 * (value - 0.05)),
+ value: 'high',
+ }];
+ } if (annotation.indexOf('<') !== -1) {
+ return [{
+ code: 'bg/out-of-range',
+ threshold: units === 'mg/dL' ? value + 1 : _.round(18 * (value + 0.05)),
+ value: 'low',
+ }];
+ }
+ return null;
+ };
+
+ const isControl = (markers) => {
+ if (markers.indexOf('E') !== -1) {
+ debug('Marking as control test');
+ return true;
+ }
+ return false;
+ };
+
+ const getOneRecord = (record, data, callback) => {
+ parseDataRecord(record, (err, r) => {
+ if (err) {
+ debug('Failure trying to read record', record);
+ debug(err);
+ return callback(err, null);
+ }
+ const [nrec, glucose, units, referenceMethod, annotations, userMarks, control, timestamp] = r;
+ const value = units === 'mg/dL' ? parseInt(glucose, 10) : parseFloat(glucose);
+ const robj = {
+ timestamp: parseInt(timestamp, 10),
+ annotations: getAnnotations(annotations, value, units),
+ control: isControl(control),
+ units,
+ glucose: value,
+ nrec: parseInt(nrec, 10),
+ referenceMethod: METHODS[referenceMethod],
+ userMarks: MARKS[userMarks],
+ };
+ return callback(null, robj);
+ });
+ };
+
+ const listenForPacket = (timeout, callback) => {
+ let listenTimer = null;
+
+ const abortTimeout = () => {
+ clearInterval(listenTimer);
+ debug('TIMEOUT');
+ callback('Timeout error. Is the meter switched on?', null);
+ };
+
+ const raw = [];
+ let abortTimer = setTimeout(abortTimeout, timeout);
+
+ listenTimer = setInterval(() => {
+ if (serialDevice.hasAvailablePacket()) {
+ // reset abort timeout
+ clearTimeout(abortTimer);
+ abortTimer = setTimeout(abortTimeout, timeout);
+
+ const { bytes } = serialDevice.nextPacket();
+ debug('Raw packet received:', common.bytes2hex(bytes));
+ _.map(bytes, (e) => { raw.push(e); });
+
+ if (_.endsWith(raw, [ASCII_CONTROL.CR, ASCII_CONTROL.LF])) {
+ // send a new ACK
+ const cmd = buildCmd(ASCII_CONTROL.ACK, 1);
+ serialDevice.writeSerial(cmd.packet, () => {
+ debug('ACK sent');
+ });
+ }
+
+ if (bytes.includes(ASCII_CONTROL.EOT)
+ || bytes.includes(ASCII_CONTROL.ACK)
+ || bytes.includes(ASCII_CONTROL.ENQ)) {
+ clearTimeout(abortTimer);
+ clearInterval(listenTimer);
+ callback(null, raw);
+ }
+ }
+ }, 20);
+ };
+
+ const bcnCommandResponse = async (commandpacket) => new Promise((resolve, reject) => {
+ try {
+ serialDevice.writeSerial(commandpacket.packet, () => {
+ listenForPacket(5000, (err, result) => {
+ if (err) {
+ reject(err);
+ }
+ const parsed = commandpacket.parser(result);
+ resolve(parsed);
+ });
+ });
+ } catch (e) {
+ // exceptions inside Promise won't be thrown, so we have to
+ // reject errors here (e.g. device unplugged during data read)
+ reject(e);
+ }
+ });
+
+ const getData = async () => {
+ // exit remote command mode
+ await bcnCommandResponse(buildCmd(ASCII_CONTROL.EOT, 1));
+
+ const cmd = buildCmdWithParser(ASCII_CONTROL.ACK, 1);
+ const datatxt = await bcnCommandResponse(cmd);
+ const header = parseHeader(datatxt.payload);
+ if (header) {
+ return header;
+ }
+ debug('Invalid header data');
+ throw (new Error('Invalid header data'));
+ };
+
+ const enterRemoteCommandMode = async () => {
+ let response;
+ try {
+ [response] = await bcnCommandResponse(buildCmd(ASCII_CONTROL.NAK, 1));
+
+ if (response === ASCII_CONTROL.ENQ) {
+ // if we get an enq, send another nak, because we want an eot
+ [response] = await bcnCommandResponse(buildCmd(ASCII_CONTROL.NAK, 1));
+ }
+
+ if (response !== ASCII_CONTROL.EOT) {
+ throw new Error(`Expected EOT, got ${response.toString(16)}`);
+ }
+
+ const [ack] = await bcnCommandResponse(buildCmd(ASCII_CONTROL.ENQ, 1));
+ if (ack !== ASCII_CONTROL.ACK) {
+ throw new Error(`Expected ACK, got ${ack.toString(16)}`);
+ }
+ } catch (error) {
+ if (retries === 3) {
+ throw error;
+ }
+ debug('Trying again ...');
+ retries += 1;
+ await enterRemoteCommandMode();
+ }
+ };
+
+ const setDateTime = async (serverTime) => {
+ const newDate = [];
+ struct.storeString(sundial.formatInTimezone(serverTime, cfg.timezone, 'YYMMDD|').concat('\r'), newDate, 0);
+ const [ack1] = await bcnCommandResponse(buildCmd(COMMANDS.WRITE, 2));
+ const [ack2] = await bcnCommandResponse(buildCmd(COMMANDS.DATE, 2));
+ const [ack3] = await bcnCommandResponse(buildCmd(newDate, 8));
+ if (ack1 !== ASCII_CONTROL.ACK || ack2 !== ASCII_CONTROL.ACK || ack3 !== ASCII_CONTROL.ACK) {
+ if (retries === 0) {
+ debug('Could not set date on meter, retrying..');
+ await enterRemoteCommandMode();
+ await setDateTime(serverTime);
+ } else {
+ throw new Error('Could not set date on meter');
+ }
+ }
+
+ const newTime = [];
+ struct.storeString(sundial.formatInTimezone(serverTime, cfg.timezone, 'HHmm|').concat('\r'), newTime, 0);
+ const [ack4] = await bcnCommandResponse(buildCmd(COMMANDS.WRITE, 2));
+ const [ack5] = await bcnCommandResponse(buildCmd(COMMANDS.TIME, 2));
+ const [ack6] = await bcnCommandResponse(buildCmd(newTime, 6));
+ if (ack4 !== ASCII_CONTROL.ACK || ack5 !== ASCII_CONTROL.ACK || ack6 !== ASCII_CONTROL.ACK) {
+ throw new Error('Could not set time on meter');
+ }
+ };
+
+ const getDeviceInfo = (cb) => {
+ debug('DEBUG: on getDeviceInfo');
+
+ (async () => {
+ retries = 0;
+ await enterRemoteCommandMode();
+
+ // read time
+ await bcnCommandResponse(buildCmd(COMMANDS.READ, 2));
+ const timePacket = await bcnCommandResponse(buildCmdWithParser(COMMANDS.TIME, 2));
+ const [, time] = _.split(timePacket.payload, '|');
+
+ // read date
+ await bcnCommandResponse(buildCmd(COMMANDS.READ, 2));
+ const datePacket = await bcnCommandResponse(buildCmdWithParser(COMMANDS.DATE, 2));
+ const [, date] = _.split(datePacket.payload, '|');
+
+ cfg.deviceInfo.deviceTime = sundial.parseFromFormat(date.concat(' ', time), 'YYMMDD HHmm');
+
+ common.checkDeviceTime(cfg, async (err, serverTime) => {
+ try {
+ if (err) {
+ if (err === 'updateTime') {
+ cfg.deviceInfo.annotations = 'wrong-device-time';
+ retries = 0;
+ await setDateTime(serverTime);
+ cb(null, await getData());
+ } else {
+ cb(err, null);
+ }
+ } else {
+ cb(null, await getData());
+ }
+ } catch (error) {
+ cb(error, null);
+ }
+ });
+ })().catch((error) => {
+ debug('Error in getDeviceInfo: ', error);
+ cb(error, null);
+ });
+ };
+
+ const processReadings = (readings) => {
+ _.each(readings, (reading, index) => {
+ readings[index].jsDate = sundial.parseFromFormat(reading.timestamp, 'YYYYMMDD HHmm');
+ readings[index].displayTime = sundial.formatDeviceTime(readings[index].jsDate);
+ });
+ };
+
+ const prepBGData = (progress, data) => {
+ // build missing data.id
+ data.id = `${data.model}-${data.serialNumber}`;
+ cfg.builder.setDefaults({ deviceId: data.id });
+ const dataToPost = [];
+ if (data.bgmReadings.length > 0) {
+ for (let i = 0; i < data.bgmReadings.length; ++i) {
+ const datum = data.bgmReadings[i];
+ if (datum.control === true) {
+ debug('Discarding control');
+ // eslint-disable-next-line no-continue
+ continue;
+ }
+ const smbg = cfg.builder.makeSMBG()
+ .with_value(datum.glucose)
+ .with_deviceTime(datum.displayTime)
+ .with_units(datum.units)
+ .set('index', datum.nrec);
+
+ if (datum.annotations) {
+ _.each(datum.annotations, (ann) => {
+ annotate.annotateEvent(smbg, ann);
+ });
+ }
+
+ cfg.tzoUtil.fillInUTCInfo(smbg, datum.jsDate);
+ dataToPost.push(smbg.done());
+ }
+ } else {
+ debug('Device has no records to upload');
+ throw (new Error('Device has no records to upload'));
+ }
+
+ return dataToPost;
+ };
+
+
+ return {
+ detect(deviceInfo, cb) {
+ debug('no detect function needed');
+ cb(null, deviceInfo);
+ },
+
+ setup(deviceInfo, progress, cb) {
+ debug('in setup!');
+ progress(100);
+ cb(null, { deviceInfo });
+ },
+
+ connect(progress, data, cb) {
+ debug('in connect!');
+ cfg.deviceComms.connect(data.deviceInfo, bcnPacketHandler, (err) => {
+ if (err) {
+ return cb(err);
+ }
+ cfg.deviceComms.flush();
+ progress(100);
+ data.connect = true;
+ return cb(null, data);
+ });
+ },
+
+ getConfigInfo(progress, data, cb) {
+ debug('in getConfigInfo', data);
+
+ getDeviceInfo((err, result) => {
+ progress(100);
+
+ if (!err) {
+ data.connect = true;
+ _.assign(data, result);
+ _.merge(cfg.deviceInfo, result);
+ cfg.deviceInfo.model = MODELS[data.model];
+ data.deviceModel = cfg.deviceInfo.model; // for metrics
+ if (cfg.deviceInfo.model == null) {
+ cfg.deviceInfo.model = 'Unknown Bayer model';
+ }
+ debug('Detected as: ', cfg.deviceInfo.model);
+ cb(null, data);
+ } else {
+ cb(err, result);
+ }
+ });
+ },
+
+ fetchData(progress, data, cb) {
+ debug('in fetchData', data);
+
+ function getOneRecordWithProgress(recnum, callback) {
+ const rec = data.rawrecords.shift();
+ progress((100.0 * recnum) / data.nrecs);
+ setTimeout(() => {
+ getOneRecord(rec, data, callback);
+ }, 20);
+ }
+
+ async.timesSeries(data.nrecs, getOneRecordWithProgress, (err, result) => {
+ if (err) {
+ debug('fetchData failed');
+ debug(err);
+ debug(result);
+ } else {
+ debug('fetchData', result);
+ }
+ data.fetchData = true;
+ data.bgmReadings = result;
+ progress(100);
+ cb(err, data);
+ });
+ },
+
+ processData(progress, data, cb) {
+ progress(0);
+ data.bg_data = processReadings(data.bgmReadings);
+ data.post_records = prepBGData(progress, data);
+ const ids = {};
+ for (let i = 0; i < data.post_records.length; ++i) {
+ delete data.post_records[i].index;
+ const id = `${data.post_records[i].time}|${data.post_records[i].deviceId}`;
+ if (ids[id]) {
+ debug('duplicate! %s @ %d == %d', id, i, ids[id] - 1);
+ debug(data.post_records[ids[id] - 1]);
+ debug(data.post_records[i]);
+ } else {
+ ids[id] = i + 1;
+ }
+ }
+ progress(100);
+ data.processData = true;
+ cb(null, data);
+ },
+
+ uploadData(progress, data, cb) {
+ progress(0);
+ const sessionInfo = {
+ deviceTags: cfg.deviceInfo.tags,
+ deviceManufacturers: cfg.deviceInfo.manufacturers,
+ deviceModel: cfg.deviceInfo.model,
+ deviceSerialNumber: cfg.deviceInfo.serialNumber,
+ deviceId: data.id,
+ start: sundial.utcDateString(),
+ timeProcessing: cfg.tzoUtil.type,
+ tzName: cfg.timezone,
+ version: cfg.version,
+ };
+
+ debug('POST records:', data.post_records);
+
+ cfg.api.upload.toPlatform(
+ data.post_records,
+ sessionInfo,
+ progress,
+ cfg.groupId,
+ (err, result) => {
+ progress(100);
+
+ if (err) {
+ debug(err);
+ debug(result);
+ return cb(err, data);
+ }
+ data.cleanup = true;
+ return cb(null, data);
+ },
+ 'dataservices',
+ );
+ },
+
+ disconnect(progress, data, cb) {
+ debug('in disconnect');
+ progress(100);
+ cb(null, data);
+ },
+
+ cleanup(progress, data, cb) {
+ debug('in cleanup');
+ cfg.deviceComms.disconnect(() => {
+ progress(100);
+ data.cleanup = true;
+ data.disconnect = true;
+ cb(null, data);
+ });
+ },
+ };
+};
diff --git a/lib/drivers/bayer/bayerContourNext.js b/lib/drivers/bayer/bayerContourNext.js
index f27785a9ed..4867e6ffc4 100644
--- a/lib/drivers/bayer/bayerContourNext.js
+++ b/lib/drivers/bayer/bayerContourNext.js
@@ -26,6 +26,7 @@ var struct = require('../../struct.js')();
var annotate = require('../../eventAnnotations');
var common = require('../../commonFunctions');
var debugMode = require('../../../app/utils/debugMode');
+var constants = require('./bayerConstants');
var TZOUtil = require('../../TimezoneOffsetUtil');
@@ -50,48 +51,18 @@ module.exports = function (config) {
/* end */
- var ASCII_CONTROL = {
- ACK : 0x06,
- CR : 0x0D,
- ENQ : 0x05,
- EOT : 0x04,
- ETB : 0x17,
- ETX : 0x03,
- LF : 0x0A,
- NAK : 0x15,
- STX : 0x02,
- CAN : 0x18
- };
-
- var MODELS = {
- 'Bayer6200' : 'Contour Next Link', // mg/dL
- 'Bayer6210' : 'Contour Next Link 2.4', // mg/dL
- 'Bayer6300' : 'Contour Next Link', // mmol/L
- 'Bayer7350' : 'Contour Next', // mg/dL & mmol/L
- 'Bayer7390' : 'Contour USB', // mg/dL
- 'Bayer7410' : 'Contour Next USB', // mg/dL & mmol/L
- 'Contour7800' : 'Contour Next One' // mg/dL & mmol/L
- };
-
- var COMMANDS = {
- READ : [0x52, 0x7c], // R|
- WRITE : [0x57,0x7c], // W|
- DATE : [0x44,0x7c], // D|
- TIME : [0x54, 0x7c] // T|
- };
-
var messageBuffer = {
- reset: function(){
+ reset: function() {
this.bytes = new Uint8Array(0);
this.messageLength = 0;
return this;
},
- clone: function(){
+ clone: function() {
return _.clone(this);
}
}.reset();
- var probe = function(cb){
+ var probe = function(cb) {
debug('attempting probe of Bayer Contour Next');
};
@@ -134,11 +105,11 @@ module.exports = function (config) {
};
var buildAckPacket = function() {
- return buildPacket([ASCII_CONTROL.ACK], 1);
+ return buildPacket([constants.ASCII_CONTROL.ACK], 1);
};
var buildNakPacket = function() {
- return buildPacket([ASCII_CONTROL.NAK], 1);
+ return buildPacket([constants.ASCII_CONTROL.NAK], 1);
};
// header data looks like
@@ -149,7 +120,7 @@ module.exports = function (config) {
|||||P|1|201505291248
01
*/
- var parseHeader = function (header, callback){
+ var parseHeader = function (header, callback) {
var pString = header.split('|');
var pInfo = pString[4].split('^');
@@ -160,9 +131,9 @@ module.exports = function (config) {
var threshold = null;
var thrs = pString[5].split('^');
- for (var i = 0; i < thrs.length; i++){
+ for (var i = 0; i < thrs.length; i++) {
var val = thrs[i].match(/^(\w+)\=/);
- if (val[1] === 'V'){
+ if (val[1] === 'V') {
threshold = thrs[i].match(/^.+\=(\d{2})(\d{3})/);
break;
}
@@ -177,9 +148,9 @@ module.exports = function (config) {
deviceTime: sundial.formatDeviceTime(jsDate)
};
- if(threshold){
- devInfo.lowThreshold = parseInt(threshold[1]);
- devInfo.hiThreshold = parseInt(threshold[2]);
+ if(threshold) {
+ devInfo.lowThreshold = parseInt(threshold[1], 10);
+ devInfo.hiThreshold = parseInt(threshold[2], 10);
} else {
devInfo.unreportedThreshold = true;
devInfo.lowThreshold = 20;
@@ -195,7 +166,7 @@ module.exports = function (config) {
* @return {string} Checksum value returned as a byte sized integer in hex base
*/
function makeChecksum (frame) {
- var sum = frame.split('').reduce( function (previousValue, currentValue, currentIndex, array) {
+ var sum = frame.split('').reduce(function (previousValue, currentValue, currentIndex, array) {
return (currentIndex == 1 ? previousValue.charCodeAt(0) : previousValue) + currentValue.charCodeAt(0);
});
return ('00' + (sum % 256).toString(16).toUpperCase()).substr(-2);
@@ -221,11 +192,11 @@ module.exports = function (config) {
var frameLength = message.length - 6; // Would normally be - 5, but we'll unpack the sequence number directly
var response = struct.unpack(message, 0, 'bb'+frameLength+'Z2Z2Z', ['messageType', 'sequenceNumber', 'frame', 'checksum', 'CRLF']);
- if(response['messageType'] === ASCII_CONTROL.STX) {
+ if(response.messageType === constants.ASCII_CONTROL.STX) {
// Turn sequenceNumber into an integer by subtracting ASCII ZERO (ie, 48) from it.
response.sequenceNumber -= 48;
var calculatedChecksum = makeChecksum(response.sequenceNumber + response.frame);
- if (calculatedChecksum != response.checksum ) {
+ if (calculatedChecksum !== response.checksum) {
throw(new Error('Checksum failed. Expected ' + response.checksum + ', calculated ' + calculatedChecksum));
}
}
@@ -239,16 +210,16 @@ module.exports = function (config) {
/* Record data looks like
5R|3|^^^Glucose|93|mg/dL^P||A/M0/T1||20150526115074
*/
- var parseDataRecord = function (data, callback){
+ var parseDataRecord = function (data, callback) {
// TODO - The NextLink 2.4 also includes seconds in its timestamp (14 digits)
var result = data.match(/^R\|(\d+)\|\^\^\^Glucose\|([0-9.]+)\|(\w+\/\w+).*\|{2}(.*)\|{2}(\d{12}).*/);
if (result != null) {
- result = result.slice(1,6);
+ result = result.slice(1, 6);
}
callback(null, result);
};
- var getAnnotations = function (annotation, data){
+ var getAnnotations = function (annotation, data) {
var annInfo = [];
if (data.unreportedThreshold) {
@@ -308,16 +279,16 @@ module.exports = function (config) {
return whilstCb(null);
}
} else {
- if (record.messageType === ASCII_CONTROL.ENQ) {
+ if (record.messageType === constants.ASCII_CONTROL.ENQ) {
debug('ENQ received, sending ACK..');
return whilstCb(null);
}
- var recordType = (record.messageType === ASCII_CONTROL.STX) ?
+ var recordType = (record.messageType === constants.ASCII_CONTROL.STX) ?
struct.extractByte(record.frame, 0) : record.messageType;
robj.recordType = recordType;
- switch(recordType) {
+ switch (recordType) {
case 'R':
parseDataRecord(record.frame, function(err, r) {
if (err) {
@@ -326,16 +297,16 @@ module.exports = function (config) {
return whilstCb(err);
} else {
if(r) {
- robj.timestamp = parseInt(r[4]);
+ robj.timestamp = parseInt(r[4], 10);
robj.annotations = getAnnotations(r[3], data);
robj.control = isControl(r[3]);
robj.units = r[2];
if(robj.units === 'mmol/L') {
robj.glucose = parseFloat(r[1]);
} else {
- robj.glucose = parseInt(r[1]);
+ robj.glucose = parseInt(r[1], 10);
}
- robj.nrec = parseInt(r[0]);
+ robj.nrec = parseInt(r[0], 10);
}
return whilstCb(null);
}
@@ -355,16 +326,16 @@ module.exports = function (config) {
break;
case 'P':
case 'L':
- case ASCII_CONTROL.EOT:
- return whilstCb(null);
- break;
+ case constants.ASCII_CONTROL.EOT:
+ default:
+ return whilstCb(null);
}
}
});
},
function () { return (Object.getOwnPropertyNames(robj).length === 0 && retry < RETRIES) && !error; },
function (err) {
- if (retry === RETRIES ) {
+ if (retry === RETRIES) {
err = new Error('Communication retry limit reached');
}
if (err) {
@@ -421,7 +392,7 @@ module.exports = function (config) {
function (callback) {
var processPacket = function(packet) {
// Only process if we get data
- if ( packet.length === 0 ) {
+ if (packet.length === 0) {
return callback(false);
}
@@ -434,19 +405,19 @@ module.exports = function (config) {
// The tail of the packet starts 6 from the end, but because we haven't stripped the
// header and length byte from packet, we're using SIZE - 2
- var packetTail = struct.unpack(packet, parseInt(packetHead['SIZE']) - 2, '2b2Z2Z', ['CR', 'FRAME_TYPE', 'CHECKSUM', 'CRLF']);
+ var packetTail = struct.unpack(packet, parseInt(packetHead.SIZE, 10) - 2, '2b2Z2Z', ['CR', 'FRAME_TYPE', 'CHECKSUM', 'CRLF']);
// HID_PACKET_SIZE - 4, because we don't include the header or size
if(waitForENQ) {
- if (packetHead['BYTE1'] == ASCII_CONTROL.ENQ) {
+ if (packetHead.BYTE1 == constants.ASCII_CONTROL.ENQ) {
clearTimeout(abortTimer);
return callback(true);
}
- } else if( packetHead['SIZE'] < ( HID_PACKET_SIZE - 4 ) ||
- packetHead['BYTE1'] == ASCII_CONTROL.ENQ ||
- packetHead['BYTE1'] == ASCII_CONTROL.EOT ||
- packetHead['BYTE1'] == ASCII_CONTROL.ACK ||
- packetTail['FRAME_TYPE'] == ASCII_CONTROL.ETX ||
- packetTail['FRAME_TYPE'] == ASCII_CONTROL.ETB ) {
+ } else if(packetHead.SIZE < (HID_PACKET_SIZE - 4) ||
+ packetHead.BYTE1 == constants.ASCII_CONTROL.ENQ ||
+ packetHead.BYTE1 == constants.ASCII_CONTROL.EOT ||
+ packetHead.BYTE1 == constants.ASCII_CONTROL.ACK ||
+ packetTail.FRAME_TYPE == constants.ASCII_CONTROL.ETX ||
+ packetTail.FRAME_TYPE == constants.ASCII_CONTROL.ETB) {
clearTimeout(abortTimer);
return callback(true);
}
@@ -526,21 +497,21 @@ module.exports = function (config) {
async.series({
- ack : function(callback){
+ ack: function(callback) {
// at least one meter (Contour Next One) does not reply with an ACK
// here, so we don't wait for a response
- hidDevice.send(buildPacket([ASCII_CONTROL.ACK],1), function (err) {
+ hidDevice.send(buildPacket([constants.ASCII_CONTROL.ACK], 1), function (err) {
if (err) {
return callback(err, null);
}
callback(null, 'ack');
});
},
- eot : function(callback){
+ eot: function(callback) {
if (cfg.deviceInfo.model !== 'Contour Next One') {
- bcnCommandResponse(buildPacket([ASCII_CONTROL.EOT],1), false, function (err, result) {
+ bcnCommandResponse(buildPacket([constants.ASCII_CONTROL.EOT], 1), false, function (err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
callback(null, 'eot');
});
@@ -548,13 +519,13 @@ module.exports = function (config) {
callback(null, 'eot');
}
},
- nak : function(callback){
+ nak: function(callback) {
function sendNAK(cb) {
- bcnCommandResponse(buildPacket([ASCII_CONTROL.NAK], 1), false, function(err, result) {
+ bcnCommandResponse(buildPacket([constants.ASCII_CONTROL.NAK], 1), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.EOT) {
+ if(result.messageType !== constants.ASCII_CONTROL.EOT) {
return cb(new Error('Expected EOT.'), null);
}
cb(null, 'nak');
@@ -565,96 +536,96 @@ module.exports = function (config) {
callback(err, result);
});
},
- enq : function(callback){
- bcnCommandResponse(buildPacket([ASCII_CONTROL.ENQ], 1), false, function(err, result) {
+ enq: function(callback) {
+ bcnCommandResponse(buildPacket([constants.ASCII_CONTROL.ENQ], 1), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.ACK) {
+ if(result.messageType !== constants.ASCII_CONTROL.ACK) {
return cb(new Error(ACK_ERROR + 'ENQ'), null);
}
callback(null, 'enq');
});
},
- write : function(callback){
- bcnCommandResponse(buildPacket(COMMANDS.WRITE, 2), false, function(err, result) {
+ write: function(callback) {
+ bcnCommandResponse(buildPacket(constants.COMMANDS.WRITE, 2), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.ACK) {
+ if(result.messageType !== constants.ASCII_CONTROL.ACK) {
return cb(new Error(ACK_ERROR + 'WRITE'), null);
}
callback(null, 'write');
});
},
- date : function(callback){
- bcnCommandResponse(buildPacket(COMMANDS.DATE, 2), false, function(err, result) {
+ date: function(callback) {
+ bcnCommandResponse(buildPacket(constants.COMMANDS.DATE, 2), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.ACK) {
+ if(result.messageType !== constants.ASCII_CONTROL.ACK) {
return cb(new Error(ACK_ERROR + 'DATE'), null);
}
callback(null, 'date');
});
},
- setDate: function(callback){
+ setDate: function(callback) {
var newDate = [];
struct.storeString(sundial.formatInTimezone(serverTime, cfg.timezone, 'YYMMDD|') + '\r', newDate, 0);
bcnCommandResponse(buildPacket(newDate, 8), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.ACK) {
+ if(result.messageType !== constants.ASCII_CONTROL.ACK) {
return cb(new Error(ACK_ERROR + 'SETDATE'), null);
}
callback(null, 'setDate');
});
},
- write2 : function(callback){
- bcnCommandResponse(buildPacket(COMMANDS.WRITE, 2), false, function(err, result) {
+ write2: function(callback) {
+ bcnCommandResponse(buildPacket(constants.COMMANDS.WRITE, 2), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.ACK) {
+ if(result.messageType !== constants.ASCII_CONTROL.ACK) {
return cb(new Error(ACK_ERROR + 'WRITE2'), null);
}
callback(null, 'write2');
});
},
- time : function(callback){
- bcnCommandResponse(buildPacket(COMMANDS.TIME, 2), false, function(err, result) {
+ time: function(callback) {
+ bcnCommandResponse(buildPacket(constants.COMMANDS.TIME, 2), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.ACK) {
+ if(result.messageType !== constants.ASCII_CONTROL.ACK) {
return cb(new Error(ACK_ERROR + 'TIME'), null);
}
callback(null, 'date');
});
},
- setTime: function(callback){
+ setTime: function(callback) {
var newTime = [];
struct.storeString(sundial.formatInTimezone(serverTime, cfg.timezone, 'HHmm|') + '\r', newTime, 0);
bcnCommandResponse(buildPacket(newTime, 6), false, function(err, result) {
if(err) {
- return cb(err,null);
+ return cb(err, null);
}
- if(result.messageType !== ASCII_CONTROL.ACK) {
+ if(result.messageType !== constants.ASCII_CONTROL.ACK) {
return cb(new Error(ACK_ERROR + 'SETTIME'), null);
}
callback(null, 'setTime');
});
}
},
- function(err, results){
- return cb(err,results);
+ function(err, results) {
+ return cb(err, results);
});
};
return {
- detect: function(deviceInfo, cb){
- debug('no detect function needed', arguments);
+ detect: function(deviceInfo, cb) {
+ debug('no detect function needed');
cb(null, deviceInfo);
},
@@ -686,7 +657,7 @@ module.exports = function (config) {
_.assign(data, result);
return cb(null, data);
} else {
- return cb(err,result);
+ return cb(err, result);
}
});
},
@@ -701,7 +672,7 @@ module.exports = function (config) {
async.whilst(
// Get records from the meter until we get the Message Terminator Record (L)
// The spec says that unless we get this, any preceding data should not be used.
- function () { return (recordType !== ASCII_CONTROL.EOT && recordType !== 'L' && !error); },
+ function () { return (recordType !== constants.ASCII_CONTROL.EOT && recordType !== 'L' && !error); },
function (callback) {
getOneRecord(data, function (err, result) {
if (err) {
@@ -722,7 +693,7 @@ module.exports = function (config) {
if(err || error) {
return cb(err, null);
} else {
- cfg.deviceInfo.model = MODELS[data.model];
+ cfg.deviceInfo.model = constants.MODELS[data.model];
if(cfg.deviceInfo.model == null) {
cfg.deviceInfo.model = 'Unknown Bayer model';
}
@@ -783,8 +754,7 @@ module.exports = function (config) {
progress(100);
data.processData = true;
cb(null, data);
- }
- catch(err) {
+ } catch(err) {
cb(new Error(err), null);
}
},
@@ -838,7 +808,7 @@ module.exports = function (config) {
cleanup: function (progress, data, cb) {
debug('in cleanup');
- if(!data.disconnect){
+ if (!data.disconnect) {
cfg.deviceComms.disconnect(data, function() {
progress(100);
data.cleanup = true;
diff --git a/lib/serialDevice.js b/lib/serialDevice.js
index 6678f85133..5eb3153ad9 100644
--- a/lib/serialDevice.js
+++ b/lib/serialDevice.js
@@ -25,6 +25,7 @@ if (!(process.env.NODE_ENV === 'test')) {
var UsbCdcAcm = require('usb-cdc-acm');
var PL2303 = require('pl2303');
var CP2102 = require('cp2102');
+ var FTDI = require('ftdi-js');
// var TUSB3410 = require('tusb3410'); TODO: waiting on upstream fix: https://github.com/tessel/node-usb/issues/159
}
import SerialPort from 'serialport';
@@ -124,19 +125,35 @@ module.exports = function(config) {
debug('in SerialDevice.connect, info ', deviceInfo);
var connectopts = {
- baudRate: bitrate
+ baudRate: bitrate,
+ autoOpen: false,
};
function openPort(cb) {
if (deviceInfo.path) {
debug('Opening port', deviceInfo.path);
- connection = new SerialPort(deviceInfo.path, connectopts, function (err) {
- if (err) {
- debug('Trying again after receiving', err);
- return cb(err, null);
- }
- cb();
- });
+ connection = new SerialPort(deviceInfo.path, connectopts);
+
+ if (connection.isOpen) {
+ debug('Attempting to close existing connection and re-open');
+ connection.close(function () {
+ connection.open(function (err) {
+ if (err) {
+ debug('Trying again after receiving', err);
+ return cb(err, null);
+ }
+ cb();
+ });
+ });
+ } else {
+ connection.open(function (err) {
+ if (err) {
+ debug('Trying again after receiving', err);
+ return cb(err, null);
+ }
+ cb();
+ });
+ }
} else {
debug('Connecting via user space driver');
@@ -160,6 +177,15 @@ module.exports = function(config) {
return cb();
});
break;
+ case 'ftdi':
+ connection = new FTDI(deviceInfo.vendorId, deviceInfo.productId, connectopts);
+ connection.on('error', function (err) {
+ return cb(err);
+ });
+ connection.on('ready', function () {
+ return cb();
+ });
+ break;
/* TODO: waiting on upstream fix, see top of file for details
case 'tusb3410':
connection = new TUSB3410(deviceInfo.vendorId, deviceInfo.productId, connectopts);
@@ -170,7 +196,7 @@ module.exports = function(config) {
*/
default:
debug('User-space driver not yet implemented for this device.');
- return cb();
+ return cb(new Error('No available user-space driver.'));
}
}
}
@@ -207,7 +233,10 @@ module.exports = function(config) {
connection.userSpaceDriver = deviceInfo.userSpaceDriver;
}
- debug('connected via ' + deviceInfo.path);
+ if (deviceInfo.path) {
+ debug('connected via ' + deviceInfo.path);
+ }
+
if(deviceInfo.ctsFlowControl) {
connection.set({ dtr : false, rts : true }, function(err){
if(err) {
@@ -347,18 +376,10 @@ module.exports = function(config) {
debug('flushing buffers..');
packetBuffer = [];
buffer = [];
- if(connection) {
-
- if(process.platform === 'win32') {
- /* Flushing buffers is broken on Windows for now,
- see https://github.com/node-serialport/node-serialport/issues/1409
- */
- debug('but not on Windows for now.');
- } else if (!connection.userSpaceDriver) {
- connection.flush(function() {
- setPaused(false);
- });
- }
+ if(connection && !connection.userSpaceDriver) {
+ connection.flush(function() {
+ setPaused(false);
+ });
}
}
diff --git a/package.json b/package.json
index 56326673e9..b6b14cc3ed 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "tidepool-uploader",
- "version": "2.27.0",
+ "version": "2.28.0",
"description": "Tidepool Project Universal Uploader",
"private": true,
"main": "main.prod.js",
@@ -52,6 +52,7 @@
"electron-log": "4.0.7",
"electron-updater": "4.2.2",
"es6-error": "4.1.1",
+ "ftdi-js": "0.0.6",
"history": "4.10.1",
"iconv-lite": "0.5.1",
"identity-obj-proxy": "3.0.0",
@@ -253,7 +254,6 @@
"less": "3.10.3",
"less-loader": "5.0.0",
"mini-css-extract-plugin": "0.9.0",
- "minimist": "1.2.0",
"node-hid": "1.1.0",
"object-invariant-test-helper": "0.1.1",
"open": "7.0.3",
diff --git a/resources/win/README.md b/resources/win/README.md
index 6d20686973..5fc9de1f2d 100755
--- a/resources/win/README.md
+++ b/resources/win/README.md
@@ -11,7 +11,7 @@ To build and sign the driver, check that you have the specified requirements ins
### Generate the .cat files from the .inf files:
- Bump version number in .inf file
-- `inf2cat /driver:. /os:7_X64,7_X86,8_X64,8_X86,6_3_X86,6_3_X64,Vista_X86,Vista_X64,XP_X86,XP_X64`
+- `inf2cat /driver:. /os:7_X64,7_X86,8_X64,8_X86,6_3_X86,6_3_X64,10_X86,10_X64,Server10_X64`
### Install certificates:
@@ -24,9 +24,9 @@ To build and sign the driver, check that you have the specified requirements ins
In `resources\win`:
-- `signtool sign /v /ac "DigiCertHighAssuranceEVRootCA.crt" /tr http://timestamp.digicert.com /td sha256 /fd sha256 /s my /n "Tidepool Project" tidepoolvcp.cat`
-- `signtool sign /v /ac "DigiCertHighAssuranceEVRootCA.crt" /tr http://timestamp.digicert.com /td sha256 /fd sha256 /s my /n "Tidepool Project" tidepoolhid.cat`
-- `signtool sign /v /ac "DigiCertHighAssuranceEVRootCA.crt" /tr http://timestamp.digicert.com /td sha256 /fd sha256 /s my /n "Tidepool Project" tidepoolusb.cat`
+- `signtool sign /v /ac "DigiCertHighAssuranceEVRootCA.crt" /tr http://timestamp.digicert.com /td sha256 /fd sha256 /s my /n "Tidepool Project" /sha1 EC02571EB23521ECF39813F1910157CAA08DE97A tidepoolvcp.cat`
+- `signtool sign /v /ac "DigiCertHighAssuranceEVRootCA.crt" /tr http://timestamp.digicert.com /td sha256 /fd sha256 /s my /n "Tidepool Project" /sha1 EC02571EB23521ECF39813F1910157CAA08DE97A tidepoolhid.cat`
+- `signtool sign /v /ac "DigiCertHighAssuranceEVRootCA.crt" /tr http://timestamp.digicert.com /td sha256 /fd sha256 /s my /n "Tidepool Project" /sha1 EC02571EB23521ECF39813F1910157CAA08DE97A tidepoolusb.cat`
### Submit Windows 10 drivers to hardware dashboard for attestation signing
diff --git a/resources/win/amd64/ftbusui.dll b/resources/win/amd64/ftbusui.dll
old mode 100755
new mode 100644
index 0535875dba..5d1a4374a1
Binary files a/resources/win/amd64/ftbusui.dll and b/resources/win/amd64/ftbusui.dll differ
diff --git a/resources/win/amd64/ftcserco.dll b/resources/win/amd64/ftcserco.dll
old mode 100755
new mode 100644
index 01d378fe4c..afc78abb9a
Binary files a/resources/win/amd64/ftcserco.dll and b/resources/win/amd64/ftcserco.dll differ
diff --git a/resources/win/amd64/ftd2xx.lib b/resources/win/amd64/ftd2xx.lib
old mode 100755
new mode 100644
index 06f1aaf762..8a04fec439
Binary files a/resources/win/amd64/ftd2xx.lib and b/resources/win/amd64/ftd2xx.lib differ
diff --git a/resources/win/amd64/ftd2xx64.dll b/resources/win/amd64/ftd2xx64.dll
old mode 100755
new mode 100644
index 2c4a9c3ee6..4c8ab6cc9a
Binary files a/resources/win/amd64/ftd2xx64.dll and b/resources/win/amd64/ftd2xx64.dll differ
diff --git a/resources/win/amd64/ftdibus.sys b/resources/win/amd64/ftdibus.sys
old mode 100755
new mode 100644
index 65a83ce6a9..ac788c75fb
Binary files a/resources/win/amd64/ftdibus.sys and b/resources/win/amd64/ftdibus.sys differ
diff --git a/resources/win/amd64/ftlang.dll b/resources/win/amd64/ftlang.dll
old mode 100755
new mode 100644
index 92d054561b..b2bc8c9fe6
Binary files a/resources/win/amd64/ftlang.dll and b/resources/win/amd64/ftlang.dll differ
diff --git a/resources/win/amd64/ftser2k.sys b/resources/win/amd64/ftser2k.sys
old mode 100755
new mode 100644
index 5505a04b19..f0e8d016cd
Binary files a/resources/win/amd64/ftser2k.sys and b/resources/win/amd64/ftser2k.sys differ
diff --git a/resources/win/amd64/ftserui2.dll b/resources/win/amd64/ftserui2.dll
old mode 100755
new mode 100644
index 61bb87bf68..1bb2f75184
Binary files a/resources/win/amd64/ftserui2.dll and b/resources/win/amd64/ftserui2.dll differ
diff --git a/resources/win/ftdibus.cat b/resources/win/ftdibus.cat
new file mode 100644
index 0000000000..a651568a46
Binary files /dev/null and b/resources/win/ftdibus.cat differ
diff --git a/resources/win/ftdibus.inf b/resources/win/ftdibus.inf
new file mode 100644
index 0000000000..12d0b4287c
--- /dev/null
+++ b/resources/win/ftdibus.inf
@@ -0,0 +1,160 @@
+; FTDIBUS.INF
+; Copyright (c) 2000-2012 FTDI Ltd.
+; Custom FTDIBUS.INF file generated using 'FT INF Generator' for Bayer HealthCare LLC
+;
+; USB serial converter driver installation for Windows 2000, XP, Server 2003, Vista, Server 2008,
+; Windows 7 and Server 2008 R2 (x86 and x64).
+;
+;
+; THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED ``AS IS'' AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+; FTDI DRIVERS MAY BE USED ONLY IN CONJUNCTION WITH PRODUCTS BASED ON FTDI PARTS.
+
+; FTDI DRIVERS MAY BE DISTRIBUTED IN ANY FORM AS LONG AS LICENSE INFORMATION IS NOT MODIFIED.
+
+; IF A CUSTOM VENDOR ID AND/OR PRODUCT ID OR DESCRIPTION STRING ARE USED, IT IS THE RESPONSIBILITY OF
+; THE PRODUCT MANUFACTURER TO MAINTAIN ANY CHANGES AND SUBSEQUENT WHQL RE-CERTIFICATION AS A RESULT OF
+; MAKING THESE CHANGES.
+;
+[Version]
+Signature="$Windows NT$"
+DriverPackageType=PlugAndPlay
+DriverPackageDisplayName=%DESC%
+Class=USB
+ClassGUID={36fc9e60-c465-11cf-8056-444553540000}
+Provider=%FTDI%
+CatalogFile=ftdibus.cat
+DriverVer=02/27/2013,2.08.28
+
+[SourceDisksNames]
+1=%DriversDisk%,,,
+
+[SourceDisksFiles]
+ftdibus.sys = 1,i386
+ftbusui.dll = 1,i386
+ftd2xx.dll = 1,i386
+FTLang.Dll = 1,i386
+
+[SourceDisksFiles.amd64]
+ftdibus.sys = 1,amd64
+ftbusui.dll = 1,amd64
+ftd2xx64.dll = 1,amd64
+ftd2xx.dll = 1,i386
+FTLang.Dll = 1,amd64
+
+[DestinationDirs]
+FtdiBus.NT.Copy = 10,system32\drivers
+FtdiBus.NT.Copy2 = 10,system32
+FtdiBus.NTamd64.Copy = 10,system32\drivers
+FtdiBus.NTamd64.Copy2 = 10,system32
+FtdiBus.NTamd64.Copy3 = 10,syswow64
+
+[Manufacturer]
+%Ftdi%=FtdiHw,NTamd64
+
+[FtdiHw]
+%USB\VID_1A79&PID_6001.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6001
+%USB\VID_1A79&PID_6011&MI_00.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_00
+%USB\VID_1A79&PID_6011&MI_01.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_01
+%USB\VID_1A79&PID_6011&MI_02.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_02
+%USB\VID_1A79&PID_6011&MI_03.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_03
+%USB\VID_1A79&PID_6010&MI_00.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6010&MI_00
+%USB\VID_1A79&PID_6010&MI_01.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6010&MI_01
+%USB\VID_1A79&PID_6014.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6014
+%USB\VID_1A79&PID_6015.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6015
+
+[FtdiHw.NTamd64]
+%USB\VID_1A79&PID_6001.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6001
+%USB\VID_1A79&PID_6011&MI_00.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_00
+%USB\VID_1A79&PID_6011&MI_01.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_01
+%USB\VID_1A79&PID_6011&MI_02.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_02
+%USB\VID_1A79&PID_6011&MI_03.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_03
+%USB\VID_1A79&PID_6010&MI_00.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6010&MI_00
+%USB\VID_1A79&PID_6010&MI_01.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6010&MI_01
+%USB\VID_1A79&PID_6014.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6014
+%USB\VID_1A79&PID_6015.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6015
+
+[ControlFlags]
+ExcludeFromSelect=*
+
+[FtdiBus.NT]
+CopyFiles=FtdiBus.NT.Copy,FtdiBus.NT.Copy2
+AddReg=FtdiBus.NT.AddReg
+
+[FtdiBus.NT.HW]
+AddReg=FtdiBus.NT.HW.AddReg
+
+[FtdiBus.NTamd64]
+CopyFiles=FtdiBus.NTamd64.Copy,FtdiBus.NTamd64.Copy2,FtdiBus.NTamd64.Copy3
+AddReg=FtdiBus.NT.AddReg
+
+[FtdiBus.NTamd64.HW]
+AddReg=FtdiBus.NT.HW.AddReg
+
+[FtdiBus.NT.Services]
+AddService = FTDIBUS, 0x00000002, FtdiBus.NT.AddService
+
+[FtdiBus.NTamd64.Services]
+AddService = FTDIBUS, 0x00000002, FtdiBus.NT.AddService
+
+[FtdiBus.NT.AddService]
+DisplayName = %SvcDesc%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %10%\system32\drivers\ftdibus.sys
+LoadOrderGroup = Base
+AddReg = FtdiBus.NT.AddService.AddReg
+
+[FtdiBus.NT.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,ftdibus.sys
+HKR,,EnumPropPages32,,"ftbusui.dll,FTBUSUIPropPageProvider"
+
+[FtdiBus.NT.HW.AddReg]
+HKR,,"USBTimeout",0x00010001,5000
+
+[FtdiBus.NT.AddService.AddReg]
+HKR,Parameters,"RetryResetCount",0x10001,50
+
+[FtdiBus.NT.Copy]
+ftdibus.sys
+
+[FtdiBus.NT.Copy2]
+ftbusui.dll
+ftd2xx.dll
+FTLang.dll
+
+[FtdiBus.NTamd64.Copy]
+ftdibus.sys
+
+[FtdiBus.NTamd64.Copy2]
+ftbusui.dll
+ftd2xx.dll,ftd2xx64.dll
+FTLang.dll
+
+[FtdiBus.NTamd64.Copy3]
+ftd2xx.dll
+
+[Strings]
+Ftdi="Bayer HealthCare LLC"
+DESC="CDM Driver Package"
+DriversDisk="FTDI USB Drivers Disk"
+USB\VID_1A79&PID_6001.DeviceDesc="Bayer USB Serial Converter"
+USB\VID_1A79&PID_6011&MI_00.DeviceDesc="Bayer USB Serial Converter A"
+USB\VID_1A79&PID_6011&MI_01.DeviceDesc="Bayer USB Serial Converter B"
+USB\VID_1A79&PID_6011&MI_02.DeviceDesc="Bayer USB Serial Converter C"
+USB\VID_1A79&PID_6011&MI_03.DeviceDesc="Bayer USB Serial Converter D"
+USB\VID_1A79&PID_6010&MI_00.DeviceDesc="Bayer USB Serial Converter A"
+USB\VID_1A79&PID_6010&MI_01.DeviceDesc="Bayer USB Serial Converter B"
+USB\VID_1A79&PID_6014.DeviceDesc="Bayer USB Serial Converter"
+USB\VID_1A79&PID_6015.DeviceDesc="Bayer USB Serial Converter"
+SvcDesc="Bayer USB Serial Converter Driver"
+ClassName="USB"
diff --git a/resources/win/i386/ftbusui.dll b/resources/win/i386/ftbusui.dll
old mode 100755
new mode 100644
index 5549f9f3d8..c55695aa20
Binary files a/resources/win/i386/ftbusui.dll and b/resources/win/i386/ftbusui.dll differ
diff --git a/resources/win/i386/ftcserco.dll b/resources/win/i386/ftcserco.dll
old mode 100755
new mode 100644
index bf8202c05e..ca6d397236
Binary files a/resources/win/i386/ftcserco.dll and b/resources/win/i386/ftcserco.dll differ
diff --git a/resources/win/i386/ftd2xx.dll b/resources/win/i386/ftd2xx.dll
old mode 100755
new mode 100644
index 12e02e14b9..ecafeb7451
Binary files a/resources/win/i386/ftd2xx.dll and b/resources/win/i386/ftd2xx.dll differ
diff --git a/resources/win/i386/ftd2xx.lib b/resources/win/i386/ftd2xx.lib
old mode 100755
new mode 100644
index 9d484de23f..b2e0a53b31
Binary files a/resources/win/i386/ftd2xx.lib and b/resources/win/i386/ftd2xx.lib differ
diff --git a/resources/win/i386/ftdibus.sys b/resources/win/i386/ftdibus.sys
old mode 100755
new mode 100644
index 9fdfa3d888..e779f0783c
Binary files a/resources/win/i386/ftdibus.sys and b/resources/win/i386/ftdibus.sys differ
diff --git a/resources/win/i386/ftlang.dll b/resources/win/i386/ftlang.dll
old mode 100755
new mode 100644
index edc0c66c61..b57a0bb70b
Binary files a/resources/win/i386/ftlang.dll and b/resources/win/i386/ftlang.dll differ
diff --git a/resources/win/i386/ftser2k.sys b/resources/win/i386/ftser2k.sys
old mode 100755
new mode 100644
index f55e47b30e..12795e87ed
Binary files a/resources/win/i386/ftser2k.sys and b/resources/win/i386/ftser2k.sys differ
diff --git a/resources/win/i386/ftserui2.dll b/resources/win/i386/ftserui2.dll
old mode 100755
new mode 100644
index 3e556e77c6..471234c2ba
Binary files a/resources/win/i386/ftserui2.dll and b/resources/win/i386/ftserui2.dll differ
diff --git a/resources/win/tidepoolhid.cat b/resources/win/tidepoolhid.cat
index 94b295269e..025dba5229 100755
Binary files a/resources/win/tidepoolhid.cat and b/resources/win/tidepoolhid.cat differ
diff --git a/resources/win/tidepoolusb.cat b/resources/win/tidepoolusb.cat
index c5ad08b076..883f60b67a 100644
Binary files a/resources/win/tidepoolusb.cat and b/resources/win/tidepoolusb.cat differ
diff --git a/resources/win/tidepoolvcp.cat b/resources/win/tidepoolvcp.cat
index 2ea9ca2e1a..ea9b25f18d 100755
Binary files a/resources/win/tidepoolvcp.cat and b/resources/win/tidepoolvcp.cat differ
diff --git a/resources/win/tidepoolvcp.inf b/resources/win/tidepoolvcp.inf
index d34f7afb35..305e72a63f 100755
--- a/resources/win/tidepoolvcp.inf
+++ b/resources/win/tidepoolvcp.inf
@@ -29,6 +29,19 @@
; USB serial port driver installation file for Windows 2000, XP, Server 2003, Vista, Server 2008,
; Windows 7, Server 2008 R2, Windows 8, Windows 8.1 and Server 2012 R2.
;
+; THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED ``AS IS'' AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+; FTDI DRIVERS MAY BE USED ONLY IN CONJUNCTION WITH PRODUCTS BASED ON FTDI PARTS.
+
+; FTDI DRIVERS MAY BE DISTRIBUTED IN ANY FORM AS LONG AS LICENSE INFORMATION IS NOT MODIFIED.
+;
; Texas Instruments:
; Texas Instruments Driver Installation file for a UMP Device main driver.
; UMP installation file for TIUSB3410 and TIUSB5052
@@ -43,7 +56,7 @@ DriverPackageDisplayName=%DESC%
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%Provider%
-DriverVer=07/27/2016,1.4.1.0
+DriverVer=03/16/2020,1.5.0.2
CatalogFile=tidepoolvcp.cat
; ================= Device section =====================
@@ -62,6 +75,7 @@ CatalogFile=tidepoolvcp.cat
%VID_0403&PID_6015.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_0403&PID_6015
%VID_0403&PID_0000.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_0403&PID_0000
%VID_0403&PID_7F38.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_0403&PID_7F38 ; Asante Snap FTDI cable
+%VID_1A79&PID_6001.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_1A79&PID_6001 ; Bayer cable
%PID_3410.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3410 ; Abbott FreeStyle USB Data Cable
%PID_3420.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3420 ; Abbott Strip Port USB Data Cable
%VID_067B&PID_2303.DeviceDesc% = ComPort.NTx86, USB\VID_067B&PID_2303 ; Prolific PL2303
@@ -78,6 +92,7 @@ CatalogFile=tidepoolvcp.cat
%VID_0403&PID_6015.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_6015
%VID_0403&PID_0000.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_0000
%VID_0403&PID_7F38.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_7F38 ; Asante Snap FTDI cable
+%VID_1A79&PID_6001.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_1A79&PID_6001 ; Bayer cable
%PID_3410.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3410 ; Abbott FreeStyle USB Data Cable
%PID_3420.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3420 ; Abbott Strip Port USB Data Cable
%VID_067B&PID_2303.DeviceDesc% = ComPort.NTamd64, USB\VID_067B&PID_2303 ; Prolific PL2303
@@ -139,7 +154,7 @@ StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\silabser.sys
-; common registry entries
+; common registry entries
[silabser.AddReg]
HKR,,NTMPDriver,,silabser.sys
HKR,,RateLimitPurgeMS, 0x10001, 0x64, 0x00, 0x00, 0x00
@@ -196,7 +211,7 @@ ser2pl64.sys=2,win7x64
[DestinationDirs]
Silabser.Files.Ext = 12
-FtdiPort.NT.Copy=10,system32\drivers
+FtdiPort.NT.Copy=10,system32\drivers
FtdiPort.NT.CopyUI=10,system32
FtdiPort.NT.CopyCoInst=10,system32
DefaultDestDir=12
@@ -239,15 +254,17 @@ AddReg=FtdiPort.NT.HW.AddReg
[FtdiPort.NTx86.Services]
AddService = FTSER2K, 0x00000002, FtdiPort.NT.AddService
+AddService=serenum,,SerenumService
DelService = FTSERIAL
[FtdiPort.NTamd64.Services]
AddService = FTSER2K, 0x00000002, FtdiPort.NT.AddService
+AddService=serenum,,SerenumService
DelService = FTSERIAL
[FtdiPort.NT.HW.AddReg]
HKR,,"UpperFilters",0x00010000,"serenum"
-HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00
+HKR,,"ConfigData",1,17,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,C0,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,00,01,00
HKR,,"MinReadTimeout",0x00010001,0
HKR,,"MinWriteTimeout",0x00010001,0
HKR,,"LatencyTimer",0x00010001,16
@@ -329,14 +346,14 @@ HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
HKR,,ImageFile,,"\SystemRoot\System32\drivers\tiusb.i51"
HKR,,SetMSRLinesZero,%REG_BINARY%,0x00 ; 0x80=DCD 0x40=RI 0x20=DSR 0x10=CTS
-HKR,,SetMSRLinesOne, %REG_BINARY%,0x00 ; 0x80=DCD 0x40=RI 0x20=DSR 0x10=CTS
+HKR,,SetMSRLinesOne, %REG_BINARY%,0x00 ; 0x80=DCD 0x40=RI 0x20=DSR 0x10=CTS
HKR,,NumComPorts,%REG_DWORD%,1
HKR,,NumLptPorts,%REG_DWORD%,0
HKR,,TIDeviceType,,"TIUSB3410"
HKR,,Port1DeviceHWID,,"VID_0451_com"
; ****
; This defines the name shown by the Found New HW wizard for the COM port child device:
-HKR,,ComPortChildDeviceText,,"UMP USB Serial Port"
+HKR,,ComPortChildDeviceText,,"UMP USB Serial Port"
[TI.CopyFiles.NT]
tiusb.i51
@@ -395,19 +412,19 @@ HKR,,NTMPDriver,,ser2pl64.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[Serial_Service_Inst.NTx86]
-DisplayName = %Serial.SVCDESC%
+DisplayName = %Serial.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %12%\ser2pl.sys
+ServiceBinary = %12%\ser2pl.sys
LoadOrderGroup = Base
[Serial_Service_Inst.NTAMD64]
-DisplayName = %Serial.SVCDESC%
+DisplayName = %Serial.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %12%\ser2pl64.sys
+ServiceBinary = %12%\ser2pl64.sys
LoadOrderGroup = Base
@@ -428,6 +445,7 @@ VID_0403&PID_6014.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
VID_0403&PID_6015.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
VID_0403&PID_0000.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
VID_0403&PID_7F38.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
+VID_1A79&PID_6001.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
PID_3410.DeviceDesc="Tidepool USB Driver (TI chipset)"
PID_3420.DeviceDesc="Tidepool USB Driver (TI chipset)"
VID_067B&PID_2303.DeviceDesc="Tidepool USB Driver (Prolific chipset)"
diff --git a/resources/win/win10/TidepoolUSBDriver.ddf b/resources/win/win10/TidepoolUSBDriver.ddf
index 1b111c5fde..c65de456a4 100644
--- a/resources/win/win10/TidepoolUSBDriver.ddf
+++ b/resources/win/win10/TidepoolUSBDriver.ddf
@@ -17,33 +17,43 @@
tidepoolvcp.inf
tidepoolhid.inf
tidepoolusb.inf
+ftdibus.inf
.Set DestinationDir=win10\amd64
-amd64\silabser.sys
+amd64\ftbusui.dll
+amd64\ftcserco.dll
+amd64\ftd2xx.lib
+amd64\ftd2xx64.dll
+amd64\ftdibus.sys
+amd64\ftlang.dll
amd64\ftser2k.sys
amd64\ftserui2.dll
-amd64\ftcserco.dll
+amd64\libusb0.dll
+amd64\libusbK.dll
+amd64\libusbK.sys
+amd64\ser2pl64.sys
+amd64\silabser.sys
amd64\tiusb.i51
amd64\tiusb.sys
-amd64\ser2pl64.sys
-amd64\libusbK.sys
-amd64\libusbK.dll
-amd64\libusb0.dll
amd64\WdfCoInstaller01009.dll
.Set DestinationDir=win10\x64
x64\WdfCoInstaller01009.dll
x64\WdfCoInstaller01011.dll
.Set DestinationDir=win10\i386
-i386\silabser.sys
+i386\ftbusui.dll
+i386\ftcserco.dll
+i386\ftd2xx.dll
+i386\ftd2xx.lib
+i386\ftdibus.sys
+i386\ftlang.dll
i386\ftser2k.sys
i386\ftserui2.dll
-i386\ftcserco.dll
+i386\ser2pl.sys
+i386\silabser.sys
i386\tiusb.i51
i386\tiusb.sys
-i386\ser2pl.sys
.Set DestinationDir=win10\x86
x86\libusbK.sys
x86\libusb0_x86.dll
x86\libusbK_x86.dll
x86\WdfCoInstaller01009.dll
x86\WdfCoInstaller01011.dll
-
diff --git a/resources/win/win10/amd64/WdfCoInstaller01009.dll b/resources/win/win10/amd64/WdfCoInstaller01009.dll
index 53719c6a64..30cd0aa50a 100644
Binary files a/resources/win/win10/amd64/WdfCoInstaller01009.dll and b/resources/win/win10/amd64/WdfCoInstaller01009.dll differ
diff --git a/resources/win/win10/amd64/ftbusui.dll b/resources/win/win10/amd64/ftbusui.dll
new file mode 100644
index 0000000000..34e7bd104e
Binary files /dev/null and b/resources/win/win10/amd64/ftbusui.dll differ
diff --git a/resources/win/win10/amd64/ftcserco.dll b/resources/win/win10/amd64/ftcserco.dll
index 8cb797744a..5ac26e8992 100644
Binary files a/resources/win/win10/amd64/ftcserco.dll and b/resources/win/win10/amd64/ftcserco.dll differ
diff --git a/resources/win/win10/amd64/ftd2xx.lib b/resources/win/win10/amd64/ftd2xx.lib
new file mode 100644
index 0000000000..8a04fec439
Binary files /dev/null and b/resources/win/win10/amd64/ftd2xx.lib differ
diff --git a/resources/win/win10/amd64/ftd2xx64.dll b/resources/win/win10/amd64/ftd2xx64.dll
new file mode 100644
index 0000000000..b41371c2db
Binary files /dev/null and b/resources/win/win10/amd64/ftd2xx64.dll differ
diff --git a/resources/win/win10/amd64/ftdibus.sys b/resources/win/win10/amd64/ftdibus.sys
new file mode 100644
index 0000000000..434bb73847
Binary files /dev/null and b/resources/win/win10/amd64/ftdibus.sys differ
diff --git a/resources/win/win10/amd64/ftlang.dll b/resources/win/win10/amd64/ftlang.dll
new file mode 100644
index 0000000000..a60b289eb4
Binary files /dev/null and b/resources/win/win10/amd64/ftlang.dll differ
diff --git a/resources/win/win10/amd64/ftser2k.sys b/resources/win/win10/amd64/ftser2k.sys
index c8fe96afe6..be5313f62b 100644
Binary files a/resources/win/win10/amd64/ftser2k.sys and b/resources/win/win10/amd64/ftser2k.sys differ
diff --git a/resources/win/win10/amd64/ftserui2.dll b/resources/win/win10/amd64/ftserui2.dll
index a4a809a219..0dc0476cd9 100644
Binary files a/resources/win/win10/amd64/ftserui2.dll and b/resources/win/win10/amd64/ftserui2.dll differ
diff --git a/resources/win/win10/amd64/libusb0.dll b/resources/win/win10/amd64/libusb0.dll
index 804bce49cc..930623370a 100644
Binary files a/resources/win/win10/amd64/libusb0.dll and b/resources/win/win10/amd64/libusb0.dll differ
diff --git a/resources/win/win10/amd64/libusbK.dll b/resources/win/win10/amd64/libusbK.dll
index 71bc4375aa..cdf9724091 100644
Binary files a/resources/win/win10/amd64/libusbK.dll and b/resources/win/win10/amd64/libusbK.dll differ
diff --git a/resources/win/win10/amd64/libusbK.sys b/resources/win/win10/amd64/libusbK.sys
index e46a878987..6a4518872d 100644
Binary files a/resources/win/win10/amd64/libusbK.sys and b/resources/win/win10/amd64/libusbK.sys differ
diff --git a/resources/win/win10/amd64/ser2pl64.sys b/resources/win/win10/amd64/ser2pl64.sys
index 6246c5305a..1a06faee04 100644
Binary files a/resources/win/win10/amd64/ser2pl64.sys and b/resources/win/win10/amd64/ser2pl64.sys differ
diff --git a/resources/win/win10/amd64/silabser.sys b/resources/win/win10/amd64/silabser.sys
index 85a75e40d5..678184541c 100644
Binary files a/resources/win/win10/amd64/silabser.sys and b/resources/win/win10/amd64/silabser.sys differ
diff --git a/resources/win/win10/amd64/tiusb.sys b/resources/win/win10/amd64/tiusb.sys
index 0a39b5024e..449282fbc9 100644
Binary files a/resources/win/win10/amd64/tiusb.sys and b/resources/win/win10/amd64/tiusb.sys differ
diff --git a/resources/win/win10/ftdibus.cat b/resources/win/win10/ftdibus.cat
new file mode 100644
index 0000000000..e658901207
Binary files /dev/null and b/resources/win/win10/ftdibus.cat differ
diff --git a/resources/win/win10/ftdibus.inf b/resources/win/win10/ftdibus.inf
new file mode 100644
index 0000000000..12d0b4287c
--- /dev/null
+++ b/resources/win/win10/ftdibus.inf
@@ -0,0 +1,160 @@
+; FTDIBUS.INF
+; Copyright (c) 2000-2012 FTDI Ltd.
+; Custom FTDIBUS.INF file generated using 'FT INF Generator' for Bayer HealthCare LLC
+;
+; USB serial converter driver installation for Windows 2000, XP, Server 2003, Vista, Server 2008,
+; Windows 7 and Server 2008 R2 (x86 and x64).
+;
+;
+; THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED ``AS IS'' AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+; FTDI DRIVERS MAY BE USED ONLY IN CONJUNCTION WITH PRODUCTS BASED ON FTDI PARTS.
+
+; FTDI DRIVERS MAY BE DISTRIBUTED IN ANY FORM AS LONG AS LICENSE INFORMATION IS NOT MODIFIED.
+
+; IF A CUSTOM VENDOR ID AND/OR PRODUCT ID OR DESCRIPTION STRING ARE USED, IT IS THE RESPONSIBILITY OF
+; THE PRODUCT MANUFACTURER TO MAINTAIN ANY CHANGES AND SUBSEQUENT WHQL RE-CERTIFICATION AS A RESULT OF
+; MAKING THESE CHANGES.
+;
+[Version]
+Signature="$Windows NT$"
+DriverPackageType=PlugAndPlay
+DriverPackageDisplayName=%DESC%
+Class=USB
+ClassGUID={36fc9e60-c465-11cf-8056-444553540000}
+Provider=%FTDI%
+CatalogFile=ftdibus.cat
+DriverVer=02/27/2013,2.08.28
+
+[SourceDisksNames]
+1=%DriversDisk%,,,
+
+[SourceDisksFiles]
+ftdibus.sys = 1,i386
+ftbusui.dll = 1,i386
+ftd2xx.dll = 1,i386
+FTLang.Dll = 1,i386
+
+[SourceDisksFiles.amd64]
+ftdibus.sys = 1,amd64
+ftbusui.dll = 1,amd64
+ftd2xx64.dll = 1,amd64
+ftd2xx.dll = 1,i386
+FTLang.Dll = 1,amd64
+
+[DestinationDirs]
+FtdiBus.NT.Copy = 10,system32\drivers
+FtdiBus.NT.Copy2 = 10,system32
+FtdiBus.NTamd64.Copy = 10,system32\drivers
+FtdiBus.NTamd64.Copy2 = 10,system32
+FtdiBus.NTamd64.Copy3 = 10,syswow64
+
+[Manufacturer]
+%Ftdi%=FtdiHw,NTamd64
+
+[FtdiHw]
+%USB\VID_1A79&PID_6001.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6001
+%USB\VID_1A79&PID_6011&MI_00.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_00
+%USB\VID_1A79&PID_6011&MI_01.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_01
+%USB\VID_1A79&PID_6011&MI_02.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_02
+%USB\VID_1A79&PID_6011&MI_03.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6011&MI_03
+%USB\VID_1A79&PID_6010&MI_00.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6010&MI_00
+%USB\VID_1A79&PID_6010&MI_01.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6010&MI_01
+%USB\VID_1A79&PID_6014.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6014
+%USB\VID_1A79&PID_6015.DeviceDesc%=FtdiBus.NT,USB\VID_1A79&PID_6015
+
+[FtdiHw.NTamd64]
+%USB\VID_1A79&PID_6001.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6001
+%USB\VID_1A79&PID_6011&MI_00.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_00
+%USB\VID_1A79&PID_6011&MI_01.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_01
+%USB\VID_1A79&PID_6011&MI_02.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_02
+%USB\VID_1A79&PID_6011&MI_03.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6011&MI_03
+%USB\VID_1A79&PID_6010&MI_00.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6010&MI_00
+%USB\VID_1A79&PID_6010&MI_01.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6010&MI_01
+%USB\VID_1A79&PID_6014.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6014
+%USB\VID_1A79&PID_6015.DeviceDesc%=FtdiBus.NTamd64,USB\VID_1A79&PID_6015
+
+[ControlFlags]
+ExcludeFromSelect=*
+
+[FtdiBus.NT]
+CopyFiles=FtdiBus.NT.Copy,FtdiBus.NT.Copy2
+AddReg=FtdiBus.NT.AddReg
+
+[FtdiBus.NT.HW]
+AddReg=FtdiBus.NT.HW.AddReg
+
+[FtdiBus.NTamd64]
+CopyFiles=FtdiBus.NTamd64.Copy,FtdiBus.NTamd64.Copy2,FtdiBus.NTamd64.Copy3
+AddReg=FtdiBus.NT.AddReg
+
+[FtdiBus.NTamd64.HW]
+AddReg=FtdiBus.NT.HW.AddReg
+
+[FtdiBus.NT.Services]
+AddService = FTDIBUS, 0x00000002, FtdiBus.NT.AddService
+
+[FtdiBus.NTamd64.Services]
+AddService = FTDIBUS, 0x00000002, FtdiBus.NT.AddService
+
+[FtdiBus.NT.AddService]
+DisplayName = %SvcDesc%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %10%\system32\drivers\ftdibus.sys
+LoadOrderGroup = Base
+AddReg = FtdiBus.NT.AddService.AddReg
+
+[FtdiBus.NT.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,ftdibus.sys
+HKR,,EnumPropPages32,,"ftbusui.dll,FTBUSUIPropPageProvider"
+
+[FtdiBus.NT.HW.AddReg]
+HKR,,"USBTimeout",0x00010001,5000
+
+[FtdiBus.NT.AddService.AddReg]
+HKR,Parameters,"RetryResetCount",0x10001,50
+
+[FtdiBus.NT.Copy]
+ftdibus.sys
+
+[FtdiBus.NT.Copy2]
+ftbusui.dll
+ftd2xx.dll
+FTLang.dll
+
+[FtdiBus.NTamd64.Copy]
+ftdibus.sys
+
+[FtdiBus.NTamd64.Copy2]
+ftbusui.dll
+ftd2xx.dll,ftd2xx64.dll
+FTLang.dll
+
+[FtdiBus.NTamd64.Copy3]
+ftd2xx.dll
+
+[Strings]
+Ftdi="Bayer HealthCare LLC"
+DESC="CDM Driver Package"
+DriversDisk="FTDI USB Drivers Disk"
+USB\VID_1A79&PID_6001.DeviceDesc="Bayer USB Serial Converter"
+USB\VID_1A79&PID_6011&MI_00.DeviceDesc="Bayer USB Serial Converter A"
+USB\VID_1A79&PID_6011&MI_01.DeviceDesc="Bayer USB Serial Converter B"
+USB\VID_1A79&PID_6011&MI_02.DeviceDesc="Bayer USB Serial Converter C"
+USB\VID_1A79&PID_6011&MI_03.DeviceDesc="Bayer USB Serial Converter D"
+USB\VID_1A79&PID_6010&MI_00.DeviceDesc="Bayer USB Serial Converter A"
+USB\VID_1A79&PID_6010&MI_01.DeviceDesc="Bayer USB Serial Converter B"
+USB\VID_1A79&PID_6014.DeviceDesc="Bayer USB Serial Converter"
+USB\VID_1A79&PID_6015.DeviceDesc="Bayer USB Serial Converter"
+SvcDesc="Bayer USB Serial Converter Driver"
+ClassName="USB"
diff --git a/resources/win/win10/i386/ftbusui.dll b/resources/win/win10/i386/ftbusui.dll
new file mode 100644
index 0000000000..a5b7d48afe
Binary files /dev/null and b/resources/win/win10/i386/ftbusui.dll differ
diff --git a/resources/win/win10/i386/ftcserco.dll b/resources/win/win10/i386/ftcserco.dll
index deecedd5d9..77e985ea1c 100644
Binary files a/resources/win/win10/i386/ftcserco.dll and b/resources/win/win10/i386/ftcserco.dll differ
diff --git a/resources/win/win10/i386/ftd2xx.dll b/resources/win/win10/i386/ftd2xx.dll
new file mode 100644
index 0000000000..34f1e6df12
Binary files /dev/null and b/resources/win/win10/i386/ftd2xx.dll differ
diff --git a/resources/win/win10/i386/ftd2xx.lib b/resources/win/win10/i386/ftd2xx.lib
new file mode 100644
index 0000000000..b2e0a53b31
Binary files /dev/null and b/resources/win/win10/i386/ftd2xx.lib differ
diff --git a/resources/win/win10/i386/ftdibus.sys b/resources/win/win10/i386/ftdibus.sys
new file mode 100644
index 0000000000..f1ec28dc9b
Binary files /dev/null and b/resources/win/win10/i386/ftdibus.sys differ
diff --git a/resources/win/win10/i386/ftlang.dll b/resources/win/win10/i386/ftlang.dll
new file mode 100644
index 0000000000..5a9e2fea97
Binary files /dev/null and b/resources/win/win10/i386/ftlang.dll differ
diff --git a/resources/win/win10/i386/ftser2k.sys b/resources/win/win10/i386/ftser2k.sys
index 9d599be7b2..801997b8fa 100644
Binary files a/resources/win/win10/i386/ftser2k.sys and b/resources/win/win10/i386/ftser2k.sys differ
diff --git a/resources/win/win10/i386/ftserui2.dll b/resources/win/win10/i386/ftserui2.dll
index fb7f9b9ddb..c11940181b 100644
Binary files a/resources/win/win10/i386/ftserui2.dll and b/resources/win/win10/i386/ftserui2.dll differ
diff --git a/resources/win/win10/i386/ser2pl.sys b/resources/win/win10/i386/ser2pl.sys
index cff2a5a5c2..9a7c41ed7f 100644
Binary files a/resources/win/win10/i386/ser2pl.sys and b/resources/win/win10/i386/ser2pl.sys differ
diff --git a/resources/win/win10/i386/silabser.sys b/resources/win/win10/i386/silabser.sys
index debd7d0ea1..6d934b539a 100644
Binary files a/resources/win/win10/i386/silabser.sys and b/resources/win/win10/i386/silabser.sys differ
diff --git a/resources/win/win10/i386/tiusb.sys b/resources/win/win10/i386/tiusb.sys
index c5a060ce76..a325015596 100644
Binary files a/resources/win/win10/i386/tiusb.sys and b/resources/win/win10/i386/tiusb.sys differ
diff --git a/resources/win/win10/tidepoolhid.cat b/resources/win/win10/tidepoolhid.cat
index 735d1acc60..2adac8c849 100644
Binary files a/resources/win/win10/tidepoolhid.cat and b/resources/win/win10/tidepoolhid.cat differ
diff --git a/resources/win/win10/tidepoolusb.cat b/resources/win/win10/tidepoolusb.cat
index 41825714c3..51013c09f0 100644
Binary files a/resources/win/win10/tidepoolusb.cat and b/resources/win/win10/tidepoolusb.cat differ
diff --git a/resources/win/win10/tidepoolvcp.cat b/resources/win/win10/tidepoolvcp.cat
index 57b272dfa1..4d294b1888 100644
Binary files a/resources/win/win10/tidepoolvcp.cat and b/resources/win/win10/tidepoolvcp.cat differ
diff --git a/resources/win/win10/tidepoolvcp.inf b/resources/win/win10/tidepoolvcp.inf
index 241f64f1ff..49c031bc8a 100644
--- a/resources/win/win10/tidepoolvcp.inf
+++ b/resources/win/win10/tidepoolvcp.inf
@@ -29,6 +29,19 @@
; USB serial port driver installation file for Windows 2000, XP, Server 2003, Vista, Server 2008,
; Windows 7, Server 2008 R2, Windows 8, Windows 8.1 and Server 2012 R2.
;
+; THIS SOFTWARE IS PROVIDED BY FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED ``AS IS'' AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FUTURE TECHNOLOGY DEVICES INTERNATIONAL LIMITED
+; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+
+; FTDI DRIVERS MAY BE USED ONLY IN CONJUNCTION WITH PRODUCTS BASED ON FTDI PARTS.
+
+; FTDI DRIVERS MAY BE DISTRIBUTED IN ANY FORM AS LONG AS LICENSE INFORMATION IS NOT MODIFIED.
+;
; Texas Instruments:
; Texas Instruments Driver Installation file for a UMP Device main driver.
; UMP installation file for TIUSB3410 and TIUSB5052
@@ -43,7 +56,7 @@ DriverPackageDisplayName=%DESC%
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%Provider%
-DriverVer=07/27/2016,1.4.1.0
+DriverVer=03/16/2020,1.5.0.2
CatalogFile=tidepoolvcp.cat
; ================= Device section =====================
@@ -62,6 +75,7 @@ CatalogFile=tidepoolvcp.cat
%VID_0403&PID_6015.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_0403&PID_6015
%VID_0403&PID_0000.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_0403&PID_0000
%VID_0403&PID_7F38.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_0403&PID_7F38 ; Asante Snap FTDI cable
+%VID_1A79&PID_6001.DeviceDesc%=FtdiPort.NTx86,FTDIBUS\COMPORT&VID_1A79&PID_6001 ; Bayer cable
%PID_3410.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3410 ; Abbott FreeStyle USB Data Cable
%PID_3420.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3420 ; Abbott Strip Port USB Data Cable
%VID_067B&PID_2303.DeviceDesc% = ComPort.NTx86, USB\VID_067B&PID_2303 ; Prolific PL2303
@@ -78,6 +92,7 @@ CatalogFile=tidepoolvcp.cat
%VID_0403&PID_6015.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_6015
%VID_0403&PID_0000.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_0000
%VID_0403&PID_7F38.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_7F38 ; Asante Snap FTDI cable
+%VID_1A79&PID_6001.DeviceDesc%=FtdiPort.NTamd64,FTDIBUS\COMPORT&VID_1A79&PID_6001 ; Bayer cable
%PID_3410.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3410 ; Abbott FreeStyle USB Data Cable
%PID_3420.DeviceDesc%=TI.Uni,USB\VID_1A61&PID_3420 ; Abbott Strip Port USB Data Cable
%VID_067B&PID_2303.DeviceDesc% = ComPort.NTamd64, USB\VID_067B&PID_2303 ; Prolific PL2303
@@ -237,15 +252,17 @@ AddReg=FtdiPort.NT.HW.AddReg
[FtdiPort.NTx86.Services]
AddService = FTSER2K, 0x00000002, FtdiPort.NT.AddService
+AddService=serenum,,SerenumService
DelService = FTSERIAL
[FtdiPort.NTamd64.Services]
AddService = FTSER2K, 0x00000002, FtdiPort.NT.AddService
+AddService=serenum,,SerenumService
DelService = FTSERIAL
[FtdiPort.NT.HW.AddReg]
HKR,,"UpperFilters",0x00010000,"serenum"
-HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00
+HKR,,"ConfigData",1,17,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,C0,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,00,01,00
HKR,,"MinReadTimeout",0x00010001,0
HKR,,"MinWriteTimeout",0x00010001,0
HKR,,"LatencyTimer",0x00010001,16
@@ -423,6 +440,7 @@ VID_0403&PID_6014.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
VID_0403&PID_6015.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
VID_0403&PID_0000.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
VID_0403&PID_7F38.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
+VID_1A79&PID_6001.DeviceDesc="Tidepool USB Driver (FTDI chipset)"
PID_3410.DeviceDesc="Tidepool USB Driver (TI chipset)"
PID_3420.DeviceDesc="Tidepool USB Driver (TI chipset)"
VID_067B&PID_2303.DeviceDesc="Tidepool USB Driver (Prolific chipset)"
diff --git a/resources/win/win10/x64/WdfCoInstaller01009.dll b/resources/win/win10/x64/WdfCoInstaller01009.dll
index 5f17411a17..2ae8d7f30f 100644
Binary files a/resources/win/win10/x64/WdfCoInstaller01009.dll and b/resources/win/win10/x64/WdfCoInstaller01009.dll differ
diff --git a/resources/win/win10/x64/WdfCoInstaller01011.dll b/resources/win/win10/x64/WdfCoInstaller01011.dll
index 516a3a96e0..05c9b2fd6f 100644
Binary files a/resources/win/win10/x64/WdfCoInstaller01011.dll and b/resources/win/win10/x64/WdfCoInstaller01011.dll differ
diff --git a/resources/win/win10/x86/WdfCoInstaller01009.dll b/resources/win/win10/x86/WdfCoInstaller01009.dll
index ef51526ff9..8f93381788 100644
Binary files a/resources/win/win10/x86/WdfCoInstaller01009.dll and b/resources/win/win10/x86/WdfCoInstaller01009.dll differ
diff --git a/resources/win/win10/x86/WdfCoInstaller01011.dll b/resources/win/win10/x86/WdfCoInstaller01011.dll
index b75e97def5..10f15a7cb1 100644
Binary files a/resources/win/win10/x86/WdfCoInstaller01011.dll and b/resources/win/win10/x86/WdfCoInstaller01011.dll differ
diff --git a/resources/win/win10/x86/libusb0_x86.dll b/resources/win/win10/x86/libusb0_x86.dll
index a1a4e3c656..3923235d05 100644
Binary files a/resources/win/win10/x86/libusb0_x86.dll and b/resources/win/win10/x86/libusb0_x86.dll differ
diff --git a/resources/win/win10/x86/libusbK.sys b/resources/win/win10/x86/libusbK.sys
index 8be2348044..939fd03b4b 100644
Binary files a/resources/win/win10/x86/libusbK.sys and b/resources/win/win10/x86/libusbK.sys differ
diff --git a/resources/win/win10/x86/libusbK_x86.dll b/resources/win/win10/x86/libusbK_x86.dll
index 098604ad9e..8ed0feba1b 100644
Binary files a/resources/win/win10/x86/libusbK_x86.dll and b/resources/win/win10/x86/libusbK_x86.dll differ
diff --git a/yarn.lock b/yarn.lock
index 3bf013ac73..a16ce7ce2b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2356,6 +2356,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.24.tgz#d4606afd8cf6c609036b854360367d1b2c78931f"
integrity sha512-1Ciqv9pqwVtW6FsIUKSZNB82E5Cu1I2bBTj1xuIHXLe/1zYLl3956Nbhg2MzSYHVfl9/rmanjbQIb7LibfCnug==
+"@types/node@^8.0.54":
+ version "8.10.59"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.59.tgz#9e34261f30183f9777017a13d185dfac6b899e04"
+ integrity sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==
+
"@types/prop-types@*":
version "15.7.1"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6"
@@ -2393,6 +2398,18 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
+"@types/usb@^1.5.1":
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/@types/usb/-/usb-1.5.1.tgz#7ade8ea0135089c9fbc1d2148084a3013fc4128f"
+ integrity sha512-1qhcYMLJ0I2HcRG3G/nBcRZ0KrrTdGdUNcCkEVgcga4KMlDXWh6LZJjVA6MiWEDa+BOaQTEfGJfuNaQ71IQOpg==
+ dependencies:
+ "@types/node" "*"
+
+"@types/w3c-web-usb@^1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@types/w3c-web-usb/-/w3c-web-usb-1.0.4.tgz#57e4181041dc1ad2bfad59b737caa7bddc7e1a27"
+ integrity sha512-aaOB3EL5WCWBBOYX7W1MKuzspOM9ZJI9s3iziRVypr1N+QyvIgXzCM4lm1iiOQ1VFzZioUPX9bsa23myCbKK4A==
+
"@types/webdriverio@^4.8.0":
version "4.13.3"
resolved "https://registry.yarnpkg.com/@types/webdriverio/-/webdriverio-4.13.3.tgz#c1571c4e62724135c0b11e7d7e36b07af5168856"
@@ -7148,6 +7165,13 @@ fstream@^1.0.0, fstream@^1.0.12, fstream@~1.0.10, fstream@~1.0.11:
mkdirp ">=0.5 0"
rimraf "2"
+ftdi-js@0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/ftdi-js/-/ftdi-js-0.0.6.tgz#2ea1d8953d105cc50471fb124df55388981ea0cc"
+ integrity sha512-o7sPXX3TS82zs65SWYlMylFMpvD3euhXI5MgsqIQrvIAHJK/qe7eCznwV8MSizCe8l/PaPv1Q4Bj9Ztke3YQwg==
+ dependencies:
+ webusb "2.0.1"
+
ftp@0.3.10:
version "0.3.10"
resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d"
@@ -10235,7 +10259,7 @@ minimist@0.0.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
+minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
@@ -15477,6 +15501,15 @@ usb@1.6.0, usb@^1.3.1:
nan "2.13.2"
prebuild-install "^5.2.4"
+usb@^1.6.0:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/usb/-/usb-1.6.2.tgz#4ed7f0d8631c70192b33635f6a4e700d9e6bfe62"
+ integrity sha512-KcovLXRQuH63iEtnqXyDQGOi5dXHpLM5lZBIUsqSJQToua8nL2sVCieQTkzQBfLe5mCuvk40MgKciI61lgevWw==
+ dependencies:
+ bindings "^1.4.0"
+ nan "2.13.2"
+ prebuild-install "^5.3.3"
+
use@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
@@ -15884,6 +15917,16 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
+webusb@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/webusb/-/webusb-2.0.1.tgz#97293cf63657d8376ec097831031537f83d2629d"
+ integrity sha512-r8bv1s2qa6jMe1kI0YoHfiWPOtG4M6BVArnAJS1GaYx3KP6gSw2gKZeFKMCr632B0KVDVji4+XdZZsc/BnkgBQ==
+ dependencies:
+ "@types/node" "^8.0.54"
+ "@types/usb" "^1.5.1"
+ "@types/w3c-web-usb" "^1.0.4"
+ usb "^1.6.0"
+
wgxpath@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wgxpath/-/wgxpath-1.0.0.tgz#eef8a4b9d558cc495ad3a9a2b751597ecd9af690"