Advertisement
Guest User

Untitled

a guest
Feb 19th, 2020
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.08 KB | None | 0 0
  1. /*
  2. * Minimal WiFi Example
  3. *
  4. * John Chajecki, @February 2020
  5. *
  6. */
  7.  
  8. //#define _DISABLE_TLS_
  9.  
  10. #include <EEPROM.h>
  11. #include <ESP8266WiFi.h>
  12. #include <Hash.h>
  13.  
  14. #include <ESP8266WebServerSecure.h>
  15.  
  16. static const char serverCert[] PROGMEM = R"EOF(
  17. -----BEGIN CERTIFICATE-----
  18. MIIBZzCCARECFBro/mMMDId0k3BfQ245XI9re76GMA0GCSqGSIb3DQEBCwUAMDUx
  19. HDAaBgNVBAoME0FSNDg4X0VTUDgyNjZfQURET04xFTATBgNVBAMMDDE5Mi4xNjgu
  20. NC44ODAeFw0yMDAyMTcyMjIwMjdaFw00NjAyMDgyMjIwMjdaMDUxHDAaBgNVBAoM
  21. E0FSNDg4X0VTUDgyNjZfQURET04xFTATBgNVBAMMDDE5Mi4xNjguNC44ODBcMA0G
  22. CSqGSIb3DQEBAQUAA0sAMEgCQQDJbBC2h0pKzhPZVohGsGZHtwMEAex8e8sROZuB
  23. u4/Cp2dpSPeF2G3pH3HGC/owsVwocYsqF4PVgeBiSiNVn0b3AgMBAAEwDQYJKoZI
  24. hvcNAQELBQADQQCCH3KP0eUS4IZ+iZlJwwTVOwj3xlZG5pHeElOGnbFIaGSoLrnA
  25. pLm3exKS7NrAm09oxwz0LlzkF1fRvw+36Tel
  26. -----END CERTIFICATE-----
  27. )EOF";
  28.  
  29. static const char serverKey[] PROGMEM = R"EOF(
  30. -----BEGIN RSA PRIVATE KEY-----
  31. MIIBOgIBAAJBAMlsELaHSkrOE9lWiEawZke3AwQB7Hx7yxE5m4G7j8KnZ2lI94XY
  32. bekfccYL+jCxXChxiyoXg9WB4GJKI1WfRvcCAwEAAQJAEYcU4T1eqqnKMmSEUVpy
  33. XBVB7uxX7vE615HixWRT+0U8hiCy0d37uNDemymOYkenQ40JHZjvOq1TrdhgkSDZ
  34. YQIhAONjoUoii8Im/SgMAEhPL5dWw5Ob1iHDL7aDHUFqf8LxAiEA4sQEjeVC0FoC
  35. tlsZUQS+Kh+jQOuToHv2wRgL9eqFWGcCIFsQXVmZOCtK/ft5wusyeza6kpycvkbL
  36. KmKHY8H86qmhAiEAj0bKmd0BGiPFEvL8S/RzMqpKu/ocjInGnrpS1E4ZcoECICIb
  37. aYuXsk+z1LDg9fffiClzZIy8iTQiZusNbBJShuGW
  38. -----END RSA PRIVATE KEY-----
  39. )EOF";
  40. ESP8266WebServerSecure *AR488srv;
  41.  
  42.  
  43.  
  44. // EEPROM size and start address
  45. #define EESIZE 512
  46. #define EESTART 2
  47.  
  48.  
  49. /***** Parameter variables *****/
  50. #define BAUD 115200 // serial baud rate
  51.  
  52. #define CR 0x13
  53. #define LF 0x10
  54.  
  55. #define TXTSZ 32
  56. #define CHKSZ 20
  57.  
  58. /***** Default WiFi AP mode config *****/
  59. const char *dfltSSID = "AR488wifi";
  60. const char *dfltPwd = "AR488-setup";
  61.  
  62.  
  63. /***** Parameters saved in EEPROM *****/
  64. union cfgObj {
  65. struct {
  66. uint16_t webp; // Web server port
  67. uint16_t gpibp; // GPIB passthrough port
  68. bool ssl; // SSL enabled switch state
  69. bool gpib; // GPIB passthrough enabled switch state
  70. bool wclient; // WiFi station (client) mode enabled
  71. bool dhcp; // Station mode DHCP enabled
  72. uint8_t addr[4]; // IP address
  73. uint8_t gate[4]; // IP gateway
  74. uint8_t mask[4]; // Subnet mask
  75. char pwdChk[CHKSZ]; // Admin password checksum
  76. };
  77. uint8_t db[CHKSZ+20];
  78. };
  79. union cfgObj AP;
  80.  
  81.  
  82. /***** Web server and client objects *****/
  83.  
  84. WiFiServer *passSrv = new WiFiServer(8488);
  85. WiFiClient passCli;
  86.  
  87.  
  88. /***** Buffers *****/
  89. // HTML page buffer
  90. const uint16_t htmlSize = 4096;
  91. char html[htmlSize];
  92. // Serial buffer
  93. const uint16_t sbSize = 64;
  94. uint8_t sBuf[sbSize];
  95. uint16_t sbPtr = 0;
  96. /***** Buffers *****/
  97.  
  98.  
  99. uint8_t pktTmo = 5; // serial timout (milliseconds) to wait before sending TCP packet
  100. char curPage[10] = {'\0'};
  101.  
  102.  
  103.  
  104. /*********************/
  105. /***** Web Pages *****/
  106. /*********************/
  107.  
  108.  
  109. /***** Main page *****/
  110. static const char wwwMainPage[] PROGMEM = R"EOF(
  111. <html>
  112. <head>
  113. <meta charset="utf-8">
  114. <title>Minimal Example Sketch</title>
  115. <link rel="stylesheet" href="style">
  116. <script defer src="/script"></script>
  117. </head>
  118. <body onload="getPage('%s')";>
  119. <div class="mpage">
  120. <div class="headr">WiFi Configuration</div>
  121. <div>
  122. <ul>
  123. <li><a id='seeStat' onclick="getPage('seeStat')">Status</a></li>
  124. <li><a id='cfgGen' onclick="getPage('cfgGen')">General</a></li>
  125. </ul>
  126. </div>
  127. <hr>
  128. <div id="cfgPage" class="conf">
  129. Loading...
  130. </div>
  131. <div>
  132. </div>
  133. </div>
  134. </body>
  135. </html>
  136. )EOF";
  137.  
  138.  
  139. /***** Status page *****/
  140. static const char seeStatPage[] PROGMEM = R"EOF(
  141. <table>
  142. <tr><th>WiFi mode:</th><td>%s</td></tr>
  143. <tr><th>WiFi status:</th><td>%s</td></tr>
  144. <tr %s><th>DHCP:</th><td>%s</td></tr>
  145. <tr><th>IP address:</th><td>%d.%d.%d.%d</td></tr>
  146. <tr %s><th>Gateway:</th><td>%d.%d.%d.%d</td></tr>
  147. <tr %s><th>Netmask:</th><td>%d.%d.%d.%d</td></tr>
  148. <tr><th>Mac addr:</th><td>%s</td></tr>
  149. <tr><th>ESSID:</th><td>%s</td></tr>
  150. </table>
  151. )EOF";
  152.  
  153.  
  154. /***** General configuration page *****/
  155. static const char cfgGenPage[] PROGMEM = R"EOF(
  156. <form method="post" action="/setGen" onchange="enableButton(0x1);"/>
  157. <table>
  158. <tr><th>SSL:</th><td>Off</td>
  159. <td><label class="switch">
  160. <input name="ssl" type="checkbox" onclick="toggleSSL(this);"/>
  161. <span class="slider"></span>
  162. </label></td>
  163. <td>On</td></tr>
  164. <tr><th>Passthrough:</th><td>Off</td>
  165. <td><label class="switch">
  166. <input name="pass" type="checkbox" onclick="togglePass(this);" %s/>
  167. <span class="slider"></span>
  168. </label></td>
  169. <td>On</td></tr>
  170. <tr><th>HTTP Port:</th><td colspan=3><input name="webp" value="%d"/></td></tr>
  171. <tr><th>PASS Port:</th><td colspan=3><input name="gpibp" value="%d" %s/></td></tr>
  172. </table>
  173. <input type="button" class="btn" id="btnApply" value="Apply" onclick="genValidate()" disabled/>
  174. </form>
  175. )EOF";
  176.  
  177.  
  178. /***** CSS definition *****/
  179. static const char css[] PROGMEM = R"EOF(
  180. body {width: 320; height: 424;}
  181. table {width: 100%%; font-size: 10pt; text-align: left;}
  182. th {width: 120px;}
  183. ul {list-style-type: none;
  184. margin: 0;
  185. padding: 0;
  186. height: 24px;
  187. font-size: 10pt;
  188. text-align: center;}
  189. li {float: left;width:20%%;}
  190. li a {display: block;
  191. border: 1px solid #777777;
  192. color: #333333;
  193. background-color: #FFEE77;
  194. text-decoration: none;}
  195. li a:hover:not(.active) {
  196. background-color: #777777;
  197. color: cyan;}
  198. .active {background-color:#77CCFF;}
  199. .headr {color: #0000AA;
  200. font-size: 14pt;
  201. font-weight: bold;
  202. width: 320;
  203. text-align: center;
  204. padding: 10px 0px 10px 0px;}
  205. .foot {font-size: 8pt;}
  206. .mpage {width: 320;
  207. height: 424;
  208. background-color: #EEEEEE;
  209. font-family: verdana;
  210. border: 1px solid #777777;
  211. margin: 7px;
  212. padding:7px;
  213. box-shadow: 3px 3px 3px #AAAAAA;
  214. }
  215. .conf {overflow-y: auto;
  216. height: 300px;
  217. }
  218. .ip {width: 40px; }
  219. .switch {
  220. position: relative;
  221. display: inline-block;
  222. width: 42px;
  223. height: 20px;
  224. }
  225. .slider {
  226. position: absolute;
  227. cursor: pointer;
  228. top: 0;
  229. left: 0;
  230. right: 0;
  231. bottom: 0;
  232. background-color: #2196F3;
  233. }
  234. .slider:before {
  235. position: absolute;
  236. content: '';
  237. height: 16px;
  238. width: 16px;
  239. left: 2px;
  240. bottom: 2px;
  241. background-color: silver;
  242. }
  243. input:checked + .slider:before {
  244. -webkit-transform: translateX(22px);
  245. -ms-transform: translateX(22px);
  246. transform: translateX(22px);
  247. background-color: gold;
  248. }
  249. .btn {float: right;
  250. width: 90px;
  251. margin: 10px 5px 0px 0px;
  252. }
  253. )EOF";
  254.  
  255.  
  256. /***** Main linking JavaScript code *****/
  257. static const char lnkScriptJs[] PROGMEM = R"EOF(
  258. var curMnObj='';
  259. function getPage(url) {
  260. var cfgPage = document.querySelector('#cfgPage');
  261. var curPage;
  262. var obj;
  263. if (url=='txtErr'){
  264. alert("SSID/password is empty or too long!");
  265. url='cfgWifi';
  266. };
  267. if (url) {
  268. curPage = '#'+url;
  269. }else{
  270. curPage = '#seeStat';
  271. url = 'seeStat';
  272. }
  273. obj = document.querySelector(curPage);
  274. if (curMnObj) curMnObj.classList.remove('active');
  275. curMnObj = obj;
  276. curMnObj.classList.add('active');
  277. cfgPage.innerHTML = "Updating...";
  278. fetch(url, {method: "POST"} )
  279. .then((resp) => resp.text())
  280. .then(function(data){
  281. cfgPage.innerHTML = data;
  282. })
  283. .catch(function(error){
  284. alert("Unable to load page!");
  285. });
  286. if (url=='cfgWiFi') wifiMode();
  287. }
  288. function enableButton(sw){
  289. if (sw&0x1) document.querySelector('#btnApply').disabled = false;
  290. if (sw&0x2) document.querySelector('#btnSave').disabled = false;
  291. }
  292. )EOF";
  293.  
  294.  
  295. /***** General configuration page JavaScript *****/
  296. static const char cfgGenJs[] PROGMEM = R"EOF(
  297. function toggleSSL(ssl){
  298. var webp = document.querySelector('[name="webp"]');
  299. if (ssl.checked && webp.value == '80') webp.value = 443;
  300. if (ssl.checked==false && webp.value == '443') webp.value = 80;
  301. }
  302. function togglePass(pass){
  303. var gpibp = document.querySelector('[name="gpibp"]');
  304. if (pass.checked) {
  305. gpibp.disabled = false;
  306. }else{
  307. gpibp.disabled = true;
  308. }
  309. }
  310. function genValidate() {
  311. var form = document.querySelector('form');
  312. var adP = document.querySelector('[name="webp"]').value;
  313. var gpP = document.querySelector('[name="gpibp"]').value;
  314. if (adP==0||gpP==0 || adP>49151||gpP>49151) {
  315. alert("TCP port is out of range!\\nPlease set a port value between 1 and 49151.");
  316. }else{
  317. form.submit();
  318. }
  319. }
  320. )EOF";
  321.  
  322.  
  323. /***** Re-direct page *****/
  324. static const char redirectPage[] PROGMEM = R"EOF(
  325. <html>
  326. <head>
  327. <meta http-equiv="refresh" content="%d; URL='%s://%d.%d.%d.%d'"/>
  328. <style>
  329. body {width: 320; height: 424;}
  330. .mpage {width: 320;
  331. height: 424;
  332. background-color: #EEEEEE;
  333. font-family: verdana;
  334. border: 1px solid #777777;
  335. margin: 7px;
  336. padding:7px;
  337. box-shadow: 3px 3px 3px #AAAAAA;
  338. font-family: verdana;
  339. font-size: 12pt;
  340. font-weight: normal;
  341. }
  342. </style>
  343. </head>
  344. <body>
  345. <div class="mpage">
  346. <p>%s</p>
  347. <p>If you have switched to a DHCP assigned address, then manually
  348. enter the new IP address into your browswer.</p>
  349. <p>If you have switched from Station to AP mode, or have restarted
  350. AP mode, then you may have to re-connect to the WiFi SSID and then
  351. enter the new IP address in your browser.</p>
  352. <p>Otherwise, please wait a few seconds for the page to reload.<p>
  353. <p>If the page does not re-load within a few seconds, please try
  354. the back button in your browser or check your WiFi connection.</p>
  355. </div>
  356. </body>
  357. </html>
  358. )EOF";
  359.  
  360.  
  361.  
  362. /**********************************/
  363. /***** MAIN PROGRAM *****/
  364. /**********************************/
  365.  
  366. void setup() {
  367.  
  368. #ifdef EEPROM_CLEAR
  369. epErase();
  370. #endif
  371.  
  372. Serial.begin(BAUD);
  373.  
  374. #ifdef DEBUG_0
  375. Serial.println();
  376. Serial.println(F("Starting WiFi..."));
  377. #endif
  378.  
  379. #ifndef DISABLE_SSL
  380. configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
  381. #endif
  382.  
  383.  
  384. // Set config defaults
  385. setDefaultCfg();
  386.  
  387. #ifdef DEBUG_0
  388. if (isEepromClear()){
  389. Serial.println(F("EEPROM is clear"));
  390. }else{
  391. Serial.println(F("EEPROM contains previous config"));
  392. }
  393. #endif
  394.  
  395. // Check if previous config saved and load
  396. if (!isEepromClear()) {
  397. #ifdef DEBUG_0
  398. Serial.println("Loading saved config...");
  399. #endif
  400. // Load previous config else clear EEPROM
  401. if (!epReadData(EESTART, &AP, sizeof(AP))) {
  402. epErase();
  403. #ifdef DEBUG_0
  404. Serial.println("EEPROM erased. Reset to defaults.");
  405. #endif
  406. }
  407. }
  408.  
  409. // Start WiFi and Web server
  410. if (startWifi()>-1) {
  411. #ifdef DEBUG_0
  412. Serial.println(F("Starting webserver..."));
  413. #endif
  414. startWebServer();
  415.  
  416. if (AP.gpib) {
  417. passSrv = new WiFiServer(AP.gpibp);
  418. passSrv->begin();
  419. }
  420. }
  421.  
  422. }
  423.  
  424.  
  425. void loop() {
  426.  
  427. // Handle requests for web server
  428. AR488srv->handleClient();
  429.  
  430. // Is GPIB passthrough enabled?
  431. if (AP.gpib) {
  432. // Handle incoming client connections
  433. if (passCli.connected()) {
  434.  
  435. // Handle TCP connection, output to serial
  436. while (passCli.available()) {
  437. if (sbPtr < sbSize - 1) {
  438. sBuf[sbPtr] = passCli.read();
  439. sbPtr++;
  440. }else{
  441. break;
  442. }
  443. }
  444.  
  445. if (sbPtr) {
  446. Serial.write(sBuf, sbPtr);
  447. clrSBuf(sbPtr);
  448. }
  449.  
  450. // Handle serial input, output to TCP
  451. while (Serial.available()) {
  452. if (sbPtr < sbSize - 1) {
  453. sBuf[sbPtr] = Serial.read();
  454. sbPtr++;
  455. }
  456. }
  457. passCli.write((char*)sBuf, sbPtr);
  458. clrSBuf(sbPtr);
  459.  
  460. #ifdef DEBUG_6
  461. if (!passCli.connected()) Serial.println("<= disconnected.");
  462. #endif
  463.  
  464. } else {
  465. // Wait for a connection
  466. passCli = passSrv->available();
  467. if (passCli.connected()) {
  468. #ifdef DEBUG_6
  469. Serial.println("Connected =>");
  470. #endif
  471. // Initialise buffer
  472. clrSBuf(64);
  473. delay(50);
  474. // Clear spurious characters after connection established
  475. while (passCli.available()) { passCli.read(); }
  476. }
  477. }
  478. }
  479.  
  480. }
  481.  
  482.  
  483. /*****************************/
  484. /***** PROGRAM FUNCTIONS *****/
  485. /*****************************/
  486.  
  487. /***** Default configuration *****/
  488. void setDefaultCfg() {
  489. #ifdef DISABLE_SSL
  490. AP = {80,8488,false,false,false,false,{192,168,4,88},{192,168,4,88},{255,255,255,0},{'\0'}};
  491. #else
  492. AP = {443,8488,false,false,false,false,{192,168,4,88},{192,168,4,88},{255,255,255,0},{'\0'}};
  493. #endif
  494. }
  495.  
  496.  
  497. /***** Start WiFi *****/
  498. /*
  499. * Flag:
  500. * -1 : fail
  501. * 0 : fallback mode
  502. * 1 : Started in AP mode
  503. * 2 : Started in Client mode
  504. */
  505. int startWifi() {
  506. int stat=-1;
  507. // Check if already configured
  508. if (isEepromClear()) {
  509. Serial.println(F("Starting AP with defaults..."));
  510. setDefaultCfg();
  511. startWifiAP(dfltSSID, dfltPwd, AP.addr, AP.addr, AP.mask);
  512. stat = 0;
  513. }else{
  514. // Start mode
  515. if (AP.wclient) {
  516. // Start station (client) mode
  517. #ifdef DEBUG_1
  518. Serial.println(F("Starting WiFi client..."));
  519. #endif
  520. if (startWifiStn("", "", AP.addr, AP.gate, AP.mask)) {
  521. stat=2;
  522. }else{
  523. // Fallback to default AP configuration
  524. #ifdef DEBUG_1
  525. Serial.println(F("Falling back to AP with defaults..."));
  526. #endif
  527. setDefaultCfg();
  528. startWifiAP(dfltSSID, dfltPwd, AP.addr, AP.addr, AP.mask);
  529. stat=0;
  530. }
  531. }else{
  532. // Start AP mode
  533. startWifiAP("","",AP.addr,AP.addr,AP.mask);
  534. #ifdef DEBUG_1
  535. Serial.println(F("Starting AP..."));
  536. #endif
  537. stat=1;
  538. }
  539. }
  540. #ifdef DEBUG_1
  541. Serial.print(F("Wifi Start status: "));Serial.println(stat);
  542. #endif
  543. return stat;
  544. }
  545.  
  546.  
  547. /***** Check whether WiFi has started *****/
  548. bool hasWifiStarted() {
  549. uint16_t tmo = 60000;
  550. uint16_t dly = 500;
  551.  
  552. // Wait for connection
  553. #ifdef DEBUG_1
  554. Serial.print(F("Waiting for connection."));
  555. #endif
  556. while ((WiFi.status() != WL_CONNECTED) && (tmo > 0)) {
  557. delay(dly);
  558. tmo = tmo - dly;
  559. #ifdef DEBUG_1
  560. Serial.print(".");
  561. #endif
  562. }
  563. #ifdef DEBUG_1
  564. Serial.print(F("\nWiFi status:"));
  565. Serial.println(WiFi.status());
  566. #endif
  567.  
  568. if (WiFi.status() == WL_CONNECTED) {
  569. // Success!
  570. #ifdef DEBUG_1
  571. Serial.println(F("WiFi started."));
  572. Serial.print(F("Connected, IP address: "));
  573. Serial.println(WiFi.localIP());
  574. #endif
  575. return true;
  576. } else {
  577. // Timed out
  578. #ifdef DEBUG_1
  579. Serial.println(F("WiFi failed."));
  580. #endif
  581. return false;
  582. }
  583. }
  584.  
  585.  
  586. /***** Start WiFi in access point mode ****/
  587. void startWifiAP(String ssid, String psks, uint8_t addr[4], uint8_t gate[4], uint8_t mask[4]) {
  588. uint8_t gway[4];
  589. bool gws = true; // Set gateway to primary address (removes compiler warning)
  590.  
  591. // If no SSID or password, then use the currently configure one
  592. if (ssid == NULL) ssid = WiFi.softAPSSID();
  593. if (psks == NULL) psks = WiFi.softAPPSK();
  594.  
  595. // Stop and disable station mode
  596. if (WiFi.getMode()==WIFI_STA) {
  597. // Disconnect client from network
  598. WiFi.disconnect();
  599. WiFi.enableSTA(false);
  600. }
  601.  
  602. // Gateway is primary address or separate address?
  603. for (uint8_t i=0; i<4; i++) {
  604. if (gws) {
  605. gway[i] = addr[i]; // Gateway set to primary address
  606. }else{
  607. gate[i] = gate[i]; // Gateway set to different IP address
  608. }
  609. }
  610.  
  611. // Restart and configure the AP
  612. // if (!WiFi.enableAP()) WiFi.enableAP(true);
  613. WiFi.enableAP(true);
  614. WiFi.mode(WIFI_AP);
  615. WiFi.setSleepMode(WIFI_NONE_SLEEP);
  616. WiFi.softAPConfig(addr, gway, mask); // set IP address
  617. WiFi.softAP(ssid, psks); // set SSID and password
  618. delay(500);
  619. }
  620.  
  621.  
  622. /***** Start WiFi in station mode *****/
  623. bool startWifiStn(String ssid, String psks, uint8_t addr[4], uint8_t gate[4], uint8_t mask[4]) {
  624.  
  625. if (ssid == NULL) ssid = WiFi.SSID();
  626. if (psks == NULL) psks = WiFi.psk();
  627.  
  628. #ifdef DEBUG_1
  629. Serial.println(F("Station mode>"));
  630. #endif
  631.  
  632. // Check whether in AP mode - is so, disconnect clients and turn off AP mode
  633. if (WiFi.getMode()==WIFI_AP) {
  634. // Disconnect clients and stop AP mode
  635. WiFi.softAPdisconnect(true);
  636. WiFi.enableAP(false);
  637. delay(500);
  638. }
  639.  
  640. // Enable and start station mode
  641. // if (!WiFi.enableSTA()) WiFi.enableSTA(true);
  642. WiFi.enableSTA(true);
  643. WiFi.mode(WIFI_STA);
  644. WiFi.setSleepMode(WIFI_NONE_SLEEP);
  645.  
  646.  
  647. if (AP.dhcp) {
  648. // DHCP mode
  649. WiFi.config(0u, 0u, 0u);
  650. }else{
  651. // Static IP mode
  652. // wifi_station_dhcpc_stop();
  653. WiFi.config(addr, gate, mask);
  654. }
  655.  
  656. // WiFi.setAutoConnect(true);
  657. // WiFi.setAutoReconnect(true);
  658.  
  659. WiFi.begin(ssid, psks);
  660. return hasWifiStarted();
  661. }
  662.  
  663.  
  664. /***** Start the web server *****/
  665. void startWebServer() {
  666. delete AR488srv;
  667.  
  668. // Create a new webserver instance
  669. AR488srv = new ESP8266WebServerSecure(AP.webp);
  670. // Apply certificate and key
  671. AR488srv->getServer().setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey));
  672.  
  673. // Pages being served
  674. AR488srv->on("/", wwwMain); // Default web page
  675. AR488srv->on("/cfgGen", cfgGen); // General options
  676. AR488srv->on("/seeStat", seeStat); // Status page
  677. AR488srv->on("/style", lnkStyle); // Stylesheet
  678. AR488srv->on("/script", lnkScript); // Main Script
  679.  
  680. // Start the server
  681. AR488srv->begin(); // Start the HTTP server
  682.  
  683. #ifdef DEBUG_2
  684. Serial.println("Web server started.");
  685. #endif
  686. }
  687.  
  688.  
  689. /***** Main page *****/
  690. void wwwMain() {
  691. snprintf(html, htmlSize, wwwMainPage, curPage);
  692. AR488srv->send(200, "text/html", html);
  693. }
  694.  
  695.  
  696. /***** Status page *****/
  697. void seeStat() {
  698. char wmodestr[8] = {0x53,0x74,0x6F,0x70,0x70,0x65,0x64,0x0};
  699. char wstatstr[14] = {0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x0};
  700. char dhcp[9] = {0x44,0x69,0x73,0x61,0x62,0x6C,0x65,0x64,0x0};
  701. char hide[7] = {'\0'};
  702.  
  703. String ssid;
  704. uint8_t wmode = WiFi.getMode();
  705. int wstatus = WiFi.status();
  706. IPAddress addr = {0};
  707. IPAddress gate = {0};
  708. IPAddress mask = {0xFF,0xFF,0xFF,0x0};
  709.  
  710. // AP mode
  711. if (wmode == 2) {
  712. strncpy(wmodestr, "Soft AP\0", 8);
  713. strncpy(hide, "hidden\0", 7);
  714. ssid = WiFi.softAPSSID();
  715. addr = WiFi.softAPIP();
  716. }
  717.  
  718. // Station (client) mode
  719. if (wmode == 1) {
  720. strncpy(wmodestr, "Station\0", 8);
  721. ssid = WiFi.SSID();
  722. addr = WiFi.localIP();
  723. gate = WiFi.gatewayIP();
  724. mask = WiFi.subnetMask();
  725. if (AP.dhcp == true) strncpy(dhcp, "Enabled\0", 8);
  726. switch(wstatus) {
  727. case WL_CONNECTED:
  728. strncpy(wstatstr, "Connected\0", 14);
  729. break;
  730. case WL_CONNECTION_LOST:
  731. strncpy(wstatstr, "Conn. lost\0", 14);
  732. break;
  733. case WL_DISCONNECTED:
  734. strncpy(wstatstr, "Disconnected\0",14);
  735. break;
  736. default:
  737. strncpy(wstatstr, "Conn. failed\0",14);
  738. }
  739. }
  740.  
  741. snprintf(html, htmlSize, seeStatPage,
  742. wmodestr,
  743. wstatstr,
  744. hide,
  745. dhcp,
  746. addr[0],
  747. addr[1],
  748. addr[2],
  749. addr[3],
  750. hide,
  751. gate[0],
  752. gate[1],
  753. gate[2],
  754. gate[3],
  755. hide,
  756. mask[0],
  757. mask[1],
  758. mask[2],
  759. mask[3],
  760. WiFi.macAddress().c_str(),
  761. ssid.c_str()
  762. );
  763. AR488srv->send(200, "text/html", html);
  764. }
  765.  
  766.  
  767. /***** General functions configuration page *****/
  768. void cfgGen() {
  769. // char chkd1[8] = {'\0'};
  770. char chkd2[8] = {'\0'};
  771. char disd[9] = {'\0'};
  772.  
  773. if (AP.gpib) {
  774. strncpy(chkd2, "checked\0", 8);
  775. } else {
  776. strncpy(disd, "disabled\0", 9);
  777. }
  778.  
  779. snprintf(html, htmlSize, cfgGenPage,
  780. chkd2,
  781. AP.webp,
  782. AP.gpibp,
  783. disd
  784. );
  785. AR488srv->send(200, "text/html", html);
  786. }
  787.  
  788.  
  789.  
  790. /***** Return CSS stylesheet *****/
  791. void lnkStyle() {
  792. snprintf(html, htmlSize, css);
  793. AR488srv->send(200, "text/html", html);
  794. }
  795.  
  796.  
  797. /***** Return main JavaScript code *****/
  798. void lnkScript() {
  799. snprintf(html, htmlSize, lnkScriptJs);
  800. AR488srv->send(200, "text/html", html);
  801. }
  802.  
  803.  
  804. /***** JavaScript code for Ceneral config page *****/
  805. void cfgGenjs() {
  806. snprintf(html, htmlSize, cfgGenJs);
  807. AR488srv->send(200, "text/html", html);
  808. }
  809.  
  810.  
  811. /***** Set general configuration options *****/
  812. void setGen() {
  813. uint16_t webp;
  814. uint16_t gpibp;
  815. bool sc = false; // State change
  816.  
  817. #ifdef DEBUG_2
  818. Serial.println(F("Received general config page..."));
  819. showArgs();
  820. #endif
  821.  
  822. webp = AR488srv->arg("webp").toInt();
  823. if (webp != AP.webp) {
  824. AP.webp = webp;
  825. delete AR488srv;
  826. startWebServer();
  827.  
  828. // ESP.reset();
  829. }
  830.  
  831. if (AR488srv->arg("pass") == "on") {
  832. #ifdef DEBUG_2
  833. Serial.println(F("Passthrough turned on."));
  834. #endif
  835. if (!AP.gpib) sc = true;
  836. AP.gpib = true;
  837. gpibp = AR488srv->arg("gpibp").toInt();
  838. if (AP.gpibp != gpibp) {
  839. sc = true;
  840. AP.gpibp = gpibp;
  841. }
  842. if (sc) {
  843. #ifdef DEBUG_2
  844. Serial.print(F("Restarting TCP server on port: "));
  845. Serial.println(AP.gpibp);
  846. #endif
  847. if (passSrv) delete passSrv;
  848. passSrv = new WiFiServer(gpibp);
  849. passSrv->begin();
  850. }
  851. } else {
  852. if (AP.gpib) {
  853. AP.gpib = false;
  854. // Disconnect any client
  855. if (passCli.connected()) passCli.stop();
  856. // Kill the server (note: causes reboot!)
  857. passSrv->stop();
  858. // delete passSrv;
  859. }
  860. }
  861. epWriteData(EESTART, &AP, sizeof(AP));
  862. updatePage("cfgGen");
  863. }
  864.  
  865.  
  866. #ifdef DEBUG_2
  867. /***** Display submitted arguments *****/
  868. void showArgs() {
  869. uint8_t acnt = AR488srv->args();
  870. for (uint8_t i = 0; i < acnt; i++) {
  871. Serial.print(AR488srv->argName(i) + ":\t");
  872. Serial.println(AR488srv->arg(i));
  873. }
  874. }
  875. #endif
  876.  
  877.  
  878. /***** Return updated selected page *****/
  879. void updatePage(const char* page) {
  880. uint8_t len = strlen(page);
  881. strncpy(curPage, page, len);
  882. wwwMain();
  883. memset(curPage, '\0', len);
  884. }
  885.  
  886.  
  887. /***** Is the reply what we expected? *****/
  888. uint8_t getReply(const char* cmd, char *reply, int rsize) {
  889. uint8_t p = 0;
  890.  
  891. // Clear the reply buffer
  892. memset(reply, '\0', rsize);
  893.  
  894. // Send cmd to controller and get response
  895. Serial.println(cmd);
  896. p = Serial.readBytesUntil(LF, reply, rsize - 1);
  897. return p;
  898. }
  899.  
  900.  
  901. /***** Flush the incoming buffer *****/
  902. void flushIncoming() {
  903. while (Serial.available()) {
  904. Serial.read();
  905. };
  906. }
  907.  
  908.  
  909. /***** Clear buffer *****/
  910. void clrSBuf(uint8_t ptr) {
  911. memset(sBuf, '\0',ptr);
  912. sbPtr = 0;
  913. }
  914.  
  915.  
  916.  
  917. /***************************/
  918. /***** EEPROM routines *****/
  919. /***************************/
  920.  
  921. /***** Clear the EEPROM *****/
  922. void epErase() {
  923. int i = EESIZE;
  924.  
  925. // Load EEPROM data from Flash
  926. EEPROM.begin(EESIZE);
  927. for (i=0; i<EESIZE; i++)
  928. EEPROM.write(i, 0xFF);
  929. EEPROM.commit();
  930. EEPROM.end();
  931. }
  932.  
  933.  
  934. /***** Write data to EEPROM (with CRC) *****/
  935. /*
  936. * addr = EEPROM address
  937. * cfg = config data union object
  938. * csize = size of config data object
  939. */
  940. void epWriteData(uint16_t addr, cfgObj * cptr, uint16_t csize) {
  941. uint16_t crc;
  942.  
  943. // Load EEPROM data from Flash
  944. EEPROM.begin(EESIZE);
  945. // Write data
  946. EEPROM.put(addr,*cptr);
  947. // Write CRC
  948. crc = getCRC16(cptr->db, csize);
  949. EEPROM.put(0, crc);
  950. // Commit write to Flash
  951. EEPROM.commit();
  952. EEPROM.end();
  953. }
  954.  
  955.  
  956. /***** Read data from EEPROM (with CRC check) *****/
  957. /*
  958. * addr = EEPROM address
  959. * cfg = config data union object
  960. * csize = size of config data object
  961. */
  962. bool epReadData(uint16_t addr, cfgObj * cptr, uint16_t csize) {
  963. uint16_t crc1;
  964. uint16_t crc2;
  965.  
  966. // Load EEPROM data from Flash
  967. EEPROM.begin(EESIZE);
  968. // Read CRC
  969. EEPROM.get(0,crc1);
  970. // Read data
  971. EEPROM.get(addr, *cptr);
  972. EEPROM.end();
  973. // Get CRC of config
  974. crc2 = getCRC16(cptr->db, csize);
  975. if (crc1==crc2) {
  976. return true;
  977. }else{
  978. return false;
  979. }
  980. }
  981.  
  982.  
  983. bool isEepromClear(){
  984. int16_t crc = 0;
  985.  
  986. // Load data from EEPROM
  987. EEPROM.begin(EESIZE);
  988. // Read data
  989. EEPROM.get(0, crc);
  990. EEPROM.end();
  991. // Return result
  992. if (crc==-1) {
  993. return true;
  994. }else{
  995. return false;
  996. }
  997. }
  998.  
  999.  
  1000. /***** Generate 16 bit CRC *****/
  1001. uint16_t getCRC16(uint8_t bytes[], uint16_t bsize){
  1002. uint8_t x;
  1003. uint16_t crc = 0xFFFF;
  1004.  
  1005. for (uint16_t idx=0; idx<bsize; ++idx) {
  1006. x = crc >> 8 ^ bytes[idx];
  1007. x ^= x>>4;
  1008. crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x <<5)) ^ ((uint16_t)x);
  1009. }
  1010. return crc;
  1011. }
  1012.  
  1013. /**********************************/
  1014. /***** End of EEPROM routines *****/
  1015. /**********************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement