Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
Revision 110:8ab752842d25, committed 2019-04-30
- Comitter:
- andrewboyson
- Date:
- Tue Apr 30 12:45:08 2019 +0000
- Parent:
- 109:3e82f62c7e1f
- Child:
- 111:aaa858678e34
- Commit message:
- Tidied. About to rename to web.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-clock-ajax.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,64 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#include "http.h"
+#include "rtc.h"
+#include "clk.h"
+#include "clktime.h"
+#include "clkgov.h"
+#include "clkutc.h"
+#include "ntpclient.h"
+#include "scan.h"
+
+void WebClockAjax()
+{
+ HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
+
+ //Time and UTC
+ clktime now = ClkNowTai();
+ clktime fraction = now & ((1UL << CLK_TIME_ONE_SECOND_SHIFT) - 1);
+ clktime ms = (fraction * 1000) >> CLK_TIME_ONE_SECOND_SHIFT;
+ HttpAddInt16AsHex(ms ); HttpAddChar('\n');
+ char byte = 0;
+ if (RtcIsSet() ) byte |= 0x01;
+ if (ClkTimeIsSet() ) byte |= 0x02;
+ if (ClkGovIsReceivingTime ) byte |= 0x04;
+ if (ClkGovRateIsSynced ) byte |= 0x08;
+ if (ClkGovTimeIsSynced ) byte |= 0x10;
+ if (ClkUtcGetNextLeapEnable() ) byte |= 0x20;
+ if (ClkUtcGetNextLeapForward()) byte |= 0x40;
+ if (ClkGovTrace) byte |= 0x80;
+ HttpAddByteAsHex (byte ); HttpAddChar('\n');
+ HttpAddInt12AsHex(ClkUtcGetNextEpochMonth1970()); HttpAddChar('\n');
+ HttpAddInt16AsHex(ClkUtcGetEpochOffset() ); HttpAddChar('\n');
+ HttpAddChar('\f');
+
+ //Governer
+ HttpAddInt32AsHex(ClkGovGetPpb() ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovFreqDivisor ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovFreqChangeMaxPpb ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovFreqSyncedLimPpb ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovFreqSyncedHysPpb ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovSlewDivisor ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovSlewChangeMaxMs ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovSlewSyncedLimNs ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovSlewSyncedHysNs ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ClkGovSlewOffsetMaxSecs ); HttpAddChar('\n');
+ HttpAddChar('\f');
+
+ //NTP
+ HttpAddText (NtpClientQueryServerName ); HttpAddChar('\n');
+ HttpAddInt32AsHex(NtpClientQueryInitialInterval); HttpAddChar('\n');
+ HttpAddInt32AsHex(NtpClientQueryNormalInterval ); HttpAddChar('\n');
+ HttpAddInt32AsHex(NtpClientQueryRetryInterval ); HttpAddChar('\n');
+ HttpAddInt32AsHex(NtpClientReplyOffsetMs ); HttpAddChar('\n');
+ HttpAddInt32AsHex(NtpClientReplyMaxDelayMs ); HttpAddChar('\n');
+ HttpAddChar('\f');
+
+ //Scan
+ HttpAddInt32AsHex(ScanAverage ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ScanMaximum ); HttpAddChar('\n');
+ HttpAddInt32AsHex(ScanMinimum ); HttpAddChar('\n');
+ HttpAddChar('\f');
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-clock-class.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,108 @@
+"//Clock class\n"
+"'use strict';\n"
+"\n"
+"class Clock\n"
+"{\n"
+" constructor()\n"
+" {\n"
+" this.leapEnable = false;\n"
+" this.leapForward = false;\n"
+" this.leapMonth = 0;\n"
+" this.leapYear = 0;\n"
+" this.leaps = 0;\n"
+" this.ms = 0;\n"
+" }\n"
+" \n"
+" set months1970(value)\n"
+" {\n"
+" this.leapMonth = value % 12;\n"
+" this.leapYear = (value - this.leapMonth) / 12;\n"
+" this.leapMonth += 1;\n"
+" this.leapYear += 1970;\n"
+" }\n"
+" get months1970()\n"
+" {\n"
+" if (this.leapYear <= 0) return 0;\n"
+" if (this.leapMonth <= 0) return 0;\n"
+" return (this.leapYear - 1970) * 12 + this.leapMonth - 1;\n"
+" }\n"
+" \n"
+" formatNumbers00(i)\n"
+" {\n"
+" if (i < 10) return '0' + i;\n"
+" return i;\n"
+" }\n"
+" formatDayOfWeek(wday)\n"
+" {\n"
+" switch(wday)\n"
+" {\n"
+" case 0: return 'Sun';\n"
+" case 1: return 'Mon';\n"
+" case 2: return 'Tue';\n"
+" case 3: return 'Wed';\n"
+" case 4: return 'Thu';\n"
+" case 5: return 'Fri';\n"
+" case 6: return 'Sat';\n"
+" default: return '---';\n"
+" }\n"
+" }\n"
+" adjustLeap(baseMs)\n"
+" {\n"
+" if (this.ms == 0) return; //Don't attempt to adjust an invalid time\n"
+" \n"
+" if (!this.leapEnable) return; // Adjustment disabled\n"
+" \n"
+" //Get the calander date and time from the ms\n"
+" let now = this.ms + baseMs;\n"
+" let leapStart = Date.UTC(this.leapYear, this.leapMonth - 1, 1, 0, 0, this.leapForward ? 0: -1);\n"
+" \n"
+" if (now < leapStart) return; //Do nothing until reached the leap start\n"
+" \n"
+" if (this.leapForward) { this.ms -= 1000; this.leaps += 1; } //repeat 59\n"
+" else { this.ms += 1000; this.leaps -= 1; } //skip 59\n"
+" \n"
+" this.leapEnable = false;\n"
+" }\n"
+" displayTime(baseMs)\n"
+" {\n"
+" if (this.ms == 0) return; //Don't attempt to display an invalid time\n"
+" \n"
+" //Get the calander date and time from the ms\n"
+" let now = new Date(this.ms + baseMs);\n"
+" let y = now.getUTCFullYear();\n"
+" let n = now.getUTCMonth () + 1;\n"
+" let d = now.getUTCDate ();\n"
+" let w = now.getUTCDay (); // 0 == Sunday\n"
+" let h = now.getUTCHours ();\n"
+" let m = now.getUTCMinutes ();\n"
+" let s = now.getUTCSeconds ();\n"
+" \n"
+" //Format time\n"
+" n = this.formatNumbers00(n);\n"
+" d = this.formatNumbers00(d);\n"
+" h = this.formatNumbers00(h);\n"
+" m = this.formatNumbers00(m);\n"
+" s = this.formatNumbers00(s);\n"
+" w = this.formatDayOfWeek(w);\n"
+" \n"
+" //Display time\n"
+" let elem;\n"
+" elem = document.getElementById('ajax-date-utc');\n"
+" if (elem) elem.textContent = y + '-' + n + '-' + d + ' ' + w + ' ' + h + ':' + m + ':' + s + ' TAI-UTC=' + this.leaps;\n"
+" \n"
+" elem = document.getElementById('ajax-date-pc');\n"
+" let options = \n"
+" {\n"
+" year: 'numeric',\n"
+" month: 'short',\n"
+" day: '2-digit',\n"
+" weekday: 'short',\n"
+" hour: '2-digit',\n"
+" minute: '2-digit',\n"
+" second: '2-digit',\n"
+" timeZoneName: 'short'\n"
+" };\n"
+" if (elem) elem.textContent = now.toLocaleString(undefined, options);\n"
+" }\n"
+"}\n"
+""
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-clock-class.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,107 @@
+//Clock class
+'use strict';
+
+class Clock
+{
+ constructor()
+ {
+ this.leapEnable = false;
+ this.leapForward = false;
+ this.leapMonth = 0;
+ this.leapYear = 0;
+ this.leaps = 0;
+ this.ms = 0;
+ }
+
+ set months1970(value)
+ {
+ this.leapMonth = value % 12;
+ this.leapYear = (value - this.leapMonth) / 12;
+ this.leapMonth += 1;
+ this.leapYear += 1970;
+ }
+ get months1970()
+ {
+ if (this.leapYear <= 0) return 0;
+ if (this.leapMonth <= 0) return 0;
+ return (this.leapYear - 1970) * 12 + this.leapMonth - 1;
+ }
+
+ formatNumbers00(i)
+ {
+ if (i < 10) return '0' + i;
+ return i;
+ }
+ formatDayOfWeek(wday)
+ {
+ switch(wday)
+ {
+ case 0: return 'Sun';
+ case 1: return 'Mon';
+ case 2: return 'Tue';
+ case 3: return 'Wed';
+ case 4: return 'Thu';
+ case 5: return 'Fri';
+ case 6: return 'Sat';
+ default: return '---';
+ }
+ }
+ adjustLeap(baseMs)
+ {
+ if (this.ms == 0) return; //Don't attempt to adjust an invalid time
+
+ if (!this.leapEnable) return; // Adjustment disabled
+
+ //Get the calander date and time from the ms
+ let now = this.ms + baseMs;
+ let leapStart = Date.UTC(this.leapYear, this.leapMonth - 1, 1, 0, 0, this.leapForward ? 0: -1);
+
+ if (now < leapStart) return; //Do nothing until reached the leap start
+
+ if (this.leapForward) { this.ms -= 1000; this.leaps += 1; } //repeat 59
+ else { this.ms += 1000; this.leaps -= 1; } //skip 59
+
+ this.leapEnable = false;
+ }
+ displayTime(baseMs)
+ {
+ if (this.ms == 0) return; //Don't attempt to display an invalid time
+
+ //Get the calander date and time from the ms
+ let now = new Date(this.ms + baseMs);
+ let y = now.getUTCFullYear();
+ let n = now.getUTCMonth () + 1;
+ let d = now.getUTCDate ();
+ let w = now.getUTCDay (); // 0 == Sunday
+ let h = now.getUTCHours ();
+ let m = now.getUTCMinutes ();
+ let s = now.getUTCSeconds ();
+
+ //Format time
+ n = this.formatNumbers00(n);
+ d = this.formatNumbers00(d);
+ h = this.formatNumbers00(h);
+ m = this.formatNumbers00(m);
+ s = this.formatNumbers00(s);
+ w = this.formatDayOfWeek(w);
+
+ //Display time
+ let elem;
+ elem = document.getElementById('ajax-date-utc');
+ if (elem) elem.textContent = y + '-' + n + '-' + d + ' ' + w + ' ' + h + ':' + m + ':' + s + ' TAI-UTC=' + this.leaps;
+
+ elem = document.getElementById('ajax-date-pc');
+ let options =
+ {
+ year: 'numeric',
+ month: 'short',
+ day: '2-digit',
+ weekday: 'short',
+ hour: '2-digit',
+ minute: '2-digit',
+ second: '2-digit',
+ timeZoneName: 'short'
+ };
+ if (elem) elem.textContent = now.toLocaleString(undefined, options);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-clock-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,68 @@
+#include <time.h>
+
+#include "http.h"
+#include "web-nav-base.h"
+#include "web-add.h"
+
+void WebClockHtml()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Clock", "settings.css", "clock.js");
+ WebAddNav(CLOCK_PAGE);
+ WebAddH1("Clock");
+
+ WebAddH2("Status");
+ WebAddAjaxLed("RTC is set" , "ajax-rtc-set" );
+ WebAddAjaxLed("Clock is set" , "ajax-clock-set" );
+ WebAddAjaxLed("External source is ok", "ajax-source-ok" );
+ WebAddAjaxLed("Time synchronised" , "ajax-time-locked");
+ WebAddAjaxLed("Rate synchronised" , "ajax-rate-locked");
+
+ WebAddH2("Server UTC time");
+ HttpAddText("<div id='ajax-date-utc'></div>\r\n");
+
+ WebAddH2("Server local time");
+ HttpAddText("<div id='ajax-date-pc'></div>\r\n");
+
+ WebAddH2("Server - PC (ms)");
+ HttpAddText("<div id='ajax-date-diff'></div>\r\n");
+
+ WebAddH2("UTC");
+ WebAddAjaxInputToggle("Enable epoch change" , "ajax-leap-enable" , "chg-clock-leap-enable" );
+ WebAddAjaxInputToggle("Direction of next epoch" , "ajax-leap-forward" , "chg-clock-leap-forward");
+ WebAddAjaxInput ("Year next epoch starts" , 4, "ajax-leap-year" , "set-clock-leap-year" );
+ WebAddAjaxInput ("Month next epoch starts" , 4, "ajax-leap-month" , "set-clock-leap-month" );
+ WebAddAjaxInput ("Current era offset" , 4, "ajax-leap-count" , "set-clock-leap-count" );
+
+ HttpAddText("<div><button type='button' onclick='displayLeap()'>Display leap</button></div>\r\n");
+
+ HttpAddText("<div>The leap seconds list is available <a href='https://www.ietf.org/timezones/data/leap-seconds.list' target='_blank'>here</a></div>\r\n");
+
+ WebAddH2("Governer");
+ WebAddAjaxInput ("Ppb" , 5, "ajax-ppb" , "ppb" );
+ WebAddAjaxInput ("Ppb divisor" , 5, "ajax-ppb-divisor" , "ppbdivisor" );
+ WebAddAjaxInput ("Ppb max change" , 5, "ajax-ppb-max-chg" , "ppbmaxchange" );
+ WebAddAjaxInput ("Ppb synced limit" , 5, "ajax-ppb-syn-lim" , "syncedlimitppb");
+ WebAddAjaxInput ("Ppb synced hysteresis" , 5, "ajax-ppb-syn-hys" , "syncedhysppb" );
+ WebAddAjaxInput ("Offset divisor" , 5, "ajax-off-divisor" , "slewdivisor" );
+ WebAddAjaxInput ("Offset max (ms)" , 5, "ajax-off-max" , "slewmax" );
+ WebAddAjaxInput ("Offset synced limit (ms)", 5, "ajax-off-syn-lim" , "syncedlimitns" );
+ WebAddAjaxInput ("Offset synced hys (ms)" , 5, "ajax-off-syn-hys" , "syncedhysns" );
+ WebAddAjaxInput ("Offset reset limit (s)" , 5, "ajax-off-rst-lim" , "maxoffsetsecs" );
+ WebAddAjaxInputToggle("Trace" , "ajax-gov-trace" , "clockgovtrace" );
+
+ WebAddH2("NTP");
+ WebAddAjaxInput ("Server url" , 5, "ajax-ntp-server" , "ntpserver" );
+ WebAddAjaxInput ("Initial interval (s)" , 5, "ajax-ntp-initial" , "clockinitial" );
+ WebAddAjaxInput ("Normal interval (m)" , 5, "ajax-ntp-normal" , "clocknormal" );
+ WebAddAjaxInput ("Retry interval (s)" , 5, "ajax-ntp-retry" , "clockretry" );
+ WebAddAjaxInput ("Offset (ms)" , 5, "ajax-ntp-offset" , "clockoffset" );
+ WebAddAjaxInput ("Max delay (ms)" , 5, "ajax-ntp-max-delay", "clockmaxdelay" );
+
+ WebAddH2("Scan times");
+ WebAddAjaxLabelled ("Program cycles avg", "ajax-scan-avg");
+ WebAddAjaxLabelled ("Program cycles max", "ajax-scan-max");
+ WebAddAjaxLabelled ("Program cycles min", "ajax-scan-min");
+
+ WebAddEnd();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-clock-script.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,18 @@
+#include "http.h"
+
+//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
+//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
+
+const char* WebClockScriptDate = __DATE__;
+const char* WebClockScriptTime = __TIME__;
+
+static const char* script =
+#include "web-clock-class.inc"
+#include "../core/web-ajax-class.inc"
+#include "web-clock-script.inc"
+;
+void WebClockScript()
+{
+ HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebClockScriptDate, WebClockScriptTime);
+ HttpAddText(script);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-clock-script.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,172 @@
+"//Clock script\n"
+"'use strict';\n"
+"\n"
+"let pseudo = new Clock();\n"
+"let rtc = new Clock();\n"
+"\n"
+"let pseudoDisplay = false;\n"
+"let pseudoStartMs = 0;\n"
+"\n"
+"let diffMs = 0;\n"
+"let rtcIsSet = false;\n"
+"let clockIsSet = false;\n"
+"let sourceIsOk = false;\n"
+"let rateIsLocked = false;\n"
+"let timeIsLocked = false;\n"
+"\n"
+"let ppb = 0;\n"
+"let ppbdivisor = 0;\n"
+"let ppbmaxchange = 0;\n"
+"let syncedlimitppb = 0;\n"
+"let syncedhysppb = 0;\n"
+"let slewdivisor = 0;\n"
+"let slewmax = 0;\n"
+"let syncedlimitns = 0;\n"
+"let syncedhysns = 0;\n"
+"let maxoffsetsecs = 0;\n"
+"let govTrace = false;\n"
+"\n"
+"let ntpserver = '';\n"
+"let ntpinitial = 0;\n"
+"let ntpnormal = 0;\n"
+"let ntpretry = 0;\n"
+"let ntpoffset = 0;\n"
+"let ntpmaxdelay = 0;\n"
+"\n"
+"let scanavg = 0;\n"
+"let scanmax = 0;\n"
+"let scanmin = 0;\n"
+"\n"
+"const DISPLAY_LEAP_MS = 10000;\n"
+"\n"
+"function parseLinesTime(text)\n"
+"{\n"
+" let lines = text.split('\\n');\n"
+" rtc.ms = Ajax.date.getTime();\n"
+" rtc.ms += parseInt(lines[0], 16);\n"
+" rtc.ms -= Ajax.ms;\n"
+" diffMs = rtc.ms + Ajax.ms - Date.now();\n"
+" rtcIsSet = Ajax.hexToBit(lines[1], 0);\n"
+" clockIsSet = Ajax.hexToBit(lines[1], 1);\n"
+" sourceIsOk = Ajax.hexToBit(lines[1], 2);\n"
+" rateIsLocked = Ajax.hexToBit(lines[1], 3);\n"
+" timeIsLocked = Ajax.hexToBit(lines[1], 4);\n"
+" rtc.leapEnable = Ajax.hexToBit(lines[1], 5);\n"
+" rtc.leapForward = Ajax.hexToBit(lines[1], 6);\n"
+" govTrace = Ajax.hexToBit(lines[1], 7);\n"
+" rtc.months1970 = parseInt(lines[2], 16);\n"
+" rtc.leaps = parseInt(lines[3], 16);\n"
+"}\n"
+"function parseLinesGov(text)\n"
+"{\n"
+" let lines = text.split('\\n');\n"
+" ppb = parseInt(lines[0], 16);\n"
+" ppbdivisor = parseInt(lines[1], 16);\n"
+" ppbmaxchange = parseInt(lines[2], 16);\n"
+" syncedlimitppb = parseInt(lines[3], 16);\n"
+" syncedhysppb = parseInt(lines[4], 16);\n"
+" slewdivisor = parseInt(lines[5], 16);\n"
+" slewmax = parseInt(lines[6], 16);\n"
+" syncedlimitns = parseInt(lines[7], 16);\n"
+" syncedhysns = parseInt(lines[8], 16);\n"
+" maxoffsetsecs = parseInt(lines[9], 16);\n"
+"}\n"
+"function parseLinesNtp(text)\n"
+"{\n"
+" let lines = text.split('\\n');\n"
+" ntpserver = lines[0];\n"
+" ntpinitial = parseInt(lines[1], 16);\n"
+" ntpnormal = parseInt(lines[2], 16);\n"
+" ntpretry = parseInt(lines[3], 16);\n"
+" ntpoffset = parseInt(lines[4], 16);\n"
+" ntpmaxdelay = parseInt(lines[5], 16);\n"
+"}\n"
+"function parseLinesScan(text)\n"
+"{\n"
+" let lines = text.split('\\n');\n"
+" scanavg = parseInt(lines[0], 16);\n"
+" scanmax = parseInt(lines[1], 16);\n"
+" scanmin = parseInt(lines[2], 16);\n"
+"}\n"
+"function parse()\n"
+"{\n"
+" let topics = Ajax.response.split('\\f');\n"
+" parseLinesTime(topics[0]);\n"
+" parseLinesGov (topics[1]);\n"
+" parseLinesNtp (topics[2]);\n"
+" parseLinesScan(topics[3]);\n"
+"}\n"
+"function display()\n"
+"{\n"
+" let elem;\n"
+" elem = Ajax.getElementOrNull('ajax-rtc-set' ); if (elem) elem.setAttribute('dir', rtcIsSet ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-clock-set' ); if (elem) elem.setAttribute('dir', clockIsSet ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-source-ok' ); if (elem) elem.setAttribute('dir', sourceIsOk ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-rate-locked' ); if (elem) elem.setAttribute('dir', rateIsLocked ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-time-locked' ); if (elem) elem.setAttribute('dir', timeIsLocked ? 'rtl' : 'ltr');\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-leap-enable' ); if (elem) elem.setAttribute('dir', rtc.leapEnable ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-leap-forward' ); if (elem) elem.setAttribute('dir', rtc.leapForward ? 'rtl' : 'ltr');\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-leap-year' ); if (elem) elem.value = rtc.months1970 ? rtc.leapYear : '';\n"
+" elem = Ajax.getElementOrNull('ajax-leap-month' ); if (elem) elem.value = rtc.months1970 ? rtc.leapMonth : '';\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-leap-count' ); if (elem) elem.value = rtc.leaps;\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-ppb' ); if (elem) elem.value = ppb;\n"
+" elem = Ajax.getElementOrNull('ajax-ppb-divisor' ); if (elem) elem.value = ppbdivisor;\n"
+" elem = Ajax.getElementOrNull('ajax-ppb-max-chg' ); if (elem) elem.value = ppbmaxchange;\n"
+" elem = Ajax.getElementOrNull('ajax-ppb-syn-lim' ); if (elem) elem.value = syncedlimitppb;\n"
+" elem = Ajax.getElementOrNull('ajax-ppb-syn-hys' ); if (elem) elem.value = syncedhysppb;\n"
+" elem = Ajax.getElementOrNull('ajax-off-divisor' ); if (elem) elem.value = slewdivisor;\n"
+" elem = Ajax.getElementOrNull('ajax-off-max' ); if (elem) elem.value = slewmax;\n"
+" elem = Ajax.getElementOrNull('ajax-off-syn-lim' ); if (elem) elem.value = syncedlimitns / 1000000;\n"
+" elem = Ajax.getElementOrNull('ajax-off-syn-hys' ); if (elem) elem.value = syncedhysns / 1000000;\n"
+" elem = Ajax.getElementOrNull('ajax-off-rst-lim' ); if (elem) elem.value = maxoffsetsecs;\n"
+" elem = Ajax.getElementOrNull('ajax-gov-trace' ); if (elem) elem.setAttribute('dir', govTrace ? 'rtl' : 'ltr');\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-ntp-server' ); if (elem) elem.value = ntpserver;\n"
+" elem = Ajax.getElementOrNull('ajax-ntp-initial' ); if (elem) elem.value = ntpinitial;\n"
+" elem = Ajax.getElementOrNull('ajax-ntp-normal' ); if (elem) elem.value = ntpnormal / 60;\n"
+" elem = Ajax.getElementOrNull('ajax-ntp-retry' ); if (elem) elem.value = ntpretry;\n"
+" elem = Ajax.getElementOrNull('ajax-ntp-offset' ); if (elem) elem.value = ntpoffset;\n"
+" elem = Ajax.getElementOrNull('ajax-ntp-max-delay'); if (elem) elem.value = ntpmaxdelay;\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-scan-avg' ); if (elem) elem.textContent = scanavg;\n"
+" elem = Ajax.getElementOrNull('ajax-scan-max' ); if (elem) elem.textContent = scanmax;\n"
+" elem = Ajax.getElementOrNull('ajax-scan-min' ); if (elem) elem.textContent = scanmin;\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-date-diff' ); if (elem) elem.textContent = diffMs;\n"
+"}\n"
+"\n"
+"function handleTick() //This typically called every 100ms\n"
+"{\n"
+" if (pseudoDisplay)\n"
+" {\n"
+" pseudo.adjustLeap (Ajax.ms);\n"
+" pseudo.displayTime(Ajax.ms);\n"
+" if (Ajax.ms >= pseudoStartMs + DISPLAY_LEAP_MS + 500) pseudoDisplay = false;\n"
+" }\n"
+" else\n"
+" {\n"
+" rtc.adjustLeap (Ajax.ms);\n"
+" rtc.displayTime(Ajax.ms);\n"
+" }\n"
+"}\n"
+"\n"
+"function displayLeap() //Called by display leap button in HTML\n"
+"{\n"
+" pseudoDisplay = true;\n"
+" pseudoStartMs = Ajax.ms;\n"
+" \n"
+" pseudo.leapEnable = true;\n"
+" pseudo.leapForward = rtc.leapForward;\n"
+" pseudo.leaps = rtc.leaps;\n"
+" pseudo.leapMonth = rtc.leapMonth;\n"
+" pseudo.leapYear = rtc.leapYear;\n"
+" pseudo.ms = Date.UTC(rtc.leapYear, rtc.leapMonth - 1, 1) - DISPLAY_LEAP_MS / 2 - Ajax.ms;\n"
+"}\n"
+"Ajax.server = '/clock-ajax';\n"
+"Ajax.onResponse = function() { parse(); display(); };\n"
+"Ajax.onTick = handleTick;\n"
+"Ajax.init();"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-clock-script.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,172 @@
+//Clock script
+'use strict';
+
+let pseudo = new Clock();
+let rtc = new Clock();
+
+let pseudoDisplay = false;
+let pseudoStartMs = 0;
+
+let diffMs = 0;
+let rtcIsSet = false;
+let clockIsSet = false;
+let sourceIsOk = false;
+let rateIsLocked = false;
+let timeIsLocked = false;
+
+let ppb = 0;
+let ppbdivisor = 0;
+let ppbmaxchange = 0;
+let syncedlimitppb = 0;
+let syncedhysppb = 0;
+let slewdivisor = 0;
+let slewmax = 0;
+let syncedlimitns = 0;
+let syncedhysns = 0;
+let maxoffsetsecs = 0;
+let govTrace = false;
+
+let ntpserver = '';
+let ntpinitial = 0;
+let ntpnormal = 0;
+let ntpretry = 0;
+let ntpoffset = 0;
+let ntpmaxdelay = 0;
+
+let scanavg = 0;
+let scanmax = 0;
+let scanmin = 0;
+
+const DISPLAY_LEAP_MS = 10000;
+
+function parseLinesTime(text)
+{
+ let lines = text.split('\n');
+ rtc.ms = Ajax.date.getTime();
+ rtc.ms += parseInt(lines[0], 16);
+ rtc.ms -= Ajax.ms;
+ diffMs = rtc.ms + Ajax.ms - Date.now();
+ rtcIsSet = Ajax.hexToBit(lines[1], 0);
+ clockIsSet = Ajax.hexToBit(lines[1], 1);
+ sourceIsOk = Ajax.hexToBit(lines[1], 2);
+ rateIsLocked = Ajax.hexToBit(lines[1], 3);
+ timeIsLocked = Ajax.hexToBit(lines[1], 4);
+ rtc.leapEnable = Ajax.hexToBit(lines[1], 5);
+ rtc.leapForward = Ajax.hexToBit(lines[1], 6);
+ govTrace = Ajax.hexToBit(lines[1], 7);
+ rtc.months1970 = parseInt(lines[2], 16);
+ rtc.leaps = parseInt(lines[3], 16);
+}
+function parseLinesGov(text)
+{
+ let lines = text.split('\n');
+ ppb = parseInt(lines[0], 16);
+ ppbdivisor = parseInt(lines[1], 16);
+ ppbmaxchange = parseInt(lines[2], 16);
+ syncedlimitppb = parseInt(lines[3], 16);
+ syncedhysppb = parseInt(lines[4], 16);
+ slewdivisor = parseInt(lines[5], 16);
+ slewmax = parseInt(lines[6], 16);
+ syncedlimitns = parseInt(lines[7], 16);
+ syncedhysns = parseInt(lines[8], 16);
+ maxoffsetsecs = parseInt(lines[9], 16);
+}
+function parseLinesNtp(text)
+{
+ let lines = text.split('\n');
+ ntpserver = lines[0];
+ ntpinitial = parseInt(lines[1], 16);
+ ntpnormal = parseInt(lines[2], 16);
+ ntpretry = parseInt(lines[3], 16);
+ ntpoffset = parseInt(lines[4], 16);
+ ntpmaxdelay = parseInt(lines[5], 16);
+}
+function parseLinesScan(text)
+{
+ let lines = text.split('\n');
+ scanavg = parseInt(lines[0], 16);
+ scanmax = parseInt(lines[1], 16);
+ scanmin = parseInt(lines[2], 16);
+}
+function parse()
+{
+ let topics = Ajax.response.split('\f');
+ parseLinesTime(topics[0]);
+ parseLinesGov (topics[1]);
+ parseLinesNtp (topics[2]);
+ parseLinesScan(topics[3]);
+}
+function display()
+{
+ let elem;
+ elem = Ajax.getElementOrNull('ajax-rtc-set' ); if (elem) elem.setAttribute('dir', rtcIsSet ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-clock-set' ); if (elem) elem.setAttribute('dir', clockIsSet ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-source-ok' ); if (elem) elem.setAttribute('dir', sourceIsOk ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-rate-locked' ); if (elem) elem.setAttribute('dir', rateIsLocked ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-time-locked' ); if (elem) elem.setAttribute('dir', timeIsLocked ? 'rtl' : 'ltr');
+
+ elem = Ajax.getElementOrNull('ajax-leap-enable' ); if (elem) elem.setAttribute('dir', rtc.leapEnable ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-leap-forward' ); if (elem) elem.setAttribute('dir', rtc.leapForward ? 'rtl' : 'ltr');
+
+ elem = Ajax.getElementOrNull('ajax-leap-year' ); if (elem) elem.value = rtc.months1970 ? rtc.leapYear : '';
+ elem = Ajax.getElementOrNull('ajax-leap-month' ); if (elem) elem.value = rtc.months1970 ? rtc.leapMonth : '';
+
+ elem = Ajax.getElementOrNull('ajax-leap-count' ); if (elem) elem.value = rtc.leaps;
+
+ elem = Ajax.getElementOrNull('ajax-ppb' ); if (elem) elem.value = ppb;
+ elem = Ajax.getElementOrNull('ajax-ppb-divisor' ); if (elem) elem.value = ppbdivisor;
+ elem = Ajax.getElementOrNull('ajax-ppb-max-chg' ); if (elem) elem.value = ppbmaxchange;
+ elem = Ajax.getElementOrNull('ajax-ppb-syn-lim' ); if (elem) elem.value = syncedlimitppb;
+ elem = Ajax.getElementOrNull('ajax-ppb-syn-hys' ); if (elem) elem.value = syncedhysppb;
+ elem = Ajax.getElementOrNull('ajax-off-divisor' ); if (elem) elem.value = slewdivisor;
+ elem = Ajax.getElementOrNull('ajax-off-max' ); if (elem) elem.value = slewmax;
+ elem = Ajax.getElementOrNull('ajax-off-syn-lim' ); if (elem) elem.value = syncedlimitns / 1000000;
+ elem = Ajax.getElementOrNull('ajax-off-syn-hys' ); if (elem) elem.value = syncedhysns / 1000000;
+ elem = Ajax.getElementOrNull('ajax-off-rst-lim' ); if (elem) elem.value = maxoffsetsecs;
+ elem = Ajax.getElementOrNull('ajax-gov-trace' ); if (elem) elem.setAttribute('dir', govTrace ? 'rtl' : 'ltr');
+
+ elem = Ajax.getElementOrNull('ajax-ntp-server' ); if (elem) elem.value = ntpserver;
+ elem = Ajax.getElementOrNull('ajax-ntp-initial' ); if (elem) elem.value = ntpinitial;
+ elem = Ajax.getElementOrNull('ajax-ntp-normal' ); if (elem) elem.value = ntpnormal / 60;
+ elem = Ajax.getElementOrNull('ajax-ntp-retry' ); if (elem) elem.value = ntpretry;
+ elem = Ajax.getElementOrNull('ajax-ntp-offset' ); if (elem) elem.value = ntpoffset;
+ elem = Ajax.getElementOrNull('ajax-ntp-max-delay'); if (elem) elem.value = ntpmaxdelay;
+
+ elem = Ajax.getElementOrNull('ajax-scan-avg' ); if (elem) elem.textContent = scanavg;
+ elem = Ajax.getElementOrNull('ajax-scan-max' ); if (elem) elem.textContent = scanmax;
+ elem = Ajax.getElementOrNull('ajax-scan-min' ); if (elem) elem.textContent = scanmin;
+
+ elem = Ajax.getElementOrNull('ajax-date-diff' ); if (elem) elem.textContent = diffMs;
+}
+
+function handleTick() //This typically called every 100ms
+{
+ if (pseudoDisplay)
+ {
+ pseudo.adjustLeap (Ajax.ms);
+ pseudo.displayTime(Ajax.ms);
+ if (Ajax.ms >= pseudoStartMs + DISPLAY_LEAP_MS + 500) pseudoDisplay = false;
+ }
+ else
+ {
+ rtc.adjustLeap (Ajax.ms);
+ rtc.displayTime(Ajax.ms);
+ }
+}
+
+function displayLeap() //Called by display leap button in HTML
+{
+ pseudoDisplay = true;
+ pseudoStartMs = Ajax.ms;
+
+ pseudo.leapEnable = true;
+ pseudo.leapForward = rtc.leapForward;
+ pseudo.leaps = rtc.leaps;
+ pseudo.leapMonth = rtc.leapMonth;
+ pseudo.leapYear = rtc.leapYear;
+ pseudo.ms = Date.UTC(rtc.leapYear, rtc.leapMonth - 1, 1) - DISPLAY_LEAP_MS / 2 - Ajax.ms;
+}
+Ajax.server = '/clock-ajax';
+Ajax.onResponse = function() { parse(); display(); };
+Ajax.onTick = handleTick;
+Ajax.init();
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/clock/web-web-query.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,62 @@
+#include "http.h"
+#include "clkgov.h"
+#include "clkutc.h"
+#include "led.h"
+#include "settings.h"
+
+void WebClockQuery(char* pQuery)
+{
+ while (pQuery)
+ {
+ char* pName;
+ char* pValue;
+ pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
+ int value = HttpQueryValueAsInt(pValue);
+
+ if (HttpSameStr(pName, "chg-clock-leap-enable" )) ClkUtcTglNextLeapEnable ();
+ if (HttpSameStr(pName, "chg-clock-leap-forward")) ClkUtcTglNextLeapForward();
+
+ int months1970 = ClkUtcGetNextEpochMonth1970();
+ int months = months1970 % 12;
+ int years = months1970 / 12;
+
+ if (HttpSameStr(pName, "set-clock-leap-year" ))
+ {
+ years = value - 1970;
+ if (years < 0) years = 0;
+ ClkUtcSetNextEpochMonth1970(years * 12 + months);
+ }
+ if (HttpSameStr(pName, "set-clock-leap-month" ))
+ {
+ months = value - 1;
+ if (months < 0) months = 0;
+ ClkUtcSetNextEpochMonth1970(years * 12 + months);
+ }
+ if (HttpSameStr(pName, "set-clock-leap-count" ))
+ {
+ uint16_t leaps = value;
+ ClkUtcSetEpochOffset(leaps);
+ }
+
+ if (HttpSameStr(pName, "ppb" )) ClkGovSetPpb (value );
+ if (HttpSameStr(pName, "slewdivisor" )) SetClockSlewDivisor (value );
+ if (HttpSameStr(pName, "slewmax" )) SetClockSlewMaxMs (value );
+ if (HttpSameStr(pName, "ppbdivisor" )) SetClockPpbDivisor (value );
+ if (HttpSameStr(pName, "ppbmaxchange" )) SetClockPpbChangeMax (value );
+ if (HttpSameStr(pName, "syncedlimitns" )) SetClockSyncedLimitNs (value * 1000000 );
+ if (HttpSameStr(pName, "syncedhysns" )) SetClockSyncedHysterisNs (value * 1000000 );
+ if (HttpSameStr(pName, "syncedlimitppb")) SetClockSyncedLimitPpb (value );
+ if (HttpSameStr(pName, "syncedhysppb" )) SetClockSyncedHysterisPpb (value );
+ if (HttpSameStr(pName, "maxoffsetsecs" )) SetClockMaxOffsetSecs (value );
+ if (HttpSameStr(pName, "clockgovtrace" )) ChgTraceSync();
+
+ if (HttpSameStr(pName, "ntpserver" )) SetNtpClientServerName (pValue );
+ if (HttpSameStr(pName, "clockinitial" )) SetNtpClientInitialInterval(value );
+ if (HttpSameStr(pName, "clocknormal" )) SetNtpClientNormalInterval (value * 60 );
+ if (HttpSameStr(pName, "clockretry" )) SetNtpClientRetryInterval (value );
+ if (HttpSameStr(pName, "clockoffset" )) SetNtpClientOffsetMs (value );
+ if (HttpSameStr(pName, "clockmaxdelay" )) SetNtpClientMaxDelayMs (value );
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/css/web-base-css.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,13 @@
+#include "http.h"
+
+static const char* cssBase =
+#include "web-base-css.inc"
+;
+const char* WebBaseCssDate = __DATE__;
+const char* WebBaseCssTime = __TIME__;
+
+void WebBaseCss()
+{
+ HttpOk("text/css; charset=UTF-8", "max-age=3600", WebBaseCssDate, WebBaseCssTime);
+ HttpAddText(cssBase);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/css/web-base-css.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,28 @@
+" * { font-size:6vw; box-sizing: border-box; }\r\n"
+"@media (min-width: 600px) { * { font-size:36px; } }\r\n"
+".line { display:flex; justify-content:space-between; align-items:center; width:15em; }\r\n"
+"\r\n"
+"* { font-family:Segoe UI, Calibri, Helvetica, Arial, sans-serif; }\r\n"
+"code, textarea, input[type=text] { font-family:Consolas, Lucida Console, Droid Sans Mono, Courier New, Courier, monospace; white-space:pre; }\r\n"
+"body { margin-left:0.1em; line-height:1.1em; padding:0; border:0; }\r\n"
+"h1 { color:darkblue; font-size:120%; font-weight:normal; margin-bottom:0.3em; }\r\n"
+"h2 { color:darkblue; font-size:110%; font-weight:normal; margin-bottom:0.3em; }\r\n"
+"a { text-decoration:none; }\r\n"
+"div { line-height:1.2em; }\r\n"
+"form { line-height:1.2em; margin:0; }\r\n"
+"button, input[type=submit] { border-radius:0.2em; border:0; box-shadow:none; margin-top:0.3em; }\r\n"
+"button:hover { color:red; }\r\n"
+"input[type=submit]:hover { color:red; }\r\n"
+"input[type=text] { border:thin none gray; margin:0; padding:0; color:darkblue; text-align:right; }\r\n"
+"\r\n"
+".toggle { display:inline-block; position:relative; cursor:pointer; width: 1.2em; height: 0.6em; }\r\n"
+".slot { background-color:lightsteelblue; display:block; position:absolute; top:0.1em; left:0.1em; bottom:0.1em; right:0.1em; border-radius:0.6em; transition:background 0.4s; }\r\n"
+".knob { background-color:steelblue; display:block; position:absolute; top:0.0em; left:0.0em; bottom:0.0em; width:0.6em; border-radius:0.6em; transition:background 0.4s, margin 0.4s; }\r\n"
+".toggle[dir=rtl] > .slot { background-color:lightsteelblue; }\r\n"
+".toggle[dir=rtl] > .knob { background-color:royalblue; margin-left:0.6em}\r\n"
+".led { background-color:lightgray; display:inline-block; width:0.6em; height:0.6em; border-radius:50%; }\r\n"
+".led[dir=rtl] { background-color:royalblue; }\r\n"
+"\r\n"
+".hamburger { display:inline-block; width:1em}\r\n"
+".bar { height:0.15em; background-color:#111; border-radius:0.15em; }\r\n"
+".space { height:0.2em; }\r\n"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/css/web-nav-css.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,13 @@
+#include "http.h"
+
+static const char* cssNav =
+#include "web-nav-css.inc"
+;
+const char* WebNavCssDate = __DATE__;
+const char* WebNavCssTime = __TIME__;
+
+void WebNavCss()
+{
+ HttpOk("text/css; charset=UTF-8", "max-age=3600", WebNavCssDate, WebNavCssTime);
+ HttpAddText(cssNav);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/css/web-nav-css.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,20 @@
+//Override the base font size 1vw = 1% width so for a width of 600px 4vw equates to 24px
+" * { font-size:4vw; } \r\n"
+"@media (min-width: 600px) { * { font-size:24px; } }\r\n"
+
+//Override the left margin to fit the nav bar and make the line spacing smaller
+"body { margin-left:6em; }\r\n"
+
+//Overide the line container to match
+".line { width:17em; }\r\n"
+
+//Specify the tab access
+".tab-shortcut { position:absolute; top:-1000em;}\r\n"
+".tab-shortcut:focus { position:fixed; top:0; left:0; z-index:999; padding:0.5em; background-color:darkblue; color:white; }\r\n"
+
+//Specify the nav bar itself
+"nav ul { list-style-type:none; margin:0; padding:0; overflow:hidden; position:fixed; top:0; left:0; width:5em; font-size:1.2em; }\r\n"
+"nav ul li { background:lightskyblue; padding:0; border-style:none; margin:0.2em; }\r\n"
+"nav ul li.this { background:coral; }\r\n"
+"nav ul li a { display:block; color:black; border:0;margin:0; padding:0.5em; }\r\n"
+"nav ul li a:hover { color:darkred; }\r\n"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/fault/web-fault-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+#include "http.h"
+#include "web-nav-base.h"
+#include "web-add.h"
+#include "fault.h"
+
+void WebFaultHtml()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Fault", "settings.css", NULL);
+ WebAddNav(FAULT_PAGE);
+ WebAddH1("Fault");
+
+ WebAddH2("Last fault");
+ int faultType = FaultTypeGet();
+ char text[20];
+ FaultTypeToString(faultType, sizeof(text), text);
+ WebAddLabelledText("Fault type", text);
+ if (faultType)
+ {
+ FaultZoneToString(FaultZoneGet(), sizeof(text), text);
+ WebAddLabelledText("Fault zone" , text);
+ WebAddLabelledInt ("After point", FaultPointGet());
+ WebAddInputButton ("Clear fault", "Clear", "/fault", "faultclear");
+ }
+ else
+ {
+ WebAddInputButton("Test fault" , "Test", "/fault", "faulttest");
+ }
+
+ WebAddEnd();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/fault/web-fault-query.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,21 @@
+#include "http.h"
+#include "fault.h"
+
+void WebFaultQuery(char* pQuery)
+{
+ while (pQuery)
+ {
+ char* pName;
+ char* pValue;
+ pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
+
+ if (HttpSameStr(pName, "faultclear")) FaultReset();
+
+ if (HttpSameStr(pName, "faulttest" ))
+ {
+ FaultPoint = 999;
+ *(volatile int *)0 = 0; //Dereferencing address 0 will hard fault the processor
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/favicon/web-favicon.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,16 @@
+#include "http.h"
+
+//Use http://tomeko.net/online_tools/file_to_hex.php to convert a favicon.ico into hex readable as an array
+static const char bytes[] = {
+#include "favicon/web-favicon.inc"
+};
+
+const char* WebFaviconDate = __DATE__;
+const char* WebFaviconTime = __TIME__;
+const int WebFaviconSize = sizeof(bytes);
+
+void WebFavicon()
+{
+ HttpOk("image/x-icon", "max-age=3600", WebFaviconDate, WebFaviconTime);
+ HttpAddData(bytes, WebFaviconSize);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware-ajax.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+#include "http.h"
+#include "firmware.h"
+#include "web-firmware.h"
+
+void WebFirmwareAjax()
+{
+ //Header
+ HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
+
+ //Upload status
+ if (FirmwareSentLength == FirmwareFileLength)
+ {
+ HttpAddText("Length ok\r\n");
+ }
+ else
+ {
+ HttpAddText("Length error\r\n");
+ HttpAddF (" sent %6d\r\n", FirmwareSentLength);
+ HttpAddF (" rcvd %6d\r\n", FirmwareRcvdLength);
+ HttpAddF (" file %6d\r\n", FirmwareFileLength);
+ }
+
+ //Save status
+ if (FirmwareFailed)
+ {
+ HttpAddText("Save failed - see log");
+ }
+ else
+ {
+ HttpAddText("Saved ok");
+ }
+
+ //Delimiter
+ HttpAddChar('\f');
+
+ //New directory list
+ WebFirmwareListSemihostFiles();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+#include "http.h"
+#include "web-nav-base.h"
+#include "web-add.h"
+#include "web-firmware.h"
+
+void WebFirmwareHtml()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Firmware", "settings.css", "firmware.js");
+ WebAddNav(FIRMWARE_PAGE);
+ WebAddH1("Firmware");
+
+ WebAddH2("Existing files on the device");
+
+ HttpAddText("<code id='list'>");
+ WebFirmwareListSemihostFiles();
+ HttpAddText("</code>\r\n");
+
+ WebAddH2("Choose a local file");
+ HttpAddText("<div><input type='file' id='fileInput'/></div>\r\n");
+
+ WebAddH2("Upload the local file to the device");
+ HttpAddText("<div><button onclick='startUpload();'>Upload</button></div>\r\n");
+ HttpAddText("<code id='uploadresult'></code>\r\n");
+
+ WebAddH2("Restart the device");
+ HttpAddText("<div><button onclick='restart();'>Restart</button></div>\r\n");
+ HttpAddText("<code id='restartresult'></code>\r\n");
+
+
+ WebAddEnd();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware-post.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,15 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "firmware.h"
+
+void WebFirmwarePost (int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream, bool* pComplete)
+{
+ if (!positionInRequestStream)
+ {
+ FirmwareStart(contentLength);
+ }
+ char* pDataStart = pRequestStream + contentStart;
+ int dataLength = size - contentStart;
+ *pComplete = FirmwareAdd(pDataStart, dataLength);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware-query.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,15 @@
+#include "http.h"
+#include "semihost.h"
+
+void WebFirmwareQuery(char* pQuery)
+{
+ while (pQuery)
+ {
+ char* pName;
+ char* pValue;
+ pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
+ int value = HttpQueryValueAsInt(pValue);
+
+ if (HttpSameStr(pName, "restart" )) SemihostReset();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware-script.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,16 @@
+#include "http.h"
+
+//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
+//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
+
+const char* WebFirmwareScriptDate = __DATE__;
+const char* WebFirmwareScriptTime = __TIME__;
+
+static const char* script =
+#include "web-firmware-script.inc"
+;
+void WebFirmwareScript()
+{
+ HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebFirmwareScriptDate, WebFirmwareScriptTime);
+ HttpAddText(script);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware-script.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,88 @@
+"'use strict';\n"
+"\n"
+"var file;\n"
+"var xhr;\n"
+"\n"
+"function logUpload(text)\n"
+"{\n"
+" document.getElementById('uploadresult').textContent = text;\n"
+"}\n"
+"function xhrUploadResponse()\n"
+"{\n"
+" var topics = xhr.responseText.split('\\f');\n"
+" logUpload(topics[0]);\n"
+" if (topics.length > 1) document.getElementById('list').textContent = topics[1];\n"
+"}\n"
+"function xhrUploadOnLoad()\n"
+"{\n"
+" if (xhr.status == 200) xhrUploadResponse();\n"
+" else logUpload('Upload failed');\n"
+"}\n"
+"function xhrUploadOnError()\n"
+"{\n"
+" logUpload('Upload error');\n"
+"}\n"
+"function xhrUploadStart()\n"
+"{\n"
+" logUpload('Uploading...');\n"
+" \n"
+" xhr = new XMLHttpRequest();\n"
+"\n"
+" xhr.onload = xhrUploadOnLoad;\n"
+" xhr.onerror = xhrUploadOnError;\n"
+"\n"
+" xhr.open('POST', '/firmware-ajax'); //Defaults to async=true\n"
+" xhr.send(file);\n"
+"}\n"
+"\n"
+"function startUpload()\n"
+"{\n"
+" var fileInput = document.getElementById('fileInput');\n"
+"\n"
+" if (fileInput.files.length == 0)\n"
+" {\n"
+" logUpload('Please choose a file');\n"
+" return;\n"
+" }\n"
+"\n"
+" if (fileInput.files.length > 1)\n"
+" {\n"
+" logUpload('Please choose just one file');\n"
+" return;\n"
+" }\n"
+" \n"
+" file = fileInput.files[0];\n"
+" \n"
+" xhrUploadStart();\n"
+"}\n"
+"function logRestart(text)\n"
+"{\n"
+" document.getElementById('restartresult').textContent = text;\n"
+"}\n"
+"function redirect()\n"
+"{\n"
+" location.href = '/firmware';\n"
+"}\n"
+"function xhrRestartOnLoad()\n"
+"{\n"
+" if (xhr.status == 200) logRestart('Restart should never have returned');\n"
+" else logRestart('Restart failed');\n"
+"}\n"
+"function xhrRestartStart()\n"
+"{\n"
+" logRestart('Restarting...');\n"
+" \n"
+" xhr = new XMLHttpRequest();\n"
+"\n"
+" xhr.onload = xhrRestartOnLoad;\n"
+"\n"
+" xhr.open('GET', '/firmware-ajax?restart='); //Defaults to async=true\n"
+" xhr.send();\n"
+" \n"
+" setTimeout(redirect, 2000);\n"
+"}\n"
+"function restart()\n"
+"{\n"
+" xhrRestartStart();\n"
+"}\n"
+""
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware-script.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,87 @@
+'use strict';
+
+var file;
+var xhr;
+
+function logUpload(text)
+{
+ document.getElementById('uploadresult').textContent = text;
+}
+function xhrUploadResponse()
+{
+ var topics = xhr.responseText.split('\f');
+ logUpload(topics[0]);
+ if (topics.length > 1) document.getElementById('list').textContent = topics[1];
+}
+function xhrUploadOnLoad()
+{
+ if (xhr.status == 200) xhrUploadResponse();
+ else logUpload('Upload failed');
+}
+function xhrUploadOnError()
+{
+ logUpload('Upload error');
+}
+function xhrUploadStart()
+{
+ logUpload('Uploading...');
+
+ xhr = new XMLHttpRequest();
+
+ xhr.onload = xhrUploadOnLoad;
+ xhr.onerror = xhrUploadOnError;
+
+ xhr.open('POST', '/firmware-ajax'); //Defaults to async=true
+ xhr.send(file);
+}
+
+function startUpload()
+{
+ var fileInput = document.getElementById('fileInput');
+
+ if (fileInput.files.length == 0)
+ {
+ logUpload('Please choose a file');
+ return;
+ }
+
+ if (fileInput.files.length > 1)
+ {
+ logUpload('Please choose just one file');
+ return;
+ }
+
+ file = fileInput.files[0];
+
+ xhrUploadStart();
+}
+function logRestart(text)
+{
+ document.getElementById('restartresult').textContent = text;
+}
+function redirect()
+{
+ location.href = '/firmware';
+}
+function xhrRestartOnLoad()
+{
+ if (xhr.status == 200) logRestart('Restart should never have returned');
+ else logRestart('Restart failed');
+}
+function xhrRestartStart()
+{
+ logRestart('Restarting...');
+
+ xhr = new XMLHttpRequest();
+
+ xhr.onload = xhrRestartOnLoad;
+
+ xhr.open('GET', '/firmware-ajax?restart='); //Defaults to async=true
+ xhr.send();
+
+ setTimeout(redirect, 2000);
+}
+function restart()
+{
+ xhrRestartStart();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/firmware/web-firmware.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,16 @@
+#include "semihost.h"
+#include "http.h"
+
+void WebFirmwareListSemihostFiles()
+{
+ XFINFO info;
+ info.fileID = 0;
+ while (SemihostXffind ("*.*", &info) == 0)
+ {
+ HttpAddF("%13s %7d bytes\r\n", info.name, info.size);
+ }
+ if (info.fileID == 0)
+ {
+ HttpAddText("No files\r\n");
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/firmware/web-firmware.h Tue Apr 30 12:45:08 2019 +0000 @@ -0,0 +1,1 @@ +extern void WebFirmwareListSemihostFiles(void); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/log/web-log-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,22 @@
+#include "http.h"
+#include "web-nav-base.h"
+#include "web-add.h"
+#include "log.h"
+
+void WebLogHtml()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Log", "settings.css", NULL);
+ WebAddNav(LOG_PAGE);
+ WebAddH1("Log");
+
+ WebAddInputButton("Existing content", "Clear", "/log", "clearlog" );
+ if (LogUart) WebAddInputButton("Output to uart is on", "Turn off", "/log", "chg-log-uart");
+ else WebAddInputButton("Output to uart is off", "Turn on", "/log", "chg-log-uart");
+
+ HttpAddText("<code>");
+ HttpAddStream(LogEnumerateStart, LogEnumerate);
+ HttpAddText("</code>");
+
+ WebAddEnd();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/log/web-log-query.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,15 @@
+#include "http.h"
+#include "log.h"
+#include "settings.h"
+
+void WebLogQuery(char* pQuery)
+{
+ while (pQuery)
+ {
+ char* pName;
+ char* pValue;
+ pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
+ if (HttpSameStr(pName, "clearlog" )) LogClear();
+ if (HttpSameStr(pName, "chg-log-uart")) ChgLogUart();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/login/web-login-css.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,12 @@
+" * { font-size:4vw; box-sizing: border-box; }\r\n"
+"@media (min-width: 600px) { * { font-size:24px; } }\r\n"
+"\r\n"
+"* { font-family:'Segoe UI', Calibri, Arial, sans-serif; }\r\n"
+"*:focus { outline: 0; }\r\n"
+"body { margin-left:0.1em; line-height:1.1em; padding:0; border:0; }\r\n"
+"h1 { color:darkblue; font-size:120%; font-weight:normal; margin-bottom:0.3em; }\r\n"
+"h2 { color:darkblue; font-size:110%; font-weight:normal; margin-bottom:0.3em; }\r\n"
+"div { line-height:1.2em; }\r\n"
+"form { line-height:1.2em; margin:0; }\r\n"
+"input[type=text] { border:thin solid gray; border-radius:0.2em; margin:0; padding:0.1em; width:9em; text-align:left}\r\n"
+"input[type=submit] { display:none; }\r\n"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/login/web-login-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,41 @@
+#include "http.h"
+#include "web-add.h"
+#include "web-login.h"
+#include "web-pages-base.h"
+
+void WebLoginHtml()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Login", NULL, NULL);
+ HttpAddText(
+"<style>"
+#include "web-login-css.inc"
+"</style>"
+ );
+ WebAddH1("Login");
+ if (WebLoginPasswordIsSet())
+ {
+ WebAddH2("Welcome - please enter the password");
+ }
+ else
+ {
+ WebAddH2("Please enter a new password following user reset");
+ HttpAddText("<p>Be careful to make it the one people expect!</p>");
+ }
+
+ HttpAddText("<form action='/login' method='get' autocomplete='off'>\r\n");
+ HttpAddText(" <div style='width:8em; display:inline-block;'>Password</div>\r\n");
+ HttpAddF (" <input type='hidden' name='todo' value='%d'>\r\n", WebLoginOriginalToDo);
+ HttpAddText(" <input type='text' name='password' value='' autofocus>\r\n");
+ HttpAddText(" <input type='submit' value='' >\r\n");
+ HttpAddF ("</form>\r\n");
+
+ WebAddEnd();
+}
+
+/*
+Device sends request for resource to server
+Server cannot validate the session cookie (or there isn't one) so sends login form with original resource number as a hidden input
+Device does a GET for /login with query containing password and original resource
+Server validates password and sends original resource with a valid session cookie.
+*/
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/login/web-login-password.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,52 @@
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "http.h"
+
+#define GPREG2 (*((volatile unsigned *) 0x4002404C))
+
+static uint32_t hash;
+static bool hashIsSet = false;
+
+void WebLoginPasswordRestore()
+{
+ hash = GPREG2;
+ hashIsSet = true;
+}
+
+uint32_t hasher(char *p) //Jenkins 'one at a time' hash
+{
+ uint32_t h = 0;
+
+ while (*p)
+ {
+ h += *p;
+ h += (h << 10);
+ h ^= (h >> 6);
+ p++;
+ }
+ h += (h << 3);
+ h ^= (h >> 11);
+ h += (h << 15);
+
+ return h;
+}
+bool WebLoginPasswordIsSet()
+{
+ return hashIsSet;
+}
+void WebLoginPasswordSet(char* password)
+{
+ if (!password) return;
+ if (!*password) return;
+ hash = hasher(password);
+ GPREG2 = hash;
+ hashIsSet = true;
+}
+bool WebLoginPasswordMatches(char* password)
+{
+ if (!hashIsSet) return false;
+ if (!password) return false;
+ if (!*password) return false;
+ return hash == hasher(password);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/login/web-login-query.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,35 @@
+
+#include "http.h"
+#include "web-pages-base.h"
+#include "web-login.h"
+
+bool WebLoginQueryPasswordOk = false;
+
+void WebLoginQuery(char* pQuery)
+{
+ WebLoginQueryPasswordOk = false;
+
+ while (pQuery)
+ {
+ char* pName;
+ char* pValue;
+ pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
+
+ int value = HttpQueryValueAsInt(pValue);
+ if (HttpSameStr(pName, "todo" )) WebLoginOriginalToDo = value;
+
+ HttpQueryUnencode(pValue);
+ if (HttpSameStr(pName, "password" ))
+ {
+ if (!WebLoginPasswordIsSet()) //This is if there has been a normal reset: not a fault nor a power on.
+ {
+ WebLoginPasswordSet(pValue);
+ WebLoginQueryPasswordOk = true;
+ }
+ else
+ {
+ WebLoginQueryPasswordOk = WebLoginPasswordMatches(pValue);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/login/web-login-session-id.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,50 @@
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "random.h"
+
+#define SESSION_ID_BIT_LENGTH 36
+
+static char sessionId[(SESSION_ID_BIT_LENGTH + 5) / 6 + 1]; //Bit lengths not divisible by 6 require an extra space
+
+void WebLoginSessionIdNew()
+{
+ char acc = 0;
+
+ for (int i = 0; i < SESSION_ID_BIT_LENGTH; i++)
+ {
+ int srcByte = i / 8;
+ int srcBit = i - srcByte * 8;
+ uint8_t srcMask = 1 << srcBit;
+
+ int dstByte = i / 6;
+ int dstBit = i - dstByte * 6;
+ uint8_t dstMask = 1 << dstBit;
+
+ //Reset the accumulator to zero at start of a 6 bit word
+ if (!dstBit) acc = 0;
+
+ //Add the bit to the accumulator
+ if (RandomBytes[srcByte] & srcMask) acc |= dstMask;
+
+ //Convert the accumulator to base64 and store in the session Id
+ if (dstBit == 5 || i == SESSION_ID_BIT_LENGTH - 1)
+ {
+ if (acc < 26) sessionId[dstByte] = acc - 0 + 'A';
+ else if (acc < 52) sessionId[dstByte] = acc - 26 + 'a';
+ else if (acc < 62) sessionId[dstByte] = acc - 52 + '0';
+ else if (acc < 63) sessionId[dstByte] = '+';
+ else sessionId[dstByte] = '/';
+ }
+ }
+ sessionId[(SESSION_ID_BIT_LENGTH + 5) / 6] = 0;
+}
+
+bool WebLoginSessionIdIsSet()
+{
+ return sessionId[0];
+}
+char* WebLoginSessionIdGet()
+{
+ return sessionId;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/login/web-login-session-name.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,37 @@
+#include "web-site-name.h"
+
+#define SESSION_LIFE 10 * 365 * 24 * 60 * 60
+
+//Do not use ' ', ';', '=' as they are part of the cookie protocol: name1=value1; name2=value2; name3=value3 etc
+static char sessionName[9]; //Limit the name to 8 characters (plus terminating zero) to keep things quick
+
+char* WebLoginSessionNameGet()
+{
+ return sessionName;
+}
+
+void WebLoginSessionNameCreate()
+{
+ //Make the session name from the site name - eg "Heating" and "GPS Clock" will be "heat_sid" and "gpsc_sid"
+ int i = 0;
+ int j = 0;
+ while (1)
+ {
+ if (i >= sizeof(sessionName) - 4 - 1) break; //Leave room for the "_sid" and the terminating NUL character
+ char c = WEB_SITE_NAME[j++];
+ if (!c) break; //Stop if run out of site name
+ if (c >= 'A' && c <= 'Z') c |= 0x20; //Make lower case
+ if (c < 'a' || c > 'z') continue; //Skip anything other than letters
+ sessionName[i++] = c; //Add the first characters of the site name for which there is room
+ }
+ for (int k = 0; k < 4; k++) //Add "_sid"
+ {
+ sessionName[i++] = "_sid"[k];
+ }
+ sessionName[i] = 0; //Add the terminating NUL character
+}
+
+int WebLoginSessionNameLife()
+{
+ return SESSION_LIFE;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/login/web-login.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,30 @@
+
+#include "web-pages-base.h"
+#include "web-login.h"
+#include "http.h"
+#include "fault.h"
+
+int WebLoginOriginalToDo = 0;
+
+bool WebLoginCookiesContainValidSessionId(char* pCookies)
+{
+ if (!WebLoginSessionIdIsSet()) return false;
+
+ while (pCookies)
+ {
+ char* pName;
+ char* pValue;
+ pCookies = HttpCookiesSplit(pCookies, &pName, &pValue);
+
+ if (HttpSameStr(pName, WebLoginSessionNameGet())) //HttpSameStr handles NULLs correctly
+ {
+ if (HttpSameStr(pValue, WebLoginSessionIdGet())) return true;
+ }
+ }
+ return false;
+}
+void WebLoginInit()
+{
+ if (FaultTypeGet()) WebLoginPasswordRestore();
+ WebLoginSessionNameCreate();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/login/web-login.h Tue Apr 30 12:45:08 2019 +0000 @@ -0,0 +1,8 @@ +#include <stdbool.h> + +extern void WebLoginSessionNameCreate(void); + +extern void WebLoginPasswordRestore (void); +extern void WebLoginPasswordSet (char* password); +extern bool WebLoginPasswordIsSet (void); +extern bool WebLoginPasswordMatches (char* password); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net-trace/web-trace-ajax.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,101 @@
+#include <stdint.h>
+
+#include "http.h"
+#include "log.h"
+#include "net.h"
+#include "link.h"
+#include "dns.h"
+#include "dnsname.h"
+#include "dnsquery.h"
+#include "dnsreply.h"
+#include "dnsserver.h"
+#include "ntp.h"
+#include "dhcp.h"
+#include "ns.h"
+#include "nr4.h"
+#include "nr6.h"
+#include "echo4.h"
+#include "echo6.h"
+#include "dest6.h"
+#include "ra.h"
+#include "rs.h"
+#include "ar4.h"
+#include "ar6.h"
+#include "arp.h"
+#include "ip4.h"
+#include "ip6.h"
+#include "udp.h"
+#include "tcp.h"
+#include "http.h"
+#include "tftp.h"
+#include "ntpclient.h"
+
+void WebTraceAjax()
+{
+ HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
+ char nibble;
+
+ nibble = 0; //0
+ if ( DnsSendRequestsViaIp4) nibble |= 2;
+ if ( NtpClientQuerySendRequestsViaIp4) nibble |= 4;
+ if (TftpSendRequestsViaIp4) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ HttpAddByteAsHex(NetTraceHost[0]); //1, 2
+ HttpAddByteAsHex(NetTraceHost[1]); //3, 4
+
+ nibble = 0; //5
+ if (NetTraceStack ) nibble |= 1;
+ if (NetTraceNewLine ) nibble |= 2;
+ if (NetTraceVerbose ) nibble |= 4;
+ if (LinkTrace ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ nibble = 0; //6
+ if (DnsNameTrace ) nibble |= 1;
+ if (DnsQueryTrace ) nibble |= 2;
+ if (DnsReplyTrace ) nibble |= 4;
+ if (DnsServerTrace ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ nibble = 0; //7
+ if (NtpTrace ) nibble |= 1;
+ if (DhcpTrace ) nibble |= 2;
+ if (NsTraceRecvSol ) nibble |= 4;
+ if (NsTraceRecvAdv ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ nibble = 0; //8
+ if (NsTraceSendSol ) nibble |= 1;
+ if (Nr4Trace ) nibble |= 2;
+ if (Nr6Trace ) nibble |= 4;
+ if (NtpClientTrace ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ nibble = 0; //9
+ if (Echo4Trace ) nibble |= 4;
+ if (Echo6Trace ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ nibble = 0; //10
+ if (Dest6Trace ) nibble |= 1;
+ if (RaTrace ) nibble |= 2;
+ if (RsTrace ) nibble |= 4;
+ if (Ar4Trace ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ nibble = 0; //11
+ if (Ar6Trace ) nibble |= 1;
+ if (ArpTrace ) nibble |= 2;
+ if (Ip4Trace ) nibble |= 4;
+ if (Ip6Trace ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+
+ nibble = 0; //12
+ if (UdpTrace ) nibble |= 1;
+ if (TcpTrace ) nibble |= 2;
+ if (HttpTrace ) nibble |= 4;
+ if (TftpTrace ) nibble |= 8;
+ HttpAddNibbleAsHex(nibble);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net-trace/web-trace-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,55 @@
+#include "web-add.h"
+#include "web-nav-base.h"
+#include "http.h"
+
+void WebTraceHtml()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Net Trace", "settings.css", "trace.js");
+ WebAddNav(TRACE_PAGE);
+ WebAddH1("Net Trace");
+
+ WebAddH2("General");
+ WebAddAjaxInput ("Trace host" , 5 , "ajax-trace-net-host" , "set-trace-net-host" );
+ WebAddAjaxInputToggle("Trace stack" , "ajax-trace-net-stack" , "chg-trace-net-stack" );
+ WebAddAjaxInputToggle("Trace new line" , "ajax-trace-net-newline", "chg-trace-net-newline");
+ WebAddAjaxInputToggle("Trace verbose" , "ajax-trace-net-verbose", "chg-trace-net-verbose");
+ WebAddH2("Net");
+ WebAddAjaxInputToggle("MAC" , "ajax-trace-link" , "chg-trace-link" );
+ WebAddAjaxInputToggle("Ip4 filtered" , "ajax-trace-ip4" , "chg-trace-ip4" );
+ WebAddAjaxInputToggle("Ip6 filtered" , "ajax-trace-ip6" , "chg-trace-ip6" );
+ WebAddAjaxInputToggle("Udp filtered" , "ajax-trace-udp" , "chg-trace-udp" );
+ WebAddAjaxInputToggle("Tcp filtered" , "ajax-trace-tcp" , "chg-trace-tcp" );
+ WebAddAjaxInputToggle("Echo4 (ping4)" , "ajax-trace-echo4" , "chg-trace-echo4" );
+ WebAddAjaxInputToggle("Echo6 (ping6)" , "ajax-trace-echo6" , "chg-trace-echo6" );
+ WebAddAjaxInputToggle("Dest6 unreacheable" , "ajax-trace-dest6" , "chg-trace-dest6" );
+ WebAddAjaxInputToggle("HTTP" , "ajax-trace-http" , "chg-trace-http" );
+ WebAddAjaxInputToggle("TFTP" , "ajax-trace-tftp" , "chg-trace-tftp" );
+ WebAddH2("Send requests via IPv4");
+ WebAddAjaxInputToggle("DNS request via IPv4" , "ajax-trace-dns-ip4" , "chg-send-dns-ip4" );
+ WebAddAjaxInputToggle("NTP request via IPv4" , "ajax-trace-ntp-ip4" , "chg-send-ntp-ip4" );
+ WebAddAjaxInputToggle("TFTP request via IPv4", "ajax-trace-tftp-ip4" , "chg-send-tftp-ip4" );
+ WebAddH2("Router Resolution");
+ WebAddAjaxInputToggle("Router advertise" , "ajax-trace-ra" , "chg-trace-ra" );
+ WebAddAjaxInputToggle("Router solicit" , "ajax-trace-rs" , "chg-trace-rs" );
+ WebAddAjaxInputToggle("DHCP" , "ajax-trace-dhcp" , "chg-trace-dhcp" );
+ WebAddH2("Address Resolution");
+ WebAddAjaxInputToggle("IP4 cache" , "ajax-trace-ar4" , "chg-trace-ar4" );
+ WebAddAjaxInputToggle("IP6 cache" , "ajax-trace-ar6" , "chg-trace-ar6" );
+ WebAddAjaxInputToggle("ARP" , "ajax-trace-arp" , "chg-trace-arp" );
+ WebAddAjaxInputToggle("NS server" , "ajax-trace-ns-recv-sol", "chg-trace-ns-recv-sol");
+ WebAddAjaxInputToggle("NS client reply" , "ajax-trace-ns-recv-adv", "chg-trace-ns-recv-adv");
+ WebAddAjaxInputToggle("NS client query" , "ajax-trace-ns-send-sol", "chg-trace-ns-send-sol");
+ WebAddH2("Name Resolution");
+ WebAddAjaxInputToggle("IP4 cache" , "ajax-trace-nr4" , "chg-trace-nr4" );
+ WebAddAjaxInputToggle("IP6 cache" , "ajax-trace-nr6" , "chg-trace-nr6" );
+ WebAddAjaxInputToggle("DNS name" , "ajax-trace-dns-name" , "chg-trace-dns-name" );
+ WebAddAjaxInputToggle("DNS client query" , "ajax-trace-dns-query" , "chg-trace-dns-query" );
+ WebAddAjaxInputToggle("DNS client reply" , "ajax-trace-dns-reply" , "chg-trace-dns-reply" );
+ WebAddAjaxInputToggle("DNS server" , "ajax-trace-dns-server" , "chg-trace-dns-server" );
+ WebAddH2("NTP");
+ WebAddAjaxInputToggle("NTP" , "ajax-trace-ntp" , "chg-trace-ntp" );
+ WebAddAjaxInputToggle("NTP client" , "ajax-trace-ntp-client" , "chg-trace-ntp-client" );
+
+ WebAddEnd();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net-trace/web-trace-query.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,49 @@
+#include "http.h"
+#include "settings.h"
+
+void WebTraceQuery(char* pQuery)
+{
+ while (pQuery)
+ {
+ char* pName;
+ char* pValue;
+ pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
+
+ if (HttpSameStr(pName, "chg-send-dns-ip4" )) ChgDnsSendRequestsViaIp4();
+ if (HttpSameStr(pName, "chg-send-ntp-ip4" )) ChgNtpSendRequestsViaIp4();
+ if (HttpSameStr(pName, "chg-send-tftp-ip4" )) ChgTftpSendRequestsViaIp4();
+ if (HttpSameStr(pName, "set-trace-net-host" )) SetTraceNetHost(pValue);
+ if (HttpSameStr(pName, "chg-trace-net-stack" )) ChgTraceNetStack();
+ if (HttpSameStr(pName, "chg-trace-net-newline" )) ChgTraceNetNewLine();
+ if (HttpSameStr(pName, "chg-trace-net-verbose" )) ChgTraceNetVerbose();
+ if (HttpSameStr(pName, "chg-trace-link" )) ChgTraceLink();
+ if (HttpSameStr(pName, "chg-trace-dns-name" )) ChgTraceDnsName();
+ if (HttpSameStr(pName, "chg-trace-dns-query" )) ChgTraceDnsQuery();
+ if (HttpSameStr(pName, "chg-trace-dns-reply" )) ChgTraceDnsReply();
+ if (HttpSameStr(pName, "chg-trace-dns-server" )) ChgTraceDnsServer();
+ if (HttpSameStr(pName, "chg-trace-ntp" )) ChgTraceNtp();
+ if (HttpSameStr(pName, "chg-trace-dhcp" )) ChgTraceDhcp();
+ if (HttpSameStr(pName, "chg-trace-ns-recv-sol" )) ChgTraceNsRecvSol();
+ if (HttpSameStr(pName, "chg-trace-ns-recv-adv" )) ChgTraceNsRecvAdv();
+ if (HttpSameStr(pName, "chg-trace-ns-send-sol" )) ChgTraceNsSendSol();
+ if (HttpSameStr(pName, "chg-trace-nr4" )) ChgTraceNr4();
+ if (HttpSameStr(pName, "chg-trace-nr6" )) ChgTraceNr6();
+ if (HttpSameStr(pName, "chg-trace-ntp-client" )) ChgTraceNtpClient();
+ if (HttpSameStr(pName, "chg-trace-sync" )) ChgTraceSync();
+ if (HttpSameStr(pName, "chg-trace-echo4" )) ChgTraceEcho4();
+ if (HttpSameStr(pName, "chg-trace-echo6" )) ChgTraceEcho6();
+ if (HttpSameStr(pName, "chg-trace-dest6" )) ChgTraceDest6();
+ if (HttpSameStr(pName, "chg-trace-ra" )) ChgTraceRa();
+ if (HttpSameStr(pName, "chg-trace-rs" )) ChgTraceRs();
+ if (HttpSameStr(pName, "chg-trace-ar4" )) ChgTraceAr4();
+ if (HttpSameStr(pName, "chg-trace-ar6" )) ChgTraceAr6();
+ if (HttpSameStr(pName, "chg-trace-arp" )) ChgTraceArp();
+ if (HttpSameStr(pName, "chg-trace-ip4" )) ChgTraceIp4();
+ if (HttpSameStr(pName, "chg-trace-ip6" )) ChgTraceIp6();
+ if (HttpSameStr(pName, "chg-trace-udp" )) ChgTraceUdp();
+ if (HttpSameStr(pName, "chg-trace-tcp" )) ChgTraceTcp();
+ if (HttpSameStr(pName, "chg-trace-http" )) ChgTraceHttp();
+ if (HttpSameStr(pName, "chg-trace-tftp" )) ChgTraceTftp();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net-trace/web-trace-script.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,17 @@
+#include "http.h"
+
+//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
+//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
+
+const char* WebTraceScriptDate = __DATE__;
+const char* WebTraceScriptTime = __TIME__;
+
+static const char* script =
+#include "../core/web-ajax-class.inc"
+#include "web-trace-script.inc"
+;
+void WebTraceScript()
+{
+ HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebTraceScriptDate, WebTraceScriptTime);
+ HttpAddText(script);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net-trace/web-trace-script.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,48 @@
+"//Net trace script\n"
+"'use strict';\n"
+"function setDirection(elem, iChar, iBit)\n"
+"{\n"
+" elem.setAttribute('dir', Ajax.hexToBit(Ajax.response.charAt(iChar), iBit) ? 'rtl' : 'ltr');\n"
+"}\n"
+"function display()\n"
+"{\n"
+" var elem;\n"
+" elem = Ajax.getElementOrNull('ajax-trace-dns-ip4' ); if (elem) setDirection(elem, 0, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ntp-ip4' ); if (elem) setDirection(elem, 0, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-tftp-ip4' ); if (elem) setDirection(elem, 0, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-net-host' ); if (elem) elem.value = Ajax.response.substr( 1, 4);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-net-stack' ); if (elem) setDirection(elem, 5, 0);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-net-newline' ); if (elem) setDirection(elem, 5, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-net-verbose' ); if (elem) setDirection(elem, 5, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-link' ); if (elem) setDirection(elem, 5, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-dns-name' ); if (elem) setDirection(elem, 6, 0);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-dns-query' ); if (elem) setDirection(elem, 6, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-dns-reply' ); if (elem) setDirection(elem, 6, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-dns-server' ); if (elem) setDirection(elem, 6, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ntp' ); if (elem) setDirection(elem, 7, 0);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-dhcp' ); if (elem) setDirection(elem, 7, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ns-recv-sol' ); if (elem) setDirection(elem, 7, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ns-recv-adv' ); if (elem) setDirection(elem, 7, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ns-send-sol' ); if (elem) setDirection(elem, 8, 0);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-nr4' ); if (elem) setDirection(elem, 8, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-nr6' ); if (elem) setDirection(elem, 8, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ntp-client' ); if (elem) setDirection(elem, 8, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-echo4' ); if (elem) setDirection(elem, 9, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-echo6' ); if (elem) setDirection(elem, 9, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-dest6' ); if (elem) setDirection(elem, 10, 0);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ra' ); if (elem) setDirection(elem, 10, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-rs' ); if (elem) setDirection(elem, 10, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ar4' ); if (elem) setDirection(elem, 10, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ar6' ); if (elem) setDirection(elem, 11, 0);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-arp' ); if (elem) setDirection(elem, 11, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ip4' ); if (elem) setDirection(elem, 11, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-ip6' ); if (elem) setDirection(elem, 11, 3);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-udp' ); if (elem) setDirection(elem, 12, 0);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-tcp' ); if (elem) setDirection(elem, 12, 1);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-http' ); if (elem) setDirection(elem, 12, 2);\n"
+" elem = Ajax.getElementOrNull('ajax-trace-tftp' ); if (elem) setDirection(elem, 12, 3);\n"
+"}\n"
+"\n"
+"Ajax.server = '/trace-ajax';\n"
+"Ajax.onResponse = display;\n"
+"Ajax.init();"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net-trace/web-trace-script.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,48 @@
+//Net trace script
+'use strict';
+function setDirection(elem, iChar, iBit)
+{
+ elem.setAttribute('dir', Ajax.hexToBit(Ajax.response.charAt(iChar), iBit) ? 'rtl' : 'ltr');
+}
+function display()
+{
+ var elem;
+ elem = Ajax.getElementOrNull('ajax-trace-dns-ip4' ); if (elem) setDirection(elem, 0, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-ntp-ip4' ); if (elem) setDirection(elem, 0, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-tftp-ip4' ); if (elem) setDirection(elem, 0, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-net-host' ); if (elem) elem.value = Ajax.response.substr( 1, 4);
+ elem = Ajax.getElementOrNull('ajax-trace-net-stack' ); if (elem) setDirection(elem, 5, 0);
+ elem = Ajax.getElementOrNull('ajax-trace-net-newline' ); if (elem) setDirection(elem, 5, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-net-verbose' ); if (elem) setDirection(elem, 5, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-link' ); if (elem) setDirection(elem, 5, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-dns-name' ); if (elem) setDirection(elem, 6, 0);
+ elem = Ajax.getElementOrNull('ajax-trace-dns-query' ); if (elem) setDirection(elem, 6, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-dns-reply' ); if (elem) setDirection(elem, 6, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-dns-server' ); if (elem) setDirection(elem, 6, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-ntp' ); if (elem) setDirection(elem, 7, 0);
+ elem = Ajax.getElementOrNull('ajax-trace-dhcp' ); if (elem) setDirection(elem, 7, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-ns-recv-sol' ); if (elem) setDirection(elem, 7, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-ns-recv-adv' ); if (elem) setDirection(elem, 7, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-ns-send-sol' ); if (elem) setDirection(elem, 8, 0);
+ elem = Ajax.getElementOrNull('ajax-trace-nr4' ); if (elem) setDirection(elem, 8, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-nr6' ); if (elem) setDirection(elem, 8, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-ntp-client' ); if (elem) setDirection(elem, 8, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-echo4' ); if (elem) setDirection(elem, 9, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-echo6' ); if (elem) setDirection(elem, 9, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-dest6' ); if (elem) setDirection(elem, 10, 0);
+ elem = Ajax.getElementOrNull('ajax-trace-ra' ); if (elem) setDirection(elem, 10, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-rs' ); if (elem) setDirection(elem, 10, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-ar4' ); if (elem) setDirection(elem, 10, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-ar6' ); if (elem) setDirection(elem, 11, 0);
+ elem = Ajax.getElementOrNull('ajax-trace-arp' ); if (elem) setDirection(elem, 11, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-ip4' ); if (elem) setDirection(elem, 11, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-ip6' ); if (elem) setDirection(elem, 11, 3);
+ elem = Ajax.getElementOrNull('ajax-trace-udp' ); if (elem) setDirection(elem, 12, 0);
+ elem = Ajax.getElementOrNull('ajax-trace-tcp' ); if (elem) setDirection(elem, 12, 1);
+ elem = Ajax.getElementOrNull('ajax-trace-http' ); if (elem) setDirection(elem, 12, 2);
+ elem = Ajax.getElementOrNull('ajax-trace-tftp' ); if (elem) setDirection(elem, 12, 3);
+}
+
+Ajax.server = '/trace-ajax';
+Ajax.onResponse = display;
+Ajax.init();
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net-class.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,69 @@
+"//Net class\n"
+"'use strict';\n"
+"\n"
+"class Net\n"
+"{\n"
+" static makeIp4(text)\n"
+" {\n"
+" let result = '';\n"
+" result += parseInt(text.substr(6, 2), 16).toString();\n"
+" result += '.';\n"
+" result += parseInt(text.substr(4, 2), 16).toString();\n"
+" result += '.';\n"
+" result += parseInt(text.substr(2, 2), 16).toString();\n"
+" result += '.';\n"
+" result += parseInt(text.substr(0, 2), 16).toString();\n"
+" return result;\n"
+" }\n"
+" static makeMac(text)\n"
+" {\n"
+" text = text.toLowerCase();\n"
+" let result = '';\n"
+" result += text.substr( 0, 2);\n"
+" result += ':';\n"
+" result += text.substr( 2, 2);\n"
+" result += ':';\n"
+" result += text.substr( 4, 2);\n"
+" result += ':';\n"
+" result += text.substr( 6, 2);\n"
+" result += ':';\n"
+" result += text.substr( 8, 2);\n"
+" result += ':';\n"
+" result += text.substr(10, 2);\n"
+" return result;\n"
+" }\n"
+"\n"
+" static hexToBit(text, iBit)\n"
+" {\n"
+" let value = parseInt(text, 16);\n"
+" value >>= iBit;\n"
+" return value & 1;\n"
+" }\n"
+" static makeIp6(text)\n"
+" {\n"
+" function makeWord(text)\n"
+" {\n"
+" let word = parseInt(text, 16);\n"
+" if (word === 0) return '';\n"
+" return word.toString(16);\n"
+" }\n"
+" text = text.toLowerCase();\n"
+" let result = '';\n"
+" result += makeWord(text.substr( 0, 4));\n"
+" result += ':';\n"
+" result += makeWord(text.substr( 4, 4));\n"
+" result += ':';\n"
+" result += makeWord(text.substr( 8, 4));\n"
+" result += ':';\n"
+" result += makeWord(text.substr(12, 4));\n"
+" result += ':';\n"
+" result += makeWord(text.substr(16, 4));\n"
+" result += ':';\n"
+" result += makeWord(text.substr(20, 4));\n"
+" result += ':';\n"
+" result += makeWord(text.substr(24, 4));\n"
+" result += ':';\n"
+" result += makeWord(text.substr(28, 4));\n"
+" return result;\n"
+" }\n"
+"}"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net-class.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,69 @@
+//Net class
+'use strict';
+
+class Net
+{
+ static makeIp4(text)
+ {
+ let result = '';
+ result += parseInt(text.substr(6, 2), 16).toString();
+ result += '.';
+ result += parseInt(text.substr(4, 2), 16).toString();
+ result += '.';
+ result += parseInt(text.substr(2, 2), 16).toString();
+ result += '.';
+ result += parseInt(text.substr(0, 2), 16).toString();
+ return result;
+ }
+ static makeMac(text)
+ {
+ text = text.toLowerCase();
+ let result = '';
+ result += text.substr( 0, 2);
+ result += ':';
+ result += text.substr( 2, 2);
+ result += ':';
+ result += text.substr( 4, 2);
+ result += ':';
+ result += text.substr( 6, 2);
+ result += ':';
+ result += text.substr( 8, 2);
+ result += ':';
+ result += text.substr(10, 2);
+ return result;
+ }
+
+ static hexToBit(text, iBit)
+ {
+ let value = parseInt(text, 16);
+ value >>= iBit;
+ return value & 1;
+ }
+ static makeIp6(text)
+ {
+ function makeWord(text)
+ {
+ let word = parseInt(text, 16);
+ if (word === 0) return '';
+ return word.toString(16);
+ }
+ text = text.toLowerCase();
+ let result = '';
+ result += makeWord(text.substr( 0, 4));
+ result += ':';
+ result += makeWord(text.substr( 4, 4));
+ result += ':';
+ result += makeWord(text.substr( 8, 4));
+ result += ':';
+ result += makeWord(text.substr(12, 4));
+ result += ':';
+ result += makeWord(text.substr(16, 4));
+ result += ':';
+ result += makeWord(text.substr(20, 4));
+ result += ':';
+ result += makeWord(text.substr(24, 4));
+ result += ':';
+ result += makeWord(text.substr(28, 4));
+ return result;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,18 @@
+#include "http.h"
+#include "web-nav-base.h"
+#include "web-add.h"
+#include "mac.h"
+
+void WebNetHtml()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Net", "settings.css", NULL);
+ WebAddNav(NET_PAGE);
+ WebAddH1("Net");
+
+ WebAddH2("Ethernet");
+ WebAddLabelledMac ("MAC", MacLocal);
+
+ WebAddEnd();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net4-ajax.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+#include "http.h"
+#include "ar4.h"
+#include "nr4.h"
+#include "dhcp.h"
+
+void WebNet4Ajax()
+{
+ HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
+
+ HttpAddInt32AsHex(DhcpLocalIp); HttpAddChar('\n');
+ HttpAddText (DhcpDomainName); HttpAddChar('\n');
+ HttpAddText (DhcpHostName); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpNtpIp); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpDnsServerIp); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpServerIp); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpRouterIp); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpSubnetMask); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpBroadcastIp); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpLeaseTime); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpRenewalT1); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpRenewalT2); HttpAddChar('\n');
+ HttpAddInt32AsHex(DhcpGetElapsedLife()); HttpAddChar('\n');
+ HttpAddChar('\f');
+
+ Ar4SendAjax();
+ HttpAddChar('\f');
+
+ Nr4SendAjax();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net4-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,34 @@
+#include "http.h"
+#include "web-add.h"
+#include "web-nav-base.h"
+
+void WebNet4Html()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Net IPv4", "settings.css", "net4.js");
+ WebAddNav(NET4_PAGE);
+ WebAddH1("Net IPv4");
+
+ WebAddH2("ARP");
+ HttpAddText("<code id='ajax-arp'></code>\r\n");
+ WebAddH2("DNS");
+ HttpAddText("<code id='ajax-dns'></code>\r\n");
+
+ WebAddH2("DHCP");
+ WebAddAjaxLabelled("IP4 address", "ajax-local-ip" );
+ WebAddAjaxLabelled("Domain", "ajax-domain-name" );
+ WebAddAjaxLabelled("Host name", "ajax-host-name" );
+ WebAddAjaxLabelled("NTP server", "ajax-ntp-ip" );
+ WebAddAjaxLabelled("DNS server", "ajax-dns-ip" );
+ WebAddAjaxLabelled("DHCP server", "ajax-dhcp-ip" );
+ WebAddAjaxLabelled("Router", "ajax-router-ip" );
+ WebAddAjaxLabelled("Subnet mask", "ajax-subnet-mask" );
+ WebAddAjaxLabelled("Broadcast IP", "ajax-broadcast-ip");
+ WebAddAjaxLabelled("Lease time IP", "ajax-lease-time" );
+ WebAddAjaxLabelled("Renewal T1", "ajax-renewal-t1" );
+ WebAddAjaxLabelled("Renewal T2", "ajax-renewal-t2" );
+ WebAddAjaxLabelled("Elapsed", "ajax-elapsed" );
+
+ WebAddEnd();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net4-script.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,18 @@
+#include "http.h"
+
+//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
+//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
+
+const char* WebNet4ScriptDate = __DATE__;
+const char* WebNet4ScriptTime = __TIME__;
+
+static const char* script =
+#include "../core/web-ajax-class.inc"
+#include "web-net-class.inc"
+#include "web-net4-script.inc"
+;
+void WebNet4Script()
+{
+ HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebNet4ScriptDate, WebNet4ScriptTime);
+ HttpAddText(script);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net4-script.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,102 @@
+"//Net4 script\n"
+"'use strict';\n"
+"\n"
+"let localIp = '';\n"
+"let domainName = '';\n"
+"let hostName = '';\n"
+"let ntpIp = '';\n"
+"let dnsIp = '';\n"
+"let dhcpIp = '';\n"
+"let routerIp = '';\n"
+"let subnetMask = '';\n"
+"let broadcastIp = '';\n"
+"let leaseTime = '';\n"
+"let renewalT1 = '';\n"
+"let renewalt2 = '';\n"
+"let elapsed = '';\n"
+"let arp = '';\n"
+"let dns = '';\n"
+"\n"
+"function parseArpLine(line)\n"
+"{\n"
+" if (line.length == 0) return;\n"
+" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
+" arp += Math.floor(minutes).toString().padStart(4, ' ');\n"
+" arp += ' ';\n"
+" arp += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');\n"
+" arp += ' ';\n"
+" arp += Net.makeMac(line.substr(16, 12));\n"
+" arp += '\\r\\n';\n"
+"}\n"
+"function parseDnsLine(line)\n"
+"{\n"
+" if (line.length == 0) return;\n"
+" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
+" dns += Math.floor(minutes).toString().padStart(4, ' ');\n"
+" dns += ' ';\n"
+" dns += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');\n"
+" dns += ' ';\n"
+" dns += line.substr(16, 1);\n"
+" dns += ' ';\n"
+" dns += line.substr(17);\n"
+" dns += '\\r\\n';\n"
+"}\n"
+"function parseArpLines(text)\n"
+"{\n"
+" arp = '';\n"
+" text.split('\\n').forEach(parseArpLine);\n"
+"}\n"
+"function parseDnsLines(text)\n"
+"{\n"
+" dns = '';\n"
+" text.split('\\n').forEach(parseDnsLine);\n"
+"}\n"
+"function parseGenLines(text)\n"
+"{\n"
+" let lines = text.split('\\n');\n"
+" localIp = Net.makeIp4(lines[ 0]) ;\n"
+" domainName = lines[ 1] ;\n"
+" hostName = lines[ 2] ;\n"
+" ntpIp = Net.makeIp4(lines[ 3]) ;\n"
+" dnsIp = Net.makeIp4(lines[ 4]) ;\n"
+" dhcpIp = Net.makeIp4(lines[ 5]) ;\n"
+" routerIp = Net.makeIp4(lines[ 6]) ;\n"
+" subnetMask = Net.makeIp4(lines[ 7]) ;\n"
+" broadcastIp = Net.makeIp4(lines[ 8]) ;\n"
+" leaseTime = parseInt(lines[ 9], 16);\n"
+" renewalT1 = parseInt(lines[10], 16);\n"
+" renewalt2 = parseInt(lines[11], 16);\n"
+" elapsed = parseInt(lines[12], 16);\n"
+"}\n"
+"function parse()\n"
+"{\n"
+" let topics = Ajax.response.split('\\f');\n"
+" parseGenLines(topics[0]);\n"
+" parseArpLines(topics[1]);\n"
+" parseDnsLines(topics[2]);\n"
+"}\n"
+"function display()\n"
+"{\n"
+" let elem;\n"
+"\n"
+" elem = Ajax.getElementOrNull('ajax-local-ip' ); if (elem) elem.textContent = localIp;\n"
+" elem = Ajax.getElementOrNull('ajax-domain-name' ); if (elem) elem.textContent = domainName;\n"
+" elem = Ajax.getElementOrNull('ajax-host-name' ); if (elem) elem.textContent = hostName;\n"
+" elem = Ajax.getElementOrNull('ajax-ntp-ip' ); if (elem) elem.textContent = ntpIp;\n"
+" elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;\n"
+" elem = Ajax.getElementOrNull('ajax-dhcp-ip' ); if (elem) elem.textContent = dhcpIp;\n"
+" elem = Ajax.getElementOrNull('ajax-router-ip' ); if (elem) elem.textContent = routerIp;\n"
+" elem = Ajax.getElementOrNull('ajax-subnet-mask' ); if (elem) elem.textContent = subnetMask;\n"
+" elem = Ajax.getElementOrNull('ajax-broadcast-ip'); if (elem) elem.textContent = broadcastIp;\n"
+" elem = Ajax.getElementOrNull('ajax-lease-time' ); if (elem) elem.textContent = leaseTime;\n"
+" elem = Ajax.getElementOrNull('ajax-renewal-t1' ); if (elem) elem.textContent = renewalT1;\n"
+" elem = Ajax.getElementOrNull('ajax-renewal-t2' ); if (elem) elem.textContent = renewalt2;\n"
+" elem = Ajax.getElementOrNull('ajax-elapsed' ); if (elem) elem.textContent = elapsed;\n"
+" elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;\n"
+" elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;\n"
+"}\n"
+"\n"
+"Ajax.server = '/net4-ajax';\n"
+"Ajax.onResponse = function() { parse(); display(); };\n"
+"Ajax.init();\n"
+""
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net4-script.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,101 @@
+//Net4 script
+'use strict';
+
+let localIp = '';
+let domainName = '';
+let hostName = '';
+let ntpIp = '';
+let dnsIp = '';
+let dhcpIp = '';
+let routerIp = '';
+let subnetMask = '';
+let broadcastIp = '';
+let leaseTime = '';
+let renewalT1 = '';
+let renewalt2 = '';
+let elapsed = '';
+let arp = '';
+let dns = '';
+
+function parseArpLine(line)
+{
+ if (line.length == 0) return;
+ let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
+ arp += Math.floor(minutes).toString().padStart(4, ' ');
+ arp += ' ';
+ arp += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');
+ arp += ' ';
+ arp += Net.makeMac(line.substr(16, 12));
+ arp += '\r\n';
+}
+function parseDnsLine(line)
+{
+ if (line.length == 0) return;
+ let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
+ dns += Math.floor(minutes).toString().padStart(4, ' ');
+ dns += ' ';
+ dns += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');
+ dns += ' ';
+ dns += line.substr(16, 1);
+ dns += ' ';
+ dns += line.substr(17);
+ dns += '\r\n';
+}
+function parseArpLines(text)
+{
+ arp = '';
+ text.split('\n').forEach(parseArpLine);
+}
+function parseDnsLines(text)
+{
+ dns = '';
+ text.split('\n').forEach(parseDnsLine);
+}
+function parseGenLines(text)
+{
+ let lines = text.split('\n');
+ localIp = Net.makeIp4(lines[ 0]) ;
+ domainName = lines[ 1] ;
+ hostName = lines[ 2] ;
+ ntpIp = Net.makeIp4(lines[ 3]) ;
+ dnsIp = Net.makeIp4(lines[ 4]) ;
+ dhcpIp = Net.makeIp4(lines[ 5]) ;
+ routerIp = Net.makeIp4(lines[ 6]) ;
+ subnetMask = Net.makeIp4(lines[ 7]) ;
+ broadcastIp = Net.makeIp4(lines[ 8]) ;
+ leaseTime = parseInt(lines[ 9], 16);
+ renewalT1 = parseInt(lines[10], 16);
+ renewalt2 = parseInt(lines[11], 16);
+ elapsed = parseInt(lines[12], 16);
+}
+function parse()
+{
+ let topics = Ajax.response.split('\f');
+ parseGenLines(topics[0]);
+ parseArpLines(topics[1]);
+ parseDnsLines(topics[2]);
+}
+function display()
+{
+ let elem;
+
+ elem = Ajax.getElementOrNull('ajax-local-ip' ); if (elem) elem.textContent = localIp;
+ elem = Ajax.getElementOrNull('ajax-domain-name' ); if (elem) elem.textContent = domainName;
+ elem = Ajax.getElementOrNull('ajax-host-name' ); if (elem) elem.textContent = hostName;
+ elem = Ajax.getElementOrNull('ajax-ntp-ip' ); if (elem) elem.textContent = ntpIp;
+ elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;
+ elem = Ajax.getElementOrNull('ajax-dhcp-ip' ); if (elem) elem.textContent = dhcpIp;
+ elem = Ajax.getElementOrNull('ajax-router-ip' ); if (elem) elem.textContent = routerIp;
+ elem = Ajax.getElementOrNull('ajax-subnet-mask' ); if (elem) elem.textContent = subnetMask;
+ elem = Ajax.getElementOrNull('ajax-broadcast-ip'); if (elem) elem.textContent = broadcastIp;
+ elem = Ajax.getElementOrNull('ajax-lease-time' ); if (elem) elem.textContent = leaseTime;
+ elem = Ajax.getElementOrNull('ajax-renewal-t1' ); if (elem) elem.textContent = renewalT1;
+ elem = Ajax.getElementOrNull('ajax-renewal-t2' ); if (elem) elem.textContent = renewalt2;
+ elem = Ajax.getElementOrNull('ajax-elapsed' ); if (elem) elem.textContent = elapsed;
+ elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;
+ elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;
+}
+
+Ajax.server = '/net4-ajax';
+Ajax.onResponse = function() { parse(); display(); };
+Ajax.init();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net6-ajax.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+#include "http.h"
+#include "ndp.h"
+#include "slaac.h"
+#include "ar6.h"
+#include "nr6.h"
+
+void WebNet6Ajax()
+{
+ HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
+
+ char nibble;
+ nibble = 0;
+ if (NdpManagedConfiguration) nibble |= 1; //4
+ if (NdpOtherConfiguration ) nibble |= 2; //4
+ if (NdpPrefixFlagL ) nibble |= 4; //4
+ if (NdpPrefixFlagA ) nibble |= 8; //4
+ HttpAddNibbleAsHex(nibble); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpHopLimit); HttpAddChar('\n');
+ for (char* p = NdpRouterMac; p < NdpRouterMac + 6; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpPrefixLength); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpPrefixValidLifetime); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpPrefixPreferredLifetime); HttpAddChar('\n');
+ for (char* p = NdpPrefix; p < NdpPrefix + 16; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpDnsLifetime); HttpAddChar('\n');
+ for (char* p = NdpDnsServer; p < NdpDnsServer + 16; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpGetLease()); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpGetElapsedLife()); HttpAddChar('\n');
+ for (char* p = SlaacLinkLocalIp; p < SlaacLinkLocalIp + 16; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
+ HttpAddInt32AsHex(NdpMtu); HttpAddChar('\n');
+ HttpAddChar('\f');
+
+ Ar6SendAjax();
+ HttpAddChar('\f');
+
+ Nr6SendAjax();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net6-html.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,37 @@
+#include "http.h"
+#include "web-nav-base.h"
+#include "web-add.h"
+
+void WebNet6Html()
+{
+ HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
+ WebAddHeader("Net IPv6", "settings.css", "net6.js");
+ WebAddNav(NET6_PAGE);
+ WebAddH1("Net IPv6");
+
+ WebAddH2("ARP");
+ HttpAddText("<code id='ajax-arp'></code>\r\n");
+ WebAddH2("DNS");
+ HttpAddText("<code id='ajax-dns'></code>\r\n");
+
+ WebAddH2("NDP");
+ WebAddAjaxLabelled("Hop limit", "ajax-hop-limit");
+ WebAddAjaxLed ("Managed address", "ajax-managed");
+ WebAddAjaxLed ("Other configuration", "ajax-other");
+ WebAddAjaxLabelled("Router MAC", "ajax-router-mac");
+ WebAddAjaxLabelled("Prefix length", "ajax-prefix-length");
+ WebAddAjaxLed ("Prefix flag L", "ajax-prefix-l");
+ WebAddAjaxLed ("Prefix flag A", "ajax-prefix-a");
+ WebAddAjaxLabelled("Prefix valid secs", "ajax-prefix-limit");
+ WebAddAjaxLabelled("Prefix preferred secs", "ajax-prefix-preferred");
+ WebAddAjaxLabelled("Prefix", "ajax-prefix");
+ WebAddAjaxLabelled("DNS life secs", "ajax-dns-life");
+ WebAddAjaxLabelled("DNS server", "ajax-dns-ip");
+ WebAddAjaxLabelled("Lease time", "ajax-ndp-lease");
+ WebAddAjaxLabelled("Elapsed", "ajax-ndp-elapsed");
+ WebAddAjaxLabelled("SLAAC", "ajax-slaac");
+ WebAddAjaxLabelled("MTU", "ajax-mtu");
+
+ WebAddEnd();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net6-script.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,18 @@
+#include "http.h"
+
+//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
+//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
+
+const char* WebNet6ScriptDate = __DATE__;
+const char* WebNet6ScriptTime = __TIME__;
+
+static const char* script =
+#include "../core/web-ajax-class.inc"
+#include "web-net-class.inc"
+#include "web-net6-script.inc"
+;
+void WebNet6Script()
+{
+ HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebNet6ScriptDate, WebNet6ScriptTime);
+ HttpAddText(script);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net6-script.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,111 @@
+"//Net6 script\n"
+"'use strict';\n"
+"\n"
+"let arp = '';\n"
+"let dns = '';\n"
+"let hopLimit = '';\n"
+"let managed = false;\n"
+"let other = false;\n"
+"let routerMac = '';\n"
+"let prefixLength = '';\n"
+"let prefixL = false;\n"
+"let prefixA = false;\n"
+"let prefixLimit = '';\n"
+"let prefixPreferred = '';\n"
+"let prefix = '';\n"
+"let dnsLife = '';\n"
+"let dnsIp = '';\n"
+"let ndpLease = '';\n"
+"let ndpElapsed = '';\n"
+"let slaac = '';\n"
+"let mtu = '';\n"
+"\n"
+"function parseArpLine(line)\n"
+"{\n"
+" if (line.length == 0) return;\n"
+" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
+" arp += Math.floor(minutes).toString().padStart(4, ' ');\n"
+" arp += ' ';\n"
+" arp += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');\n"
+" arp += ' ';\n"
+" arp += Net.makeMac(line.substr(40, 12));\n"
+" arp += '\\r\\n';\n"
+"}\n"
+"function parseDnsLine(line)\n"
+"{\n"
+" if (line.length == 0) return;\n"
+" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
+" dns += Math.floor(minutes).toString().padStart(4, ' ');\n"
+" dns += ' ';\n"
+" dns += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');\n"
+" dns += ' ';\n"
+" dns += line.substr(40, 1);\n"
+" dns += ' ';\n"
+" dns += line.substr(41);\n"
+" dns += '\\r\\n';\n"
+"}\n"
+"function parseArpLines(text)\n"
+"{\n"
+" arp = '';\n"
+" text.split('\\n').forEach(parseArpLine);\n"
+"}\n"
+"function parseDnsLines(text)\n"
+"{\n"
+" dns = '';\n"
+" text.split('\\n').forEach(parseDnsLine);\n"
+"}\n"
+"function parseGenLines(text)\n"
+"{\n"
+" let lines = text.split('\\n');\n"
+" \n"
+" hopLimit = parseInt(lines[ 1], 16);\n"
+" managed = Net.hexToBit(lines[ 0], 0);\n"
+" other = Net.hexToBit(lines[ 0], 1);\n"
+" routerMac = Net.makeMac (lines[ 2], 16);\n"
+" prefixLength = parseInt(lines[ 3], 16);\n"
+" prefixL = Net.hexToBit(lines[ 0], 2);\n"
+" prefixA = Net.hexToBit(lines[ 0], 3);\n"
+" prefixLimit = parseInt(lines[ 4], 16);\n"
+" prefixPreferred = parseInt(lines[ 5], 16);\n"
+" prefix = Net.makeIp6 (lines[ 6] );\n"
+" dnsLife = parseInt(lines[ 7], 16);\n"
+" dnsIp = Net.makeIp6 (lines[ 8] );\n"
+" ndpLease = parseInt(lines[ 9], 16);\n"
+" ndpElapsed = parseInt(lines[10], 16);\n"
+" slaac = Net.makeIp6 (lines[11] );\n"
+" mtu = parseInt(lines[12], 16);\n"
+"}\n"
+"function parse()\n"
+"{\n"
+" let topics = Ajax.response.split('\\f');\n"
+" parseGenLines(topics[0]);\n"
+" parseArpLines(topics[1]);\n"
+" parseDnsLines(topics[2]);\n"
+"}\n"
+"function display()\n"
+"{\n"
+" let elem;\n"
+" \n"
+" elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;\n"
+" elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;\n"
+" elem = Ajax.getElementOrNull('ajax-hop-limit' ); if (elem) elem.textContent = hopLimit;\n"
+" elem = Ajax.getElementOrNull('ajax-managed' ); if (elem) elem.setAttribute('dir', managed ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-other' ); if (elem) elem.setAttribute('dir', other ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-router-mac' ); if (elem) elem.textContent = routerMac;\n"
+" elem = Ajax.getElementOrNull('ajax-prefix-length' ); if (elem) elem.textContent = prefixLength;\n"
+" elem = Ajax.getElementOrNull('ajax-prefix-l' ); if (elem) elem.setAttribute('dir', prefixL ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-prefix-a' ); if (elem) elem.setAttribute('dir', prefixA ? 'rtl' : 'ltr');\n"
+" elem = Ajax.getElementOrNull('ajax-prefix-limit' ); if (elem) elem.textContent = prefixLimit;\n"
+" elem = Ajax.getElementOrNull('ajax-prefix-preferred'); if (elem) elem.textContent = prefixPreferred;\n"
+" elem = Ajax.getElementOrNull('ajax-prefix' ); if (elem) elem.textContent = prefix;\n"
+" elem = Ajax.getElementOrNull('ajax-dns-life' ); if (elem) elem.textContent = dnsLife;\n"
+" elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;\n"
+" elem = Ajax.getElementOrNull('ajax-ndp-lease' ); if (elem) elem.textContent = ndpLease;\n"
+" elem = Ajax.getElementOrNull('ajax-ndp-elapsed' ); if (elem) elem.textContent = ndpElapsed;\n"
+" elem = Ajax.getElementOrNull('ajax-slaac' ); if (elem) elem.textContent = slaac;\n"
+" elem = Ajax.getElementOrNull('ajax-mtu' ); if (elem) elem.textContent = mtu;\n"
+"}\n"
+"\n"
+"Ajax.server = '/net6-ajax';\n"
+"Ajax.onResponse = function() { parse(); display(); };\n"
+"Ajax.init();"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/net/web-net6-script.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,111 @@
+//Net6 script
+'use strict';
+
+let arp = '';
+let dns = '';
+let hopLimit = '';
+let managed = false;
+let other = false;
+let routerMac = '';
+let prefixLength = '';
+let prefixL = false;
+let prefixA = false;
+let prefixLimit = '';
+let prefixPreferred = '';
+let prefix = '';
+let dnsLife = '';
+let dnsIp = '';
+let ndpLease = '';
+let ndpElapsed = '';
+let slaac = '';
+let mtu = '';
+
+function parseArpLine(line)
+{
+ if (line.length == 0) return;
+ let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
+ arp += Math.floor(minutes).toString().padStart(4, ' ');
+ arp += ' ';
+ arp += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');
+ arp += ' ';
+ arp += Net.makeMac(line.substr(40, 12));
+ arp += '\r\n';
+}
+function parseDnsLine(line)
+{
+ if (line.length == 0) return;
+ let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
+ dns += Math.floor(minutes).toString().padStart(4, ' ');
+ dns += ' ';
+ dns += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');
+ dns += ' ';
+ dns += line.substr(40, 1);
+ dns += ' ';
+ dns += line.substr(41);
+ dns += '\r\n';
+}
+function parseArpLines(text)
+{
+ arp = '';
+ text.split('\n').forEach(parseArpLine);
+}
+function parseDnsLines(text)
+{
+ dns = '';
+ text.split('\n').forEach(parseDnsLine);
+}
+function parseGenLines(text)
+{
+ let lines = text.split('\n');
+
+ hopLimit = parseInt(lines[ 1], 16);
+ managed = Net.hexToBit(lines[ 0], 0);
+ other = Net.hexToBit(lines[ 0], 1);
+ routerMac = Net.makeMac (lines[ 2], 16);
+ prefixLength = parseInt(lines[ 3], 16);
+ prefixL = Net.hexToBit(lines[ 0], 2);
+ prefixA = Net.hexToBit(lines[ 0], 3);
+ prefixLimit = parseInt(lines[ 4], 16);
+ prefixPreferred = parseInt(lines[ 5], 16);
+ prefix = Net.makeIp6 (lines[ 6] );
+ dnsLife = parseInt(lines[ 7], 16);
+ dnsIp = Net.makeIp6 (lines[ 8] );
+ ndpLease = parseInt(lines[ 9], 16);
+ ndpElapsed = parseInt(lines[10], 16);
+ slaac = Net.makeIp6 (lines[11] );
+ mtu = parseInt(lines[12], 16);
+}
+function parse()
+{
+ let topics = Ajax.response.split('\f');
+ parseGenLines(topics[0]);
+ parseArpLines(topics[1]);
+ parseDnsLines(topics[2]);
+}
+function display()
+{
+ let elem;
+
+ elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;
+ elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;
+ elem = Ajax.getElementOrNull('ajax-hop-limit' ); if (elem) elem.textContent = hopLimit;
+ elem = Ajax.getElementOrNull('ajax-managed' ); if (elem) elem.setAttribute('dir', managed ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-other' ); if (elem) elem.setAttribute('dir', other ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-router-mac' ); if (elem) elem.textContent = routerMac;
+ elem = Ajax.getElementOrNull('ajax-prefix-length' ); if (elem) elem.textContent = prefixLength;
+ elem = Ajax.getElementOrNull('ajax-prefix-l' ); if (elem) elem.setAttribute('dir', prefixL ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-prefix-a' ); if (elem) elem.setAttribute('dir', prefixA ? 'rtl' : 'ltr');
+ elem = Ajax.getElementOrNull('ajax-prefix-limit' ); if (elem) elem.textContent = prefixLimit;
+ elem = Ajax.getElementOrNull('ajax-prefix-preferred'); if (elem) elem.textContent = prefixPreferred;
+ elem = Ajax.getElementOrNull('ajax-prefix' ); if (elem) elem.textContent = prefix;
+ elem = Ajax.getElementOrNull('ajax-dns-life' ); if (elem) elem.textContent = dnsLife;
+ elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;
+ elem = Ajax.getElementOrNull('ajax-ndp-lease' ); if (elem) elem.textContent = ndpLease;
+ elem = Ajax.getElementOrNull('ajax-ndp-elapsed' ); if (elem) elem.textContent = ndpElapsed;
+ elem = Ajax.getElementOrNull('ajax-slaac' ); if (elem) elem.textContent = slaac;
+ elem = Ajax.getElementOrNull('ajax-mtu' ); if (elem) elem.textContent = mtu;
+}
+
+Ajax.server = '/net6-ajax';
+Ajax.onResponse = function() { parse(); display(); };
+Ajax.init();
\ No newline at end of file
--- a/base/web-ajax-class.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-"//Ajax class\n"
-"'use strict';\n"
-"\n"
-"//Exposed properties\n"
-"let ajaxResponse_ = '';\n"
-"let ajaxHeaders_ = '';\n"
-"let ajaxDate_ = null;\n"
-"let ajaxMs_ = 0;\n"
-"let ajaxOnResponse_ = null;\n"
-"let ajaxOnTick_ = null;\n"
-"let ajaxServer_ = '';\n"
-"\n"
-"//Private variables\n"
-"let ajaxOverrideBlockUpdateOnFocus_ = false;\n"
-"let ajaxXhr_ = null;\n"
-"let ajaxMsCountAtAjaxSend_ = 0;\n"
-"const ajaxTickMs_ = 100;\n"
-"const ajaxUpdateMs_ = 10000;\n"
-"\n"
-"//Private utilities\n"
-"function ajaxGetElementOrNull_(elementName) //Returns the element if it: exists; block is overidden; does not have focus\n"
-"{\n"
-" let elem = document.getElementById(elementName);\n"
-" if (!elem) return null;\n"
-" if (ajaxOverrideBlockUpdateOnFocus_) return elem;\n"
-" if (elem !== document.activeElement) return elem;\n"
-" return null;\n"
-"}\n"
-"function ajaxHexToBit_(text, iBit)\n"
-"{\n"
-" let value = parseInt(text, 16);\n"
-" value >>= iBit;\n"
-" return value & 1;\n"
-"}\n"
-"function ajaxHexToSignedInt8_(text)\n"
-"{\n"
-" let value = parseInt(text, 16);\n"
-" if (value < 0x80) return value;\n"
-" return value - 0x100;\n"
-"}\n"
-"function ajaxHexToSignedInt16_(text)\n"
-"{\n"
-" let value = parseInt(text, 16);\n"
-" if (value < 0x8000) return value;\n"
-" return value - 0x10000;\n"
-"}\n"
-"function ajaxHexToSignedInt32_(text)\n"
-"{\n"
-" let value = parseInt(text, 16);\n"
-" if (value < 0x80000000) return value;\n"
-" return value - 0x100000000;\n"
-"}\n"
-"\n"
-"\n"
-"//Private ajax functions\n"
-"function ajaxHandleAjaxResponse_()\n"
-"{\n"
-" if (ajaxXhr_.readyState == 4 && ajaxXhr_.status == 200)\n"
-" {\n"
-" ajaxResponse_ = ajaxXhr_.responseText;\n"
-" ajaxHeaders_ = ajaxXhr_.getAllResponseHeaders();\n"
-" let iDateStart = Ajax.headers.toLowerCase().indexOf('date:');\n"
-" let iDateEnd = Ajax.headers.indexOf('\\r', iDateStart);\n"
-" ajaxDate_ = new Date(Ajax.headers.slice(iDateStart + 5, iDateEnd));\n"
-"\n"
-" let elem;\n"
-" elem = ajaxGetElementOrNull_('ajax-response' ); if (elem) elem.textContent = ajaxResponse_;\n"
-" elem = ajaxGetElementOrNull_('ajax-headers' ); if (elem) elem.textContent = ajaxHeaders_;\n"
-" elem = ajaxGetElementOrNull_('ajax-date-local' );\n"
-" if (elem)\n"
-" {\n"
-" elem.textContent = ajaxDate_.toLocaleString( undefined, { weekday : 'short' ,\n"
-" day : '2-digit',\n"
-" month : 'short' ,\n"
-" year : 'numeric',\n"
-" hour : '2-digit',\n"
-" minute : '2-digit',\n"
-" timeZoneName: 'short'\n"
-" }\n"
-" );\n"
-" }\n"
-" if (ajaxOnResponse_) ajaxOnResponse_();\n"
-" ajaxOverrideBlockUpdateOnFocus_ = false; //Received response so reset override after display\n"
-" }\n"
-"}\n"
-"function ajaxSendAjaxRequest_(request) //Used by this script and from HTML page\n"
-"{\n"
-" ajaxXhr_ = new XMLHttpRequest();\n"
-" ajaxXhr_.onreadystatechange = ajaxHandleAjaxResponse_;\n"
-" if (request)\n"
-" {\n"
-" request = request.split('+').join('%2B');\n"
-" ajaxXhr_.open('GET', ajaxServer_ + '?' + request, true);\n"
-" }\n"
-" else\n"
-" {\n"
-" ajaxXhr_.open('GET', ajaxServer_ , true);\n"
-" }\n"
-" ajaxXhr_.send();\n"
-" ajaxMsCountAtAjaxSend_ = ajaxMs_;\n"
-"}\n"
-"function AjaxRequest(request) //From html\n"
-"{\n"
-" ajaxOverrideBlockUpdateOnFocus_ = true; //Request has come from an update\n"
-" ajaxSendAjaxRequest_(request);\n"
-"}\n"
-"\n"
-"//Private functions\n"
-"function ajaxTick_() //Called about every 100ms\n"
-"{\n"
-" ajaxMs_ += ajaxTickMs_; //Don't use Date.now() as we don't know when the PC's clock will be updated around a leap second\n"
-" if (ajaxMs_ >= ajaxMsCountAtAjaxSend_ + ajaxUpdateMs_) ajaxSendAjaxRequest_('');\n"
-" if (ajaxOnTick_) ajaxOnTick_();\n"
-"}\n"
-"function ajaxInit_()\n"
-"{\n"
-" setInterval(ajaxTick_, ajaxTickMs_);\n"
-" ajaxSendAjaxRequest_('');\n"
-"}\n"
-"\n"
-"//Exposed public\n"
-"class Ajax\n"
-"{\n"
-" static get ms () { return ajaxMs_ ; }\n"
-" static get response () { return ajaxResponse_ ; }\n"
-" static get headers () { return ajaxHeaders_ ; }\n"
-" static get date () { return ajaxDate_ ; }\n"
-" \n"
-" static set tickMs (v) { ajaxTickMs_ = v; }\n"
-" static set updateMs (v) { ajaxUpdateMs_ = v; }\n"
-" static set server (v) { ajaxServer_ = v; }\n"
-" static set onResponse(v) { ajaxOnResponse_ = v; }\n"
-" static set onTick (v) { ajaxOnTick_ = v; }\n"
-"\n"
-" static getElementOrNull(elementName) { return ajaxGetElementOrNull_(elementName) ; }\n"
-" static hexToBit (text, iBit ) { return ajaxHexToBit_ (text, iBit ) ; }\n"
-" static hexToSignedInt8 (text ) { return ajaxHexToSignedInt8_ (text ) ; }\n"
-" static hexToSignedInt16(text ) { return ajaxHexToSignedInt16_(text ) ; }\n"
-" static hexToSignedInt32(text ) { return ajaxHexToSignedInt32_(text ) ; }\n"
-" \n"
-" static init()\n"
-" {\n"
-" if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', ajaxInit_ ); // Loading hasn't finished yet\n"
-" else ajaxInit_(); //`DOMContentLoaded` has already fired\n"
-" }\n"
-"}"
\ No newline at end of file
--- a/base/web-ajax-class.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-//Ajax class
-'use strict';
-
-//Exposed properties
-let ajaxResponse_ = '';
-let ajaxHeaders_ = '';
-let ajaxDate_ = null;
-let ajaxMs_ = 0;
-let ajaxOnResponse_ = null;
-let ajaxOnTick_ = null;
-let ajaxServer_ = '';
-
-//Private variables
-let ajaxOverrideBlockUpdateOnFocus_ = false;
-let ajaxXhr_ = null;
-let ajaxMsCountAtAjaxSend_ = 0;
-const ajaxTickMs_ = 100;
-const ajaxUpdateMs_ = 10000;
-
-//Private utilities
-function ajaxGetElementOrNull_(elementName) //Returns the element if it: exists; block is overidden; does not have focus
-{
- let elem = document.getElementById(elementName);
- if (!elem) return null;
- if (ajaxOverrideBlockUpdateOnFocus_) return elem;
- if (elem !== document.activeElement) return elem;
- return null;
-}
-function ajaxHexToBit_(text, iBit)
-{
- let value = parseInt(text, 16);
- value >>= iBit;
- return value & 1;
-}
-function ajaxHexToSignedInt8_(text)
-{
- let value = parseInt(text, 16);
- if (value < 0x80) return value;
- return value - 0x100;
-}
-function ajaxHexToSignedInt16_(text)
-{
- let value = parseInt(text, 16);
- if (value < 0x8000) return value;
- return value - 0x10000;
-}
-function ajaxHexToSignedInt32_(text)
-{
- let value = parseInt(text, 16);
- if (value < 0x80000000) return value;
- return value - 0x100000000;
-}
-
-
-//Private ajax functions
-function ajaxHandleAjaxResponse_()
-{
- if (ajaxXhr_.readyState == 4 && ajaxXhr_.status == 200)
- {
- ajaxResponse_ = ajaxXhr_.responseText;
- ajaxHeaders_ = ajaxXhr_.getAllResponseHeaders();
- let iDateStart = Ajax.headers.toLowerCase().indexOf('date:');
- let iDateEnd = Ajax.headers.indexOf('\r', iDateStart);
- ajaxDate_ = new Date(Ajax.headers.slice(iDateStart + 5, iDateEnd));
-
- let elem;
- elem = ajaxGetElementOrNull_('ajax-response' ); if (elem) elem.textContent = ajaxResponse_;
- elem = ajaxGetElementOrNull_('ajax-headers' ); if (elem) elem.textContent = ajaxHeaders_;
- elem = ajaxGetElementOrNull_('ajax-date-local' );
- if (elem)
- {
- elem.textContent = ajaxDate_.toLocaleString( undefined, { weekday : 'short' ,
- day : '2-digit',
- month : 'short' ,
- year : 'numeric',
- hour : '2-digit',
- minute : '2-digit',
- timeZoneName: 'short'
- }
- );
- }
- if (ajaxOnResponse_) ajaxOnResponse_();
- ajaxOverrideBlockUpdateOnFocus_ = false; //Received response so reset override after display
- }
-}
-function ajaxSendAjaxRequest_(request) //Used by this script and from HTML page
-{
- ajaxXhr_ = new XMLHttpRequest();
- ajaxXhr_.onreadystatechange = ajaxHandleAjaxResponse_;
- if (request)
- {
- request = request.split('+').join('%2B');
- ajaxXhr_.open('GET', ajaxServer_ + '?' + request, true);
- }
- else
- {
- ajaxXhr_.open('GET', ajaxServer_ , true);
- }
- ajaxXhr_.send();
- ajaxMsCountAtAjaxSend_ = ajaxMs_;
-}
-function AjaxRequest(request) //From html
-{
- ajaxOverrideBlockUpdateOnFocus_ = true; //Request has come from an update
- ajaxSendAjaxRequest_(request);
-}
-
-//Private functions
-function ajaxTick_() //Called about every 100ms
-{
- ajaxMs_ += ajaxTickMs_; //Don't use Date.now() as we don't know when the PC's clock will be updated around a leap second
- if (ajaxMs_ >= ajaxMsCountAtAjaxSend_ + ajaxUpdateMs_) ajaxSendAjaxRequest_('');
- if (ajaxOnTick_) ajaxOnTick_();
-}
-function ajaxInit_()
-{
- setInterval(ajaxTick_, ajaxTickMs_);
- ajaxSendAjaxRequest_('');
-}
-
-//Exposed public
-class Ajax
-{
- static get ms () { return ajaxMs_ ; }
- static get response () { return ajaxResponse_ ; }
- static get headers () { return ajaxHeaders_ ; }
- static get date () { return ajaxDate_ ; }
-
- static set tickMs (v) { ajaxTickMs_ = v; }
- static set updateMs (v) { ajaxUpdateMs_ = v; }
- static set server (v) { ajaxServer_ = v; }
- static set onResponse(v) { ajaxOnResponse_ = v; }
- static set onTick (v) { ajaxOnTick_ = v; }
-
- static getElementOrNull(elementName) { return ajaxGetElementOrNull_(elementName) ; }
- static hexToBit (text, iBit ) { return ajaxHexToBit_ (text, iBit ) ; }
- static hexToSignedInt8 (text ) { return ajaxHexToSignedInt8_ (text ) ; }
- static hexToSignedInt16(text ) { return ajaxHexToSignedInt16_(text ) ; }
- static hexToSignedInt32(text ) { return ajaxHexToSignedInt32_(text ) ; }
-
- static init()
- {
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', ajaxInit_ ); // Loading hasn't finished yet
- else ajaxInit_(); //`DOMContentLoaded` has already fired
- }
-}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/web-nav-base.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,14 @@
+#include "web-add.h"
+#include "web-nav-base.h"
+
+void WebNavBase(int page)
+{
+ WebAddNavItem(page == CLOCK_PAGE, "/clock", "Clock" );
+ WebAddNavItem(page == FAULT_PAGE, "/fault", "Fault" );
+ WebAddNavItem(page == NET_PAGE, "/net", "Net" );
+ WebAddNavItem(page == NET4_PAGE, "/net4", "Net IPv4" );
+ WebAddNavItem(page == NET6_PAGE, "/net6", "Net IPv6" );
+ WebAddNavItem(page == TRACE_PAGE, "/trace", "Net Trace");
+ WebAddNavItem(page == LOG_PAGE, "/log", "Log" );
+ WebAddNavItem(page == FIRMWARE_PAGE, "/firmware", "Firmware" );
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/web-nav-base.h Tue Apr 30 12:45:08 2019 +0000 @@ -0,0 +1,10 @@ +extern void WebNavBase(int page); + +#define FAULT_PAGE 0 +#define CLOCK_PAGE 1 +#define NET_PAGE 2 +#define NET4_PAGE 3 +#define NET6_PAGE 4 +#define TRACE_PAGE 5 +#define LOG_PAGE 6 +#define FIRMWARE_PAGE 7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/web-pages-base.h Tue Apr 30 12:45:08 2019 +0000 @@ -0,0 +1,69 @@ +#include <stdint.h> +#include <stdbool.h> + +extern void WebLoginHtml (void); +extern void WebLoginQuery (char* pQuery); +extern bool WebLoginQueryPasswordOk; +extern int WebLoginOriginalToDo; +extern bool WebLoginCookiesContainValidSessionId(char* pCookies); +extern char* WebLoginSessionNameGet(void); +extern int WebLoginSessionNameLife(void); +extern char* WebLoginSessionIdGet(void); +extern void WebLoginSessionIdNew(void); +extern bool WebLoginSessionIdIsSet(void); +extern void WebLoginInit(void); + +extern void WebFavicon (void); +extern const char* WebFaviconDate; +extern const char* WebFaviconTime; +extern const int WebFaviconSize; + +extern void WebBaseCss (void); +extern const char* WebBaseCssDate; +extern const char* WebBaseCssTime; +extern void WebNavCss (void); +extern const char* WebNavCssDate; +extern const char* WebNavCssTime; + +extern void WebClockHtml (void); +extern void WebClockScript (void); +extern const char* WebClockScriptDate; +extern const char* WebClockScriptTime; +extern void WebClockAjax (void); +extern void WebClockQuery (char* pQuery); + +extern void WebLogHtml (void); +extern void WebLogQuery (char* pQuery); + +extern void WebTraceHtml (void); +extern void WebTraceScript (void); +extern const char* WebTraceScriptDate; +extern const char* WebTraceScriptTime; +extern void WebTraceAjax (void); +extern void WebTraceQuery (char* pQuery); + +extern void WebNetHtml (void); +extern void WebNet4Html (void); +extern void WebNet4Script (void); +extern const char* WebNet4ScriptDate; +extern const char* WebNet4ScriptTime; +extern void WebNet4Ajax (void); +extern void WebNet6Html (void); +extern void WebNet6Script (void); +extern const char* WebNet6ScriptDate; +extern const char* WebNet6ScriptTime; +extern void WebNet6Ajax (void); + +extern void WebFaultHtml (void); +extern void WebFaultQuery (char* pQuery); + +extern void WebFirmwareHtml (void); +extern void WebFirmwareScript(void); +extern const char* WebFirmwareScriptDate; +extern const char* WebFirmwareScriptTime; +extern void WebFirmwareQuery (char* pQuery); +extern int WebFirmwareTargetLength; +extern int WebFirmwareActualLength; +extern char* WebFirmwareFileName; +extern void WebFirmwarePost (int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream, bool* pComplete); +extern void WebFirmwareAjax (void);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/base/web-server-base.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,104 @@
+#include "http.h"
+#include "web.h"
+#include "web-pages-base.h"
+
+#define DO_FAVICON DO_BASE + 1
+#define DO_BASE_CSS DO_BASE + 2
+#define DO_NAV_CSS DO_BASE + 3
+#define DO_CLOCK_HTML DO_BASE + 4
+#define DO_CLOCK_AJAX DO_BASE + 5
+#define DO_CLOCK_SCRIPT DO_BASE + 6
+#define DO_NET_HTML DO_BASE + 7
+#define DO_NET4_HTML DO_BASE + 8
+#define DO_NET4_AJAX DO_BASE + 9
+#define DO_NET4_SCRIPT DO_BASE + 10
+#define DO_NET6_HTML DO_BASE + 11
+#define DO_NET6_AJAX DO_BASE + 12
+#define DO_NET6_SCRIPT DO_BASE + 13
+#define DO_TRACE_HTML DO_BASE + 14
+#define DO_TRACE_AJAX DO_BASE + 15
+#define DO_TRACE_SCRIPT DO_BASE + 16
+#define DO_LOG_HTML DO_BASE + 17
+#define DO_FAULT_HTML DO_BASE + 18
+#define DO_FIRMWARE_HTML DO_BASE + 19
+#define DO_FIRMWARE_AJAX DO_BASE + 20
+#define DO_FIRMWARE_SCRIPT DO_BASE + 21
+
+int WebServerBaseDecideWhatToDo(char *pPath, char* pLastModified)
+{
+ if (HttpSameStr(pPath, "/clock" )) return DO_CLOCK_HTML;
+ if (HttpSameStr(pPath, "/clock-ajax" )) return DO_CLOCK_AJAX;
+ if (HttpSameStr(pPath, "/net" )) return DO_NET_HTML;
+ if (HttpSameStr(pPath, "/net4" )) return DO_NET4_HTML;
+ if (HttpSameStr(pPath, "/net4-ajax" )) return DO_NET4_AJAX;
+ if (HttpSameStr(pPath, "/net6" )) return DO_NET6_HTML;
+ if (HttpSameStr(pPath, "/net6-ajax" )) return DO_NET6_AJAX;
+ if (HttpSameStr(pPath, "/log" )) return DO_LOG_HTML;
+ if (HttpSameStr(pPath, "/trace" )) return DO_TRACE_HTML;
+ if (HttpSameStr(pPath, "/trace-ajax" )) return DO_TRACE_AJAX;
+ if (HttpSameStr(pPath, "/fault" )) return DO_FAULT_HTML;
+ if (HttpSameStr(pPath, "/firmware" )) return DO_FIRMWARE_HTML;
+ if (HttpSameStr(pPath, "/firmware-ajax")) return DO_FIRMWARE_AJAX;
+
+ if (HttpSameStr(pPath, "/favicon.ico" )) return HttpSameDate(WebFaviconDate, WebFaviconTime, pLastModified) ? DO_NOT_MODIFIED : DO_FAVICON;
+ if (HttpSameStr(pPath, "/base.css" )) return HttpSameDate(WebBaseCssDate, WebBaseCssTime, pLastModified) ? DO_NOT_MODIFIED : DO_BASE_CSS;
+ if (HttpSameStr(pPath, "/settings.css" )) return HttpSameDate(WebNavCssDate, WebNavCssTime, pLastModified) ? DO_NOT_MODIFIED : DO_NAV_CSS;
+ if (HttpSameStr(pPath, "/net4.js" )) return HttpSameDate(WebNet4ScriptDate, WebNet4ScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_NET4_SCRIPT;
+ if (HttpSameStr(pPath, "/net6.js" )) return HttpSameDate(WebNet6ScriptDate, WebNet6ScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_NET6_SCRIPT;
+ if (HttpSameStr(pPath, "/trace.js" )) return HttpSameDate(WebTraceScriptDate, WebTraceScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_TRACE_SCRIPT;
+ if (HttpSameStr(pPath, "/clock.js" )) return HttpSameDate(WebClockScriptDate, WebClockScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_CLOCK_SCRIPT;
+ if (HttpSameStr(pPath, "/firmware.js" )) return HttpSameDate(WebFirmwareScriptDate, WebFirmwareScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_FIRMWARE_SCRIPT;
+
+ return DO_NOT_FOUND;
+}
+
+bool WebServerBaseHandleQuery(int todo, char* pQuery)
+{
+ switch (todo)
+ {
+ case DO_TRACE_AJAX: WebTraceQuery (pQuery); return true;
+ case DO_CLOCK_AJAX: WebClockQuery (pQuery); return true;
+ case DO_CLOCK_HTML: WebClockQuery (pQuery); return true;
+ case DO_LOG_HTML: WebLogQuery (pQuery); return true;
+ case DO_FAULT_HTML: WebFaultQuery (pQuery); return true;
+ case DO_FIRMWARE_HTML: WebFirmwareQuery(pQuery); return true;
+ case DO_FIRMWARE_AJAX: WebFirmwareQuery(pQuery); return true;
+ }
+ return false;
+}
+bool WebServerBasePost(int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream, bool* pComplete)
+{
+ switch (todo)
+ {
+ case DO_FIRMWARE_AJAX: WebFirmwarePost(contentLength, contentStart, size, pRequestStream, positionInRequestStream, pComplete); return true;
+ }
+ return false;
+}
+bool WebServerBaseReply(int todo)
+{
+ switch (todo)
+ {
+ case DO_FAVICON: WebFavicon (); return true;
+ case DO_BASE_CSS: WebBaseCss (); return true;
+ case DO_NAV_CSS: WebNavCss (); return true;
+ case DO_TRACE_HTML: WebTraceHtml (); return true;
+ case DO_TRACE_AJAX: WebTraceAjax (); return true;
+ case DO_TRACE_SCRIPT: WebTraceScript (); return true;
+ case DO_CLOCK_HTML: WebClockHtml (); return true;
+ case DO_CLOCK_AJAX: WebClockAjax (); return true;
+ case DO_CLOCK_SCRIPT: WebClockScript (); return true;
+ case DO_NET_HTML: WebNetHtml (); return true;
+ case DO_NET4_HTML: WebNet4Html (); return true;
+ case DO_NET4_AJAX: WebNet4Ajax (); return true;
+ case DO_NET4_SCRIPT: WebNet4Script (); return true;
+ case DO_NET6_HTML: WebNet6Html (); return true;
+ case DO_NET6_AJAX: WebNet6Ajax (); return true;
+ case DO_NET6_SCRIPT: WebNet6Script (); return true;
+ case DO_LOG_HTML: WebLogHtml (); return true;
+ case DO_FAULT_HTML: WebFaultHtml (); return true;
+ case DO_FIRMWARE_HTML: WebFirmwareHtml (); return true;
+ case DO_FIRMWARE_AJAX: WebFirmwareAjax (); return true;
+ case DO_FIRMWARE_SCRIPT: WebFirmwareScript(); return true;
+ }
+ return false;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/web-server-base.h Tue Apr 30 12:45:08 2019 +0000 @@ -0,0 +1,7 @@ +#include <stdint.h> +#include <stdbool.h> + +extern int WebServerBaseDecideWhatToDo(char *pPath, char* pLastModified); +extern bool WebServerBaseHandleQuery (int todo, char* pQuery); +extern bool WebServerBasePost (int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream, bool* pComplete); +extern bool WebServerBaseReply (int todo);
--- a/clock/web-clock-ajax.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-
-#include "http.h"
-#include "rtc.h"
-#include "clk.h"
-#include "clktime.h"
-#include "clkgov.h"
-#include "clkutc.h"
-#include "ntpclient.h"
-#include "scan.h"
-
-void WebClockAjax()
-{
- HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
-
- //Time and UTC
- clktime now = ClkNowTai();
- clktime fraction = now & ((1UL << CLK_TIME_ONE_SECOND_SHIFT) - 1);
- clktime ms = (fraction * 1000) >> CLK_TIME_ONE_SECOND_SHIFT;
- HttpAddInt16AsHex(ms ); HttpAddChar('\n');
- char byte = 0;
- if (RtcIsSet() ) byte |= 0x01;
- if (ClkTimeIsSet() ) byte |= 0x02;
- if (ClkGovIsReceivingTime ) byte |= 0x04;
- if (ClkGovRateIsSynced ) byte |= 0x08;
- if (ClkGovTimeIsSynced ) byte |= 0x10;
- if (ClkUtcGetNextLeapEnable() ) byte |= 0x20;
- if (ClkUtcGetNextLeapForward()) byte |= 0x40;
- if (ClkGovTrace) byte |= 0x80;
- HttpAddByteAsHex (byte ); HttpAddChar('\n');
- HttpAddInt12AsHex(ClkUtcGetNextEpochMonth1970()); HttpAddChar('\n');
- HttpAddInt16AsHex(ClkUtcGetEpochOffset() ); HttpAddChar('\n');
- HttpAddChar('\f');
-
- //Governer
- HttpAddInt32AsHex(ClkGovGetPpb() ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovFreqDivisor ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovFreqChangeMaxPpb ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovFreqSyncedLimPpb ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovFreqSyncedHysPpb ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovSlewDivisor ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovSlewChangeMaxMs ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovSlewSyncedLimNs ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovSlewSyncedHysNs ); HttpAddChar('\n');
- HttpAddInt32AsHex(ClkGovSlewOffsetMaxSecs ); HttpAddChar('\n');
- HttpAddChar('\f');
-
- //NTP
- HttpAddText (NtpClientQueryServerName ); HttpAddChar('\n');
- HttpAddInt32AsHex(NtpClientQueryInitialInterval); HttpAddChar('\n');
- HttpAddInt32AsHex(NtpClientQueryNormalInterval ); HttpAddChar('\n');
- HttpAddInt32AsHex(NtpClientQueryRetryInterval ); HttpAddChar('\n');
- HttpAddInt32AsHex(NtpClientReplyOffsetMs ); HttpAddChar('\n');
- HttpAddInt32AsHex(NtpClientReplyMaxDelayMs ); HttpAddChar('\n');
- HttpAddChar('\f');
-
- //Scan
- HttpAddInt32AsHex(ScanAverage ); HttpAddChar('\n');
- HttpAddInt32AsHex(ScanMaximum ); HttpAddChar('\n');
- HttpAddInt32AsHex(ScanMinimum ); HttpAddChar('\n');
- HttpAddChar('\f');
-}
-
--- a/clock/web-clock-class.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-"//Clock class\n"
-"'use strict';\n"
-"\n"
-"class Clock\n"
-"{\n"
-" constructor()\n"
-" {\n"
-" this.leapEnable = false;\n"
-" this.leapForward = false;\n"
-" this.leapMonth = 0;\n"
-" this.leapYear = 0;\n"
-" this.leaps = 0;\n"
-" this.ms = 0;\n"
-" }\n"
-" \n"
-" set months1970(value)\n"
-" {\n"
-" this.leapMonth = value % 12;\n"
-" this.leapYear = (value - this.leapMonth) / 12;\n"
-" this.leapMonth += 1;\n"
-" this.leapYear += 1970;\n"
-" }\n"
-" get months1970()\n"
-" {\n"
-" if (this.leapYear <= 0) return 0;\n"
-" if (this.leapMonth <= 0) return 0;\n"
-" return (this.leapYear - 1970) * 12 + this.leapMonth - 1;\n"
-" }\n"
-" \n"
-" formatNumbers00(i)\n"
-" {\n"
-" if (i < 10) return '0' + i;\n"
-" return i;\n"
-" }\n"
-" formatDayOfWeek(wday)\n"
-" {\n"
-" switch(wday)\n"
-" {\n"
-" case 0: return 'Sun';\n"
-" case 1: return 'Mon';\n"
-" case 2: return 'Tue';\n"
-" case 3: return 'Wed';\n"
-" case 4: return 'Thu';\n"
-" case 5: return 'Fri';\n"
-" case 6: return 'Sat';\n"
-" default: return '---';\n"
-" }\n"
-" }\n"
-" adjustLeap(baseMs)\n"
-" {\n"
-" if (this.ms == 0) return; //Don't attempt to adjust an invalid time\n"
-" \n"
-" if (!this.leapEnable) return; // Adjustment disabled\n"
-" \n"
-" //Get the calander date and time from the ms\n"
-" let now = this.ms + baseMs;\n"
-" let leapStart = Date.UTC(this.leapYear, this.leapMonth - 1, 1, 0, 0, this.leapForward ? 0: -1);\n"
-" \n"
-" if (now < leapStart) return; //Do nothing until reached the leap start\n"
-" \n"
-" if (this.leapForward) { this.ms -= 1000; this.leaps += 1; } //repeat 59\n"
-" else { this.ms += 1000; this.leaps -= 1; } //skip 59\n"
-" \n"
-" this.leapEnable = false;\n"
-" }\n"
-" displayTime(baseMs)\n"
-" {\n"
-" if (this.ms == 0) return; //Don't attempt to display an invalid time\n"
-" \n"
-" //Get the calander date and time from the ms\n"
-" let now = new Date(this.ms + baseMs);\n"
-" let y = now.getUTCFullYear();\n"
-" let n = now.getUTCMonth () + 1;\n"
-" let d = now.getUTCDate ();\n"
-" let w = now.getUTCDay (); // 0 == Sunday\n"
-" let h = now.getUTCHours ();\n"
-" let m = now.getUTCMinutes ();\n"
-" let s = now.getUTCSeconds ();\n"
-" \n"
-" //Format time\n"
-" n = this.formatNumbers00(n);\n"
-" d = this.formatNumbers00(d);\n"
-" h = this.formatNumbers00(h);\n"
-" m = this.formatNumbers00(m);\n"
-" s = this.formatNumbers00(s);\n"
-" w = this.formatDayOfWeek(w);\n"
-" \n"
-" //Display time\n"
-" let elem;\n"
-" elem = document.getElementById('ajax-date-utc');\n"
-" if (elem) elem.textContent = y + '-' + n + '-' + d + ' ' + w + ' ' + h + ':' + m + ':' + s + ' TAI-UTC=' + this.leaps;\n"
-" \n"
-" elem = document.getElementById('ajax-date-pc');\n"
-" let options = \n"
-" {\n"
-" year: 'numeric',\n"
-" month: 'short',\n"
-" day: '2-digit',\n"
-" weekday: 'short',\n"
-" hour: '2-digit',\n"
-" minute: '2-digit',\n"
-" second: '2-digit',\n"
-" timeZoneName: 'short'\n"
-" };\n"
-" if (elem) elem.textContent = now.toLocaleString(undefined, options);\n"
-" }\n"
-"}\n"
-""
\ No newline at end of file
--- a/clock/web-clock-class.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-//Clock class
-'use strict';
-
-class Clock
-{
- constructor()
- {
- this.leapEnable = false;
- this.leapForward = false;
- this.leapMonth = 0;
- this.leapYear = 0;
- this.leaps = 0;
- this.ms = 0;
- }
-
- set months1970(value)
- {
- this.leapMonth = value % 12;
- this.leapYear = (value - this.leapMonth) / 12;
- this.leapMonth += 1;
- this.leapYear += 1970;
- }
- get months1970()
- {
- if (this.leapYear <= 0) return 0;
- if (this.leapMonth <= 0) return 0;
- return (this.leapYear - 1970) * 12 + this.leapMonth - 1;
- }
-
- formatNumbers00(i)
- {
- if (i < 10) return '0' + i;
- return i;
- }
- formatDayOfWeek(wday)
- {
- switch(wday)
- {
- case 0: return 'Sun';
- case 1: return 'Mon';
- case 2: return 'Tue';
- case 3: return 'Wed';
- case 4: return 'Thu';
- case 5: return 'Fri';
- case 6: return 'Sat';
- default: return '---';
- }
- }
- adjustLeap(baseMs)
- {
- if (this.ms == 0) return; //Don't attempt to adjust an invalid time
-
- if (!this.leapEnable) return; // Adjustment disabled
-
- //Get the calander date and time from the ms
- let now = this.ms + baseMs;
- let leapStart = Date.UTC(this.leapYear, this.leapMonth - 1, 1, 0, 0, this.leapForward ? 0: -1);
-
- if (now < leapStart) return; //Do nothing until reached the leap start
-
- if (this.leapForward) { this.ms -= 1000; this.leaps += 1; } //repeat 59
- else { this.ms += 1000; this.leaps -= 1; } //skip 59
-
- this.leapEnable = false;
- }
- displayTime(baseMs)
- {
- if (this.ms == 0) return; //Don't attempt to display an invalid time
-
- //Get the calander date and time from the ms
- let now = new Date(this.ms + baseMs);
- let y = now.getUTCFullYear();
- let n = now.getUTCMonth () + 1;
- let d = now.getUTCDate ();
- let w = now.getUTCDay (); // 0 == Sunday
- let h = now.getUTCHours ();
- let m = now.getUTCMinutes ();
- let s = now.getUTCSeconds ();
-
- //Format time
- n = this.formatNumbers00(n);
- d = this.formatNumbers00(d);
- h = this.formatNumbers00(h);
- m = this.formatNumbers00(m);
- s = this.formatNumbers00(s);
- w = this.formatDayOfWeek(w);
-
- //Display time
- let elem;
- elem = document.getElementById('ajax-date-utc');
- if (elem) elem.textContent = y + '-' + n + '-' + d + ' ' + w + ' ' + h + ':' + m + ':' + s + ' TAI-UTC=' + this.leaps;
-
- elem = document.getElementById('ajax-date-pc');
- let options =
- {
- year: 'numeric',
- month: 'short',
- day: '2-digit',
- weekday: 'short',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- timeZoneName: 'short'
- };
- if (elem) elem.textContent = now.toLocaleString(undefined, options);
- }
-}
--- a/clock/web-clock-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-#include <time.h>
-
-#include "http.h"
-#include "web-page-base.h"
-#include "web-add.h"
-
-void WebClockHtml()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Clock", "settings.css", "clock.js");
- WebAddNav(CLOCK_PAGE);
- WebAddH1("Clock");
-
- WebAddH2("Status");
- WebAddAjaxLed("RTC is set" , "ajax-rtc-set" );
- WebAddAjaxLed("Clock is set" , "ajax-clock-set" );
- WebAddAjaxLed("External source is ok", "ajax-source-ok" );
- WebAddAjaxLed("Time synchronised" , "ajax-time-locked");
- WebAddAjaxLed("Rate synchronised" , "ajax-rate-locked");
-
- WebAddH2("Server UTC time");
- HttpAddText("<div id='ajax-date-utc'></div>\r\n");
-
- WebAddH2("Server local time");
- HttpAddText("<div id='ajax-date-pc'></div>\r\n");
-
- WebAddH2("Server - PC (ms)");
- HttpAddText("<div id='ajax-date-diff'></div>\r\n");
-
- WebAddH2("UTC");
- WebAddAjaxInputToggle("Enable epoch change" , "ajax-leap-enable" , "chg-clock-leap-enable" );
- WebAddAjaxInputToggle("Direction of next epoch" , "ajax-leap-forward" , "chg-clock-leap-forward");
- WebAddAjaxInput ("Year next epoch starts" , 4, "ajax-leap-year" , "set-clock-leap-year" );
- WebAddAjaxInput ("Month next epoch starts" , 4, "ajax-leap-month" , "set-clock-leap-month" );
- WebAddAjaxInput ("Current era offset" , 4, "ajax-leap-count" , "set-clock-leap-count" );
-
- HttpAddText("<div><button type='button' onclick='displayLeap()'>Display leap</button></div>\r\n");
-
- HttpAddText("<div>The leap seconds list is available <a href='https://www.ietf.org/timezones/data/leap-seconds.list' target='_blank'>here</a></div>\r\n");
-
- WebAddH2("Governer");
- WebAddAjaxInput ("Ppb" , 5, "ajax-ppb" , "ppb" );
- WebAddAjaxInput ("Ppb divisor" , 5, "ajax-ppb-divisor" , "ppbdivisor" );
- WebAddAjaxInput ("Ppb max change" , 5, "ajax-ppb-max-chg" , "ppbmaxchange" );
- WebAddAjaxInput ("Ppb synced limit" , 5, "ajax-ppb-syn-lim" , "syncedlimitppb");
- WebAddAjaxInput ("Ppb synced hysteresis" , 5, "ajax-ppb-syn-hys" , "syncedhysppb" );
- WebAddAjaxInput ("Offset divisor" , 5, "ajax-off-divisor" , "slewdivisor" );
- WebAddAjaxInput ("Offset max (ms)" , 5, "ajax-off-max" , "slewmax" );
- WebAddAjaxInput ("Offset synced limit (ms)", 5, "ajax-off-syn-lim" , "syncedlimitns" );
- WebAddAjaxInput ("Offset synced hys (ms)" , 5, "ajax-off-syn-hys" , "syncedhysns" );
- WebAddAjaxInput ("Offset reset limit (s)" , 5, "ajax-off-rst-lim" , "maxoffsetsecs" );
- WebAddAjaxInputToggle("Trace" , "ajax-gov-trace" , "clockgovtrace" );
-
- WebAddH2("NTP");
- WebAddAjaxInput ("Server url" , 5, "ajax-ntp-server" , "ntpserver" );
- WebAddAjaxInput ("Initial interval (s)" , 5, "ajax-ntp-initial" , "clockinitial" );
- WebAddAjaxInput ("Normal interval (m)" , 5, "ajax-ntp-normal" , "clocknormal" );
- WebAddAjaxInput ("Retry interval (s)" , 5, "ajax-ntp-retry" , "clockretry" );
- WebAddAjaxInput ("Offset (ms)" , 5, "ajax-ntp-offset" , "clockoffset" );
- WebAddAjaxInput ("Max delay (ms)" , 5, "ajax-ntp-max-delay", "clockmaxdelay" );
-
- WebAddH2("Scan times");
- WebAddAjaxLabelled ("Program cycles avg", "ajax-scan-avg");
- WebAddAjaxLabelled ("Program cycles max", "ajax-scan-max");
- WebAddAjaxLabelled ("Program cycles min", "ajax-scan-min");
-
- WebAddEnd();
-}
--- a/clock/web-clock-script.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include "http.h"
-
-//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
-//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
-
-const char* WebClockScriptDate = __DATE__;
-const char* WebClockScriptTime = __TIME__;
-
-static const char* script =
-#include "web-clock-class.inc"
-#include "../base/web-ajax-class.inc"
-#include "web-clock-script.inc"
-;
-void WebClockScript()
-{
- HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebClockScriptDate, WebClockScriptTime);
- HttpAddText(script);
-}
--- a/clock/web-clock-script.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-"//Clock script\n"
-"'use strict';\n"
-"\n"
-"let pseudo = new Clock();\n"
-"let rtc = new Clock();\n"
-"\n"
-"let pseudoDisplay = false;\n"
-"let pseudoStartMs = 0;\n"
-"\n"
-"let diffMs = 0;\n"
-"let rtcIsSet = false;\n"
-"let clockIsSet = false;\n"
-"let sourceIsOk = false;\n"
-"let rateIsLocked = false;\n"
-"let timeIsLocked = false;\n"
-"\n"
-"let ppb = 0;\n"
-"let ppbdivisor = 0;\n"
-"let ppbmaxchange = 0;\n"
-"let syncedlimitppb = 0;\n"
-"let syncedhysppb = 0;\n"
-"let slewdivisor = 0;\n"
-"let slewmax = 0;\n"
-"let syncedlimitns = 0;\n"
-"let syncedhysns = 0;\n"
-"let maxoffsetsecs = 0;\n"
-"let govTrace = false;\n"
-"\n"
-"let ntpserver = '';\n"
-"let ntpinitial = 0;\n"
-"let ntpnormal = 0;\n"
-"let ntpretry = 0;\n"
-"let ntpoffset = 0;\n"
-"let ntpmaxdelay = 0;\n"
-"\n"
-"let scanavg = 0;\n"
-"let scanmax = 0;\n"
-"let scanmin = 0;\n"
-"\n"
-"const DISPLAY_LEAP_MS = 10000;\n"
-"\n"
-"function parseLinesTime(text)\n"
-"{\n"
-" let lines = text.split('\\n');\n"
-" rtc.ms = Ajax.date.getTime();\n"
-" rtc.ms += parseInt(lines[0], 16);\n"
-" rtc.ms -= Ajax.ms;\n"
-" diffMs = rtc.ms + Ajax.ms - Date.now();\n"
-" rtcIsSet = Ajax.hexToBit(lines[1], 0);\n"
-" clockIsSet = Ajax.hexToBit(lines[1], 1);\n"
-" sourceIsOk = Ajax.hexToBit(lines[1], 2);\n"
-" rateIsLocked = Ajax.hexToBit(lines[1], 3);\n"
-" timeIsLocked = Ajax.hexToBit(lines[1], 4);\n"
-" rtc.leapEnable = Ajax.hexToBit(lines[1], 5);\n"
-" rtc.leapForward = Ajax.hexToBit(lines[1], 6);\n"
-" govTrace = Ajax.hexToBit(lines[1], 7);\n"
-" rtc.months1970 = parseInt(lines[2], 16);\n"
-" rtc.leaps = parseInt(lines[3], 16);\n"
-"}\n"
-"function parseLinesGov(text)\n"
-"{\n"
-" let lines = text.split('\\n');\n"
-" ppb = parseInt(lines[0], 16);\n"
-" ppbdivisor = parseInt(lines[1], 16);\n"
-" ppbmaxchange = parseInt(lines[2], 16);\n"
-" syncedlimitppb = parseInt(lines[3], 16);\n"
-" syncedhysppb = parseInt(lines[4], 16);\n"
-" slewdivisor = parseInt(lines[5], 16);\n"
-" slewmax = parseInt(lines[6], 16);\n"
-" syncedlimitns = parseInt(lines[7], 16);\n"
-" syncedhysns = parseInt(lines[8], 16);\n"
-" maxoffsetsecs = parseInt(lines[9], 16);\n"
-"}\n"
-"function parseLinesNtp(text)\n"
-"{\n"
-" let lines = text.split('\\n');\n"
-" ntpserver = lines[0];\n"
-" ntpinitial = parseInt(lines[1], 16);\n"
-" ntpnormal = parseInt(lines[2], 16);\n"
-" ntpretry = parseInt(lines[3], 16);\n"
-" ntpoffset = parseInt(lines[4], 16);\n"
-" ntpmaxdelay = parseInt(lines[5], 16);\n"
-"}\n"
-"function parseLinesScan(text)\n"
-"{\n"
-" let lines = text.split('\\n');\n"
-" scanavg = parseInt(lines[0], 16);\n"
-" scanmax = parseInt(lines[1], 16);\n"
-" scanmin = parseInt(lines[2], 16);\n"
-"}\n"
-"function parse()\n"
-"{\n"
-" let topics = Ajax.response.split('\\f');\n"
-" parseLinesTime(topics[0]);\n"
-" parseLinesGov (topics[1]);\n"
-" parseLinesNtp (topics[2]);\n"
-" parseLinesScan(topics[3]);\n"
-"}\n"
-"function display()\n"
-"{\n"
-" let elem;\n"
-" elem = Ajax.getElementOrNull('ajax-rtc-set' ); if (elem) elem.setAttribute('dir', rtcIsSet ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-clock-set' ); if (elem) elem.setAttribute('dir', clockIsSet ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-source-ok' ); if (elem) elem.setAttribute('dir', sourceIsOk ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-rate-locked' ); if (elem) elem.setAttribute('dir', rateIsLocked ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-time-locked' ); if (elem) elem.setAttribute('dir', timeIsLocked ? 'rtl' : 'ltr');\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-leap-enable' ); if (elem) elem.setAttribute('dir', rtc.leapEnable ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-leap-forward' ); if (elem) elem.setAttribute('dir', rtc.leapForward ? 'rtl' : 'ltr');\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-leap-year' ); if (elem) elem.value = rtc.months1970 ? rtc.leapYear : '';\n"
-" elem = Ajax.getElementOrNull('ajax-leap-month' ); if (elem) elem.value = rtc.months1970 ? rtc.leapMonth : '';\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-leap-count' ); if (elem) elem.value = rtc.leaps;\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-ppb' ); if (elem) elem.value = ppb;\n"
-" elem = Ajax.getElementOrNull('ajax-ppb-divisor' ); if (elem) elem.value = ppbdivisor;\n"
-" elem = Ajax.getElementOrNull('ajax-ppb-max-chg' ); if (elem) elem.value = ppbmaxchange;\n"
-" elem = Ajax.getElementOrNull('ajax-ppb-syn-lim' ); if (elem) elem.value = syncedlimitppb;\n"
-" elem = Ajax.getElementOrNull('ajax-ppb-syn-hys' ); if (elem) elem.value = syncedhysppb;\n"
-" elem = Ajax.getElementOrNull('ajax-off-divisor' ); if (elem) elem.value = slewdivisor;\n"
-" elem = Ajax.getElementOrNull('ajax-off-max' ); if (elem) elem.value = slewmax;\n"
-" elem = Ajax.getElementOrNull('ajax-off-syn-lim' ); if (elem) elem.value = syncedlimitns / 1000000;\n"
-" elem = Ajax.getElementOrNull('ajax-off-syn-hys' ); if (elem) elem.value = syncedhysns / 1000000;\n"
-" elem = Ajax.getElementOrNull('ajax-off-rst-lim' ); if (elem) elem.value = maxoffsetsecs;\n"
-" elem = Ajax.getElementOrNull('ajax-gov-trace' ); if (elem) elem.setAttribute('dir', govTrace ? 'rtl' : 'ltr');\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-ntp-server' ); if (elem) elem.value = ntpserver;\n"
-" elem = Ajax.getElementOrNull('ajax-ntp-initial' ); if (elem) elem.value = ntpinitial;\n"
-" elem = Ajax.getElementOrNull('ajax-ntp-normal' ); if (elem) elem.value = ntpnormal / 60;\n"
-" elem = Ajax.getElementOrNull('ajax-ntp-retry' ); if (elem) elem.value = ntpretry;\n"
-" elem = Ajax.getElementOrNull('ajax-ntp-offset' ); if (elem) elem.value = ntpoffset;\n"
-" elem = Ajax.getElementOrNull('ajax-ntp-max-delay'); if (elem) elem.value = ntpmaxdelay;\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-scan-avg' ); if (elem) elem.textContent = scanavg;\n"
-" elem = Ajax.getElementOrNull('ajax-scan-max' ); if (elem) elem.textContent = scanmax;\n"
-" elem = Ajax.getElementOrNull('ajax-scan-min' ); if (elem) elem.textContent = scanmin;\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-date-diff' ); if (elem) elem.textContent = diffMs;\n"
-"}\n"
-"\n"
-"function handleTick() //This typically called every 100ms\n"
-"{\n"
-" if (pseudoDisplay)\n"
-" {\n"
-" pseudo.adjustLeap (Ajax.ms);\n"
-" pseudo.displayTime(Ajax.ms);\n"
-" if (Ajax.ms >= pseudoStartMs + DISPLAY_LEAP_MS + 500) pseudoDisplay = false;\n"
-" }\n"
-" else\n"
-" {\n"
-" rtc.adjustLeap (Ajax.ms);\n"
-" rtc.displayTime(Ajax.ms);\n"
-" }\n"
-"}\n"
-"\n"
-"function displayLeap() //Called by display leap button in HTML\n"
-"{\n"
-" pseudoDisplay = true;\n"
-" pseudoStartMs = Ajax.ms;\n"
-" \n"
-" pseudo.leapEnable = true;\n"
-" pseudo.leapForward = rtc.leapForward;\n"
-" pseudo.leaps = rtc.leaps;\n"
-" pseudo.leapMonth = rtc.leapMonth;\n"
-" pseudo.leapYear = rtc.leapYear;\n"
-" pseudo.ms = Date.UTC(rtc.leapYear, rtc.leapMonth - 1, 1) - DISPLAY_LEAP_MS / 2 - Ajax.ms;\n"
-"}\n"
-"Ajax.server = '/clock-ajax';\n"
-"Ajax.onResponse = function() { parse(); display(); };\n"
-"Ajax.onTick = handleTick;\n"
-"Ajax.init();"
\ No newline at end of file
--- a/clock/web-clock-script.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-//Clock script
-'use strict';
-
-let pseudo = new Clock();
-let rtc = new Clock();
-
-let pseudoDisplay = false;
-let pseudoStartMs = 0;
-
-let diffMs = 0;
-let rtcIsSet = false;
-let clockIsSet = false;
-let sourceIsOk = false;
-let rateIsLocked = false;
-let timeIsLocked = false;
-
-let ppb = 0;
-let ppbdivisor = 0;
-let ppbmaxchange = 0;
-let syncedlimitppb = 0;
-let syncedhysppb = 0;
-let slewdivisor = 0;
-let slewmax = 0;
-let syncedlimitns = 0;
-let syncedhysns = 0;
-let maxoffsetsecs = 0;
-let govTrace = false;
-
-let ntpserver = '';
-let ntpinitial = 0;
-let ntpnormal = 0;
-let ntpretry = 0;
-let ntpoffset = 0;
-let ntpmaxdelay = 0;
-
-let scanavg = 0;
-let scanmax = 0;
-let scanmin = 0;
-
-const DISPLAY_LEAP_MS = 10000;
-
-function parseLinesTime(text)
-{
- let lines = text.split('\n');
- rtc.ms = Ajax.date.getTime();
- rtc.ms += parseInt(lines[0], 16);
- rtc.ms -= Ajax.ms;
- diffMs = rtc.ms + Ajax.ms - Date.now();
- rtcIsSet = Ajax.hexToBit(lines[1], 0);
- clockIsSet = Ajax.hexToBit(lines[1], 1);
- sourceIsOk = Ajax.hexToBit(lines[1], 2);
- rateIsLocked = Ajax.hexToBit(lines[1], 3);
- timeIsLocked = Ajax.hexToBit(lines[1], 4);
- rtc.leapEnable = Ajax.hexToBit(lines[1], 5);
- rtc.leapForward = Ajax.hexToBit(lines[1], 6);
- govTrace = Ajax.hexToBit(lines[1], 7);
- rtc.months1970 = parseInt(lines[2], 16);
- rtc.leaps = parseInt(lines[3], 16);
-}
-function parseLinesGov(text)
-{
- let lines = text.split('\n');
- ppb = parseInt(lines[0], 16);
- ppbdivisor = parseInt(lines[1], 16);
- ppbmaxchange = parseInt(lines[2], 16);
- syncedlimitppb = parseInt(lines[3], 16);
- syncedhysppb = parseInt(lines[4], 16);
- slewdivisor = parseInt(lines[5], 16);
- slewmax = parseInt(lines[6], 16);
- syncedlimitns = parseInt(lines[7], 16);
- syncedhysns = parseInt(lines[8], 16);
- maxoffsetsecs = parseInt(lines[9], 16);
-}
-function parseLinesNtp(text)
-{
- let lines = text.split('\n');
- ntpserver = lines[0];
- ntpinitial = parseInt(lines[1], 16);
- ntpnormal = parseInt(lines[2], 16);
- ntpretry = parseInt(lines[3], 16);
- ntpoffset = parseInt(lines[4], 16);
- ntpmaxdelay = parseInt(lines[5], 16);
-}
-function parseLinesScan(text)
-{
- let lines = text.split('\n');
- scanavg = parseInt(lines[0], 16);
- scanmax = parseInt(lines[1], 16);
- scanmin = parseInt(lines[2], 16);
-}
-function parse()
-{
- let topics = Ajax.response.split('\f');
- parseLinesTime(topics[0]);
- parseLinesGov (topics[1]);
- parseLinesNtp (topics[2]);
- parseLinesScan(topics[3]);
-}
-function display()
-{
- let elem;
- elem = Ajax.getElementOrNull('ajax-rtc-set' ); if (elem) elem.setAttribute('dir', rtcIsSet ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-clock-set' ); if (elem) elem.setAttribute('dir', clockIsSet ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-source-ok' ); if (elem) elem.setAttribute('dir', sourceIsOk ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-rate-locked' ); if (elem) elem.setAttribute('dir', rateIsLocked ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-time-locked' ); if (elem) elem.setAttribute('dir', timeIsLocked ? 'rtl' : 'ltr');
-
- elem = Ajax.getElementOrNull('ajax-leap-enable' ); if (elem) elem.setAttribute('dir', rtc.leapEnable ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-leap-forward' ); if (elem) elem.setAttribute('dir', rtc.leapForward ? 'rtl' : 'ltr');
-
- elem = Ajax.getElementOrNull('ajax-leap-year' ); if (elem) elem.value = rtc.months1970 ? rtc.leapYear : '';
- elem = Ajax.getElementOrNull('ajax-leap-month' ); if (elem) elem.value = rtc.months1970 ? rtc.leapMonth : '';
-
- elem = Ajax.getElementOrNull('ajax-leap-count' ); if (elem) elem.value = rtc.leaps;
-
- elem = Ajax.getElementOrNull('ajax-ppb' ); if (elem) elem.value = ppb;
- elem = Ajax.getElementOrNull('ajax-ppb-divisor' ); if (elem) elem.value = ppbdivisor;
- elem = Ajax.getElementOrNull('ajax-ppb-max-chg' ); if (elem) elem.value = ppbmaxchange;
- elem = Ajax.getElementOrNull('ajax-ppb-syn-lim' ); if (elem) elem.value = syncedlimitppb;
- elem = Ajax.getElementOrNull('ajax-ppb-syn-hys' ); if (elem) elem.value = syncedhysppb;
- elem = Ajax.getElementOrNull('ajax-off-divisor' ); if (elem) elem.value = slewdivisor;
- elem = Ajax.getElementOrNull('ajax-off-max' ); if (elem) elem.value = slewmax;
- elem = Ajax.getElementOrNull('ajax-off-syn-lim' ); if (elem) elem.value = syncedlimitns / 1000000;
- elem = Ajax.getElementOrNull('ajax-off-syn-hys' ); if (elem) elem.value = syncedhysns / 1000000;
- elem = Ajax.getElementOrNull('ajax-off-rst-lim' ); if (elem) elem.value = maxoffsetsecs;
- elem = Ajax.getElementOrNull('ajax-gov-trace' ); if (elem) elem.setAttribute('dir', govTrace ? 'rtl' : 'ltr');
-
- elem = Ajax.getElementOrNull('ajax-ntp-server' ); if (elem) elem.value = ntpserver;
- elem = Ajax.getElementOrNull('ajax-ntp-initial' ); if (elem) elem.value = ntpinitial;
- elem = Ajax.getElementOrNull('ajax-ntp-normal' ); if (elem) elem.value = ntpnormal / 60;
- elem = Ajax.getElementOrNull('ajax-ntp-retry' ); if (elem) elem.value = ntpretry;
- elem = Ajax.getElementOrNull('ajax-ntp-offset' ); if (elem) elem.value = ntpoffset;
- elem = Ajax.getElementOrNull('ajax-ntp-max-delay'); if (elem) elem.value = ntpmaxdelay;
-
- elem = Ajax.getElementOrNull('ajax-scan-avg' ); if (elem) elem.textContent = scanavg;
- elem = Ajax.getElementOrNull('ajax-scan-max' ); if (elem) elem.textContent = scanmax;
- elem = Ajax.getElementOrNull('ajax-scan-min' ); if (elem) elem.textContent = scanmin;
-
- elem = Ajax.getElementOrNull('ajax-date-diff' ); if (elem) elem.textContent = diffMs;
-}
-
-function handleTick() //This typically called every 100ms
-{
- if (pseudoDisplay)
- {
- pseudo.adjustLeap (Ajax.ms);
- pseudo.displayTime(Ajax.ms);
- if (Ajax.ms >= pseudoStartMs + DISPLAY_LEAP_MS + 500) pseudoDisplay = false;
- }
- else
- {
- rtc.adjustLeap (Ajax.ms);
- rtc.displayTime(Ajax.ms);
- }
-}
-
-function displayLeap() //Called by display leap button in HTML
-{
- pseudoDisplay = true;
- pseudoStartMs = Ajax.ms;
-
- pseudo.leapEnable = true;
- pseudo.leapForward = rtc.leapForward;
- pseudo.leaps = rtc.leaps;
- pseudo.leapMonth = rtc.leapMonth;
- pseudo.leapYear = rtc.leapYear;
- pseudo.ms = Date.UTC(rtc.leapYear, rtc.leapMonth - 1, 1) - DISPLAY_LEAP_MS / 2 - Ajax.ms;
-}
-Ajax.server = '/clock-ajax';
-Ajax.onResponse = function() { parse(); display(); };
-Ajax.onTick = handleTick;
-Ajax.init();
\ No newline at end of file
--- a/clock/web-web-query.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#include "http.h"
-#include "clkgov.h"
-#include "clkutc.h"
-#include "led.h"
-#include "settings.h"
-
-void WebClockQuery(char* pQuery)
-{
- while (pQuery)
- {
- char* pName;
- char* pValue;
- pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
- int value = HttpQueryValueAsInt(pValue);
-
- if (HttpSameStr(pName, "chg-clock-leap-enable" )) ClkUtcTglNextLeapEnable ();
- if (HttpSameStr(pName, "chg-clock-leap-forward")) ClkUtcTglNextLeapForward();
-
- int months1970 = ClkUtcGetNextEpochMonth1970();
- int months = months1970 % 12;
- int years = months1970 / 12;
-
- if (HttpSameStr(pName, "set-clock-leap-year" ))
- {
- years = value - 1970;
- if (years < 0) years = 0;
- ClkUtcSetNextEpochMonth1970(years * 12 + months);
- }
- if (HttpSameStr(pName, "set-clock-leap-month" ))
- {
- months = value - 1;
- if (months < 0) months = 0;
- ClkUtcSetNextEpochMonth1970(years * 12 + months);
- }
- if (HttpSameStr(pName, "set-clock-leap-count" ))
- {
- uint16_t leaps = value;
- ClkUtcSetEpochOffset(leaps);
- }
-
- if (HttpSameStr(pName, "ppb" )) ClkGovSetPpb (value );
- if (HttpSameStr(pName, "slewdivisor" )) SetClockSlewDivisor (value );
- if (HttpSameStr(pName, "slewmax" )) SetClockSlewMaxMs (value );
- if (HttpSameStr(pName, "ppbdivisor" )) SetClockPpbDivisor (value );
- if (HttpSameStr(pName, "ppbmaxchange" )) SetClockPpbChangeMax (value );
- if (HttpSameStr(pName, "syncedlimitns" )) SetClockSyncedLimitNs (value * 1000000 );
- if (HttpSameStr(pName, "syncedhysns" )) SetClockSyncedHysterisNs (value * 1000000 );
- if (HttpSameStr(pName, "syncedlimitppb")) SetClockSyncedLimitPpb (value );
- if (HttpSameStr(pName, "syncedhysppb" )) SetClockSyncedHysterisPpb (value );
- if (HttpSameStr(pName, "maxoffsetsecs" )) SetClockMaxOffsetSecs (value );
- if (HttpSameStr(pName, "clockgovtrace" )) ChgTraceSync();
-
- if (HttpSameStr(pName, "ntpserver" )) SetNtpClientServerName (pValue );
- if (HttpSameStr(pName, "clockinitial" )) SetNtpClientInitialInterval(value );
- if (HttpSameStr(pName, "clocknormal" )) SetNtpClientNormalInterval (value * 60 );
- if (HttpSameStr(pName, "clockretry" )) SetNtpClientRetryInterval (value );
- if (HttpSameStr(pName, "clockoffset" )) SetNtpClientOffsetMs (value );
- if (HttpSameStr(pName, "clockmaxdelay" )) SetNtpClientMaxDelayMs (value );
-
- }
-}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core/web-add.c Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,215 @@
+#include <stdio.h>
+
+#include "http.h"
+#include "web-nav-base.h"
+#include "web-nav-derived.h"
+#include "web-site-name.h"
+#include "mac.h"
+#include "ip4addr.h"
+#include "ip6addr.h"
+
+void WebAddNavItem(int highlight, char* href, char* title)
+{
+ char *p;
+ HttpAddText("<li ");
+ if (highlight) p = "class='this'";
+ else p = " ";
+ HttpAddText(p);
+ HttpAddText("><a href='");
+ HttpAddText(href);
+ HttpAddText("'>");
+ HttpAddText(title);
+ HttpAddText("</a></li>\r\n");
+}
+void WebAddNav(int page)
+{
+ HttpAddText("<a class='tab-shortcut' href='#main-content'>Skip to content</a>\r\n");
+
+ HttpAddText("<nav><ul>\r\n");
+ WebNavDerived(page);
+ WebNavBase(page);
+ HttpAddText("</ul></nav>\r\n");
+}
+
+void WebAddHeader(const char* title, const char* style, const char* script)
+{
+ HttpAddText("<!DOCTYPE html>\r\n"
+ "<html>\r\n"
+ "<head>\r\n");
+ HttpAddText(" <title>");
+ HttpAddText(WEB_SITE_NAME);
+ if (title)
+ {
+ HttpAddText(" - ");
+ HttpAddText(title);
+ }
+ HttpAddText("</title>\r\n");
+
+ HttpAddText(" <link rel='stylesheet' href='/base.css' type='text/css'/>\r\n");
+ if (style)
+ {
+ HttpAddText(" <link rel='stylesheet' href='/");
+ HttpAddText(style);
+ HttpAddText("' type='text/css'/>\r\n");
+ }
+ if (script)
+ {
+ HttpAddText(" <script src='/");
+ HttpAddText(script);
+ HttpAddText("' type='text/javascript'></script>\r\n");
+ }
+ HttpAddText(" <meta name='viewport' content='width=device-width, initial-scale=1'>\r\n"
+ " <link rel='icon' href='/favicon.ico' type='image/x-icon'/>\r\n"
+ "</head>\r\n"
+ "<body>\r\n");
+
+}
+void WebAddH1(const char* pageName)
+{
+ HttpAddText("<h1 id='main-content'>");
+ HttpAddText(WEB_SITE_NAME);
+ HttpAddText(" - ");
+ HttpAddText(pageName);
+ HttpAddText("</h1>\r\n");
+}
+void WebAddH2(const char* text)
+{
+ HttpAddText("<h2>");
+ HttpAddText(text);
+ HttpAddText("</h2>\r\n");
+}
+void WebAddEnd()
+{
+ HttpAddText("</body>\r\n"
+ "</html>\r\n");
+}
+
+void WebAddLabelledPrefixSuffix(char* label, char* prefix, char* text, char* suffix)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <div>%s%s%s</div>\r\n", prefix, text, suffix);
+ HttpAddText("</div>\r\n");
+}
+void WebAddLabelledText(char* label, char* text)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <div>%s</div>\r\n", text);
+ HttpAddText("</div>\r\n");
+}
+
+void WebAddLabelledMac(char* label, char* mac)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddText(" <div>"); MacHttp(mac); HttpAddText("</div>\r\n");
+ HttpAddText("</div>\r\n");
+}
+
+void WebAddLabelledIp4(char* label, uint32_t ip)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddText(" <div>"); Ip4AddressHttp(ip); HttpAddText("</div>\r\n");
+ HttpAddText("</div>\r\n");
+}
+
+void WebAddLabelledIp6(char* label, char* ip)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddText(" <div>"); Ip6AddressHttp(ip); HttpAddText("</div>\r\n");
+ HttpAddText("</div>\r\n");
+}
+void WebAddLabelledOnOff(char* label, bool value)
+{
+ if (value) WebAddLabelledText(label, "On");
+ else WebAddLabelledText(label, "Off");
+}
+void WebAddLabelledInt(char* label, int value)
+{
+ char text[30];
+ snprintf(text, sizeof(text), "%8d", value); //Right align with enough spaces so that the length is always constant.
+ WebAddLabelledText(label, text);
+}
+void WebAddInputText(char* label, float inputwidth, char* value, char* action, char* name)
+{
+ HttpAddF ("<form action='%s' method='get'>\r\n", action);
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <input type='text' name='%s' style='width:%.1fem;' value='%s'>\r\n", name, inputwidth, value);
+ HttpAddText("</div>\r\n");
+ HttpAddText("<input type='submit' value='Set' style='display:none;'>\r\n");
+ HttpAddF ("</form>\r\n");
+
+}
+void WebAddInputInt(char* label, float inputwidth, int value, char* action, char* name)
+{
+ char text[30];
+ snprintf(text, sizeof(text), "%d", value);
+ WebAddInputText(label, inputwidth, text, action, name);
+}
+void WebAddInputButton(char* label, char* value, char* action, char* name)
+{
+ HttpAddF ("<form action='%s' method='get'>\r\n", action);
+ HttpAddF ("<input type='hidden' name='%s'>\r\n", name);
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <input type='submit' value='%s'>\r\n", value);
+ HttpAddText("</div>\r\n");
+ HttpAddText("</form>\r\n");
+}
+void WebAddAjaxInputToggle(char* label, char* id, char* name)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <div class='toggle' id='%s' tabindex='0' dir='ltr' onclick='AjaxRequest(\"%s=1\")' onkeydown='return event.keyCode != 13 || AjaxRequest(\"%s=1\")'>\r\n", id, name, name);
+ HttpAddText(" <div class='slot'></div><div class='knob'></div>\r\n");
+ HttpAddText(" </div>\r\n");
+ HttpAddText("</div>\r\n");
+}
+void WebAddAjaxLed(char* label, char* id)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <div class='led' id='%s' dir='ltr'></div>\r\n", id);
+ HttpAddText("</div>\r\n");
+}
+void WebAddAjaxInput(char* label, float inputwidth, char* id, char* name)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>\r\n", inputwidth, id, name);
+ HttpAddText("</div>\r\n");
+}
+void WebAddAjaxInputSuffix(char* label, float inputwidth, char* id, char* name, char* suffix)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>%s\r\n", inputwidth, id, name, suffix);
+ HttpAddText("</div>\r\n");
+}
+void WebAddAjaxLabelled(char* label, char* id)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <div id='%s'></div>\r\n", id);
+ HttpAddText("</div>\r\n");
+}
+void WebAddAjaxLabelledSuffix(char* label, char* id, char* suffix)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div>%s</div>\r\n", label);
+ HttpAddF (" <div><span id='%s'></span>%s</div>\r\n", id, suffix);
+ HttpAddText("</div>\r\n");
+}
+void WebAddAjaxInputLabelId(char* labelId, float inputwidth, char* id, char* name)
+{
+ HttpAddText("<div class='line'>\r\n");
+ HttpAddF (" <div id='%s'></div>\r\n", labelId);
+ HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>\r\n", inputwidth, id, name);
+ HttpAddText("</div>\r\n");
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/web-add.h Tue Apr 30 12:45:08 2019 +0000 @@ -0,0 +1,29 @@ +#include <stdint.h> +#include <stdbool.h> + +extern void WebAddNavItem (int highlight, char* href, char* title); +extern void WebAddNav (int page); +extern void WebAddHeader (const char* title, const char* style, const char* script); +extern void WebAddH1 (const char* pageName); +extern void WebAddH2 (const char* text); +extern void WebAddEnd (void); + +extern void WebAddLabelledText (char* label, char* text); +extern void WebAddLabelledPrefixSuffix(char* label, char* prefix, char* text, char* suffix); +extern void WebAddLabelledMac (char* label, char* mac); +extern void WebAddLabelledIp4 (char* label, uint32_t ip); +extern void WebAddLabelledIp6 (char* label, char* ip); +extern void WebAddLabelledOnOff (char* label, bool value); +extern void WebAddLabelledInt (char* label, int value); + +extern void WebAddInputText (char* label, float inputwidth, char* value, char* action, char* name); +extern void WebAddInputInt (char* label, float inputwidth, int value, char* action, char* name); +extern void WebAddInputButton (char* label, char* value, char* action, char* name); + +extern void WebAddAjaxLed (char* label, char* id); +extern void WebAddAjaxLabelled (char* label, char* id); +extern void WebAddAjaxLabelledSuffix (char* label, char* id, char* suffix); +extern void WebAddAjaxInputToggle (char* label, char* id, char* name); +extern void WebAddAjaxInput (char* label, float inputwidth, char* id, char* name); +extern void WebAddAjaxInputSuffix (char* label, float inputwidth, char* id, char* name, char* suffix); +extern void WebAddAjaxInputLabelId (char* labelId, float inputwidth, char* id, char* name);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core/web-ajax-class.inc Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,146 @@
+"//Ajax class\n"
+"'use strict';\n"
+"\n"
+"//Exposed properties\n"
+"let ajaxResponse_ = '';\n"
+"let ajaxHeaders_ = '';\n"
+"let ajaxDate_ = null;\n"
+"let ajaxMs_ = 0;\n"
+"let ajaxOnResponse_ = null;\n"
+"let ajaxOnTick_ = null;\n"
+"let ajaxServer_ = '';\n"
+"\n"
+"//Private variables\n"
+"let ajaxOverrideBlockUpdateOnFocus_ = false;\n"
+"let ajaxXhr_ = null;\n"
+"let ajaxMsCountAtAjaxSend_ = 0;\n"
+"const ajaxTickMs_ = 100;\n"
+"const ajaxUpdateMs_ = 10000;\n"
+"\n"
+"//Private utilities\n"
+"function ajaxGetElementOrNull_(elementName) //Returns the element if it: exists; block is overidden; does not have focus\n"
+"{\n"
+" let elem = document.getElementById(elementName);\n"
+" if (!elem) return null;\n"
+" if (ajaxOverrideBlockUpdateOnFocus_) return elem;\n"
+" if (elem !== document.activeElement) return elem;\n"
+" return null;\n"
+"}\n"
+"function ajaxHexToBit_(text, iBit)\n"
+"{\n"
+" let value = parseInt(text, 16);\n"
+" value >>= iBit;\n"
+" return value & 1;\n"
+"}\n"
+"function ajaxHexToSignedInt8_(text)\n"
+"{\n"
+" let value = parseInt(text, 16);\n"
+" if (value < 0x80) return value;\n"
+" return value - 0x100;\n"
+"}\n"
+"function ajaxHexToSignedInt16_(text)\n"
+"{\n"
+" let value = parseInt(text, 16);\n"
+" if (value < 0x8000) return value;\n"
+" return value - 0x10000;\n"
+"}\n"
+"function ajaxHexToSignedInt32_(text)\n"
+"{\n"
+" let value = parseInt(text, 16);\n"
+" if (value < 0x80000000) return value;\n"
+" return value - 0x100000000;\n"
+"}\n"
+"\n"
+"\n"
+"//Private ajax functions\n"
+"function ajaxHandleAjaxResponse_()\n"
+"{\n"
+" if (ajaxXhr_.readyState == 4 && ajaxXhr_.status == 200)\n"
+" {\n"
+" ajaxResponse_ = ajaxXhr_.responseText;\n"
+" ajaxHeaders_ = ajaxXhr_.getAllResponseHeaders();\n"
+" let iDateStart = Ajax.headers.toLowerCase().indexOf('date:');\n"
+" let iDateEnd = Ajax.headers.indexOf('\\r', iDateStart);\n"
+" ajaxDate_ = new Date(Ajax.headers.slice(iDateStart + 5, iDateEnd));\n"
+"\n"
+" let elem;\n"
+" elem = ajaxGetElementOrNull_('ajax-response' ); if (elem) elem.textContent = ajaxResponse_;\n"
+" elem = ajaxGetElementOrNull_('ajax-headers' ); if (elem) elem.textContent = ajaxHeaders_;\n"
+" elem = ajaxGetElementOrNull_('ajax-date-local' );\n"
+" if (elem)\n"
+" {\n"
+" elem.textContent = ajaxDate_.toLocaleString( undefined, { weekday : 'short' ,\n"
+" day : '2-digit',\n"
+" month : 'short' ,\n"
+" year : 'numeric',\n"
+" hour : '2-digit',\n"
+" minute : '2-digit',\n"
+" timeZoneName: 'short'\n"
+" }\n"
+" );\n"
+" }\n"
+" if (ajaxOnResponse_) ajaxOnResponse_();\n"
+" ajaxOverrideBlockUpdateOnFocus_ = false; //Received response so reset override after display\n"
+" }\n"
+"}\n"
+"function ajaxSendAjaxRequest_(request) //Used by this script and from HTML page\n"
+"{\n"
+" ajaxXhr_ = new XMLHttpRequest();\n"
+" ajaxXhr_.onreadystatechange = ajaxHandleAjaxResponse_;\n"
+" if (request)\n"
+" {\n"
+" request = request.split('+').join('%2B');\n"
+" ajaxXhr_.open('GET', ajaxServer_ + '?' + request, true);\n"
+" }\n"
+" else\n"
+" {\n"
+" ajaxXhr_.open('GET', ajaxServer_ , true);\n"
+" }\n"
+" ajaxXhr_.send();\n"
+" ajaxMsCountAtAjaxSend_ = ajaxMs_;\n"
+"}\n"
+"function AjaxRequest(request) //From html\n"
+"{\n"
+" ajaxOverrideBlockUpdateOnFocus_ = true; //Request has come from an update\n"
+" ajaxSendAjaxRequest_(request);\n"
+"}\n"
+"\n"
+"//Private functions\n"
+"function ajaxTick_() //Called about every 100ms\n"
+"{\n"
+" ajaxMs_ += ajaxTickMs_; //Don't use Date.now() as we don't know when the PC's clock will be updated around a leap second\n"
+" if (ajaxMs_ >= ajaxMsCountAtAjaxSend_ + ajaxUpdateMs_) ajaxSendAjaxRequest_('');\n"
+" if (ajaxOnTick_) ajaxOnTick_();\n"
+"}\n"
+"function ajaxInit_()\n"
+"{\n"
+" setInterval(ajaxTick_, ajaxTickMs_);\n"
+" ajaxSendAjaxRequest_('');\n"
+"}\n"
+"\n"
+"//Exposed public\n"
+"class Ajax\n"
+"{\n"
+" static get ms () { return ajaxMs_ ; }\n"
+" static get response () { return ajaxResponse_ ; }\n"
+" static get headers () { return ajaxHeaders_ ; }\n"
+" static get date () { return ajaxDate_ ; }\n"
+" \n"
+" static set tickMs (v) { ajaxTickMs_ = v; }\n"
+" static set updateMs (v) { ajaxUpdateMs_ = v; }\n"
+" static set server (v) { ajaxServer_ = v; }\n"
+" static set onResponse(v) { ajaxOnResponse_ = v; }\n"
+" static set onTick (v) { ajaxOnTick_ = v; }\n"
+"\n"
+" static getElementOrNull(elementName) { return ajaxGetElementOrNull_(elementName) ; }\n"
+" static hexToBit (text, iBit ) { return ajaxHexToBit_ (text, iBit ) ; }\n"
+" static hexToSignedInt8 (text ) { return ajaxHexToSignedInt8_ (text ) ; }\n"
+" static hexToSignedInt16(text ) { return ajaxHexToSignedInt16_(text ) ; }\n"
+" static hexToSignedInt32(text ) { return ajaxHexToSignedInt32_(text ) ; }\n"
+" \n"
+" static init()\n"
+" {\n"
+" if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', ajaxInit_ ); // Loading hasn't finished yet\n"
+" else ajaxInit_(); //`DOMContentLoaded` has already fired\n"
+" }\n"
+"}"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core/web-ajax-class.js Tue Apr 30 12:45:08 2019 +0000
@@ -0,0 +1,146 @@
+//Ajax class
+'use strict';
+
+//Exposed properties
+let ajaxResponse_ = '';
+let ajaxHeaders_ = '';
+let ajaxDate_ = null;
+let ajaxMs_ = 0;
+let ajaxOnResponse_ = null;
+let ajaxOnTick_ = null;
+let ajaxServer_ = '';
+
+//Private variables
+let ajaxOverrideBlockUpdateOnFocus_ = false;
+let ajaxXhr_ = null;
+let ajaxMsCountAtAjaxSend_ = 0;
+const ajaxTickMs_ = 100;
+const ajaxUpdateMs_ = 10000;
+
+//Private utilities
+function ajaxGetElementOrNull_(elementName) //Returns the element if it: exists; block is overidden; does not have focus
+{
+ let elem = document.getElementById(elementName);
+ if (!elem) return null;
+ if (ajaxOverrideBlockUpdateOnFocus_) return elem;
+ if (elem !== document.activeElement) return elem;
+ return null;
+}
+function ajaxHexToBit_(text, iBit)
+{
+ let value = parseInt(text, 16);
+ value >>= iBit;
+ return value & 1;
+}
+function ajaxHexToSignedInt8_(text)
+{
+ let value = parseInt(text, 16);
+ if (value < 0x80) return value;
+ return value - 0x100;
+}
+function ajaxHexToSignedInt16_(text)
+{
+ let value = parseInt(text, 16);
+ if (value < 0x8000) return value;
+ return value - 0x10000;
+}
+function ajaxHexToSignedInt32_(text)
+{
+ let value = parseInt(text, 16);
+ if (value < 0x80000000) return value;
+ return value - 0x100000000;
+}
+
+
+//Private ajax functions
+function ajaxHandleAjaxResponse_()
+{
+ if (ajaxXhr_.readyState == 4 && ajaxXhr_.status == 200)
+ {
+ ajaxResponse_ = ajaxXhr_.responseText;
+ ajaxHeaders_ = ajaxXhr_.getAllResponseHeaders();
+ let iDateStart = Ajax.headers.toLowerCase().indexOf('date:');
+ let iDateEnd = Ajax.headers.indexOf('\r', iDateStart);
+ ajaxDate_ = new Date(Ajax.headers.slice(iDateStart + 5, iDateEnd));
+
+ let elem;
+ elem = ajaxGetElementOrNull_('ajax-response' ); if (elem) elem.textContent = ajaxResponse_;
+ elem = ajaxGetElementOrNull_('ajax-headers' ); if (elem) elem.textContent = ajaxHeaders_;
+ elem = ajaxGetElementOrNull_('ajax-date-local' );
+ if (elem)
+ {
+ elem.textContent = ajaxDate_.toLocaleString( undefined, { weekday : 'short' ,
+ day : '2-digit',
+ month : 'short' ,
+ year : 'numeric',
+ hour : '2-digit',
+ minute : '2-digit',
+ timeZoneName: 'short'
+ }
+ );
+ }
+ if (ajaxOnResponse_) ajaxOnResponse_();
+ ajaxOverrideBlockUpdateOnFocus_ = false; //Received response so reset override after display
+ }
+}
+function ajaxSendAjaxRequest_(request) //Used by this script and from HTML page
+{
+ ajaxXhr_ = new XMLHttpRequest();
+ ajaxXhr_.onreadystatechange = ajaxHandleAjaxResponse_;
+ if (request)
+ {
+ request = request.split('+').join('%2B');
+ ajaxXhr_.open('GET', ajaxServer_ + '?' + request, true);
+ }
+ else
+ {
+ ajaxXhr_.open('GET', ajaxServer_ , true);
+ }
+ ajaxXhr_.send();
+ ajaxMsCountAtAjaxSend_ = ajaxMs_;
+}
+function AjaxRequest(request) //From html
+{
+ ajaxOverrideBlockUpdateOnFocus_ = true; //Request has come from an update
+ ajaxSendAjaxRequest_(request);
+}
+
+//Private functions
+function ajaxTick_() //Called about every 100ms
+{
+ ajaxMs_ += ajaxTickMs_; //Don't use Date.now() as we don't know when the PC's clock will be updated around a leap second
+ if (ajaxMs_ >= ajaxMsCountAtAjaxSend_ + ajaxUpdateMs_) ajaxSendAjaxRequest_('');
+ if (ajaxOnTick_) ajaxOnTick_();
+}
+function ajaxInit_()
+{
+ setInterval(ajaxTick_, ajaxTickMs_);
+ ajaxSendAjaxRequest_('');
+}
+
+//Exposed public
+class Ajax
+{
+ static get ms () { return ajaxMs_ ; }
+ static get response () { return ajaxResponse_ ; }
+ static get headers () { return ajaxHeaders_ ; }
+ static get date () { return ajaxDate_ ; }
+
+ static set tickMs (v) { ajaxTickMs_ = v; }
+ static set updateMs (v) { ajaxUpdateMs_ = v; }
+ static set server (v) { ajaxServer_ = v; }
+ static set onResponse(v) { ajaxOnResponse_ = v; }
+ static set onTick (v) { ajaxOnTick_ = v; }
+
+ static getElementOrNull(elementName) { return ajaxGetElementOrNull_(elementName) ; }
+ static hexToBit (text, iBit ) { return ajaxHexToBit_ (text, iBit ) ; }
+ static hexToSignedInt8 (text ) { return ajaxHexToSignedInt8_ (text ) ; }
+ static hexToSignedInt16(text ) { return ajaxHexToSignedInt16_(text ) ; }
+ static hexToSignedInt32(text ) { return ajaxHexToSignedInt32_(text ) ; }
+
+ static init()
+ {
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', ajaxInit_ ); // Loading hasn't finished yet
+ else ajaxInit_(); //`DOMContentLoaded` has already fired
+ }
+}
\ No newline at end of file
--- a/css/web-base-css.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-#include "http.h"
-
-static const char* cssBase =
-#include "web-base-css.inc"
-;
-const char* WebBaseCssDate = __DATE__;
-const char* WebBaseCssTime = __TIME__;
-
-void WebBaseCss()
-{
- HttpOk("text/css; charset=UTF-8", "max-age=3600", WebBaseCssDate, WebBaseCssTime);
- HttpAddText(cssBase);
-}
--- a/css/web-base-css.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-" * { font-size:6vw; box-sizing: border-box; }\r\n"
-"@media (min-width: 600px) { * { font-size:36px; } }\r\n"
-".line { display:flex; justify-content:space-between; align-items:center; width:15em; }\r\n"
-"\r\n"
-"* { font-family:Segoe UI, Calibri, Helvetica, Arial, sans-serif; }\r\n"
-"code, textarea, input[type=text] { font-family:Consolas, Lucida Console, Droid Sans Mono, Courier New, Courier, monospace; white-space:pre; }\r\n"
-"body { margin-left:0.1em; line-height:1.1em; padding:0; border:0; }\r\n"
-"h1 { color:darkblue; font-size:120%; font-weight:normal; margin-bottom:0.3em; }\r\n"
-"h2 { color:darkblue; font-size:110%; font-weight:normal; margin-bottom:0.3em; }\r\n"
-"a { text-decoration:none; }\r\n"
-"div { line-height:1.2em; }\r\n"
-"form { line-height:1.2em; margin:0; }\r\n"
-"button, input[type=submit] { border-radius:0.2em; border:0; box-shadow:none; margin-top:0.3em; }\r\n"
-"button:hover { color:red; }\r\n"
-"input[type=submit]:hover { color:red; }\r\n"
-"input[type=text] { border:thin none gray; margin:0; padding:0; color:darkblue; text-align:right; }\r\n"
-"\r\n"
-".toggle { display:inline-block; position:relative; cursor:pointer; width: 1.2em; height: 0.6em; }\r\n"
-".slot { background-color:lightsteelblue; display:block; position:absolute; top:0.1em; left:0.1em; bottom:0.1em; right:0.1em; border-radius:0.6em; transition:background 0.4s; }\r\n"
-".knob { background-color:steelblue; display:block; position:absolute; top:0.0em; left:0.0em; bottom:0.0em; width:0.6em; border-radius:0.6em; transition:background 0.4s, margin 0.4s; }\r\n"
-".toggle[dir=rtl] > .slot { background-color:lightsteelblue; }\r\n"
-".toggle[dir=rtl] > .knob { background-color:royalblue; margin-left:0.6em}\r\n"
-".led { background-color:lightgray; display:inline-block; width:0.6em; height:0.6em; border-radius:50%; }\r\n"
-".led[dir=rtl] { background-color:royalblue; }\r\n"
-"\r\n"
-".hamburger { display:inline-block; width:1em}\r\n"
-".bar { height:0.15em; background-color:#111; border-radius:0.15em; }\r\n"
-".space { height:0.2em; }\r\n"
--- a/css/web-nav-css.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-#include "http.h"
-
-static const char* cssNav =
-#include "web-nav-css.inc"
-;
-const char* WebNavCssDate = __DATE__;
-const char* WebNavCssTime = __TIME__;
-
-void WebNavCss()
-{
- HttpOk("text/css; charset=UTF-8", "max-age=3600", WebNavCssDate, WebNavCssTime);
- HttpAddText(cssNav);
-}
--- a/css/web-nav-css.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-//Override the base font size 1vw = 1% width so for a width of 600px 4vw equates to 24px
-" * { font-size:4vw; } \r\n"
-"@media (min-width: 600px) { * { font-size:24px; } }\r\n"
-
-//Override the left margin to fit the nav bar and make the line spacing smaller
-"body { margin-left:6em; }\r\n"
-
-//Overide the line container to match
-".line { width:17em; }\r\n"
-
-//Specify the tab access
-".tab-shortcut { position:absolute; top:-1000em;}\r\n"
-".tab-shortcut:focus { position:fixed; top:0; left:0; z-index:999; padding:0.5em; background-color:darkblue; color:white; }\r\n"
-
-//Specify the nav bar itself
-"nav ul { list-style-type:none; margin:0; padding:0; overflow:hidden; position:fixed; top:0; left:0; width:5em; font-size:1.2em; }\r\n"
-"nav ul li { background:lightskyblue; padding:0; border-style:none; margin:0.2em; }\r\n"
-"nav ul li.this { background:coral; }\r\n"
-"nav ul li a { display:block; color:black; border:0;margin:0; padding:0.5em; }\r\n"
-"nav ul li a:hover { color:darkred; }\r\n"
--- a/fault/web-fault-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include <stdio.h>
-
-#include "http.h"
-#include "web-page-base.h"
-#include "web-add.h"
-#include "fault.h"
-
-void WebFaultHtml()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Fault", "settings.css", NULL);
- WebAddNav(FAULT_PAGE);
- WebAddH1("Fault");
-
- WebAddH2("Last fault");
- int faultType = FaultTypeGet();
- char text[20];
- FaultTypeToString(faultType, sizeof(text), text);
- WebAddLabelledText("Fault type", text);
- if (faultType)
- {
- FaultZoneToString(FaultZoneGet(), sizeof(text), text);
- WebAddLabelledText("Fault zone" , text);
- WebAddLabelledInt ("After point", FaultPointGet());
- WebAddInputButton ("Clear fault", "Clear", "/fault", "faultclear");
- }
- else
- {
- WebAddInputButton("Test fault" , "Test", "/fault", "faulttest");
- }
-
- WebAddEnd();
-}
-
--- a/fault/web-fault-query.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#include "http.h"
-#include "fault.h"
-
-void WebFaultQuery(char* pQuery)
-{
- while (pQuery)
- {
- char* pName;
- char* pValue;
- pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
-
- if (HttpSameStr(pName, "faultclear")) FaultReset();
-
- if (HttpSameStr(pName, "faulttest" ))
- {
- FaultPoint = 999;
- *(volatile int *)0 = 0; //Dereferencing address 0 will hard fault the processor
- }
-
- }
-}
--- a/favicon/web-favicon.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#include "http.h"
-
-//Use http://tomeko.net/online_tools/file_to_hex.php to convert a favicon.ico into hex readable as an array
-static const char bytes[] = {
-#include "favicon/web-favicon.inc"
-};
-
-const char* WebFaviconDate = __DATE__;
-const char* WebFaviconTime = __TIME__;
-const int WebFaviconSize = sizeof(bytes);
-
-void WebFavicon()
-{
- HttpOk("image/x-icon", "max-age=3600", WebFaviconDate, WebFaviconTime);
- HttpAddData(bytes, WebFaviconSize);
-}
--- a/firmware/web-firmware-ajax.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#include <stdio.h>
-
-#include "http.h"
-#include "web-base.h"
-#include "firmware.h"
-#include "web-firmware.h"
-
-void WebFirmwareAjax()
-{
- //Header
- HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
-
- //Upload status
- if (FirmwareSentLength == FirmwareFileLength)
- {
- HttpAddText("Length ok\r\n");
- }
- else
- {
- HttpAddText("Length error\r\n");
- HttpAddF (" sent %6d\r\n", FirmwareSentLength);
- HttpAddF (" rcvd %6d\r\n", FirmwareRcvdLength);
- HttpAddF (" file %6d\r\n", FirmwareFileLength);
- }
-
- //Save status
- if (FirmwareFailed)
- {
- HttpAddText("Save failed - see log");
- }
- else
- {
- HttpAddText("Saved ok");
- }
-
- //Delimiter
- HttpAddChar('\f');
-
- //New directory list
- WebFirmwareListSemihostFiles();
-}
--- a/firmware/web-firmware-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include <stdio.h>
-
-#include "http.h"
-#include "web-page-base.h"
-#include "web-add.h"
-#include "web-firmware.h"
-
-void WebFirmwareHtml()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Firmware", "settings.css", "firmware.js");
- WebAddNav(FIRMWARE_PAGE);
- WebAddH1("Firmware");
-
- WebAddH2("Existing files on the device");
-
- HttpAddText("<code id='list'>");
- WebFirmwareListSemihostFiles();
- HttpAddText("</code>\r\n");
-
- WebAddH2("Choose a local file");
- HttpAddText("<div><input type='file' id='fileInput'/></div>\r\n");
-
- WebAddH2("Upload the local file to the device");
- HttpAddText("<div><button onclick='startUpload();'>Upload</button></div>\r\n");
- HttpAddText("<code id='uploadresult'></code>\r\n");
-
- WebAddH2("Restart the device");
- HttpAddText("<div><button onclick='restart();'>Restart</button></div>\r\n");
- HttpAddText("<code id='restartresult'></code>\r\n");
-
-
- WebAddEnd();
-}
--- a/firmware/web-firmware-post.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "firmware.h"
-
-bool WebFirmwarePost (int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream)
-{
- if (!positionInRequestStream)
- {
- FirmwareStart(contentLength);
- }
- char* pDataStart = pRequestStream + contentStart;
- int dataLength = size - contentStart;
- return FirmwareAdd(pDataStart, dataLength);
-}
\ No newline at end of file
--- a/firmware/web-firmware-query.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-#include "http.h"
-#include "semihost.h"
-
-void WebFirmwareQuery(char* pQuery)
-{
- while (pQuery)
- {
- char* pName;
- char* pValue;
- pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
- int value = HttpQueryValueAsInt(pValue);
-
- if (HttpSameStr(pName, "restart" )) SemihostReset();
- }
-}
--- a/firmware/web-firmware-script.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#include "http.h"
-
-//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
-//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
-
-const char* WebFirmwareScriptDate = __DATE__;
-const char* WebFirmwareScriptTime = __TIME__;
-
-static const char* script =
-#include "web-firmware-script.inc"
-;
-void WebFirmwareScript()
-{
- HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebFirmwareScriptDate, WebFirmwareScriptTime);
- HttpAddText(script);
-}
--- a/firmware/web-firmware-script.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-"'use strict';\n"
-"\n"
-"var file;\n"
-"var xhr;\n"
-"\n"
-"function logUpload(text)\n"
-"{\n"
-" document.getElementById('uploadresult').textContent = text;\n"
-"}\n"
-"function xhrUploadResponse()\n"
-"{\n"
-" var topics = xhr.responseText.split('\\f');\n"
-" logUpload(topics[0]);\n"
-" if (topics.length > 1) document.getElementById('list').textContent = topics[1];\n"
-"}\n"
-"function xhrUploadOnLoad()\n"
-"{\n"
-" if (xhr.status == 200) xhrUploadResponse();\n"
-" else logUpload('Upload failed');\n"
-"}\n"
-"function xhrUploadOnError()\n"
-"{\n"
-" logUpload('Upload error');\n"
-"}\n"
-"function xhrUploadStart()\n"
-"{\n"
-" logUpload('Uploading...');\n"
-" \n"
-" xhr = new XMLHttpRequest();\n"
-"\n"
-" xhr.onload = xhrUploadOnLoad;\n"
-" xhr.onerror = xhrUploadOnError;\n"
-"\n"
-" xhr.open('POST', '/firmware-ajax'); //Defaults to async=true\n"
-" xhr.send(file);\n"
-"}\n"
-"\n"
-"function startUpload()\n"
-"{\n"
-" var fileInput = document.getElementById('fileInput');\n"
-"\n"
-" if (fileInput.files.length == 0)\n"
-" {\n"
-" logUpload('Please choose a file');\n"
-" return;\n"
-" }\n"
-"\n"
-" if (fileInput.files.length > 1)\n"
-" {\n"
-" logUpload('Please choose just one file');\n"
-" return;\n"
-" }\n"
-" \n"
-" file = fileInput.files[0];\n"
-" \n"
-" xhrUploadStart();\n"
-"}\n"
-"function logRestart(text)\n"
-"{\n"
-" document.getElementById('restartresult').textContent = text;\n"
-"}\n"
-"function redirect()\n"
-"{\n"
-" location.href = '/firmware';\n"
-"}\n"
-"function xhrRestartOnLoad()\n"
-"{\n"
-" if (xhr.status == 200) logRestart('Restart should never have returned');\n"
-" else logRestart('Restart failed');\n"
-"}\n"
-"function xhrRestartStart()\n"
-"{\n"
-" logRestart('Restarting...');\n"
-" \n"
-" xhr = new XMLHttpRequest();\n"
-"\n"
-" xhr.onload = xhrRestartOnLoad;\n"
-"\n"
-" xhr.open('GET', '/firmware-ajax?restart='); //Defaults to async=true\n"
-" xhr.send();\n"
-" \n"
-" setTimeout(redirect, 2000);\n"
-"}\n"
-"function restart()\n"
-"{\n"
-" xhrRestartStart();\n"
-"}\n"
-""
\ No newline at end of file
--- a/firmware/web-firmware-script.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-'use strict';
-
-var file;
-var xhr;
-
-function logUpload(text)
-{
- document.getElementById('uploadresult').textContent = text;
-}
-function xhrUploadResponse()
-{
- var topics = xhr.responseText.split('\f');
- logUpload(topics[0]);
- if (topics.length > 1) document.getElementById('list').textContent = topics[1];
-}
-function xhrUploadOnLoad()
-{
- if (xhr.status == 200) xhrUploadResponse();
- else logUpload('Upload failed');
-}
-function xhrUploadOnError()
-{
- logUpload('Upload error');
-}
-function xhrUploadStart()
-{
- logUpload('Uploading...');
-
- xhr = new XMLHttpRequest();
-
- xhr.onload = xhrUploadOnLoad;
- xhr.onerror = xhrUploadOnError;
-
- xhr.open('POST', '/firmware-ajax'); //Defaults to async=true
- xhr.send(file);
-}
-
-function startUpload()
-{
- var fileInput = document.getElementById('fileInput');
-
- if (fileInput.files.length == 0)
- {
- logUpload('Please choose a file');
- return;
- }
-
- if (fileInput.files.length > 1)
- {
- logUpload('Please choose just one file');
- return;
- }
-
- file = fileInput.files[0];
-
- xhrUploadStart();
-}
-function logRestart(text)
-{
- document.getElementById('restartresult').textContent = text;
-}
-function redirect()
-{
- location.href = '/firmware';
-}
-function xhrRestartOnLoad()
-{
- if (xhr.status == 200) logRestart('Restart should never have returned');
- else logRestart('Restart failed');
-}
-function xhrRestartStart()
-{
- logRestart('Restarting...');
-
- xhr = new XMLHttpRequest();
-
- xhr.onload = xhrRestartOnLoad;
-
- xhr.open('GET', '/firmware-ajax?restart='); //Defaults to async=true
- xhr.send();
-
- setTimeout(redirect, 2000);
-}
-function restart()
-{
- xhrRestartStart();
-}
--- a/firmware/web-firmware.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#include "semihost.h"
-#include "http.h"
-
-void WebFirmwareListSemihostFiles()
-{
- XFINFO info;
- info.fileID = 0;
- while (SemihostXffind ("*.*", &info) == 0)
- {
- HttpAddF("%13s %7d bytes\r\n", info.name, info.size);
- }
- if (info.fileID == 0)
- {
- HttpAddText("No files\r\n");
- }
-}
\ No newline at end of file
--- a/firmware/web-firmware.h Mon Apr 29 14:45:30 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -extern void WebFirmwareListSemihostFiles(void); \ No newline at end of file
--- a/log/web-log-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#include "http.h"
-#include "web-page-base.h"
-#include "web-add.h"
-#include "log.h"
-
-void WebLogHtml()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Log", "settings.css", NULL);
- WebAddNav(LOG_PAGE);
- WebAddH1("Log");
-
- WebAddInputButton("Existing content", "Clear", "/log", "clearlog" );
- if (LogUart) WebAddInputButton("Output to uart is on", "Turn off", "/log", "chg-log-uart");
- else WebAddInputButton("Output to uart is off", "Turn on", "/log", "chg-log-uart");
-
- HttpAddText("<code>");
- HttpAddStream(LogEnumerateStart, LogEnumerate);
- HttpAddText("</code>");
-
- WebAddEnd();
-}
--- a/log/web-log-query.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-#include "http.h"
-#include "log.h"
-#include "settings.h"
-
-void WebLogQuery(char* pQuery)
-{
- while (pQuery)
- {
- char* pName;
- char* pValue;
- pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
- if (HttpSameStr(pName, "clearlog" )) LogClear();
- if (HttpSameStr(pName, "chg-log-uart")) ChgLogUart();
- }
-}
--- a/login/web-login-css.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-" * { font-size:4vw; box-sizing: border-box; }\r\n"
-"@media (min-width: 600px) { * { font-size:24px; } }\r\n"
-"\r\n"
-"* { font-family:'Segoe UI', Calibri, Arial, sans-serif; }\r\n"
-"*:focus { outline: 0; }\r\n"
-"body { margin-left:0.1em; line-height:1.1em; padding:0; border:0; }\r\n"
-"h1 { color:darkblue; font-size:120%; font-weight:normal; margin-bottom:0.3em; }\r\n"
-"h2 { color:darkblue; font-size:110%; font-weight:normal; margin-bottom:0.3em; }\r\n"
-"div { line-height:1.2em; }\r\n"
-"form { line-height:1.2em; margin:0; }\r\n"
-"input[type=text] { border:thin solid gray; border-radius:0.2em; margin:0; padding:0.1em; width:9em; text-align:left}\r\n"
-"input[type=submit] { display:none; }\r\n"
\ No newline at end of file
--- a/login/web-login-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#include "http.h"
-#include "web-add.h"
-#include "web-login.h"
-#include "web-base.h"
-#include "web-page-base.h"
-
-void WebLoginHtml()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Login", NULL, NULL);
- HttpAddText(
-"<style>"
-#include "web-login-css.inc"
-"</style>"
- );
- WebAddH1("Login");
- if (WebLoginPasswordIsSet())
- {
- WebAddH2("Welcome - please enter the password");
- }
- else
- {
- WebAddH2("Please enter a new password following user reset");
- HttpAddText("<p>Be careful to make it the one people expect!</p>");
- }
-
- HttpAddText("<form action='/login' method='get' autocomplete='off'>\r\n");
- HttpAddText(" <div style='width:8em; display:inline-block;'>Password</div>\r\n");
- HttpAddF (" <input type='hidden' name='todo' value='%d'>\r\n", WebLoginOriginalToDo);
- HttpAddText(" <input type='text' name='password' value='' autofocus>\r\n");
- HttpAddText(" <input type='submit' value='' >\r\n");
- HttpAddF ("</form>\r\n");
-
- WebAddEnd();
-}
-
-/*
-Device sends request for resource to server
-Server cannot validate the session cookie (or there isn't one) so sends login form with original resource number as a hidden input
-Device does a GET for /login with query containing password and original resource
-Server validates password and sends original resource with a valid session cookie.
-*/
\ No newline at end of file
--- a/login/web-login-password.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "http.h"
-
-#define GPREG2 (*((volatile unsigned *) 0x4002404C))
-
-static uint32_t hash;
-static bool hashIsSet = false;
-
-void WebLoginPasswordRestore()
-{
- hash = GPREG2;
- hashIsSet = true;
-}
-
-uint32_t hasher(char *p) //Jenkins 'one at a time' hash
-{
- uint32_t h = 0;
-
- while (*p)
- {
- h += *p;
- h += (h << 10);
- h ^= (h >> 6);
- p++;
- }
- h += (h << 3);
- h ^= (h >> 11);
- h += (h << 15);
-
- return h;
-}
-bool WebLoginPasswordIsSet()
-{
- return hashIsSet;
-}
-void WebLoginPasswordSet(char* password)
-{
- if (!password) return;
- if (!*password) return;
- hash = hasher(password);
- GPREG2 = hash;
- hashIsSet = true;
-}
-bool WebLoginPasswordMatches(char* password)
-{
- if (!hashIsSet) return false;
- if (!password) return false;
- if (!*password) return false;
- return hash == hasher(password);
-}
--- a/login/web-login-query.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-
-#include "http.h"
-#include "web-base.h"
-#include "web-login.h"
-
-bool WebLoginQueryPasswordOk = false;
-
-void WebLoginQuery(char* pQuery)
-{
- WebLoginQueryPasswordOk = false;
-
- while (pQuery)
- {
- char* pName;
- char* pValue;
- pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
-
- int value = HttpQueryValueAsInt(pValue);
- if (HttpSameStr(pName, "todo" )) WebLoginOriginalToDo = value;
-
- HttpQueryUnencode(pValue);
- if (HttpSameStr(pName, "password" ))
- {
- if (!WebLoginPasswordIsSet()) //This is if there has been a normal reset: not a fault nor a power on.
- {
- WebLoginPasswordSet(pValue);
- WebLoginQueryPasswordOk = true;
- }
- else
- {
- WebLoginQueryPasswordOk = WebLoginPasswordMatches(pValue);
- }
- }
- }
-}
--- a/login/web-login-session-id.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "random.h"
-
-#define SESSION_ID_BIT_LENGTH 36
-
-static char sessionId[(SESSION_ID_BIT_LENGTH + 5) / 6 + 1]; //Bit lengths not divisible by 6 require an extra space
-
-void WebLoginSessionIdNew()
-{
- char acc = 0;
-
- for (int i = 0; i < SESSION_ID_BIT_LENGTH; i++)
- {
- int srcByte = i / 8;
- int srcBit = i - srcByte * 8;
- uint8_t srcMask = 1 << srcBit;
-
- int dstByte = i / 6;
- int dstBit = i - dstByte * 6;
- uint8_t dstMask = 1 << dstBit;
-
- //Reset the accumulator to zero at start of a 6 bit word
- if (!dstBit) acc = 0;
-
- //Add the bit to the accumulator
- if (RandomBytes[srcByte] & srcMask) acc |= dstMask;
-
- //Convert the accumulator to base64 and store in the session Id
- if (dstBit == 5 || i == SESSION_ID_BIT_LENGTH - 1)
- {
- if (acc < 26) sessionId[dstByte] = acc - 0 + 'A';
- else if (acc < 52) sessionId[dstByte] = acc - 26 + 'a';
- else if (acc < 62) sessionId[dstByte] = acc - 52 + '0';
- else if (acc < 63) sessionId[dstByte] = '+';
- else sessionId[dstByte] = '/';
- }
- }
- sessionId[(SESSION_ID_BIT_LENGTH + 5) / 6] = 0;
-}
-
-bool WebLoginSessionIdIsSet()
-{
- return sessionId[0];
-}
-char* WebLoginSessionIdGet()
-{
- return sessionId;
-}
--- a/login/web-login-session-name.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#include "web-site-name.h"
-
-#define SESSION_LIFE 10 * 365 * 24 * 60 * 60
-
-//Do not use ' ', ';', '=' as they are part of the cookie protocol: name1=value1; name2=value2; name3=value3 etc
-static char sessionName[9]; //Limit the name to 8 characters (plus terminating zero) to keep things quick
-
-char* WebLoginSessionNameGet()
-{
- return sessionName;
-}
-
-void WebLoginSessionNameCreate()
-{
- //Make the session name from the site name - eg "Heating" and "GPS Clock" will be "heat_sid" and "gpsc_sid"
- int i = 0;
- int j = 0;
- while (1)
- {
- if (i >= sizeof(sessionName) - 4 - 1) break; //Leave room for the "_sid" and the terminating NUL character
- char c = WEB_SITE_NAME[j++];
- if (!c) break; //Stop if run out of site name
- if (c >= 'A' && c <= 'Z') c |= 0x20; //Make lower case
- if (c < 'a' || c > 'z') continue; //Skip anything other than letters
- sessionName[i++] = c; //Add the first characters of the site name for which there is room
- }
- for (int k = 0; k < 4; k++) //Add "_sid"
- {
- sessionName[i++] = "_sid"[k];
- }
- sessionName[i] = 0; //Add the terminating NUL character
-}
-
-int WebLoginSessionNameLife()
-{
- return SESSION_LIFE;
-}
--- a/login/web-login.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-
-#include "web-base.h"
-#include "web-login.h"
-#include "http.h"
-#include "fault.h"
-
-int WebLoginOriginalToDo = 0;
-
-bool WebLoginCookiesContainValidSessionId(char* pCookies)
-{
- if (!WebLoginSessionIdIsSet()) return false;
-
- while (pCookies)
- {
- char* pName;
- char* pValue;
- pCookies = HttpCookiesSplit(pCookies, &pName, &pValue);
-
- if (HttpSameStr(pName, WebLoginSessionNameGet())) //HttpSameStr handles NULLs correctly
- {
- if (HttpSameStr(pValue, WebLoginSessionIdGet())) return true;
- }
- }
- return false;
-}
-void WebLoginInit()
-{
- if (FaultTypeGet()) WebLoginPasswordRestore();
- WebLoginSessionNameCreate();
-}
\ No newline at end of file
--- a/login/web-login.h Mon Apr 29 14:45:30 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#include <stdbool.h> - -extern void WebLoginSessionNameCreate(void); - -extern void WebLoginPasswordRestore (void); -extern void WebLoginPasswordSet (char* password); -extern bool WebLoginPasswordIsSet (void); -extern bool WebLoginPasswordMatches (char* password); \ No newline at end of file
--- a/net-trace/web-trace-ajax.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-#include <stdint.h>
-
-#include "http.h"
-#include "web-base.h"
-#include "log.h"
-#include "net.h"
-#include "link.h"
-#include "dns.h"
-#include "dnsname.h"
-#include "dnsquery.h"
-#include "dnsreply.h"
-#include "dnsserver.h"
-#include "ntp.h"
-#include "dhcp.h"
-#include "ns.h"
-#include "nr4.h"
-#include "nr6.h"
-#include "echo4.h"
-#include "echo6.h"
-#include "dest6.h"
-#include "ra.h"
-#include "rs.h"
-#include "ar4.h"
-#include "ar6.h"
-#include "arp.h"
-#include "ip4.h"
-#include "ip6.h"
-#include "udp.h"
-#include "tcp.h"
-#include "http.h"
-#include "tftp.h"
-#include "ntpclient.h"
-
-void WebTraceAjax()
-{
- HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
- char nibble;
-
- nibble = 0; //0
- if ( DnsSendRequestsViaIp4) nibble |= 2;
- if ( NtpClientQuerySendRequestsViaIp4) nibble |= 4;
- if (TftpSendRequestsViaIp4) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- HttpAddByteAsHex(NetTraceHost[0]); //1, 2
- HttpAddByteAsHex(NetTraceHost[1]); //3, 4
-
- nibble = 0; //5
- if (NetTraceStack ) nibble |= 1;
- if (NetTraceNewLine ) nibble |= 2;
- if (NetTraceVerbose ) nibble |= 4;
- if (LinkTrace ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- nibble = 0; //6
- if (DnsNameTrace ) nibble |= 1;
- if (DnsQueryTrace ) nibble |= 2;
- if (DnsReplyTrace ) nibble |= 4;
- if (DnsServerTrace ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- nibble = 0; //7
- if (NtpTrace ) nibble |= 1;
- if (DhcpTrace ) nibble |= 2;
- if (NsTraceRecvSol ) nibble |= 4;
- if (NsTraceRecvAdv ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- nibble = 0; //8
- if (NsTraceSendSol ) nibble |= 1;
- if (Nr4Trace ) nibble |= 2;
- if (Nr6Trace ) nibble |= 4;
- if (NtpClientTrace ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- nibble = 0; //9
- if (Echo4Trace ) nibble |= 4;
- if (Echo6Trace ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- nibble = 0; //10
- if (Dest6Trace ) nibble |= 1;
- if (RaTrace ) nibble |= 2;
- if (RsTrace ) nibble |= 4;
- if (Ar4Trace ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- nibble = 0; //11
- if (Ar6Trace ) nibble |= 1;
- if (ArpTrace ) nibble |= 2;
- if (Ip4Trace ) nibble |= 4;
- if (Ip6Trace ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-
- nibble = 0; //12
- if (UdpTrace ) nibble |= 1;
- if (TcpTrace ) nibble |= 2;
- if (HttpTrace ) nibble |= 4;
- if (TftpTrace ) nibble |= 8;
- HttpAddNibbleAsHex(nibble);
-}
-
--- a/net-trace/web-trace-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-#include "web-add.h"
-#include "web-page-base.h"
-#include "http.h"
-
-void WebTraceHtml()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Net Trace", "settings.css", "trace.js");
- WebAddNav(TRACE_PAGE);
- WebAddH1("Net Trace");
-
- WebAddH2("General");
- WebAddAjaxInput ("Trace host" , 5 , "ajax-trace-net-host" , "set-trace-net-host" );
- WebAddAjaxInputToggle("Trace stack" , "ajax-trace-net-stack" , "chg-trace-net-stack" );
- WebAddAjaxInputToggle("Trace new line" , "ajax-trace-net-newline", "chg-trace-net-newline");
- WebAddAjaxInputToggle("Trace verbose" , "ajax-trace-net-verbose", "chg-trace-net-verbose");
- WebAddH2("Net");
- WebAddAjaxInputToggle("MAC" , "ajax-trace-link" , "chg-trace-link" );
- WebAddAjaxInputToggle("Ip4 filtered" , "ajax-trace-ip4" , "chg-trace-ip4" );
- WebAddAjaxInputToggle("Ip6 filtered" , "ajax-trace-ip6" , "chg-trace-ip6" );
- WebAddAjaxInputToggle("Udp filtered" , "ajax-trace-udp" , "chg-trace-udp" );
- WebAddAjaxInputToggle("Tcp filtered" , "ajax-trace-tcp" , "chg-trace-tcp" );
- WebAddAjaxInputToggle("Echo4 (ping4)" , "ajax-trace-echo4" , "chg-trace-echo4" );
- WebAddAjaxInputToggle("Echo6 (ping6)" , "ajax-trace-echo6" , "chg-trace-echo6" );
- WebAddAjaxInputToggle("Dest6 unreacheable" , "ajax-trace-dest6" , "chg-trace-dest6" );
- WebAddAjaxInputToggle("HTTP" , "ajax-trace-http" , "chg-trace-http" );
- WebAddAjaxInputToggle("TFTP" , "ajax-trace-tftp" , "chg-trace-tftp" );
- WebAddH2("Send requests via IPv4");
- WebAddAjaxInputToggle("DNS request via IPv4" , "ajax-trace-dns-ip4" , "chg-send-dns-ip4" );
- WebAddAjaxInputToggle("NTP request via IPv4" , "ajax-trace-ntp-ip4" , "chg-send-ntp-ip4" );
- WebAddAjaxInputToggle("TFTP request via IPv4", "ajax-trace-tftp-ip4" , "chg-send-tftp-ip4" );
- WebAddH2("Router Resolution");
- WebAddAjaxInputToggle("Router advertise" , "ajax-trace-ra" , "chg-trace-ra" );
- WebAddAjaxInputToggle("Router solicit" , "ajax-trace-rs" , "chg-trace-rs" );
- WebAddAjaxInputToggle("DHCP" , "ajax-trace-dhcp" , "chg-trace-dhcp" );
- WebAddH2("Address Resolution");
- WebAddAjaxInputToggle("IP4 cache" , "ajax-trace-ar4" , "chg-trace-ar4" );
- WebAddAjaxInputToggle("IP6 cache" , "ajax-trace-ar6" , "chg-trace-ar6" );
- WebAddAjaxInputToggle("ARP" , "ajax-trace-arp" , "chg-trace-arp" );
- WebAddAjaxInputToggle("NS server" , "ajax-trace-ns-recv-sol", "chg-trace-ns-recv-sol");
- WebAddAjaxInputToggle("NS client reply" , "ajax-trace-ns-recv-adv", "chg-trace-ns-recv-adv");
- WebAddAjaxInputToggle("NS client query" , "ajax-trace-ns-send-sol", "chg-trace-ns-send-sol");
- WebAddH2("Name Resolution");
- WebAddAjaxInputToggle("IP4 cache" , "ajax-trace-nr4" , "chg-trace-nr4" );
- WebAddAjaxInputToggle("IP6 cache" , "ajax-trace-nr6" , "chg-trace-nr6" );
- WebAddAjaxInputToggle("DNS name" , "ajax-trace-dns-name" , "chg-trace-dns-name" );
- WebAddAjaxInputToggle("DNS client query" , "ajax-trace-dns-query" , "chg-trace-dns-query" );
- WebAddAjaxInputToggle("DNS client reply" , "ajax-trace-dns-reply" , "chg-trace-dns-reply" );
- WebAddAjaxInputToggle("DNS server" , "ajax-trace-dns-server" , "chg-trace-dns-server" );
- WebAddH2("NTP");
- WebAddAjaxInputToggle("NTP" , "ajax-trace-ntp" , "chg-trace-ntp" );
- WebAddAjaxInputToggle("NTP client" , "ajax-trace-ntp-client" , "chg-trace-ntp-client" );
-
- WebAddEnd();
-}
--- a/net-trace/web-trace-query.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#include "http.h"
-#include "settings.h"
-
-void WebTraceQuery(char* pQuery)
-{
- while (pQuery)
- {
- char* pName;
- char* pValue;
- pQuery = HttpQuerySplit(pQuery, &pName, &pValue);
-
- if (HttpSameStr(pName, "chg-send-dns-ip4" )) ChgDnsSendRequestsViaIp4();
- if (HttpSameStr(pName, "chg-send-ntp-ip4" )) ChgNtpSendRequestsViaIp4();
- if (HttpSameStr(pName, "chg-send-tftp-ip4" )) ChgTftpSendRequestsViaIp4();
- if (HttpSameStr(pName, "set-trace-net-host" )) SetTraceNetHost(pValue);
- if (HttpSameStr(pName, "chg-trace-net-stack" )) ChgTraceNetStack();
- if (HttpSameStr(pName, "chg-trace-net-newline" )) ChgTraceNetNewLine();
- if (HttpSameStr(pName, "chg-trace-net-verbose" )) ChgTraceNetVerbose();
- if (HttpSameStr(pName, "chg-trace-link" )) ChgTraceLink();
- if (HttpSameStr(pName, "chg-trace-dns-name" )) ChgTraceDnsName();
- if (HttpSameStr(pName, "chg-trace-dns-query" )) ChgTraceDnsQuery();
- if (HttpSameStr(pName, "chg-trace-dns-reply" )) ChgTraceDnsReply();
- if (HttpSameStr(pName, "chg-trace-dns-server" )) ChgTraceDnsServer();
- if (HttpSameStr(pName, "chg-trace-ntp" )) ChgTraceNtp();
- if (HttpSameStr(pName, "chg-trace-dhcp" )) ChgTraceDhcp();
- if (HttpSameStr(pName, "chg-trace-ns-recv-sol" )) ChgTraceNsRecvSol();
- if (HttpSameStr(pName, "chg-trace-ns-recv-adv" )) ChgTraceNsRecvAdv();
- if (HttpSameStr(pName, "chg-trace-ns-send-sol" )) ChgTraceNsSendSol();
- if (HttpSameStr(pName, "chg-trace-nr4" )) ChgTraceNr4();
- if (HttpSameStr(pName, "chg-trace-nr6" )) ChgTraceNr6();
- if (HttpSameStr(pName, "chg-trace-ntp-client" )) ChgTraceNtpClient();
- if (HttpSameStr(pName, "chg-trace-sync" )) ChgTraceSync();
- if (HttpSameStr(pName, "chg-trace-echo4" )) ChgTraceEcho4();
- if (HttpSameStr(pName, "chg-trace-echo6" )) ChgTraceEcho6();
- if (HttpSameStr(pName, "chg-trace-dest6" )) ChgTraceDest6();
- if (HttpSameStr(pName, "chg-trace-ra" )) ChgTraceRa();
- if (HttpSameStr(pName, "chg-trace-rs" )) ChgTraceRs();
- if (HttpSameStr(pName, "chg-trace-ar4" )) ChgTraceAr4();
- if (HttpSameStr(pName, "chg-trace-ar6" )) ChgTraceAr6();
- if (HttpSameStr(pName, "chg-trace-arp" )) ChgTraceArp();
- if (HttpSameStr(pName, "chg-trace-ip4" )) ChgTraceIp4();
- if (HttpSameStr(pName, "chg-trace-ip6" )) ChgTraceIp6();
- if (HttpSameStr(pName, "chg-trace-udp" )) ChgTraceUdp();
- if (HttpSameStr(pName, "chg-trace-tcp" )) ChgTraceTcp();
- if (HttpSameStr(pName, "chg-trace-http" )) ChgTraceHttp();
- if (HttpSameStr(pName, "chg-trace-tftp" )) ChgTraceTftp();
- }
-}
-
--- a/net-trace/web-trace-script.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-#include "http.h"
-
-//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
-//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
-
-const char* WebTraceScriptDate = __DATE__;
-const char* WebTraceScriptTime = __TIME__;
-
-static const char* script =
-#include "../base/web-ajax-class.inc"
-#include "web-trace-script.inc"
-;
-void WebTraceScript()
-{
- HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebTraceScriptDate, WebTraceScriptTime);
- HttpAddText(script);
-}
--- a/net-trace/web-trace-script.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-"//Net trace script\n"
-"'use strict';\n"
-"function setDirection(elem, iChar, iBit)\n"
-"{\n"
-" elem.setAttribute('dir', Ajax.hexToBit(Ajax.response.charAt(iChar), iBit) ? 'rtl' : 'ltr');\n"
-"}\n"
-"function display()\n"
-"{\n"
-" var elem;\n"
-" elem = Ajax.getElementOrNull('ajax-trace-dns-ip4' ); if (elem) setDirection(elem, 0, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ntp-ip4' ); if (elem) setDirection(elem, 0, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-tftp-ip4' ); if (elem) setDirection(elem, 0, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-net-host' ); if (elem) elem.value = Ajax.response.substr( 1, 4);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-net-stack' ); if (elem) setDirection(elem, 5, 0);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-net-newline' ); if (elem) setDirection(elem, 5, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-net-verbose' ); if (elem) setDirection(elem, 5, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-link' ); if (elem) setDirection(elem, 5, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-dns-name' ); if (elem) setDirection(elem, 6, 0);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-dns-query' ); if (elem) setDirection(elem, 6, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-dns-reply' ); if (elem) setDirection(elem, 6, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-dns-server' ); if (elem) setDirection(elem, 6, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ntp' ); if (elem) setDirection(elem, 7, 0);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-dhcp' ); if (elem) setDirection(elem, 7, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ns-recv-sol' ); if (elem) setDirection(elem, 7, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ns-recv-adv' ); if (elem) setDirection(elem, 7, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ns-send-sol' ); if (elem) setDirection(elem, 8, 0);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-nr4' ); if (elem) setDirection(elem, 8, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-nr6' ); if (elem) setDirection(elem, 8, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ntp-client' ); if (elem) setDirection(elem, 8, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-echo4' ); if (elem) setDirection(elem, 9, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-echo6' ); if (elem) setDirection(elem, 9, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-dest6' ); if (elem) setDirection(elem, 10, 0);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ra' ); if (elem) setDirection(elem, 10, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-rs' ); if (elem) setDirection(elem, 10, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ar4' ); if (elem) setDirection(elem, 10, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ar6' ); if (elem) setDirection(elem, 11, 0);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-arp' ); if (elem) setDirection(elem, 11, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ip4' ); if (elem) setDirection(elem, 11, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-ip6' ); if (elem) setDirection(elem, 11, 3);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-udp' ); if (elem) setDirection(elem, 12, 0);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-tcp' ); if (elem) setDirection(elem, 12, 1);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-http' ); if (elem) setDirection(elem, 12, 2);\n"
-" elem = Ajax.getElementOrNull('ajax-trace-tftp' ); if (elem) setDirection(elem, 12, 3);\n"
-"}\n"
-"\n"
-"Ajax.server = '/trace-ajax';\n"
-"Ajax.onResponse = display;\n"
-"Ajax.init();"
\ No newline at end of file
--- a/net-trace/web-trace-script.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-//Net trace script
-'use strict';
-function setDirection(elem, iChar, iBit)
-{
- elem.setAttribute('dir', Ajax.hexToBit(Ajax.response.charAt(iChar), iBit) ? 'rtl' : 'ltr');
-}
-function display()
-{
- var elem;
- elem = Ajax.getElementOrNull('ajax-trace-dns-ip4' ); if (elem) setDirection(elem, 0, 1);
- elem = Ajax.getElementOrNull('ajax-trace-ntp-ip4' ); if (elem) setDirection(elem, 0, 2);
- elem = Ajax.getElementOrNull('ajax-trace-tftp-ip4' ); if (elem) setDirection(elem, 0, 3);
- elem = Ajax.getElementOrNull('ajax-trace-net-host' ); if (elem) elem.value = Ajax.response.substr( 1, 4);
- elem = Ajax.getElementOrNull('ajax-trace-net-stack' ); if (elem) setDirection(elem, 5, 0);
- elem = Ajax.getElementOrNull('ajax-trace-net-newline' ); if (elem) setDirection(elem, 5, 1);
- elem = Ajax.getElementOrNull('ajax-trace-net-verbose' ); if (elem) setDirection(elem, 5, 2);
- elem = Ajax.getElementOrNull('ajax-trace-link' ); if (elem) setDirection(elem, 5, 3);
- elem = Ajax.getElementOrNull('ajax-trace-dns-name' ); if (elem) setDirection(elem, 6, 0);
- elem = Ajax.getElementOrNull('ajax-trace-dns-query' ); if (elem) setDirection(elem, 6, 1);
- elem = Ajax.getElementOrNull('ajax-trace-dns-reply' ); if (elem) setDirection(elem, 6, 2);
- elem = Ajax.getElementOrNull('ajax-trace-dns-server' ); if (elem) setDirection(elem, 6, 3);
- elem = Ajax.getElementOrNull('ajax-trace-ntp' ); if (elem) setDirection(elem, 7, 0);
- elem = Ajax.getElementOrNull('ajax-trace-dhcp' ); if (elem) setDirection(elem, 7, 1);
- elem = Ajax.getElementOrNull('ajax-trace-ns-recv-sol' ); if (elem) setDirection(elem, 7, 2);
- elem = Ajax.getElementOrNull('ajax-trace-ns-recv-adv' ); if (elem) setDirection(elem, 7, 3);
- elem = Ajax.getElementOrNull('ajax-trace-ns-send-sol' ); if (elem) setDirection(elem, 8, 0);
- elem = Ajax.getElementOrNull('ajax-trace-nr4' ); if (elem) setDirection(elem, 8, 1);
- elem = Ajax.getElementOrNull('ajax-trace-nr6' ); if (elem) setDirection(elem, 8, 2);
- elem = Ajax.getElementOrNull('ajax-trace-ntp-client' ); if (elem) setDirection(elem, 8, 3);
- elem = Ajax.getElementOrNull('ajax-trace-echo4' ); if (elem) setDirection(elem, 9, 2);
- elem = Ajax.getElementOrNull('ajax-trace-echo6' ); if (elem) setDirection(elem, 9, 3);
- elem = Ajax.getElementOrNull('ajax-trace-dest6' ); if (elem) setDirection(elem, 10, 0);
- elem = Ajax.getElementOrNull('ajax-trace-ra' ); if (elem) setDirection(elem, 10, 1);
- elem = Ajax.getElementOrNull('ajax-trace-rs' ); if (elem) setDirection(elem, 10, 2);
- elem = Ajax.getElementOrNull('ajax-trace-ar4' ); if (elem) setDirection(elem, 10, 3);
- elem = Ajax.getElementOrNull('ajax-trace-ar6' ); if (elem) setDirection(elem, 11, 0);
- elem = Ajax.getElementOrNull('ajax-trace-arp' ); if (elem) setDirection(elem, 11, 1);
- elem = Ajax.getElementOrNull('ajax-trace-ip4' ); if (elem) setDirection(elem, 11, 2);
- elem = Ajax.getElementOrNull('ajax-trace-ip6' ); if (elem) setDirection(elem, 11, 3);
- elem = Ajax.getElementOrNull('ajax-trace-udp' ); if (elem) setDirection(elem, 12, 0);
- elem = Ajax.getElementOrNull('ajax-trace-tcp' ); if (elem) setDirection(elem, 12, 1);
- elem = Ajax.getElementOrNull('ajax-trace-http' ); if (elem) setDirection(elem, 12, 2);
- elem = Ajax.getElementOrNull('ajax-trace-tftp' ); if (elem) setDirection(elem, 12, 3);
-}
-
-Ajax.server = '/trace-ajax';
-Ajax.onResponse = display;
-Ajax.init();
\ No newline at end of file
--- a/net/web-net-class.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-"//Net class\n"
-"'use strict';\n"
-"\n"
-"class Net\n"
-"{\n"
-" static makeIp4(text)\n"
-" {\n"
-" let result = '';\n"
-" result += parseInt(text.substr(6, 2), 16).toString();\n"
-" result += '.';\n"
-" result += parseInt(text.substr(4, 2), 16).toString();\n"
-" result += '.';\n"
-" result += parseInt(text.substr(2, 2), 16).toString();\n"
-" result += '.';\n"
-" result += parseInt(text.substr(0, 2), 16).toString();\n"
-" return result;\n"
-" }\n"
-" static makeMac(text)\n"
-" {\n"
-" text = text.toLowerCase();\n"
-" let result = '';\n"
-" result += text.substr( 0, 2);\n"
-" result += ':';\n"
-" result += text.substr( 2, 2);\n"
-" result += ':';\n"
-" result += text.substr( 4, 2);\n"
-" result += ':';\n"
-" result += text.substr( 6, 2);\n"
-" result += ':';\n"
-" result += text.substr( 8, 2);\n"
-" result += ':';\n"
-" result += text.substr(10, 2);\n"
-" return result;\n"
-" }\n"
-"\n"
-" static hexToBit(text, iBit)\n"
-" {\n"
-" let value = parseInt(text, 16);\n"
-" value >>= iBit;\n"
-" return value & 1;\n"
-" }\n"
-" static makeIp6(text)\n"
-" {\n"
-" function makeWord(text)\n"
-" {\n"
-" let word = parseInt(text, 16);\n"
-" if (word === 0) return '';\n"
-" return word.toString(16);\n"
-" }\n"
-" text = text.toLowerCase();\n"
-" let result = '';\n"
-" result += makeWord(text.substr( 0, 4));\n"
-" result += ':';\n"
-" result += makeWord(text.substr( 4, 4));\n"
-" result += ':';\n"
-" result += makeWord(text.substr( 8, 4));\n"
-" result += ':';\n"
-" result += makeWord(text.substr(12, 4));\n"
-" result += ':';\n"
-" result += makeWord(text.substr(16, 4));\n"
-" result += ':';\n"
-" result += makeWord(text.substr(20, 4));\n"
-" result += ':';\n"
-" result += makeWord(text.substr(24, 4));\n"
-" result += ':';\n"
-" result += makeWord(text.substr(28, 4));\n"
-" return result;\n"
-" }\n"
-"}"
\ No newline at end of file
--- a/net/web-net-class.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-//Net class
-'use strict';
-
-class Net
-{
- static makeIp4(text)
- {
- let result = '';
- result += parseInt(text.substr(6, 2), 16).toString();
- result += '.';
- result += parseInt(text.substr(4, 2), 16).toString();
- result += '.';
- result += parseInt(text.substr(2, 2), 16).toString();
- result += '.';
- result += parseInt(text.substr(0, 2), 16).toString();
- return result;
- }
- static makeMac(text)
- {
- text = text.toLowerCase();
- let result = '';
- result += text.substr( 0, 2);
- result += ':';
- result += text.substr( 2, 2);
- result += ':';
- result += text.substr( 4, 2);
- result += ':';
- result += text.substr( 6, 2);
- result += ':';
- result += text.substr( 8, 2);
- result += ':';
- result += text.substr(10, 2);
- return result;
- }
-
- static hexToBit(text, iBit)
- {
- let value = parseInt(text, 16);
- value >>= iBit;
- return value & 1;
- }
- static makeIp6(text)
- {
- function makeWord(text)
- {
- let word = parseInt(text, 16);
- if (word === 0) return '';
- return word.toString(16);
- }
- text = text.toLowerCase();
- let result = '';
- result += makeWord(text.substr( 0, 4));
- result += ':';
- result += makeWord(text.substr( 4, 4));
- result += ':';
- result += makeWord(text.substr( 8, 4));
- result += ':';
- result += makeWord(text.substr(12, 4));
- result += ':';
- result += makeWord(text.substr(16, 4));
- result += ':';
- result += makeWord(text.substr(20, 4));
- result += ':';
- result += makeWord(text.substr(24, 4));
- result += ':';
- result += makeWord(text.substr(28, 4));
- return result;
- }
-}
\ No newline at end of file
--- a/net/web-net-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include "http.h"
-#include "web-page-base.h"
-#include "web-add.h"
-#include "mac.h"
-
-void WebNetHtml()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Net", "settings.css", NULL);
- WebAddNav(NET_PAGE);
- WebAddH1("Net");
-
- WebAddH2("Ethernet");
- WebAddLabelledMac ("MAC", MacLocal);
-
- WebAddEnd();
-
-}
--- a/net/web-net4-ajax.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#include <stdio.h>
-
-#include "http.h"
-#include "web-base.h"
-#include "ar4.h"
-#include "nr4.h"
-#include "dhcp.h"
-
-void WebNet4Ajax()
-{
- HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
-
- HttpAddInt32AsHex(DhcpLocalIp); HttpAddChar('\n');
- HttpAddText (DhcpDomainName); HttpAddChar('\n');
- HttpAddText (DhcpHostName); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpNtpIp); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpDnsServerIp); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpServerIp); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpRouterIp); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpSubnetMask); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpBroadcastIp); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpLeaseTime); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpRenewalT1); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpRenewalT2); HttpAddChar('\n');
- HttpAddInt32AsHex(DhcpGetElapsedLife()); HttpAddChar('\n');
- HttpAddChar('\f');
-
- Ar4SendAjax();
- HttpAddChar('\f');
-
- Nr4SendAjax();
-}
--- a/net/web-net4-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include "http.h"
-#include "web-add.h"
-#include "web-page-base.h"
-
-void WebNet4Html()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Net IPv4", "settings.css", "net4.js");
- WebAddNav(NET4_PAGE);
- WebAddH1("Net IPv4");
-
- WebAddH2("ARP");
- HttpAddText("<code id='ajax-arp'></code>\r\n");
- WebAddH2("DNS");
- HttpAddText("<code id='ajax-dns'></code>\r\n");
-
- WebAddH2("DHCP");
- WebAddAjaxLabelled("IP4 address", "ajax-local-ip" );
- WebAddAjaxLabelled("Domain", "ajax-domain-name" );
- WebAddAjaxLabelled("Host name", "ajax-host-name" );
- WebAddAjaxLabelled("NTP server", "ajax-ntp-ip" );
- WebAddAjaxLabelled("DNS server", "ajax-dns-ip" );
- WebAddAjaxLabelled("DHCP server", "ajax-dhcp-ip" );
- WebAddAjaxLabelled("Router", "ajax-router-ip" );
- WebAddAjaxLabelled("Subnet mask", "ajax-subnet-mask" );
- WebAddAjaxLabelled("Broadcast IP", "ajax-broadcast-ip");
- WebAddAjaxLabelled("Lease time IP", "ajax-lease-time" );
- WebAddAjaxLabelled("Renewal T1", "ajax-renewal-t1" );
- WebAddAjaxLabelled("Renewal T2", "ajax-renewal-t2" );
- WebAddAjaxLabelled("Elapsed", "ajax-elapsed" );
-
- WebAddEnd();
-
-}
--- a/net/web-net4-script.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include "http.h"
-
-//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
-//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
-
-const char* WebNet4ScriptDate = __DATE__;
-const char* WebNet4ScriptTime = __TIME__;
-
-static const char* script =
-#include "../base/web-ajax-class.inc"
-#include "web-net-class.inc"
-#include "web-net4-script.inc"
-;
-void WebNet4Script()
-{
- HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebNet4ScriptDate, WebNet4ScriptTime);
- HttpAddText(script);
-}
--- a/net/web-net4-script.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-"//Net4 script\n"
-"'use strict';\n"
-"\n"
-"let localIp = '';\n"
-"let domainName = '';\n"
-"let hostName = '';\n"
-"let ntpIp = '';\n"
-"let dnsIp = '';\n"
-"let dhcpIp = '';\n"
-"let routerIp = '';\n"
-"let subnetMask = '';\n"
-"let broadcastIp = '';\n"
-"let leaseTime = '';\n"
-"let renewalT1 = '';\n"
-"let renewalt2 = '';\n"
-"let elapsed = '';\n"
-"let arp = '';\n"
-"let dns = '';\n"
-"\n"
-"function parseArpLine(line)\n"
-"{\n"
-" if (line.length == 0) return;\n"
-" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
-" arp += Math.floor(minutes).toString().padStart(4, ' ');\n"
-" arp += ' ';\n"
-" arp += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');\n"
-" arp += ' ';\n"
-" arp += Net.makeMac(line.substr(16, 12));\n"
-" arp += '\\r\\n';\n"
-"}\n"
-"function parseDnsLine(line)\n"
-"{\n"
-" if (line.length == 0) return;\n"
-" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
-" dns += Math.floor(minutes).toString().padStart(4, ' ');\n"
-" dns += ' ';\n"
-" dns += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');\n"
-" dns += ' ';\n"
-" dns += line.substr(16, 1);\n"
-" dns += ' ';\n"
-" dns += line.substr(17);\n"
-" dns += '\\r\\n';\n"
-"}\n"
-"function parseArpLines(text)\n"
-"{\n"
-" arp = '';\n"
-" text.split('\\n').forEach(parseArpLine);\n"
-"}\n"
-"function parseDnsLines(text)\n"
-"{\n"
-" dns = '';\n"
-" text.split('\\n').forEach(parseDnsLine);\n"
-"}\n"
-"function parseGenLines(text)\n"
-"{\n"
-" let lines = text.split('\\n');\n"
-" localIp = Net.makeIp4(lines[ 0]) ;\n"
-" domainName = lines[ 1] ;\n"
-" hostName = lines[ 2] ;\n"
-" ntpIp = Net.makeIp4(lines[ 3]) ;\n"
-" dnsIp = Net.makeIp4(lines[ 4]) ;\n"
-" dhcpIp = Net.makeIp4(lines[ 5]) ;\n"
-" routerIp = Net.makeIp4(lines[ 6]) ;\n"
-" subnetMask = Net.makeIp4(lines[ 7]) ;\n"
-" broadcastIp = Net.makeIp4(lines[ 8]) ;\n"
-" leaseTime = parseInt(lines[ 9], 16);\n"
-" renewalT1 = parseInt(lines[10], 16);\n"
-" renewalt2 = parseInt(lines[11], 16);\n"
-" elapsed = parseInt(lines[12], 16);\n"
-"}\n"
-"function parse()\n"
-"{\n"
-" let topics = Ajax.response.split('\\f');\n"
-" parseGenLines(topics[0]);\n"
-" parseArpLines(topics[1]);\n"
-" parseDnsLines(topics[2]);\n"
-"}\n"
-"function display()\n"
-"{\n"
-" let elem;\n"
-"\n"
-" elem = Ajax.getElementOrNull('ajax-local-ip' ); if (elem) elem.textContent = localIp;\n"
-" elem = Ajax.getElementOrNull('ajax-domain-name' ); if (elem) elem.textContent = domainName;\n"
-" elem = Ajax.getElementOrNull('ajax-host-name' ); if (elem) elem.textContent = hostName;\n"
-" elem = Ajax.getElementOrNull('ajax-ntp-ip' ); if (elem) elem.textContent = ntpIp;\n"
-" elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;\n"
-" elem = Ajax.getElementOrNull('ajax-dhcp-ip' ); if (elem) elem.textContent = dhcpIp;\n"
-" elem = Ajax.getElementOrNull('ajax-router-ip' ); if (elem) elem.textContent = routerIp;\n"
-" elem = Ajax.getElementOrNull('ajax-subnet-mask' ); if (elem) elem.textContent = subnetMask;\n"
-" elem = Ajax.getElementOrNull('ajax-broadcast-ip'); if (elem) elem.textContent = broadcastIp;\n"
-" elem = Ajax.getElementOrNull('ajax-lease-time' ); if (elem) elem.textContent = leaseTime;\n"
-" elem = Ajax.getElementOrNull('ajax-renewal-t1' ); if (elem) elem.textContent = renewalT1;\n"
-" elem = Ajax.getElementOrNull('ajax-renewal-t2' ); if (elem) elem.textContent = renewalt2;\n"
-" elem = Ajax.getElementOrNull('ajax-elapsed' ); if (elem) elem.textContent = elapsed;\n"
-" elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;\n"
-" elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;\n"
-"}\n"
-"\n"
-"Ajax.server = '/net4-ajax';\n"
-"Ajax.onResponse = function() { parse(); display(); };\n"
-"Ajax.init();\n"
-""
\ No newline at end of file
--- a/net/web-net4-script.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-//Net4 script
-'use strict';
-
-let localIp = '';
-let domainName = '';
-let hostName = '';
-let ntpIp = '';
-let dnsIp = '';
-let dhcpIp = '';
-let routerIp = '';
-let subnetMask = '';
-let broadcastIp = '';
-let leaseTime = '';
-let renewalT1 = '';
-let renewalt2 = '';
-let elapsed = '';
-let arp = '';
-let dns = '';
-
-function parseArpLine(line)
-{
- if (line.length == 0) return;
- let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
- arp += Math.floor(minutes).toString().padStart(4, ' ');
- arp += ' ';
- arp += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');
- arp += ' ';
- arp += Net.makeMac(line.substr(16, 12));
- arp += '\r\n';
-}
-function parseDnsLine(line)
-{
- if (line.length == 0) return;
- let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
- dns += Math.floor(minutes).toString().padStart(4, ' ');
- dns += ' ';
- dns += Net.makeIp4(line.substr(8, 8)).padEnd(15, ' ');
- dns += ' ';
- dns += line.substr(16, 1);
- dns += ' ';
- dns += line.substr(17);
- dns += '\r\n';
-}
-function parseArpLines(text)
-{
- arp = '';
- text.split('\n').forEach(parseArpLine);
-}
-function parseDnsLines(text)
-{
- dns = '';
- text.split('\n').forEach(parseDnsLine);
-}
-function parseGenLines(text)
-{
- let lines = text.split('\n');
- localIp = Net.makeIp4(lines[ 0]) ;
- domainName = lines[ 1] ;
- hostName = lines[ 2] ;
- ntpIp = Net.makeIp4(lines[ 3]) ;
- dnsIp = Net.makeIp4(lines[ 4]) ;
- dhcpIp = Net.makeIp4(lines[ 5]) ;
- routerIp = Net.makeIp4(lines[ 6]) ;
- subnetMask = Net.makeIp4(lines[ 7]) ;
- broadcastIp = Net.makeIp4(lines[ 8]) ;
- leaseTime = parseInt(lines[ 9], 16);
- renewalT1 = parseInt(lines[10], 16);
- renewalt2 = parseInt(lines[11], 16);
- elapsed = parseInt(lines[12], 16);
-}
-function parse()
-{
- let topics = Ajax.response.split('\f');
- parseGenLines(topics[0]);
- parseArpLines(topics[1]);
- parseDnsLines(topics[2]);
-}
-function display()
-{
- let elem;
-
- elem = Ajax.getElementOrNull('ajax-local-ip' ); if (elem) elem.textContent = localIp;
- elem = Ajax.getElementOrNull('ajax-domain-name' ); if (elem) elem.textContent = domainName;
- elem = Ajax.getElementOrNull('ajax-host-name' ); if (elem) elem.textContent = hostName;
- elem = Ajax.getElementOrNull('ajax-ntp-ip' ); if (elem) elem.textContent = ntpIp;
- elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;
- elem = Ajax.getElementOrNull('ajax-dhcp-ip' ); if (elem) elem.textContent = dhcpIp;
- elem = Ajax.getElementOrNull('ajax-router-ip' ); if (elem) elem.textContent = routerIp;
- elem = Ajax.getElementOrNull('ajax-subnet-mask' ); if (elem) elem.textContent = subnetMask;
- elem = Ajax.getElementOrNull('ajax-broadcast-ip'); if (elem) elem.textContent = broadcastIp;
- elem = Ajax.getElementOrNull('ajax-lease-time' ); if (elem) elem.textContent = leaseTime;
- elem = Ajax.getElementOrNull('ajax-renewal-t1' ); if (elem) elem.textContent = renewalT1;
- elem = Ajax.getElementOrNull('ajax-renewal-t2' ); if (elem) elem.textContent = renewalt2;
- elem = Ajax.getElementOrNull('ajax-elapsed' ); if (elem) elem.textContent = elapsed;
- elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;
- elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;
-}
-
-Ajax.server = '/net4-ajax';
-Ajax.onResponse = function() { parse(); display(); };
-Ajax.init();
--- a/net/web-net6-ajax.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#include <stdio.h>
-
-#include "http.h"
-#include "web-base.h"
-#include "ndp.h"
-#include "slaac.h"
-#include "ar6.h"
-#include "nr6.h"
-
-void WebNet6Ajax()
-{
- HttpOk("text/plain; charset=UTF-8", "no-cache", NULL, NULL);
-
- char nibble;
- nibble = 0;
- if (NdpManagedConfiguration) nibble |= 1; //4
- if (NdpOtherConfiguration ) nibble |= 2; //4
- if (NdpPrefixFlagL ) nibble |= 4; //4
- if (NdpPrefixFlagA ) nibble |= 8; //4
- HttpAddNibbleAsHex(nibble); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpHopLimit); HttpAddChar('\n');
- for (char* p = NdpRouterMac; p < NdpRouterMac + 6; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpPrefixLength); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpPrefixValidLifetime); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpPrefixPreferredLifetime); HttpAddChar('\n');
- for (char* p = NdpPrefix; p < NdpPrefix + 16; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpDnsLifetime); HttpAddChar('\n');
- for (char* p = NdpDnsServer; p < NdpDnsServer + 16; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpGetLease()); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpGetElapsedLife()); HttpAddChar('\n');
- for (char* p = SlaacLinkLocalIp; p < SlaacLinkLocalIp + 16; p++) HttpAddByteAsHex(*p); HttpAddChar('\n');
- HttpAddInt32AsHex(NdpMtu); HttpAddChar('\n');
- HttpAddChar('\f');
-
- Ar6SendAjax();
- HttpAddChar('\f');
-
- Nr6SendAjax();
-}
--- a/net/web-net6-html.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#include "http.h"
-#include "web-page-base.h"
-#include "web-add.h"
-
-void WebNet6Html()
-{
- HttpOk("text/html; charset=UTF-8", "no-cache", NULL, NULL);
- WebAddHeader("Net IPv6", "settings.css", "net6.js");
- WebAddNav(NET6_PAGE);
- WebAddH1("Net IPv6");
-
- WebAddH2("ARP");
- HttpAddText("<code id='ajax-arp'></code>\r\n");
- WebAddH2("DNS");
- HttpAddText("<code id='ajax-dns'></code>\r\n");
-
- WebAddH2("NDP");
- WebAddAjaxLabelled("Hop limit", "ajax-hop-limit");
- WebAddAjaxLed ("Managed address", "ajax-managed");
- WebAddAjaxLed ("Other configuration", "ajax-other");
- WebAddAjaxLabelled("Router MAC", "ajax-router-mac");
- WebAddAjaxLabelled("Prefix length", "ajax-prefix-length");
- WebAddAjaxLed ("Prefix flag L", "ajax-prefix-l");
- WebAddAjaxLed ("Prefix flag A", "ajax-prefix-a");
- WebAddAjaxLabelled("Prefix valid secs", "ajax-prefix-limit");
- WebAddAjaxLabelled("Prefix preferred secs", "ajax-prefix-preferred");
- WebAddAjaxLabelled("Prefix", "ajax-prefix");
- WebAddAjaxLabelled("DNS life secs", "ajax-dns-life");
- WebAddAjaxLabelled("DNS server", "ajax-dns-ip");
- WebAddAjaxLabelled("Lease time", "ajax-ndp-lease");
- WebAddAjaxLabelled("Elapsed", "ajax-ndp-elapsed");
- WebAddAjaxLabelled("SLAAC", "ajax-slaac");
- WebAddAjaxLabelled("MTU", "ajax-mtu");
-
- WebAddEnd();
-
-}
--- a/net/web-net6-script.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include "http.h"
-
-//Use http://tomeko.net/online_tools/cpp_text_escape.php to convert from text to c-multiline
-//Use http://tomeko.net/online_tools/cpp_text_unescape.php to convert from c-multiline to text
-
-const char* WebNet6ScriptDate = __DATE__;
-const char* WebNet6ScriptTime = __TIME__;
-
-static const char* script =
-#include "../base/web-ajax-class.inc"
-#include "web-net-class.inc"
-#include "web-net6-script.inc"
-;
-void WebNet6Script()
-{
- HttpOk("application/javascript; charset=UTF-8", "max-age=3600", WebNet6ScriptDate, WebNet6ScriptTime);
- HttpAddText(script);
-}
--- a/net/web-net6-script.inc Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-"//Net6 script\n"
-"'use strict';\n"
-"\n"
-"let arp = '';\n"
-"let dns = '';\n"
-"let hopLimit = '';\n"
-"let managed = false;\n"
-"let other = false;\n"
-"let routerMac = '';\n"
-"let prefixLength = '';\n"
-"let prefixL = false;\n"
-"let prefixA = false;\n"
-"let prefixLimit = '';\n"
-"let prefixPreferred = '';\n"
-"let prefix = '';\n"
-"let dnsLife = '';\n"
-"let dnsIp = '';\n"
-"let ndpLease = '';\n"
-"let ndpElapsed = '';\n"
-"let slaac = '';\n"
-"let mtu = '';\n"
-"\n"
-"function parseArpLine(line)\n"
-"{\n"
-" if (line.length == 0) return;\n"
-" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
-" arp += Math.floor(minutes).toString().padStart(4, ' ');\n"
-" arp += ' ';\n"
-" arp += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');\n"
-" arp += ' ';\n"
-" arp += Net.makeMac(line.substr(40, 12));\n"
-" arp += '\\r\\n';\n"
-"}\n"
-"function parseDnsLine(line)\n"
-"{\n"
-" if (line.length == 0) return;\n"
-" let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;\n"
-" dns += Math.floor(minutes).toString().padStart(4, ' ');\n"
-" dns += ' ';\n"
-" dns += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');\n"
-" dns += ' ';\n"
-" dns += line.substr(40, 1);\n"
-" dns += ' ';\n"
-" dns += line.substr(41);\n"
-" dns += '\\r\\n';\n"
-"}\n"
-"function parseArpLines(text)\n"
-"{\n"
-" arp = '';\n"
-" text.split('\\n').forEach(parseArpLine);\n"
-"}\n"
-"function parseDnsLines(text)\n"
-"{\n"
-" dns = '';\n"
-" text.split('\\n').forEach(parseDnsLine);\n"
-"}\n"
-"function parseGenLines(text)\n"
-"{\n"
-" let lines = text.split('\\n');\n"
-" \n"
-" hopLimit = parseInt(lines[ 1], 16);\n"
-" managed = Net.hexToBit(lines[ 0], 0);\n"
-" other = Net.hexToBit(lines[ 0], 1);\n"
-" routerMac = Net.makeMac (lines[ 2], 16);\n"
-" prefixLength = parseInt(lines[ 3], 16);\n"
-" prefixL = Net.hexToBit(lines[ 0], 2);\n"
-" prefixA = Net.hexToBit(lines[ 0], 3);\n"
-" prefixLimit = parseInt(lines[ 4], 16);\n"
-" prefixPreferred = parseInt(lines[ 5], 16);\n"
-" prefix = Net.makeIp6 (lines[ 6] );\n"
-" dnsLife = parseInt(lines[ 7], 16);\n"
-" dnsIp = Net.makeIp6 (lines[ 8] );\n"
-" ndpLease = parseInt(lines[ 9], 16);\n"
-" ndpElapsed = parseInt(lines[10], 16);\n"
-" slaac = Net.makeIp6 (lines[11] );\n"
-" mtu = parseInt(lines[12], 16);\n"
-"}\n"
-"function parse()\n"
-"{\n"
-" let topics = Ajax.response.split('\\f');\n"
-" parseGenLines(topics[0]);\n"
-" parseArpLines(topics[1]);\n"
-" parseDnsLines(topics[2]);\n"
-"}\n"
-"function display()\n"
-"{\n"
-" let elem;\n"
-" \n"
-" elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;\n"
-" elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;\n"
-" elem = Ajax.getElementOrNull('ajax-hop-limit' ); if (elem) elem.textContent = hopLimit;\n"
-" elem = Ajax.getElementOrNull('ajax-managed' ); if (elem) elem.setAttribute('dir', managed ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-other' ); if (elem) elem.setAttribute('dir', other ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-router-mac' ); if (elem) elem.textContent = routerMac;\n"
-" elem = Ajax.getElementOrNull('ajax-prefix-length' ); if (elem) elem.textContent = prefixLength;\n"
-" elem = Ajax.getElementOrNull('ajax-prefix-l' ); if (elem) elem.setAttribute('dir', prefixL ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-prefix-a' ); if (elem) elem.setAttribute('dir', prefixA ? 'rtl' : 'ltr');\n"
-" elem = Ajax.getElementOrNull('ajax-prefix-limit' ); if (elem) elem.textContent = prefixLimit;\n"
-" elem = Ajax.getElementOrNull('ajax-prefix-preferred'); if (elem) elem.textContent = prefixPreferred;\n"
-" elem = Ajax.getElementOrNull('ajax-prefix' ); if (elem) elem.textContent = prefix;\n"
-" elem = Ajax.getElementOrNull('ajax-dns-life' ); if (elem) elem.textContent = dnsLife;\n"
-" elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;\n"
-" elem = Ajax.getElementOrNull('ajax-ndp-lease' ); if (elem) elem.textContent = ndpLease;\n"
-" elem = Ajax.getElementOrNull('ajax-ndp-elapsed' ); if (elem) elem.textContent = ndpElapsed;\n"
-" elem = Ajax.getElementOrNull('ajax-slaac' ); if (elem) elem.textContent = slaac;\n"
-" elem = Ajax.getElementOrNull('ajax-mtu' ); if (elem) elem.textContent = mtu;\n"
-"}\n"
-"\n"
-"Ajax.server = '/net6-ajax';\n"
-"Ajax.onResponse = function() { parse(); display(); };\n"
-"Ajax.init();"
\ No newline at end of file
--- a/net/web-net6-script.js Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-//Net6 script
-'use strict';
-
-let arp = '';
-let dns = '';
-let hopLimit = '';
-let managed = false;
-let other = false;
-let routerMac = '';
-let prefixLength = '';
-let prefixL = false;
-let prefixA = false;
-let prefixLimit = '';
-let prefixPreferred = '';
-let prefix = '';
-let dnsLife = '';
-let dnsIp = '';
-let ndpLease = '';
-let ndpElapsed = '';
-let slaac = '';
-let mtu = '';
-
-function parseArpLine(line)
-{
- if (line.length == 0) return;
- let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
- arp += Math.floor(minutes).toString().padStart(4, ' ');
- arp += ' ';
- arp += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');
- arp += ' ';
- arp += Net.makeMac(line.substr(40, 12));
- arp += '\r\n';
-}
-function parseDnsLine(line)
-{
- if (line.length == 0) return;
- let minutes = parseInt(line.substr(0, 8), 16) / 1000 / 60;
- dns += Math.floor(minutes).toString().padStart(4, ' ');
- dns += ' ';
- dns += Net.makeIp6(line.substr(8, 32)).padEnd(40, ' ');
- dns += ' ';
- dns += line.substr(40, 1);
- dns += ' ';
- dns += line.substr(41);
- dns += '\r\n';
-}
-function parseArpLines(text)
-{
- arp = '';
- text.split('\n').forEach(parseArpLine);
-}
-function parseDnsLines(text)
-{
- dns = '';
- text.split('\n').forEach(parseDnsLine);
-}
-function parseGenLines(text)
-{
- let lines = text.split('\n');
-
- hopLimit = parseInt(lines[ 1], 16);
- managed = Net.hexToBit(lines[ 0], 0);
- other = Net.hexToBit(lines[ 0], 1);
- routerMac = Net.makeMac (lines[ 2], 16);
- prefixLength = parseInt(lines[ 3], 16);
- prefixL = Net.hexToBit(lines[ 0], 2);
- prefixA = Net.hexToBit(lines[ 0], 3);
- prefixLimit = parseInt(lines[ 4], 16);
- prefixPreferred = parseInt(lines[ 5], 16);
- prefix = Net.makeIp6 (lines[ 6] );
- dnsLife = parseInt(lines[ 7], 16);
- dnsIp = Net.makeIp6 (lines[ 8] );
- ndpLease = parseInt(lines[ 9], 16);
- ndpElapsed = parseInt(lines[10], 16);
- slaac = Net.makeIp6 (lines[11] );
- mtu = parseInt(lines[12], 16);
-}
-function parse()
-{
- let topics = Ajax.response.split('\f');
- parseGenLines(topics[0]);
- parseArpLines(topics[1]);
- parseDnsLines(topics[2]);
-}
-function display()
-{
- let elem;
-
- elem = Ajax.getElementOrNull('ajax-arp' ); if (elem) elem.textContent = arp;
- elem = Ajax.getElementOrNull('ajax-dns' ); if (elem) elem.textContent = dns;
- elem = Ajax.getElementOrNull('ajax-hop-limit' ); if (elem) elem.textContent = hopLimit;
- elem = Ajax.getElementOrNull('ajax-managed' ); if (elem) elem.setAttribute('dir', managed ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-other' ); if (elem) elem.setAttribute('dir', other ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-router-mac' ); if (elem) elem.textContent = routerMac;
- elem = Ajax.getElementOrNull('ajax-prefix-length' ); if (elem) elem.textContent = prefixLength;
- elem = Ajax.getElementOrNull('ajax-prefix-l' ); if (elem) elem.setAttribute('dir', prefixL ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-prefix-a' ); if (elem) elem.setAttribute('dir', prefixA ? 'rtl' : 'ltr');
- elem = Ajax.getElementOrNull('ajax-prefix-limit' ); if (elem) elem.textContent = prefixLimit;
- elem = Ajax.getElementOrNull('ajax-prefix-preferred'); if (elem) elem.textContent = prefixPreferred;
- elem = Ajax.getElementOrNull('ajax-prefix' ); if (elem) elem.textContent = prefix;
- elem = Ajax.getElementOrNull('ajax-dns-life' ); if (elem) elem.textContent = dnsLife;
- elem = Ajax.getElementOrNull('ajax-dns-ip' ); if (elem) elem.textContent = dnsIp;
- elem = Ajax.getElementOrNull('ajax-ndp-lease' ); if (elem) elem.textContent = ndpLease;
- elem = Ajax.getElementOrNull('ajax-ndp-elapsed' ); if (elem) elem.textContent = ndpElapsed;
- elem = Ajax.getElementOrNull('ajax-slaac' ); if (elem) elem.textContent = slaac;
- elem = Ajax.getElementOrNull('ajax-mtu' ); if (elem) elem.textContent = mtu;
-}
-
-Ajax.server = '/net6-ajax';
-Ajax.onResponse = function() { parse(); display(); };
-Ajax.init();
\ No newline at end of file
--- a/page/web-nav-base.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#include "web-add.h"
-#include "web-page-base.h"
-
-void WebNavBase(int page)
-{
- WebAddNavItem(page == CLOCK_PAGE, "/clock", "Clock" );
- WebAddNavItem(page == FAULT_PAGE, "/fault", "Fault" );
- WebAddNavItem(page == NET_PAGE, "/net", "Net" );
- WebAddNavItem(page == NET4_PAGE, "/net4", "Net IPv4" );
- WebAddNavItem(page == NET6_PAGE, "/net6", "Net IPv6" );
- WebAddNavItem(page == TRACE_PAGE, "/trace", "Net Trace");
- WebAddNavItem(page == LOG_PAGE, "/log", "Log" );
- WebAddNavItem(page == FIRMWARE_PAGE, "/firmware", "Firmware" );
-}
\ No newline at end of file
--- a/page/web-nav-base.h Mon Apr 29 14:45:30 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -extern void WebNavBase(int page); \ No newline at end of file
--- a/page/web-page-base.h Mon Apr 29 14:45:30 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#define FAULT_PAGE 0 -#define CLOCK_PAGE 1 -#define NET_PAGE 2 -#define NET4_PAGE 3 -#define NET6_PAGE 4 -#define TRACE_PAGE 5 -#define LOG_PAGE 6 -#define FIRMWARE_PAGE 7 -
--- a/web-add.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-#include <stdio.h>
-
-#include "http.h"
-#include "web-nav-base.h"
-#include "web-nav-derived.h"
-#include "web-site-name.h"
-#include "mac.h"
-#include "ip4addr.h"
-#include "ip6addr.h"
-
-void WebAddNavItem(int highlight, char* href, char* title)
-{
- char *p;
- HttpAddText("<li ");
- if (highlight) p = "class='this'";
- else p = " ";
- HttpAddText(p);
- HttpAddText("><a href='");
- HttpAddText(href);
- HttpAddText("'>");
- HttpAddText(title);
- HttpAddText("</a></li>\r\n");
-}
-void WebAddNav(int page)
-{
- HttpAddText("<a class='tab-shortcut' href='#main-content'>Skip to content</a>\r\n");
-
- HttpAddText("<nav><ul>\r\n");
- WebNavDerived(page);
- WebNavBase(page);
- HttpAddText("</ul></nav>\r\n");
-}
-
-void WebAddHeader(const char* title, const char* style, const char* script)
-{
- HttpAddText("<!DOCTYPE html>\r\n"
- "<html>\r\n"
- "<head>\r\n");
- HttpAddText(" <title>");
- HttpAddText(WEB_SITE_NAME);
- if (title)
- {
- HttpAddText(" - ");
- HttpAddText(title);
- }
- HttpAddText("</title>\r\n");
-
- HttpAddText(" <link rel='stylesheet' href='/base.css' type='text/css'/>\r\n");
- if (style)
- {
- HttpAddText(" <link rel='stylesheet' href='/");
- HttpAddText(style);
- HttpAddText("' type='text/css'/>\r\n");
- }
- if (script)
- {
- HttpAddText(" <script src='/");
- HttpAddText(script);
- HttpAddText("' type='text/javascript'></script>\r\n");
- }
- HttpAddText(" <meta name='viewport' content='width=device-width, initial-scale=1'>\r\n"
- " <link rel='icon' href='/favicon.ico' type='image/x-icon'/>\r\n"
- "</head>\r\n"
- "<body>\r\n");
-
-}
-void WebAddH1(const char* pageName)
-{
- HttpAddText("<h1 id='main-content'>");
- HttpAddText(WEB_SITE_NAME);
- HttpAddText(" - ");
- HttpAddText(pageName);
- HttpAddText("</h1>\r\n");
-}
-void WebAddH2(const char* text)
-{
- HttpAddText("<h2>");
- HttpAddText(text);
- HttpAddText("</h2>\r\n");
-}
-void WebAddEnd()
-{
- HttpAddText("</body>\r\n"
- "</html>\r\n");
-}
-
-void WebAddLabelledPrefixSuffix(char* label, char* prefix, char* text, char* suffix)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <div>%s%s%s</div>\r\n", prefix, text, suffix);
- HttpAddText("</div>\r\n");
-}
-void WebAddLabelledText(char* label, char* text)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <div>%s</div>\r\n", text);
- HttpAddText("</div>\r\n");
-}
-
-void WebAddLabelledMac(char* label, char* mac)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddText(" <div>"); MacHttp(mac); HttpAddText("</div>\r\n");
- HttpAddText("</div>\r\n");
-}
-
-void WebAddLabelledIp4(char* label, uint32_t ip)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddText(" <div>"); Ip4AddressHttp(ip); HttpAddText("</div>\r\n");
- HttpAddText("</div>\r\n");
-}
-
-void WebAddLabelledIp6(char* label, char* ip)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddText(" <div>"); Ip6AddressHttp(ip); HttpAddText("</div>\r\n");
- HttpAddText("</div>\r\n");
-}
-void WebAddLabelledOnOff(char* label, bool value)
-{
- if (value) WebAddLabelledText(label, "On");
- else WebAddLabelledText(label, "Off");
-}
-void WebAddLabelledInt(char* label, int value)
-{
- char text[30];
- snprintf(text, sizeof(text), "%8d", value); //Right align with enough spaces so that the length is always constant.
- WebAddLabelledText(label, text);
-}
-void WebAddInputText(char* label, float inputwidth, char* value, char* action, char* name)
-{
- HttpAddF ("<form action='%s' method='get'>\r\n", action);
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <input type='text' name='%s' style='width:%.1fem;' value='%s'>\r\n", name, inputwidth, value);
- HttpAddText("</div>\r\n");
- HttpAddText("<input type='submit' value='Set' style='display:none;'>\r\n");
- HttpAddF ("</form>\r\n");
-
-}
-void WebAddInputInt(char* label, float inputwidth, int value, char* action, char* name)
-{
- char text[30];
- snprintf(text, sizeof(text), "%d", value);
- WebAddInputText(label, inputwidth, text, action, name);
-}
-void WebAddInputButton(char* label, char* value, char* action, char* name)
-{
- HttpAddF ("<form action='%s' method='get'>\r\n", action);
- HttpAddF ("<input type='hidden' name='%s'>\r\n", name);
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <input type='submit' value='%s'>\r\n", value);
- HttpAddText("</div>\r\n");
- HttpAddText("</form>\r\n");
-}
-void WebAddAjaxInputToggle(char* label, char* id, char* name)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <div class='toggle' id='%s' tabindex='0' dir='ltr' onclick='AjaxRequest(\"%s=1\")' onkeydown='return event.keyCode != 13 || AjaxRequest(\"%s=1\")'>\r\n", id, name, name);
- HttpAddText(" <div class='slot'></div><div class='knob'></div>\r\n");
- HttpAddText(" </div>\r\n");
- HttpAddText("</div>\r\n");
-}
-void WebAddAjaxLed(char* label, char* id)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <div class='led' id='%s' dir='ltr'></div>\r\n", id);
- HttpAddText("</div>\r\n");
-}
-void WebAddAjaxInput(char* label, float inputwidth, char* id, char* name)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>\r\n", inputwidth, id, name);
- HttpAddText("</div>\r\n");
-}
-void WebAddAjaxInputSuffix(char* label, float inputwidth, char* id, char* name, char* suffix)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>%s\r\n", inputwidth, id, name, suffix);
- HttpAddText("</div>\r\n");
-}
-void WebAddAjaxLabelled(char* label, char* id)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <div id='%s'></div>\r\n", id);
- HttpAddText("</div>\r\n");
-}
-void WebAddAjaxLabelledSuffix(char* label, char* id, char* suffix)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div>%s</div>\r\n", label);
- HttpAddF (" <div><span id='%s'></span>%s</div>\r\n", id, suffix);
- HttpAddText("</div>\r\n");
-}
-void WebAddAjaxInputLabelId(char* labelId, float inputwidth, char* id, char* name)
-{
- HttpAddText("<div class='line'>\r\n");
- HttpAddF (" <div id='%s'></div>\r\n", labelId);
- HttpAddF (" <input type='text' style='width:%.1fem;' id='%s' onchange='AjaxRequest(\"%s=\" + this.value)'>\r\n", inputwidth, id, name);
- HttpAddText("</div>\r\n");
-}
-
-
--- a/web-add.h Mon Apr 29 14:45:30 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#include <stdint.h> -#include <stdbool.h> - -extern void WebAddNavItem (int highlight, char* href, char* title); -extern void WebAddNav (int page); -extern void WebAddHeader (const char* title, const char* style, const char* script); -extern void WebAddH1 (const char* pageName); -extern void WebAddH2 (const char* text); -extern void WebAddEnd (void); - -extern void WebAddLabelledText (char* label, char* text); -extern void WebAddLabelledPrefixSuffix(char* label, char* prefix, char* text, char* suffix); -extern void WebAddLabelledMac (char* label, char* mac); -extern void WebAddLabelledIp4 (char* label, uint32_t ip); -extern void WebAddLabelledIp6 (char* label, char* ip); -extern void WebAddLabelledOnOff (char* label, bool value); -extern void WebAddLabelledInt (char* label, int value); - -extern void WebAddInputText (char* label, float inputwidth, char* value, char* action, char* name); -extern void WebAddInputInt (char* label, float inputwidth, int value, char* action, char* name); -extern void WebAddInputButton (char* label, char* value, char* action, char* name); - -extern void WebAddAjaxLed (char* label, char* id); -extern void WebAddAjaxLabelled (char* label, char* id); -extern void WebAddAjaxLabelledSuffix (char* label, char* id, char* suffix); -extern void WebAddAjaxInputToggle (char* label, char* id, char* name); -extern void WebAddAjaxInput (char* label, float inputwidth, char* id, char* name); -extern void WebAddAjaxInputSuffix (char* label, float inputwidth, char* id, char* name, char* suffix); -extern void WebAddAjaxInputLabelId (char* labelId, float inputwidth, char* id, char* name);
--- a/web-base.h Mon Apr 29 14:45:30 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -#include <stdint.h> -#include <stdbool.h> - -#include "web-derived.h" - -extern void WebLoginHtml (void); -extern void WebLoginQuery (char* pQuery); -extern bool WebLoginQueryPasswordOk; -extern int WebLoginOriginalToDo; -extern bool WebLoginCookiesContainValidSessionId(char* pCookies); -extern char* WebLoginSessionNameGet(void); -extern int WebLoginSessionNameLife(void); -extern char* WebLoginSessionIdGet(void); -extern void WebLoginSessionIdNew(void); -extern bool WebLoginSessionIdIsSet(void); -extern void WebLoginInit(void); - -extern void WebFavicon (void); -extern const char* WebFaviconDate; -extern const char* WebFaviconTime; -extern const int WebFaviconSize; - -extern void WebBaseCss (void); -extern const char* WebBaseCssDate; -extern const char* WebBaseCssTime; -extern void WebNavCss (void); -extern const char* WebNavCssDate; -extern const char* WebNavCssTime; - -extern void WebTraceHtml (void); -extern void WebTraceScript (void); -extern const char* WebTraceScriptDate; -extern const char* WebTraceScriptTime; -extern void WebTraceAjax (void); -extern void WebTraceQuery (char* pQuery); - -extern void WebClockHtml (void); -extern void WebClockScript (void); -extern const char* WebClockScriptDate; -extern const char* WebClockScriptTime; -extern void WebClockAjax (void); -extern void WebClockQuery (char* pQuery); - -extern void WebLogHtml (void); -extern void WebLogQuery (char* pQuery); - -extern void WebNetHtml (void); -extern void WebNet4Html (void); -extern void WebNet4Script (void); -extern const char* WebNet4ScriptDate; -extern const char* WebNet4ScriptTime; -extern void WebNet4Ajax (void); -extern void WebNet6Html (void); -extern void WebNet6Script (void); -extern const char* WebNet6ScriptDate; -extern const char* WebNet6ScriptTime; -extern void WebNet6Ajax (void); - -extern void WebFaultHtml (void); -extern void WebFaultQuery (char* pQuery); - -extern void WebFirmwareHtml (void); -extern void WebFirmwareScript(void); -extern const char* WebFirmwareScriptDate; -extern const char* WebFirmwareScriptTime; -extern void WebFirmwareQuery (char* pQuery); -extern int WebFirmwareTargetLength; -extern int WebFirmwareActualLength; -extern char* WebFirmwareFileName; -extern bool WebFirmwarePost (int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream); -extern void WebFirmwareAjax (void);
--- a/web-server-base.c Mon Apr 29 14:45:30 2019 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-#include "web-base.h"
-#include "web-server-derived.h"
-#include "web-server-base.h"
-#include "http.h"
-#include "fault.h"
-#include "led.h"
-
-#define DO_FAVICON DO_BASE + 0
-#define DO_BASE_CSS DO_BASE + 1
-#define DO_NAV_CSS DO_BASE + 2
-#define DO_TRACE_HTML DO_BASE + 3
-#define DO_TRACE_AJAX DO_BASE + 4
-#define DO_TRACE_SCRIPT DO_BASE + 5
-#define DO_CLOCK_HTML DO_BASE + 6
-#define DO_CLOCK_AJAX DO_BASE + 7
-#define DO_CLOCK_SCRIPT DO_BASE + 8
-#define DO_NET_HTML DO_BASE + 9
-#define DO_NET4_HTML DO_BASE + 10
-#define DO_NET4_AJAX DO_BASE + 11
-#define DO_NET4_SCRIPT DO_BASE + 12
-#define DO_NET6_HTML DO_BASE + 13
-#define DO_NET6_AJAX DO_BASE + 14
-#define DO_NET6_SCRIPT DO_BASE + 15
-#define DO_LOG_HTML DO_BASE + 16
-#define DO_FAULT_HTML DO_BASE + 17
-#define DO_FIRMWARE_HTML DO_BASE + 18
-#define DO_FIRMWARE_AJAX DO_BASE + 19
-#define DO_FIRMWARE_SCRIPT DO_BASE + 20
-
-int WebServerBaseDecideWhatToDo(char *pPath, char* pLastModified)
-{
- if (HttpSameStr(pPath, "/login" )) return DO_LOGIN;
- if (HttpSameStr(pPath, "/clock" )) return DO_CLOCK_HTML;
- if (HttpSameStr(pPath, "/clock-ajax" )) return DO_CLOCK_AJAX;
- if (HttpSameStr(pPath, "/net" )) return DO_NET_HTML;
- if (HttpSameStr(pPath, "/net4" )) return DO_NET4_HTML;
- if (HttpSameStr(pPath, "/net4-ajax" )) return DO_NET4_AJAX;
- if (HttpSameStr(pPath, "/net6" )) return DO_NET6_HTML;
- if (HttpSameStr(pPath, "/net6-ajax" )) return DO_NET6_AJAX;
- if (HttpSameStr(pPath, "/log" )) return DO_LOG_HTML;
- if (HttpSameStr(pPath, "/trace" )) return DO_TRACE_HTML;
- if (HttpSameStr(pPath, "/trace-ajax" )) return DO_TRACE_AJAX;
- if (HttpSameStr(pPath, "/fault" )) return DO_FAULT_HTML;
- if (HttpSameStr(pPath, "/firmware" )) return DO_FIRMWARE_HTML;
- if (HttpSameStr(pPath, "/firmware-ajax")) return DO_FIRMWARE_AJAX;
-
- if (HttpSameStr(pPath, "/favicon.ico" )) return HttpSameDate(WebFaviconDate, WebFaviconTime, pLastModified) ? DO_NOT_MODIFIED : DO_FAVICON;
- if (HttpSameStr(pPath, "/base.css" )) return HttpSameDate(WebBaseCssDate, WebBaseCssTime, pLastModified) ? DO_NOT_MODIFIED : DO_BASE_CSS;
- if (HttpSameStr(pPath, "/settings.css" )) return HttpSameDate(WebNavCssDate, WebNavCssTime, pLastModified) ? DO_NOT_MODIFIED : DO_NAV_CSS;
- if (HttpSameStr(pPath, "/net4.js" )) return HttpSameDate(WebNet4ScriptDate, WebNet4ScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_NET4_SCRIPT;
- if (HttpSameStr(pPath, "/net6.js" )) return HttpSameDate(WebNet6ScriptDate, WebNet6ScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_NET6_SCRIPT;
- if (HttpSameStr(pPath, "/trace.js" )) return HttpSameDate(WebTraceScriptDate, WebTraceScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_TRACE_SCRIPT;
- if (HttpSameStr(pPath, "/clock.js" )) return HttpSameDate(WebClockScriptDate, WebClockScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_CLOCK_SCRIPT;
- if (HttpSameStr(pPath, "/firmware.js" )) return HttpSameDate(WebFirmwareScriptDate, WebFirmwareScriptTime, pLastModified) ? DO_NOT_MODIFIED : DO_FIRMWARE_SCRIPT;
-
- return WebServerDerivedRequest(pPath, pLastModified);
-}
-void WebServerBaseHandleQuery(int todo, char* pQuery)
-{
- switch (todo)
- {
- case DO_LOGIN: WebLoginQuery (pQuery); return;
- case DO_TRACE_AJAX: WebTraceQuery (pQuery); return;
- case DO_CLOCK_AJAX: WebClockQuery (pQuery); return;
- case DO_CLOCK_HTML: WebClockQuery (pQuery); return;
- case DO_LOG_HTML: WebLogQuery (pQuery); return;
- case DO_FAULT_HTML: WebFaultQuery (pQuery); return;
- case DO_FIRMWARE_HTML: WebFirmwareQuery(pQuery); return;
- case DO_FIRMWARE_AJAX: WebFirmwareQuery(pQuery); return;
- }
- WebServerDerivedGet(todo, pQuery);
-}
-bool WebServerBaseHandlePost(int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream)
-{
- switch (todo)
- {
- case DO_FIRMWARE_AJAX: return WebFirmwarePost(contentLength, contentStart, size, pRequestStream, positionInRequestStream);
- }
- return WebServerDerivedPost(todo, contentLength, size, pRequestStream, positionInRequestStream);
-}
-
-void WebServerBaseReply(int todo)
-{
- //Try all the base modules
- switch (todo)
- {
- case DO_NOT_FOUND: HttpNotFound (); return;
- case DO_NOT_MODIFIED: HttpNotModified (); return;
- case DO_LOGIN: WebLoginHtml (); return;
- case DO_FAVICON: WebFavicon (); return;
- case DO_BASE_CSS: WebBaseCss (); return;
- case DO_NAV_CSS: WebNavCss (); return;
- case DO_TRACE_HTML: WebTraceHtml (); return;
- case DO_TRACE_AJAX: WebTraceAjax (); return;
- case DO_TRACE_SCRIPT: WebTraceScript (); return;
- case DO_CLOCK_HTML: WebClockHtml (); return;
- case DO_CLOCK_AJAX: WebClockAjax (); return;
- case DO_CLOCK_SCRIPT: WebClockScript (); return;
- case DO_NET_HTML: WebNetHtml (); return;
- case DO_NET4_HTML: WebNet4Html (); return;
- case DO_NET4_AJAX: WebNet4Ajax (); return;
- case DO_NET4_SCRIPT: WebNet4Script (); return;
- case DO_NET6_HTML: WebNet6Html (); return;
- case DO_NET6_AJAX: WebNet6Ajax (); return;
- case DO_NET6_SCRIPT: WebNet6Script (); return;
- case DO_LOG_HTML: WebLogHtml (); return;
- case DO_FAULT_HTML: WebFaultHtml (); return;
- case DO_FIRMWARE_HTML: WebFirmwareHtml (); return;
- case DO_FIRMWARE_AJAX: WebFirmwareAjax (); return;
- case DO_FIRMWARE_SCRIPT: WebFirmwareScript(); return;
- }
-
- //If not called then call the derived (child) module
- WebServerDerivedReply(todo);
-}
-
--- a/web-server-base.h Mon Apr 29 14:45:30 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -extern int WebServerBaseDecideWhatToDo(char *pPath, char* pLastModified); -extern void WebServerBaseHandleQuery(int todo, char* pQuery); -extern bool WebServerBaseHandlePost(int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream); - -extern void WebServerBaseReply(int todo); - -#define DO_NOTHING 0 -#define DO_NOT_FOUND 1 -#define DO_NOT_MODIFIED 2 -#define DO_LOGIN 3 -#define DO_BASE 100 -#define DO_DERIVED 200 -#define DO_SEND_SESSION_ID 300 \ No newline at end of file
--- a/web.c Mon Apr 29 14:45:30 2019 +0000
+++ b/web.c Tue Apr 30 12:45:08 2019 +0000
@@ -1,10 +1,53 @@
#include "http.h"
#include "web-server-base.h"
-#include "web-base.h"
+#include "web-server-derived.h"
+#include "web.h"
+#include "web-pages-base.h"
#include "mstimer.h"
#define LOGIN_DELAY_MS 200
+#define DO_LOGIN DO_SERVER + 0
+
+static int decideWhatToDo(char *pPath, char* pLastModified)
+{
+ if (HttpSameStr(pPath, "/login")) return DO_LOGIN;
+
+ int todo;
+ todo = WebServerBaseDecideWhatToDo (pPath, pLastModified); if (todo != DO_NOT_FOUND) return todo;
+ todo = WebServerDerivedDecideWhatToDo(pPath, pLastModified); if (todo != DO_NOT_FOUND) return todo;
+ return DO_NOT_FOUND;
+}
+static void handleQuery(int todo, char* pQuery)
+{
+ switch (todo)
+ {
+ case DO_LOGIN: WebLoginQuery (pQuery); return;
+ }
+ if (WebServerBaseHandleQuery (todo, pQuery)) return;
+ if (WebServerDerivedHandleQuery(todo, pQuery)) return;
+}
+static void handlePost(int todo, int contentLength, int contentStart, int size, char* pRequestStream, uint32_t positionInRequestStream, bool* pComplete)
+{
+ if (WebServerBasePost (todo, contentLength, contentStart, size, pRequestStream, positionInRequestStream, pComplete)) return;
+ if (WebServerDerivedPost(todo, contentLength, contentStart, size, pRequestStream, positionInRequestStream, pComplete)) return;
+}
+
+static void reply(int todo)
+{
+ //Try all the base modules
+ switch (todo)
+ {
+ case DO_LOGIN: WebLoginHtml (); return;
+ case DO_NOT_FOUND: HttpNotFound (); return;
+ case DO_NOT_MODIFIED: HttpNotModified (); return;
+ }
+
+ //If not called then call the derived (child) module
+ if (WebServerBaseReply (todo)) return;
+ if (WebServerDerivedReply(todo)) return;
+}
+
static void handleRequest(int size, char* pRequestStream, uint32_t positionInRequestStream, int* pToDo, bool* pPostComplete, uint32_t* pDelayUntil)
{
//Handle request for the first packet of data received but leave todo the same after that.
@@ -21,7 +64,7 @@
contentStart = HttpRequestRead(pRequestStream, size, &pMethod, &pPath, &pQuery, &pLastModified, &pCookies, &contentLength);
//Ask the web server what to do
- *pToDo = WebServerBaseDecideWhatToDo(pPath, pLastModified);
+ *pToDo = decideWhatToDo(pPath, pLastModified);
//If what to do is NOTHING, NOT_FOUND or NOT_MODIFIED then no query or post will be valid so stop now
if (*pToDo < DO_LOGIN) { *pPostComplete = true; return; }
@@ -29,7 +72,7 @@
//If what to do is LOGIN then the user has just returned the login form
if (*pToDo == DO_LOGIN)
{
- WebServerBaseHandleQuery(*pToDo, pQuery); //Read the password and the original location
+ handleQuery(*pToDo, pQuery); //Read the password and the original location
if (WebLoginQueryPasswordOk)
{
if (!WebLoginSessionIdIsSet()) //If there isn't a session id already
@@ -54,11 +97,11 @@
}
//Handle the query
- WebServerBaseHandleQuery(*pToDo, pQuery);
+ handleQuery(*pToDo, pQuery);
}
//Do the upload of anything that needs it. Todos it doesn't understand are ignored.
- if (!*pPostComplete) *pPostComplete = WebServerBaseHandlePost(*pToDo, contentLength, contentStart, size, pRequestStream, positionInRequestStream);
+ if (!*pPostComplete) handlePost(*pToDo, contentLength, contentStart, size, pRequestStream, positionInRequestStream, pPostComplete);
}
static void sendReply(int todo)
@@ -78,7 +121,7 @@
HttpOkCookieMaxAge = -1;
}
- WebServerBaseReply(todo);
+ reply(todo);
}
int WebInit()
--- a/web.h Mon Apr 29 14:45:30 2019 +0000 +++ b/web.h Tue Apr 30 12:45:08 2019 +0000 @@ -1,2 +1,10 @@ extern int WebInit(void); + +#define DO_NOTHING 0 +#define DO_NOT_FOUND 1 +#define DO_NOT_MODIFIED 2 +#define DO_SERVER 10 +#define DO_BASE 100 +#define DO_DERIVED 200 +#define DO_SEND_SESSION_ID 300 \ No newline at end of file