tools-survey.asp

 avatar
user_1586496
javascript
3 months ago
17 kB
17
Indexable
Never
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="robots" content="noindex,nofollow">
<title>[<% ident(); %>] Tools: Wireless Survey</title>
<link rel="stylesheet" type="text/css" href="tomato.css">
<% css(); %>
<script src="tomato.js"></script>
<style>
#ellipses2 { border: 1px solid #ccccdd; }
#ellipses5 { border: 1px solid #ccdddd; }
}
</style>
<script>
// <% nvram("wl0_radio,wl1_radio,wl2_radio,wl0_channel,wl1_channel,wl2_channel,wl0_nband,wl1_nband,wl2_nband,wl0_nbw,wl1_nbw,wl2_nbw,wl0_mode,wl1_mode,wl2_mode,wl0_nctrlsb,wl1_nctrlsb,wl2_nctrlsb,wl0_ssid,wl1_ssid,wl2_ssid"); %>
var w10_n = parseInt(nvram.wl0_nband);
var wl0_r = parseInt(nvram.wl0_radio);
var wl0_c = parseInt(nvram.wl0_channel);
var wl0_w = parseInt(nvram.wl0_nbw);
var wl0_m = nvram.wl0_mode;
var wl0_s = nvram.wl0_nctrlsb;
var wl0_d = nvram.wl0_ssid;
var w11_n = parseInt(nvram.wl1_nband);
var wl1_r = parseInt(nvram.wl1_radio);
var wl1_c = parseInt(nvram.wl1_channel);
var wl1_w = parseInt(nvram.wl1_nbw);
var wl1_m = nvram.wl1_mode;
var wl1_s = nvram.wl1_nctrlsb;
var wl1_d = nvram.wl1_ssid;
var w12_n = parseInt(nvram.wl2_nband);
var wl2_r = parseInt(nvram.wl2_radio);
var wl2_c = parseInt(nvram.wl2_channel);
var wl2_w = parseInt(nvram.wl2_nbw);
var wl2_m = nvram.wl2_mode;
var wl2_s = nvram.wl2_nctrlsb;
var wl2_d = nvram.wl2_ssid;
function hexToDecimal(hexColor) {
hexColor = hexColor.replace('#', '');
// Extract red, green, and blue components
var red = parseInt(hexColor.substring(0, 2), 16);
var green = parseInt(hexColor.substring(2, 4), 16);
var blue = parseInt(hexColor.substring(4, 6), 16);
// Return comma-separated decimal values
return red + ', ' + green + ', ' + blue;
}
var colors = [
    "FF6347", // Tomato
    "32CD32", // LimeGreen
    "4169E1", // RoyalBlue
    "FFD700", // Gold
    "FF69B4", // HotPink
    "00CED1", // DarkTurquoise
    "9932CC", // DarkOrchid
    "FFA500", // Orange
    "008080", // Teal
    "FFC0CB", // Pink
    "800000", // Maroon
    "808000", // Olive
    "008000", // Green
    "000080", // Navy
    "800080", // Purple
    "FFD700", // Gold
    "7FFFD4", // Aquamarine
    "A52A2A", // Brown
    "2E8B57", // SeaGreen
    "8A2BE2"  // BlueViolet
];
var limit=20;
var wlscandata = [];
var entries = [];
// var labelSelect = 'on';
var dayOfWeek = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
var cmd = null;
var ref = new TomatoRefresh('update.cgi', 'exec=wlscan', 0, 'tools_survey_refresh');
ref.refresh = function(text) {
try {
eval(text);
}
catch (ex) {
}
sg.removeAllData();
sg.populate();
sg.resort();
}
var sg = new TomatoGrid();
sg.setup = function() {
this.init('survey-grid','sort');
this.headerSet(['Last Seen','RGB','SSID','BSSID','RSSI &nbsp; &nbsp; ','Quality','Control<br>Channel','Security','Rates']);
this.populate();
this.sort(0);
}
function calculateCentralChannelForty(channel, sideband) {
    if (sideband.toLowerCase() === "upper") {
        return channel - 2;
    } else if (sideband.toLowerCase() === "lower") {
        return channel + 2;
    } else {
        return "Invalid sideband";
    }
}
function drawEllipse(c, m, q, col, ssid, alpha)
    {
				// console.log(c);
				// console.log(m);
				// console.log(q);
				// console.log(col);
		if (c<35){ var canvas  = document.getElementById("ellipses2");
        var ctx = canvas.getContext('2d');
		if (m==20) { mf = (canvas.width/19)*2.2; }
		else if (m==40){ mf = (canvas.width/19)*4.4; }
		if (c==1) { cf = (canvas.width/19)*3; }
		else if (c==14) { cf = ( canvas.width / 19) * 16.6 }
		else { cf = ((canvas.width/19)*3) + ((canvas.width/19)*(c-1)); }
		rf = q*2;
}
		else if (c>35){ var canvas  = document.getElementById("ellipses5");
        var ctx = canvas.getContext('2d');
		var cc = c;
		if (m==20) { mf = ((canvas.width/38)*0.45); }
		else if (m==40) { mf = ((canvas.width/38)*0.95); // 52 =54 [ 50 - 58 ] 
				cc = getDisplayChannel(c,m);				
				<!-- console.log(c); -->
				<!-- console.log(m); -->
				<!-- console.log(cc);  -->
				}
		else if (m==80) { mf = ((canvas.width/38)*1.8); // 100 = 106 [ 98 - 114 ]
				cc = getDisplayChannel(c,m); 
				<!-- console.log(c); -->
				<!-- console.log(m); -->
				<!-- console.log(cc);  -->
				} 
		cc = cc-36;
		cf = (canvas.width/38) + ((canvas.width/38)*(cc/4));
		rf = q * 2;
}	    
		ctx.beginPath();
		var decimalColor = hexToDecimal(col);
		if (typeof alpha === 'undefined') { var alpha = 0.65; }
		ctx.fillStyle = "rgba( " + decimalColor + ", " + alpha + ")";
		// ctx.fillStyle = "rgba( " + decimalColor + ", 0.6)";
        ctx.ellipse(cf, 200, mf, rf, 0, 0, 2 * Math.PI, false);
		ctx.strokeStyle = "#666666";
        ctx.stroke();
        ctx.fill();
		// if (labelSelect=='On') {
		ctx.save();
		ctx.fillStyle = "#000000"; // Black
        ctx.font = '8px Arial'; // Set your desired font style
        ctx.textAlign = 'center';
		ctx.textBaseline = "middle";
        ctx.fillText(ssid, cf, 206-rf);
		ctx.restore();
		// }
		ctx.closePath();
    }
