Skip to content

Instantly share code, notes, and snippets.

@JosePedroDias
Created October 5, 2016 11:42
Show Gist options
  • Save JosePedroDias/754642ce43f7f75c51aefeedf316e996 to your computer and use it in GitHub Desktop.
Save JosePedroDias/754642ce43f7f75c51aefeedf316e996 to your computer and use it in GitHub Desktop.
wifi location server (draft). using the find android client here: https://github.com/schollz/find
'use strict';
const fs = require('fs');
const http = require('http');
const os = require('os');
const HEADERS = {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
};
const FILE = 'reads.json';
const PORT = 6789;
function time() {
const d = new Date();
return d.toTimeString().split(' ')[0];
}
function getMyIPs() {
const ips = {};
const ifaces = os.networkInterfaces();
for (let dev in ifaces) {
ifaces[dev].forEach((details) => {
if (details.family === 'IPv4') {
ips[dev] = details.address;
}
});
}
return ips;
};
function getMyIP() {
const o = getMyIPs();
for (let k in o) {
const v = o[k];
if (v !== '127.0.0.1') {
return v;
}
}
}
function load() {
try {
return JSON.parse( fs.readFileSync(FILE).toString() );
} catch (ex) {}
}
function save(o) {
try {
fs.writeFileSync(FILE, JSON.stringify(o));
return true;
} catch (ex) {}
}
function returnJSON(res, o, isError) {
res.writeHead(isError ? 500 : 200, HEADERS);
return res.end(JSON.stringify(o));
}
function clone(o) {
return JSON.parse( JSON.stringify(o) );
}
function byMac(a, b) {
a = a.mac;
b = b.mac;
if (a < b) { return -1; }
if (a > b) { return 1; }
return 0;
}
function arrayOfMacs(o) {
o = clone(o).sort(byMac);
return o.map((row) => { return row.mac; })
}
function cmpMacs(a, b) {
const o = {a:0, b:0, both:0};
a.forEach((k) => {
if (b.indexOf(k) !== -1) { ++o.both; }
else { ++o.a; }
});
b.forEach((k) => {
if (a.indexOf(k) === -1) { ++o.b; }
});
return o;
}
function calc(reads, read) {
const r0 = arrayOfMacs(read);
let bestH = 0;
let bestV = '?';
for (let k in reads) {
const r = arrayOfMacs(reads[k]);
const d = cmpMacs(r0, r);
const h = d.both - d.a/10 - d.b/20;
if (h > bestH) {
bestV = k;
bestH = h;
}
console.log('diff against ' + k, d, h);
}
console.log('BEST: ' + bestV);
return {h:bestH, v:bestV};
}
let latestRead = [];
const namedReads = load() || {};
console.log(`named reads loaded: ${Object.keys(namedReads).length}`);
http.createServer((req, res) => {
if (req.url === '/favicon.ico') {
res.writeHead(200, {'Content-Type': 'image/x-icon'} );
return res.end();
}
console.log(`${time()} - ${req.method} ${req.url}`);
if (req.url === '/latest') {
return returnJSON(res, latestRead);
}
if (req.url === '/reads') {
return returnJSON(res, namedReads);
}
const body = [];
req.on('data', function(chunk) {
body.push(chunk.toString());
});
req.on('end', function() {
// if (body.length === 0) { return; }
try {
const o = JSON.parse( body.join('') );
latestRead = o['wifi-fingerprint'];
if (req.url === '/learn') {
namedReads[o.location] = latestRead;
save(namedReads);
console.log('learn', o.location, latestRead);
return returnJSON(res, 'ok');
} else { // location === 'tracking'
let loc = calc(namedReads, latestRead);
//console.log('track', latestRead, '->', loc);
console.log('track', loc);
return returnJSON(res, loc);
}
} catch (ex) {
console.error(ex);
return returnJSON(res, ex.toString() + ex.stack, true);
}
});
}).listen(PORT);
const ip = getMyIP();
console.log(`Running WIFI location server on port http://${ip}:${PORT} ...`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment