wpilib-riolog
Version:
228 lines • 7.19 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const net = require("net");
const timers = require("timers");
async function properRace(promises) {
if (promises.length < 1) {
return Promise.reject('Can\'t start a race without promises!');
}
// There is no way to know which promise is rejected.
// So we map it to a new promise to return the index when it fails
const indexPromises = promises.map((p, index) => p.catch(() => { throw index; }));
try {
return await Promise.race(indexPromises);
}
catch (index) {
// The promise has rejected, remove it from the list of promises and just continue the race.
console.log('reject promise');
// tslint:disable-next-line:no-unsafe-any
const p = promises.splice(index, 1)[0];
p.catch((e) => console.log('A promise has been rejected, but awaiting others', e));
return properRace(promises);
}
}
const constantIps = [
'172.22.11.2',
'127.0.0.1',
];
const teamIps = [
'roboRIO-TEAM-FRC.local',
'roboRIO-TEAM-FRC.lan',
'roboRIO-TEAM-FRC.frc-field.local',
];
function timerPromise(ms) {
let timer;
return {
promise: new Promise((resolve, _) => {
timer = timers.setTimeout(() => {
resolve(undefined);
}, ms);
}),
cancel() {
if (timer === undefined) {
return;
}
console.log('cancelled timer');
timers.clearTimeout(timer);
},
};
}
class DSSocketPromisePair {
constructor(rs, ds, p) {
this.socket = rs;
this.promise = p;
this.dsSocket = ds;
}
dispose() {
this.socket.emit('dispose');
this.dsSocket.emit('dispose');
}
}
function getSocketFromDS(port) {
const s = new net.Socket();
const ds = new net.Socket();
const retVal = new DSSocketPromisePair(s, ds, new Promise((resolve, reject) => {
// First connect to ds, and wait for data
ds.on('data', (data) => {
const parsed = JSON.parse(data.toString());
if (parsed.robotIP === 0) {
ds.end();
ds.destroy();
ds.removeAllListeners();
reject();
return;
}
let ipAddr = '';
const ip = parsed.robotIP;
// tslint:disable-next-line:no-bitwise
ipAddr += ((ip >> 24) & 0xff) + '.';
// tslint:disable-next-line:no-bitwise
ipAddr += ((ip >> 16) & 0xff) + '.';
// tslint:disable-next-line:no-bitwise
ipAddr += ((ip >> 8) & 0xff) + '.';
// tslint:disable-next-line:no-bitwise
ipAddr += (ip & 0xff);
s.on('error', (_) => {
console.log('failed connection to ' + ip + ' at ' + port);
s.end();
s.destroy();
s.removeAllListeners();
reject();
});
s.on('timeout', () => {
console.log('failed connection to ' + ip + ' at ' + port);
s.end();
s.destroy();
s.removeAllListeners();
reject();
});
s.on('close', () => {
console.log('failed connection to ' + ip + ' at ' + port);
s.end();
s.destroy();
s.removeAllListeners();
reject();
});
s.on('dispose', () => {
console.log('disposed ds connected');
reject();
s.end();
s.destroy();
s.removeAllListeners();
});
s.connect(port, ipAddr, () => {
s.removeAllListeners();
resolve(s);
});
ds.end();
ds.destroy();
ds.removeAllListeners();
});
ds.on('error', () => {
reject();
});
ds.on('dispose', () => {
console.log('disposed ds');
reject();
ds.end();
ds.destroy();
ds.removeAllListeners();
});
ds.connect(1742, '127.0.0.1');
}));
return retVal;
}
class RawSocketPromisePair {
constructor(rs, p) {
this.socket = rs;
this.promise = p;
}
dispose() {
this.socket.emit('dispose');
}
}
function getSocketFromIP(port, ip) {
const s = new net.Socket();
return new RawSocketPromisePair(s, new Promise((resolve, reject) => {
s.on('error', (_) => {
console.log('failed connection to ' + ip + ' at ' + port);
s.end();
s.destroy();
s.removeAllListeners();
reject();
});
s.on('timeout', () => {
console.log('failed connection to ' + ip + ' at ' + port);
s.end();
s.destroy();
s.removeAllListeners();
reject();
});
s.on('close', () => {
s.end();
s.destroy();
s.removeAllListeners();
reject();
});
s.on('dispose', () => {
console.log('disposed', ip);
reject();
s.end();
s.destroy();
s.removeAllListeners();
});
s.connect(port, ip, () => {
s.removeAllListeners();
resolve(s);
});
}));
}
async function connectToRobot(port, teamNumber, timeout) {
const pairs = [];
teamNumber = Math.trunc(teamNumber);
for (const c of constantIps) {
pairs.push(getSocketFromIP(port, c));
}
for (const c of teamIps) {
pairs.push(getSocketFromIP(port, c.replace('TEAM', teamNumber.toString())));
}
pairs.push(getSocketFromIP(port, `10.${Math.trunc(teamNumber / 100)}.${teamNumber % 100}.2`));
pairs.push(getSocketFromDS(port));
const connectors = [];
for (const p of pairs) {
connectors.push(p.promise);
}
const timer = timerPromise(timeout);
connectors.push(timer.promise);
const firstDone = await properRace(connectors);
if (firstDone === undefined) {
// Kill all
for (const p of pairs) {
p.dispose();
try {
await p.promise;
// tslint:disable-next-line:no-empty
}
catch (_a) {
}
}
}
else {
// Kill all but me
timer.cancel();
for (const p of pairs) {
if (firstDone !== p.socket) {
p.dispose();
try {
await p.promise;
// tslint:disable-next-line:no-empty
}
catch (_b) {
}
}
}
}
return firstDone;
}
exports.connectToRobot = connectToRobot;
//# sourceMappingURL=rioconnector.js.map