function getDisplayChannel(channelNum, channelWidth) {
    const centerFreq40MHz = [38, 46, 54, 62, 102, 110, 118, 126, 134, 142, 151, 159, 167, 175];
    const centerFreq80MHz = [42, 58, 106, 122, 138, 155, 163];
    if (channelWidth === 80) {
        let minDiff = Infinity;
        let bestChannel = null;

        for (let i = 0; i < centerFreq80MHz.length; i++) {
            const diff = Math.abs(channelNum - centerFreq80MHz[i]);
            if (diff < minDiff) {
                minDiff = diff;
                bestChannel = centerFreq80MHz[i];
            }
        }
        return bestChannel;
    } else if (channelWidth === 40) {
        let minDiff = Infinity;
        let bestChannel = null;

        for (let i = 0; i < centerFreq40MHz.length; i++) {
            const diff = Math.abs(channelNum - centerFreq40MHz[i]);
            if (diff < minDiff) {
                minDiff = diff;
                bestChannel = centerFreq40MHz[i];
            }
        }
        return bestChannel;
    }
    return null;
}
function sortByProperty(array, property) {
array.sort(function(a, b) {
return b[property] - a[property];
});
return array;
}
sg.populate = function() {
var added = 0;
var removed = 0;
var i, j, k, t, e, s;
if ((wlscandata.length == 1) && (!wlscandata[0][0])) {
setMsg('error: '+wlscandata[0][1]);
return;
}
clearCanvas('ellipses2');
clearCanvas('ellipses5');
drawBoard('ellipses2');
drawBoard('ellipses5');
var lim2=1;
var lim5=1;
for (i = 0; i < wlscandata.length; ++i) {
s = wlscandata[i];
e = null;
sortByProperty(entries, "rssi");
// console.log(entries);
for (j = 0; j < entries.length; ++j) {
if (entries[j].bssid == s[0]) {
e = entries[j];
break;
}
}
if (!e) {
++added;
e = {};
e.firstSeen = new Date();
entries.push(e);
}
e.lastSeen = new Date();
e.bssid = s[0];
if (s[1] === '') {
// e.ssid = "\<\<\< H I D D E N \>\>\>";
e.ssid = "HIDDEN";
} else {
e.ssid = s[1];
}
e.channel = s[3];
e.channel = e.channel+'<br><small>'+s[9]+' GHz<\/small><br><small>'+s[4]+' MHz<\/small>';
e.rssi = s[2];
e.mhz = s[4];
e.cap = s[7]+ '<br>'+s[8];
e.rates = s[6];
if (e.rssi != -999) {
if (e.rssi >= -50)
e.qual = 100;
else if (e.rssi >= -80) 
e.qual = Math.round(24 + ((e.rssi + 80) * 26)/10);
else if (e.rssi >= -90) 
e.qual = Math.round(24 + ((e.rssi + 90) * 26)/10);
else
e.qual = 0;
}
else {
e.qual = -1;
}
}
t = E('expire-time').value;
if (t > 0) {
var cut = (new Date()).getTime() - (t * 1000);
for (i = 0; i < entries.length; ) {
if (entries[i].lastSeen.getTime() < cut) {
entries.splice(i, 1);
++removed;
}
else
++i;
}
}
drawFT();
for (i = 0; i < entries.length; ++i) {
var seen, m, mac;
e = entries[i];
seen = e.lastSeen.toWHMS();
if (useAjax()) {
m = Math.floor(((new Date()).getTime() - e.firstSeen.getTime()) / 60000);
if (m <= 10)
seen += '<br> <b><small>NEW ('+m+'m)<\/small><\/b>';
}
mac = e.bssid;
var chan = e.channel.split("<");
if (lim2<=limit && chan[0]<35) {
var decimalColor = hexToDecimal(colors[i]);
e.col = '<div style="padding: 5px; width: 15px; height: 30px; background-color: rgba(' + decimalColor +', 0.8);"></div>';
drawEllipse(chan[0], e.mhz, (100+e.rssi), colors[i], e.ssid);
lim2++;
} else if (lim2>limit && chan[0]<35) {
e.col = '<div></div>';
} else if (lim5<=limit && chan[0]>35) {
var decimalColor = hexToDecimal(colors[i]);
e.col = '<div style="padding: 5px; width: 15px; height: 30px; background-color: rgba(' + decimalColor +', 0.8);"></div>';
drawEllipse(chan[0], e.mhz, (100+e.rssi), colors[i], e.ssid);
lim5++;
} else if (lim5>limit && chan[0]>35) {
e.col = '<div></div>';
}

console.log(chan[0]);
console.log(lim2);
console.log(lim5);
console.log(e.col);

if (mac.match(/^(..):(..):(..)/))
mac = '<a href="javascript:searchOUI(\''+RegExp.$1+'-'+RegExp.$2+'-'+RegExp.$3+'\','+i+')" title="OUI Search">'+mac+'<\/a><div style="display:none" id="gW_'+i+'">&nbsp; <img src="spin.gif" alt="" style="vertical-align:middle"><\/div>';
sg.insert(-1, e, [ '<small>'+seen+'<\/small>', ''+e.col, ''+e.ssid, mac, (e.rssi < 0 ? e.rssi+' <small>dBm<\/small>' : ''),
(e.qual < 0 ? '' : '<small>'+e.qual+'<\/small> <img src="bar'+MIN(MAX(Math.floor(e.qual / 12), 1), 6)+'.gif" id="bar_'+i+'" alt="">'),
''+e.channel, ''+e.cap, ''+e.rates], false);
}
drawCoordinates('ellipses2', -2, 17, 1, 13, 19, 1); //min, max, display min, display max, total num, increment
drawCoordinates('ellipses5', 32, 184, 36, 180, 38, 4);
s = '';
if (useAjax())
s = added+' added, '+removed+' removed, ';
s += entries.length+' total.';
s += '<br><br><small>Last updated: '+(new Date()).toWHMS()+'<\/small>';
setMsg(s);
wlscandata = [];
}
sg.sortCompare = function(a, b) {
var col = this.sortColumn;
var da = a.getRowData();
var db = b.getRowData();
var r;
switch (col) {
case 0:
r = -cmpDate(da.lastSeen, db.lastSeen);
break;
case 3:
r = cmpInt(da.rssi, db.rssi);
break;
case 4:
r = cmpInt(da.qual, db.qual);
break;
case 5:
r = cmpInt(da.channel, db.channel);
break;
default:
r = cmpText(a.cells[col].innerHTML, b.cells[col].innerHTML);
}
if (r == 0)
r = cmpText(da.bssid, db.bssid);
return this.sortAscending ? r : -r;
}
Date.prototype.toWHMS = function() {
return dayOfWeek[this.getDay()]+' '+this.getHours()+':'+this.getMinutes().pad(2)+ ':'+this.getSeconds().pad(2);
}
function setMsg(msg) {
elem.setInnerHTML(E('survey-msg'), msg);
}
function drawFT() {
	const me=0.95;
	const clocal="#888888"
if (typeof wl0_r !== 'undefined' && wl0_r == 1 && wl0_m != 'sta') {
			if (wl0_w == 40) {
			var c=calculateCentralChannelForty(wl0_c, wl0_s);
			} else var c=wl0_c;
	drawEllipse(c, wl0_w, 100, clocal, wl0_d, me);
	}
if (typeof wl1_r !== 'undefined' && wl1_r == 1 && wl1_m != 'sta') {
			if (wl1_w == 40) {
			var c=calculateCentralChannelForty(wl1_c, wl1_s);
			} else var c=wl1_c;
			drawEllipse(wl1_c, wl1_w, 100, clocal, wl1_d, me);
	}
if (typeof wl2_r !== 'undefined' && wl2_r == 1 && wl2_m != 'sta' ) {
	drawEllipse(wl2_c, wl2_w, 100, clocal, wl2_d, me);
	}
<!-- drawEllipse('11',  '20', '80', '888888'); -->
<!-- drawEllipse('14',  '20', '80', '888888'); -->
<!-- drawEllipse('36',  '20', '80', '888888'); -->
<!-- drawEllipse(102,  40, 80, '888888'); -->
<!-- drawEllipse(120, 80, 80, '#888888'); -->
<!-- drawEllipse('176', '20', '80', '888888');  -->
}

function drawCoordinates(a, b, c, d, e, f, g) {
    // Get the canvas element
    var canvas = document.getElementById(a);
    var ctx = canvas.getContext('2d');
    var minX = b
    var maxX = c
	var minV = d
	var maxV = e
    var numDivisions = f;
    var incrementX = g;
const fontSize = 10; // Set your desired font size
const fontFamily = "Arial Narrow"; // Set your desired narrow font family
    ctx.font = fontSize + "px " + fontFamily; // Set the font
    // Draw x-axis
    ctx.beginPath();	
    ctx.moveTo(0, canvas.height);
    ctx.lineTo(canvas.width, canvas.height);
	ctx.fillStyle = "black";
    ctx.textBaseline = "bottom"; // Align text vertically at the middle		
if (a=='ellipses2') {
for (let i = 0; i <= numDivisions; i++) {
  let x;
  if (i === 0) {
    x = minX + 2 * incrementX;
  } else if (i === numDivisions) {
    x = maxX - 2 * incrementX;
  } else {
    x = minX + i * incrementX;
  }
  if (x >= 1 && x <= 13) {
    let xPos = (canvas.width / (maxX - minX)) * (x - minX);
	ctx.textAlign = "center";	
    ctx.fillText(x, xPos, canvas.height + 2);
  }
}
  	ctx.textAlign = "center";
    xPos = ( canvas.width / (maxX - minX)) * 16.6
 	ctx.fillText(14, xPos, canvas.height + 2);
}
else if (a=='ellipses5') {
for (let i = 0; i <= numDivisions; i++) {
  let x;
  if (i === 0) {
    x = minX + 1 * incrementX;
  } else if (i === numDivisions) {
    x = maxX - 1 * incrementX;
  } else {
    x = minX + (i + 1) * incrementX;
  }
  if (x >= 32 && x <= 64 || x >=100 && x <= 144 ) {
    let xPos = (canvas.width / (maxX - minX)) * (x - minX);
	ctx.textAlign = "center";
    ctx.fillText(x, xPos, canvas.height+2);
  }
}
for (let i = 0; i <= 38; i++) {
  let x;
  if (i === 0) {
    x = 33 + 1 * 4;
  } else if (i === 38) {
    x = 184 - 1 * 4;
  } else {
    x = 33 + (i + 1) * 4;
  }
  if (x >= 149 && x <= 177 ) {
    let xPos = (canvas.width / (184 - 33)) * (x - 33);
	ctx.textAlign = "center";
    ctx.fillText(x, xPos, canvas.height + 2);
  }
}
}
// draw y-axis
for (let i = 0; i < 11; i++) {
  let y;
  if (i === 0) {
    y = -10;
  } else {
    y = -10 * i;
  }
  
  if (y !== -100) { // Exclude -100 from being displayed
    let yPos = (canvas.height / 100) * (-y);
    // Draw x-axis	
    // ctx.textAlign = "right";
    ctx.textBaseline = "middle"; // Align text vertically at the middle
    ctx.fillText(y.toString(), 6, yPos); // Adjust yPos for vertical centering
    ctx.fillText(y.toString(), 750, yPos); // Adjust yPos for vertical centering
  }
}

}
function drawBoard(can){
	var bw = 750;
	var bh = 200;
	// Padding
	var p = 0;
	var canvas = document.getElementById(can);
	var context = canvas.getContext("2d");	
	// Add sepia areas
	if (can == 'ellipses2') {
	    for (var x = 0; x <= bw; x += (canvas.width/19)) {
        context.moveTo(0.5 + x + p, p);
        context.lineTo(0.5 + x + p, bh + p);
    }
		    for (var x = 0; x <= bh; x += (canvas.height/10)) {
        context.moveTo(p, 0.5 + x + p);
        context.lineTo(bw + p, 0.5 + x + p);
    }
		context.strokeStyle = "#eeeeee";
		context.stroke();
		context.rect(0, 0, canvas.width/19*3, 200);
		context.rect(canvas.width/19*15, 0, canvas.width/19*11, 200);
		context.fillStyle = "rgba(112,66,20,0.08)";
		context.fill();
		context.rect(canvas.width/19*13, 0, canvas.width/19*15, 200);
		context.fillStyle = "rgba(112,66,20,0.06)";
		context.fill();
	}	
	else if (can == 'ellipses5') {
	    for (var x = 0; x <= bw; x += (canvas.width/38)) {
        context.moveTo(0.5 + x + p, p);
        context.lineTo(0.5 + x + p, bh + p);
    }
		    for (var x = 0; x <= bh; x += (canvas.height/10)) {
        context.moveTo(p, 0.5 + x + p);
        context.lineTo(bw + p, 0.5 + x + p);
    }
		context.strokeStyle = "#eeeeee";
		context.stroke();
		context.rect(0, 0, canvas.width/38, 200);
		context.rect(canvas.width/38*8, 0, canvas.width/38*9, 200);
		context.rect(canvas.width/38*36.25, 0, canvas.width, 200);
		context.fillStyle = "rgba(112,66,20,0.08";
		context.fill();
		context.rect(canvas.width/38*28.3, 0, canvas.width/38*0.6, 200);
		context.fillStyle = "rgba(112,66,20,0.06)";
		context.fill();		
	}
}
function clearCanvas(canvas) {
canvas = document.getElementById(canvas);
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#fdfdfd";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
function earlyInit() {
if (!useAjax())
E('expire-time').style.display = 'none';
sg.setup();
}
function init() {
sg.recolor();
ref.initPage();
}
</script>
</head>
<body onload="init()">
<form action="javascript:{}">
<table id="container">
<tr><td colspan="2" id="header">
<div class="title">FreshTomato</div>
<div class="version">Version <% version(); %> on <% nv("t_model_name"); %></div>
</td></tr>
<tr id="body"><td id="navi"><script>navi()</script></td>
<td id="content">
<div id="ident"><% ident(); %> | <script>wikiLink();</script></div>
<div class="tomato-chart">Wireless Channel Congestion 2.4 GHz</div>
<canvas id="ellipses2" width="756" height="200" border=1></canvas>
<p>
<div class="tomato-chart">Wireless Channel Congestion 5 GHz</div>
<canvas id="ellipses5" width="756" height="200" border=1></canvas>
<p>
<div class="section-title">Wireless Site Survey</div>
<div class="section">
<div id="survey-grid" class="tomato-grid"></div>
<div id="survey-msg"></div>
<div id="survey-warn">
<script>
if ('<% wlclient(); %>' == '0')
document.write('<b>Warning:<\/b> Wireless connections to this router may be disrupted while using this tool.<br>');
</script>
<b>Note:</b> Wireless Survey will not show any results with WL filter turned on in 'permit only' mode.
</div>
</div>
<div id="footer">
<div id="survey-controls">
<img src="spin.gif" alt="" id="refresh-spinner">
<script>
genStdTimeList('expire-time', 'Expires = ♾️',3);
genStdTimeList('refresh-time', 'One off', 3);
</script>
<input type="button" value="Refresh" onclick="ref.toggle()" id="refresh-button">
</div>
</div>
</td></tr>
</table>
</form>
<script>earlyInit();</script>
</body>
</html>
Leave a Comment