diff --git a/CMakeLists.txt b/CMakeLists.txt index 6131385..ee97acb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,7 +86,6 @@ set(SOURCE_FILES esp_iot_sdk_v1.5.2/include/json/jsonparse.h esp_iot_sdk_v1.5.2/include/json/json.h - include/uart_hw.h include/user_config.h include/ets_sys_extra.h user/io.c @@ -97,10 +96,9 @@ set(SOURCE_FILES user/cgi_persist.h user/cgi_network.c user/cgi_network.h - user/cgi_appcfg.c - user/cgi_appcfg.h - user/cgi_ping.c - user/cgi_reset.c + user/cgi_term_cfg.c + user/cgi_term_cfg.h + user/cgi_system.c user/uart_driver.c user/uart_handler.c user/ansi_parser.c @@ -123,7 +121,10 @@ set(SOURCE_FILES user/wifimgr.c user/wifimgr.h user/persist.c - user/persist.h include/helpers.h) + user/persist.h + include/helpers.h + user/syscfg.c + user/syscfg.h) include_directories(include) include_directories(user) diff --git a/html_orig/_debug_replacements.php b/html_orig/_debug_replacements.php index e693ea1..bbaa401 100644 --- a/html_orig/_debug_replacements.php +++ b/html_orig/_debug_replacements.php @@ -21,19 +21,21 @@ return [ "screen": "70 t259" }', + '%opmode%' => '2', + '%sta_enable%' => '0', '%ap_enable%' => '1', + '%tpw%' => '60', '%ap_channel%' => '7', '%ap_ssid%' => 'ESP-123456', '%ap_password%' => 'Passw0rd!', '%ap_hidden%' => '0', + '%sta_ssid%' => 'Chlivek', '%sta_password%' => 'windows XP is The Best', '%sta_active_ip%' => '1.2.3.4', '%sta_active_ssid%' => 'Chlivek', - '%sta_enable%' => '1', - '%opmode%' => '3', '%vers_fw%' => '1.2.3', '%date%' => date('Y-m-d'), '%time%' => date('G:i'), @@ -59,4 +61,8 @@ return [ '%term_height%' => '10', '%default_bg%' => '0', '%default_fg%' => '7', + + '%uart_baud%' => 115200, + '%uart_stopbits%' => 1, + '%uart_parity%' => 2, ]; diff --git a/html_orig/_pages.php b/html_orig/_pages.php index 47ae0f2..8d99c1e 100644 --- a/html_orig/_pages.php +++ b/html_orig/_pages.php @@ -27,13 +27,15 @@ pg('wifi_scan', 'api', '', '/cfg/wifi/scan'); pg('cfg_network', 'cfg', 'network', '/cfg/network'); pg('network_set', 'api', '', '/cfg/network/set'); -pg('cfg_app', 'cfg', 'terminal', '/cfg/app'); -pg('app_set', 'api', '', '/cfg/app/set'); +pg('cfg_term', 'cfg', 'terminal', '/cfg/term'); +pg('term_set', 'api', '', '/cfg/term/set'); -pg('cfg_admin', 'cfg', 'persist', '/cfg/admin'); -pg('write_defaults', 'api', '', '/cfg/admin/write_defaults'); -pg('restore_defaults', 'api', '', '/cfg/admin/restore_defaults'); -pg('restore_hard', 'api', '', '/cfg/admin/restore_hard'); +pg('cfg_system', 'cfg', 'configure', '/cfg/system'); +pg('system_set', 'api', '', '/cfg/system/set'); + +pg('write_defaults', 'api', '', '/cfg/system/write_defaults'); +pg('restore_defaults', 'api', '', '/cfg/system/restore_defaults'); +pg('restore_hard', 'api', '', '/cfg/system/restore_hard'); pg('help', 'cfg page-help', 'help', '/help'); pg('about', 'cfg page-about', 'about', '/about'); diff --git a/html_orig/css/app.css b/html_orig/css/app.css index 67bd40a..5e352c3 100644 --- a/html_orig/css/app.css +++ b/html_orig/css/app.css @@ -311,7 +311,7 @@ th { /* Fontello data, processed by the unpack script. */ @font-face { font-family: 'fontello'; - src: url("data:application/octet-stream;base64,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") format("woff"), url("data:application/octet-stream;base64,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") format("truetype"); } + src: url("data:application/octet-stream;base64,d09GRgABAAAAABjgAA8AAAAAKBQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABWAAAADsAAABUIIslek9TLzIAAAGUAAAAQwAAAFZ8JWGjY21hcAAAAdgAAACmAAACMBHmxANjdnQgAAACgAAAABQAAAAgBzn/aGZwZ20AAAKUAAAFkAAAC3CKkZBZZ2FzcAAACCQAAAAIAAAACAAAABBnbHlmAAAILAAADZwAABPw1hdt4GhlYWQAABXIAAAAMwAAADYOv3AxaGhlYQAAFfwAAAAgAAAAJAfjBBpobXR4AAAWHAAAACgAAAA0L/z/+WxvY2EAABZEAAAAHAAAABwbQiEabWF4cAAAFmAAAAAgAAAAIAFYDZ5uYW1lAAAWgAAAAXcAAALNzJ0dH3Bvc3QAABf4AAAAbAAAAJDryILFcHJlcAAAGGQAAAB6AAAAhuVBK7x4nGNgZGBg4GIwYLBjYHJx8wlh4MtJLMljkGJgYYAAkDwymzEnMz2RgQPGA8qxgGkOIGaDiAIAJjsFSAB4nGNgZN7IOIGBlYGBqYppDwMDQw+EZnzAYMjIBBRlYGVmwAoC0lxTGBzUWP//Z275P4chirmFIQUozAiSAwADsgybAHic7ZG9DcJADIWfSS78SxSZ4dzQMEt6qtSZIBNQ0aZjB3qWItCGZ7uIkBgBW9+d/OQ7WX4AEoCCHEkJyBUCiwtVcb3AxvUSZ9YHJvtzyn0etNZGW+2m6ZfyFeIv5zRlwZ9KTlBhybLCP3Z+3uYqp8C8yH3AvSEPgXmhdWD+aROYr9oG3C+0C7hpee4dYAUZTw6w5v1wQL9lfDvAFvK6O5znA4clJJ4AAHicY2BAAxIQyNzyfw4IAwAVjASleJytVml300YUHXlJnIQsJQstamHExGmwRiZswYAJQbJjIF2crZWgixQ76b7xid/gX/Nk2nPoN35a7xsvJJC053Cak6N3583VzNtlElqS2AvrkZSbL8XU1iaN7DwJ6YZNy1F8KDt7IWWKyd8FURCtltq3HYdERCJQta6wRBD7HlmaZHzoUUbLtqRXTcotPekuW+NBvVXffho6yrE7oaRmM3RoPbIlVRhVokimPVLSpmWo+itJK7y/wsxXzVDCiE4iabwZxtBI3htntMpoNbbjKIpsstwoUiSa4UEUeZTVEufkigkMygfNkPLKpxHlw/yIrNijnFawS7bT/L4vead3OT+xX29RtuRAH8iO7ODsdCVfhFtbYdy0k+0oVBF213dCbNnsVP9mj/KaRgO3KzK90IxgqXyFECs/ocz+IVktnE/5kkejWrKRE0HrZU7sSz6B1uOIKXHNGFnQ3dEJEdT9kjMM9pg+Hvzx3imWCxMCeBzLekclnAgTKWFzNEnaMHJgJWWLKqn1rpg45XVaxFvCfu3a0ZfOaONQd2I8Ww8dWzlRyfFoUqeZTJ3aSc2jKQ2ilHQmeMyvAyg/oklebWM1iZVH0zhmxoREIgIt3EtTQSw7saQpBM2jGb25G6a5di1apMkD9dyj9/TmVri501PaDvSzRn9Wp2I62AvT6WnkL/Fp2uUiRen66Rl+TOJB1gIykS02w5SDB2/9DtLL15YchdcG2O7t8yuofdZE8KQB+xvQHk/VKQlMhZhViFZAYq1rWZbJ1awWqcjUd0OaVr6s0wSKchwXx76Mcf1fMzOWmBK+34nTsyMuPXPtSwjTHHybdT2a16nFcgFxZnlOp1mW7+s0x/IDneZZntfpCEtbp6MsP9RpgeVHOh1jeUELmnTfwZCLMOQCDpAwhKUDQ1hegiEsFQxhuQhDWBZhCMslGMLyYxjCchmGsLysZdXUU0nj2plYBmxCYGKOHrnMReVqKrlUQrtoVGpDnhJulVQUz6p/ZaBePPKGObAWSJfIml8xzpWPRuX41hUtbxo7V8Cx6m8fjvY58VLWi4U/Bf/V1lQlvWLNw5Or8BuGnmwnqjapeHRNl89VPbr+X1RUWAv0G0iFWCjKsmxwZyKEjzqdhmqglUPMbMw8tOt1y5qfw/03MUIWUP34NxQaC9yDTllJWe3grNXX27LcO4NyOBMsSTE38/pW+CIjs9J+kVnKno98HnAFjEpl2GoDrRW82ScxD5neJM8EcVtRNkja2M4EiQ0c84B5850EJmHqqg3kTuGGDfgFYW7BeSdconqjLIfuRezzKKT8W6fiRPaoaIzAs9kbYa/vQspvcQwkNPmlfgxUFaGpGDUV0DRSbqgGX8bZum1Cxg70Iyp2w7Ks4sPHFveVkm0ZhHykiNWjo5/WXqJOqtx+ZhSX752+BcEgNTF/e990cZDKu1rJMkdtA1O3GpVT15pD41WH6uZR9b3j7BM5a5puuiceel/TqtvBxVwssPZtDtJSJhfU9WGFDaLLxaVQ6mU0Se+4BxgWGNDvUIqN/6v62HyeK1WF0XEk307Ut9HnYAz8D9h/R/UD0Pdj6HINLs/3mhOfbvThbJmuohfrp+g3MGutuVm6BtzQdAPiIUetjrjKDXynBnF6pLkc6SHgY90V4gHAJoDF4BPdtYzmUwCj+Yw5PsDnzGHQZA6DLeYw2GbOGsAOcxjsMofBHnMYfMGcdYAvmcMgZA6DiDkMnjAnAHjKHAZfMYfB18xh8A1z7gN8yxwGMXMYJMxhsK/p1jDMLV7QXaC2QVWgA1NPWNzD4lBTZcj+jheG/b1BzP7BIKb+qOn2kPoTLwz1Z4OY+otBTP1V050h9TdeGOrvBjH1D4OY+ky/GMtlBr+MfJcKB5RdbD7n74n3D9vFQLkAAQAB//8AD3icxVhbbFzHeZ5/rue2Z29nz6HI5ZJckrsUSS2t5V5kUqLXupGW1qpMUTIp2A4RX6JakWWosoM6sGu4ejBiwwkCNHEDR4kBGwiKOnDSuNfE6EPsFAmK2i0gq00DtDWKqnkI0EJBATda9ZslraYvRdGHlrs758zMP//8881/JSPGbv5CvCousBHW7Hi5tCeFYpyWj75ZPL7eCYgYZ48zzgN+11DHQ4efxxh7ZOOt4SgRKpmhKE35QhTSHBldrjQb7XzVtpPtVn2EVCxeTf/wtqAQ/PtHQRzQbT8KR2jgGX80eJoGRvlQkH6n98+BnyFz6ZLJedKh5J10UFBTvSTpTSlm5ftQbIh9bDdb6ixOk1CTw1wKvsykICHpHCMuiJ9ligmpxCYkZHwNArN1vLDuzmYynkxoNQhBQ27KlWqlcQe14qRE8/UlUeNlbZJYzxBmmo3WCC1hvMTFxsELXz+1+c29UnV1Vu588sDCmePTvNb99PmHpu7O5pOP0hHNZlf2fmX13ssX99MXbMtX79KhvFuRbi7Uuo9efLRbm5q8O7MrDj8ayOdWbl86ePEyY0zjTK/JOfFZ5rAcG2JPsd9n/8Je6fz2z/6ay/DR+7ly3vvu44Kpt3/360+sdg+ND7vEfu9yR3Ba2MU1/61nuS/M8j/9mIeHniP/oEeOq1xHnWOaG67NORYy6YZyk7kOc9eYShEjxQCNJr5mr9QIMptM+L5YY0L468wXfvcfP/zBu7/zjRc+d+7TD33y9EajPjOdj6Ion0tb7BqVso7ieks1KiEl9k3YoRLVW6YQ6TRpEydxZEIqz+EdH4tos1qpQin6+rBE7coc1WgfNVq4gLa9iLYFewQdfBapHo9QnEBtkrgQ9TmOUImoEIFdbNtxy7tcDclssQQLcMNidMByvo7VCZj3GVh5sr+8tlLtr/0fLqXra0+u4UtvzO6ZpemFWdp+XnXkvTrIj0gZHMyoTiHWRqbOaC+VT/bLlD4u1YSTMieV46hTxt+i87Tu5Ae0EZaQQHmnSql75EDWSemTWtMjJ7RX5AdJFYb9wDezgg6KYc+cOGG8YdHIkJx2stliIvkBXnQxvE097fSp5X9LTF9YtOdY+3B4lk+NDE9P8w00i9PTf/4pyBLmk6FJHcjsfln39d6hlAOBgrqUR9NKObPBQJwix5xRtyhVBpSes3ewT+nvtpRSlwqpoXzAnd5fHHOddHhHyPnU0CSR36ApztFPO+4x182k7EzJbUAJpxKq2qlUxuXzmNtaVbVTQaO6tcjFIufWIp+oemuRw6xvYEy8zn/ICmy4M5iGltMyfBc/jyk6j8lHoiTa8lHGKg71TR8K129i8XqmN5qZzfR+mk538XyNHkPbzfCVGBPpNMX9buZ1Op/JdNNM3LwBX/QJ+KI0a7ODbKVzaCcp4RKHk4Q/4gKO6RwTigt1lhnGpeGb8Etbxke45zVIqNeZJt0tlGbycaUy7qjizGSzUYG56GGKYphBK9+o0XjZaMg4X4eN1KGTGqaVFLbmrQEtiQQ+t1zjmIaRXPecs47Xbz6/dN/u55fd1BGpXVWa3DMdD43vpf7UQK7olaLggwvvXvuzx/RT373+x89c+niZR7+xe632mZTflqYyVMoVBoP0/skIE7myn9GDxanVJ75/8eL3f2qbbb98TSyxIhvrlLJ97DlZ3IUND8SSQspnRSpKFc0oYF+tCfjXNnxrAtnrsb0Suh76vdfS3nR58KWnyytLtXw02zk8/vRLz/Ze94Y9Op72Wq3jk5/9HA1MlwvRxNQgvfjzZ3vf8vr7/yt/WTzJIrbrLepvf/TNCYQs3yrG4+gHhIjl3lKFje8kCVfxjMtj61z62tDeUoSIv9T7gHZ63v1+0e990vfpslfy7vf43/au9j7ov3r0NTzpsu/f75Ws2vV1wcalgL5H/8Y/c/RN9/j6nXvZ99ifsD9kX2NfYs/D0QuQfp7ZGCrY37C/YufYBruH7WdLbJ6Nsh3Ms2pCl+ll+hK9SC/QU/QEPUwPkmB/z/6OBeBg6ATdTVNY70BvrtOP6X36Ef0pvU17aB5jZMfZ8tDRNz3sf2B79+eZtIoHaQgr1f+BDIYt48zEbMg+PPT/B8TGRv8mOk3GhREcwdBoYfRZph2hnbPMIeHQWajHYwiqQrA1PJhYV7BeJrpbMHYWJPIMrsTDjBvFDYxZqy0eaouH+k8eSm3xUKdwdnVk6H+588bGnTusVtNVukJ/RH9A99Ip9gP2DnuLfYd9i32T/Tp7EhghdwAahJ+H7aIZa/wf+wFCYKwvURORtpVUbJC9g3SlGZlGRTdrcg4Kb3O0aJqisi6bVrUy3qpU52u8WrPDMATEc2NjuQ3luowXhMlqxdhfvWKWaNwyrcY2fLfq8XzcqNb7BDqxxNigCrbgWq3YfslGU4OtdGxqVI2r42WbC7QbSVWbumWFmFuxAdpAAizVpsSjdmywDAurFR3PWz4jEKitRwQ8h7b8mqCK261qjTdt9qBLfB5y10tyRMT1fm4Xt8s2dSiUKGk1wQWNPX2lldRbOC6OFenCeMtGA4ybsglFBSLYftXKBSfbwDniFjhB4Lhd4kCn1bZZ4xIhrWnWAEE/j6nWQVGGNEhlYtu241ZliQrt1riV0QJcbwIQgVQD6UsLOZD9pgknKwCvGm4tTZVWxeLe0oWQCjVqQ/DYJlFJpGN64+K7Fz722JTnDtJdKbKFvEeIuBqpnJbSU1qSg0gkhMQfIgxHUig1KMkJSBWRMnMQhMSNCxKC1pHxuFQpIaIwLx3khsSVyynvasmV9oQjofxCu+CmXOTWgitJofHTMiPAFbm6Yx9gLCSXOSWCANvzYMeQ0ErllfBlysdGWjrSlffUpeJaCRrwIIOSVk5sScQ9Y3LSuBIb8hB9HnLJedoRYC0USThfcFCB4cIRrom1RnKVkRH4gLkIUQV4ysl6HH+kOHpcBIIDDcgHQ/SxD3ci4WCBPbcCSviSHBCugAAixUMLByofriEDcJLSOMoEEh0kzaovSCB5Dsu5Cl3OPQdQaW2UG3i/+mvHEWxSWF+wbsMCrQLYPP7ISu7hhjigBhEEkX6auOuR2LcdS9H0fkIOuIFYKB9kYBGQZ/q4EkfSpYGrJHu5eOCdOxZWW//gro1wjGek0iqwqoGjBS5AUTiCyHIROnZcuLhWoSmUHlgqHMuTxhhylWMcgCQsllAHT4jQTiskL0ga0lxYZxYCAKnxgRC7fkXaW5c67UEGJYFH5HPSg5wSaJxQkRAZYCwd5UjyB1IqwKll4IQyJM+PDNwnIMdd5IQnpas0F14fYJ5xclZ/IYeHdMdeJfDOqLT1xdzHodGVA6EbKpeglYAaoMNMFE9DR/qFoHAUUl8HQIbc8xQGpO8qqxq4A5xZwiAAgSYcDwvtvaPppQon7Zk1T5O1A0DNPaExBHRDzS2N1SfLRxWdrBu6AZcZgzBr86BX+c/hkXcglp1mRzsrG6vHlkGfstGOL7tkHHOeOdw5b0VEdgp/b4toxc4zBWVGhaZsVqh09+Ta+PDRdjk3U8x7anhmEq69JpZ4idStt6RRsbkhHCncqYlKom3r2DZKL2nKNblV3eCHigZlTWIdkq1o6OGwXJsAxKP1Uo4e/KXO+rE7k1NTm9WTA/u7NNFaPVJ7oHZkdU/5mXJ8ZO3RU/WZlfuOdRfy4910cd/pfaunTxxZuG9xON39SVyb4hP1qUZZTs8O/JfOgQcCrYMHDuxemY3howanul+8eGhmqRzhQr2B8p6JQxcvbeyqd26fnYtytWm6vbN718Y2ljanEmwM9f4hdk/n2Mz0eBk2RMspe+MOP8w8A9XyUN06DHEVFb9GPNT0AC6ZuS5btU/mrjOXud3Ovj3NpDKfzS9msxkfiLbHmmNqPtvol6K2ch0fs4X/eHYeyen8WD02YjsZt8k2oG2p7DZRdovABpYr9EbvBF1fCdRXoQ2lpPd2XKKVldECvR+P0hXk0yagrfahUnIjh7AxGnOVtNKvZOKZK1foujNoXtEBXYtHR+NrN1r9J5W+bXPxb9u13o2P7BD/WTw6EH413bKljuw3tv7wkDMtsFX2Quf5ZfKdOUBTgFNF5k1yOZvivqMdX59DZWWkrULOpa1bsvZxzmYOTuBZ9OCX9Sa4Wjez2c89bH3C1kOwYd3FxbExZMJscXVxtXv00IHOHWMLYwuN+V0z1Ul/1B8d3JHPpUOtmEdeDjn+JCBqLFFsIt1GVCsjnvX/G7TEY1tTY9CmGeVQjG8Nk41x2+NcbxXoKMgnRmV/mC/6x+nw7AqtvkjTKyuH49hbU7PPPXdpRq29pHX3uZNzm4f3jHJ3TR957+pf3qUxah682rvykNHuGukzNEqzVP6UWquv+rkBXsz4q18uFothuOYZPXMbb+zUxlt7WS3soYHyxABG1ZFVfqyrMPpltb7O7zulLOmZCxfOWErG+M2bNz+Uc+IS6r85dltnV7/yG7XeehmGLlB0bPmgTdyTWodVB+yuJkJ7Jer//wlaVx2DzWajGIrUykOxzFgEGLYVDOg18WxvK5q45jm/+E2DKK/F0yY43JjsvZ/LUJTu/UM6olyu995EixqT4unJBp2m9/uEvTmDaHn1xqsYi2rIa+I4dMqzhdYE/8Rko8H+A1aSn2V4nGNgZGBgAOLec3ud4/ltvjJwM78AijBcXSQmBKP///2/hCWeuQXI5WBgAokCAGYHDMQAeJxjYGRgYG75P4eBgaXs/9//v1jiGYAiKIAXAKypBwR4nGN+wcDAvACIIxkYWPSBNIgf+f8viGY6BWXD5MtAav7/BwAzTA0aAAAAAABQALoCXgKWAxwDXAOcB6AIRgjWCZYJ+AABAAAADQH4AAYAAAAAAAIAJAA0AHMAAACtC3AAAAAAeJx1kN1qwjAYht/Mn20K29hgp8vRUMbqDwxBEASHnmwnMjwdtda2UhtJo+Bt7B52MbuJXcte2ziGspY0z/fky5evAXCNbwjkzxNHzgJnjHI+wSl6lgv0z5aL5BfLJVTxZrlM/265ggcElqu4wQcriOI5owU+LQtciUvLJ7gQd5YL9I+Wi+Se5RJuxavlMr1nuYKJSC1XcS++Bmq11VEQGlkb1GW72erI6VYqqihxY+muTah0KvtyrhLjx7FyPLXc89gP1rGr9+F+nvg6jVQiW05zr0Z+4mvX+LNd9XQTtI2Zy7lWSzm0GXKl1cL3jBMas+o2Gn/PwwAKK2yhEfGqQhhI1GjrnNtoooUOacoMycw8K0ICFzGNizV3hNlKyrjPMWeU0PrMiMkOPH6XR35MCrg/ZhV9tHoYT0i7M6LMS/blsLvDrBEpyTLdzM5+e0+x4WltWsNduy511pXE8KCG5H3s1hY0Hr2T3Yqh7aLB95//+wHmboRRAHicbcFBEoMgDAVQvkVQW3tHsFEzWHBCGK/votu+ZzrzM5n/ZnR4wKKHg8eAEROeeGHG2/QhlqZeqGoRGpeSV96aUFeS3ek43afkoGRjWJLPpFeR5DbWvUV/klSuai9eeVCSL+dwGHMDEm4d5nicY/DewXAiKGIjI2Nf5AbGnRwMHAzJBRsZWJ02MTAyaIEYm7mYGDkgLD4GMIvNaRfTAaA0J5DN7rSLwQHCZmZw2ajC2BEYscGhI2Ijc4rLRjUQbxdHAwMji0NHckgESEkkEGzmYWLk0drB+L91A0vvRiYGFwAMdiP0AAA=") format("woff"), url("data:application/octet-stream;base64,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") format("truetype"); } [class^="icn-"]::before, [class*=" icn-"]::before { font-family: "fontello"; font-style: normal; @@ -347,6 +347,9 @@ th { .icn-restore::before { content: '\267c'; } +.icn-configure::before { + content: '\2699'; } + .icn-ok::before { content: '\2714'; } @@ -539,6 +542,13 @@ ul > * { width: 160px; color: white; } +#content { + opacity: 0; + transition: opacity 0.15s ease-in; } + +#content.load { + opacity: 1; } + #loader { position: absolute; right: 1.618rem; @@ -601,10 +611,13 @@ ul > * { margin-top: 0.61805rem; } .Box .Row.explain { max-width: 600px; - margin-left: 0; } + margin-left: 0; + line-height: 1.2; } @media screen and (max-width: 544px) { .Box .Row.explain { margin-top: 60px; } } + .Box .Row.explain.nomargintop { + margin-top: 12px !important; } .Box.mobopen .Row.explain { margin-top: 12px; } @media screen and (max-width: 544px) { @@ -615,10 +628,11 @@ ul > * { .Box.mobcol h2 { position: relative; cursor: pointer; - padding-right: 1.3rem; } + padding: 2px 1.3rem 2px 5px; + margin: 0 -5px 0 -5px; } .Box.mobcol h2::after { position: absolute; - right: 0; + right: 4px; content: '▸'; top: 50%; font-size: 120%; @@ -776,6 +790,12 @@ button, input[type=submit], .button { button:focus, input[type=submit]:focus, .button:focus { outline-color: #ff0099; } +input[type="number"], input[type="password"], input[type="text"], textarea, select, label.select-wrap { + width: 250px; } + +input[type="number"], input.short, select.short { + width: 125px; } + input[type="number"], input[type="password"], input[type="text"], textarea, select { border: 0 none; border-bottom: 2px solid #2972ba; @@ -833,12 +853,6 @@ form { padding: 0; text-decoration: none; } -input[type="number"], input[type="password"], input[type="text"], textarea, select, label.select-wrap { - width: 250px; } - -input[type="number"], input.short { - width: 125px; } - .Box.errors .list { color: crimson; font-weight: bold; } @@ -861,9 +875,9 @@ input[type="number"], input.short { @media screen and (max-width: 544px) { .Row .spacer { display: none; } } - .Row.buttons { + .Row.buttons, .Row.buttons2 { margin: 16px auto; } - .Row.buttons input, .Row.buttons .button { + .Row.buttons input, .Row.buttons .button, .Row.buttons2 input, .Row.buttons2 .button { margin-right: 0.61805rem; } .Row.centered { justify-content: center; } @@ -960,7 +974,8 @@ form span.required { border-radius: 5px; padding: 0.38198rem; margin-bottom: 0.38198rem; - margin-top: 0.38198rem; } + margin-top: 0.38198rem; + font-size: 110%; } #ap-noscan { font-weight: bold; } diff --git a/html_orig/dump_js_lang.php b/html_orig/dump_js_lang.php index 41cf168..14b0db6 100755 --- a/html_orig/dump_js_lang.php +++ b/html_orig/dump_js_lang.php @@ -7,6 +7,7 @@ require_once __DIR__ . '/base.php'; $selected = [ 'wifi.connected_ip_is', 'wifi.not_conn', + 'wifi.enter_passwd', ]; $out = []; diff --git a/html_orig/fontello/fontello.zip b/html_orig/fontello/fontello.zip index 5b59d96..a9d757f 100644 Binary files a/html_orig/fontello/fontello.zip and b/html_orig/fontello/fontello.zip differ diff --git a/html_orig/js/app.js b/html_orig/js/app.js index 7ed55a3..0465e07 100644 --- a/html_orig/js/app.js +++ b/html_orig/js/app.js @@ -488,7 +488,7 @@ // Multiple select for (j = 0; j < value.length; j += 1) { elm[i].selected = ''; - if (elm[i].value === value[j]) { + if (elm[i].value === ""+value[j]) { elm[i].selected = 'selected'; break; } @@ -1007,10 +1007,17 @@ $.ready(function () { $._loader = function(vis) { $('#loader').toggleClass('show', vis); }; + +$.ready(function() { + setTimeout(function() { + $('#content').addClass('load'); + }, 1); +}); // Generated from PHP locale file var _tr = { "wifi.connected_ip_is": "Connected, IP is ", - "wifi.not_conn": "Not connected." + "wifi.not_conn": "Not connected.", + "wifi.enter_passwd": "Enter password for \":ssid:\"" }; function tr(key) { return _tr[key] || '?'+key+'?'; } @@ -1039,21 +1046,6 @@ function tr(key) { return _tr[key] || '?'+key+'?'; } $('#sta-nw .ip').html(ip.length>0 ? tr('wifi.connected_ip_is')+ip : tr('wifi.not_conn')); } - function submitPskModal(e, open) { - var passwd = $('#conn-passwd').val(); - var ssid = $('#conn-ssid').val(); - - if (open || passwd.length) { - $('#sta_password').val(passwd); - $('#sta_ssid').val(ssid); - selectSta(ssid, passwd, ''); - } - - if (e) e.preventDefault(); - Modal.hide('#psk-modal'); - return false; - } - /** Update display for received response */ function onScan(resp, status) { //var ap_json = { @@ -1123,19 +1115,18 @@ function tr(key) { return _tr[key] || '?'+key+'?'; } $item.on('click', function () { var $th = $(this); - var ssid = $th.data('ssid'); - - $('#conn-ssid').val(ssid); - $('#conn-passwd').val(''); + var conn_ssid = $th.data('ssid'); + var conn_pass = ''; if (+$th.data('pwd')) { // this AP needs a password - Modal.show('#psk-modal'); - $('#conn-passwd')[0].focus(); - } else { - //Modal.show('#reset-modal'); - submitPskModal(null, true); + conn_pass = prompt(tr("wifi.enter_passwd").replace(":ssid:", conn_ssid)); + if (!conn_pass) return; } + + $('#sta_password').val(conn_pass); + $('#sta_ssid').val(conn_ssid); + selectSta(conn_ssid, conn_pass, ''); }); @@ -1148,6 +1139,7 @@ function tr(key) { return _tr[key] || '?'+key+'?'; } $('#ap-loader').removeClass('hidden'); $('#ap-scan').addClass('hidden'); $('#ap-loader .anim-dots').html('.'); + scanAPs(); } @@ -1162,12 +1154,6 @@ function tr(key) { return _tr[key] || '?'+key+'?'; } /** Set up the WiFi page */ function wifiInit(cfg) { - // Hide what should be hidden in this mode - cfg.mode = +cfg.mode; - - $('#ap-noscan').toggleClass('hidden', cfg.mode != 2); - $('#ap-scan').toggleClass('hidden', cfg.mode == 2); - // Update slider value displays $('.Row.range').forEach(function(x) { var inp = x.querySelector('input'); diff --git a/html_orig/jssrc/appcommon.js b/html_orig/jssrc/appcommon.js index 0e5616b..4344bcd 100644 --- a/html_orig/jssrc/appcommon.js +++ b/html_orig/jssrc/appcommon.js @@ -108,3 +108,9 @@ $.ready(function () { $._loader = function(vis) { $('#loader').toggleClass('show', vis); }; + +$.ready(function() { + setTimeout(function() { + $('#content').addClass('load'); + }, 1); +}); diff --git a/html_orig/jssrc/chibi.js b/html_orig/jssrc/chibi.js index db51e2c..ae975ca 100755 --- a/html_orig/jssrc/chibi.js +++ b/html_orig/jssrc/chibi.js @@ -488,7 +488,7 @@ // Multiple select for (j = 0; j < value.length; j += 1) { elm[i].selected = ''; - if (elm[i].value === value[j]) { + if (elm[i].value === ""+value[j]) { elm[i].selected = 'selected'; break; } diff --git a/html_orig/jssrc/lang.js b/html_orig/jssrc/lang.js index 6ef4755..327dae9 100644 --- a/html_orig/jssrc/lang.js +++ b/html_orig/jssrc/lang.js @@ -1,7 +1,8 @@ // Generated from PHP locale file var _tr = { "wifi.connected_ip_is": "Connected, IP is ", - "wifi.not_conn": "Not connected." + "wifi.not_conn": "Not connected.", + "wifi.enter_passwd": "Enter password for \":ssid:\"" }; function tr(key) { return _tr[key] || '?'+key+'?'; } diff --git a/html_orig/jssrc/wifi.js b/html_orig/jssrc/wifi.js index ece92c7..6b8c238 100644 --- a/html_orig/jssrc/wifi.js +++ b/html_orig/jssrc/wifi.js @@ -23,21 +23,6 @@ $('#sta-nw .ip').html(ip.length>0 ? tr('wifi.connected_ip_is')+ip : tr('wifi.not_conn')); } - function submitPskModal(e, open) { - var passwd = $('#conn-passwd').val(); - var ssid = $('#conn-ssid').val(); - - if (open || passwd.length) { - $('#sta_password').val(passwd); - $('#sta_ssid').val(ssid); - selectSta(ssid, passwd, ''); - } - - if (e) e.preventDefault(); - Modal.hide('#psk-modal'); - return false; - } - /** Update display for received response */ function onScan(resp, status) { //var ap_json = { @@ -107,19 +92,18 @@ $item.on('click', function () { var $th = $(this); - var ssid = $th.data('ssid'); - - $('#conn-ssid').val(ssid); - $('#conn-passwd').val(''); + var conn_ssid = $th.data('ssid'); + var conn_pass = ''; if (+$th.data('pwd')) { // this AP needs a password - Modal.show('#psk-modal'); - $('#conn-passwd')[0].focus(); - } else { - //Modal.show('#reset-modal'); - submitPskModal(null, true); + conn_pass = prompt(tr("wifi.enter_passwd").replace(":ssid:", conn_ssid)); + if (!conn_pass) return; } + + $('#sta_password').val(conn_pass); + $('#sta_ssid').val(conn_ssid); + selectSta(conn_ssid, conn_pass, ''); }); @@ -132,6 +116,7 @@ $('#ap-loader').removeClass('hidden'); $('#ap-scan').addClass('hidden'); $('#ap-loader .anim-dots').html('.'); + scanAPs(); } @@ -146,12 +131,6 @@ /** Set up the WiFi page */ function wifiInit(cfg) { - // Hide what should be hidden in this mode - cfg.mode = +cfg.mode; - - $('#ap-noscan').toggleClass('hidden', cfg.mode != 2); - $('#ap-scan').toggleClass('hidden', cfg.mode == 2); - // Update slider value displays $('.Row.range').forEach(function(x) { var inp = x.querySelector('input'); diff --git a/html_orig/lang/en.php b/html_orig/lang/en.php index c3d6b69..d25b3b6 100644 --- a/html_orig/lang/en.php +++ b/html_orig/lang/en.php @@ -4,13 +4,13 @@ return [ 'appname' => 'ESPTerm', 'menu.cfg_wifi' => 'WiFi Settings', - 'menu.cfg_network' => 'Network Configuration', - 'menu.cfg_app' => 'Terminal Settings', + 'menu.cfg_network' => 'Network Settings', + 'menu.cfg_term' => 'Terminal Settings', 'menu.about' => 'About ESPTerm', 'menu.help' => 'Quick Reference', 'menu.term' => 'Back to Terminal', - 'menu.cfg_admin' => 'Reset & Restore', - 'menu.cfg_wifi_conn' => 'Connecting to External Network', + 'menu.cfg_system' => 'System Settings', + 'menu.cfg_wifi_conn' => 'Connecting to Network', 'menu.settings' => 'Settings', @@ -22,30 +22,31 @@ return [ 'net.ap_mac' => 'AP MAC', 'net.details' => 'MAC addresses', - 'app.defaults' => 'Initial settings', - 'app.explain_initials' => ' - Those are the initial settings used after ESPTerm restarts, and they - will also be applied immediately after you submit this form. - They can be subsequently changed by ESC commands, but those changes - aren\'t persistent and will be lost when the device powers off.', - - 'app.term_title' => 'Header text', - 'app.term_width' => 'Screen width', - 'app.term_height' => 'Screen height', - 'app.default_fg' => 'Base text color', - 'app.default_bg' => 'Base background', - 'app.btn1' => 'Button 1 text', - 'app.btn2' => 'Button 2 text', - 'app.btn3' => 'Button 3 text', - 'app.btn4' => 'Button 4 text', - 'app.btn5' => 'Button 5 text', - + 'term.defaults' => 'Initial Settings', + 'term.explain_initials' => ' + Those are the initial settings used after ESPTerm powers on. They + will also be applied immediately after you submit this form.', + + 'term.example' => 'Color settings example', + + 'term.term_title' => 'Header text', + 'term.term_width' => 'Screen width', + 'term.term_height' => 'Screen height', + 'term.default_fg' => 'Text color', + 'term.default_bg' => 'Background', + 'term.btn1' => 'Button 1 text', + 'term.btn2' => 'Button 2 text', + 'term.btn3' => 'Button 3 text', + 'term.btn4' => 'Button 4 text', + 'term.btn5' => 'Button 5 text', + + // terminal color labels 'color.0' => 'Black', 'color.1' => 'Dark Red', 'color.2' => 'Dark Green', 'color.3' => 'Dim Yellow', 'color.4' => 'Deep Blue', - 'color.5' => 'Dark Violet', + 'color.5' => 'Deep Purple', 'color.6' => 'Dark Cyan', 'color.7' => 'Silver', 'color.8' => 'Gray', @@ -53,21 +54,15 @@ return [ 'color.10' => 'Light Green', 'color.11' => 'Light Yellow', 'color.12' => 'Light Blue', - 'color.13' => 'Light Violet', + 'color.13' => 'Light Purple', 'color.14' => 'Light Cyan', 'color.15' => 'White', 'net.explain_sta' => ' - Those settings affect the built-in DHCP client used for - connecting to an external network. Switching DHCP (dynamic IP) off - makes ESPTerm use the configured static IP. Please double-check - those settings before submitting, setting them incorrectly may - make it hard to access ESPTerm via the external network.', + Switch off Dynamic IP to configure the static IP address.', 'net.explain_ap' => ' - Those settings affect the built-in DHCP server in AP mode. - Please double-check those settings before submitting, setting them - incorrectly may render ESPTerm inaccessible via the AP.', + Those settings affect the built-in DHCP server in AP mode.', 'net.ap_dhcp_time' => 'Lease time', 'net.ap_dhcp_start' => 'Pool start IP', @@ -81,7 +76,7 @@ return [ 'net.sta_addr_gw' => 'Gateway IP', 'wifi.ap' => 'Built-in Access Point', - 'wifi.sta' => 'Connect to External Network', + 'wifi.sta' => 'Join Existing Network', 'wifi.enable' => 'Enabled', 'wifi.tpw' => 'Transmit power', @@ -99,9 +94,11 @@ return [ 'wifi.sta_password' => 'Password:', 'wifi.scanning' => 'Scanning', - 'wifi.scan_now' => 'Start scanning!', - 'wifi.cant_scan_no_sta' => 'Can\'t scan with Client mode disabled.', + 'wifi.scan_now' => 'Click here to start scanning!', + 'wifi.cant_scan_no_sta' => 'Click here to enable client mode and start scanning!', 'wifi.select_ssid' => 'Available networks:', + 'wifi.enter_passwd' => 'Enter password for ":ssid:"', + 'wifi.sta_explain' => 'After selecting a network, press Apply to connect.', 'wifi.conn.status' => 'Status:', 'wifi.conn.back_to_config' => 'Back to WiFi config', @@ -113,22 +110,36 @@ return [ 'wifi.conn.working' => "Connecting to selected AP", 'wifi.conn.fail' => "Connection failed, check settings & try again. Cause: ", - 'admin.confirm_restore' => 'Restore all settings to their default values?', - 'admin.confirm_restore_hard' => + 'system.save_restore' => 'Save & Restore', + 'system.confirm_restore' => 'Restore all settings to their default values?', + 'system.confirm_restore_hard' => 'Restore to firmware default settings? This will reset ' . 'all active settings and switch to AP mode with the default SSID.', - 'admin.confirm_store_defaults' => + 'system.confirm_store_defaults' => 'Enter admin password to confirm you want to store the current settings as defaults.', - 'admin.password' => 'Admin password:', - 'admin.restore_defaults' => 'Reset to default settings', - 'admin.write_defaults' => 'Save current settings as default', - 'admin.restore_hard' => 'Reset to firmware default settings', - 'admin.explain' => ' + 'system.password' => 'Admin password:', + 'system.restore_defaults' => 'Reset to default settings', + 'system.write_defaults' => 'Save current settings as default', + 'system.restore_hard' => 'Reset to firmware default settings', + 'system.explain_persist' => ' ESPTerm contains two persistent memory banks, one for default and one for active settings. Active settings can be stored as defaults by the administrator. Use the following button to revert all active settings to their stored default values. ', + 'system.uart' => 'Serial Port', + 'system.explain_uart' => ' + This form controls the primary UART. The debug port is fixed at 115200 baud, one stop-bit and no parity. + ', + 'uart.baud' => 'Baud rate', + 'uart.parity' => 'Parity', + 'uart.parity.none' => 'None', + 'uart.parity.odd' => 'Odd', + 'uart.parity.even' => 'Even', + 'uart.stop_bits' => 'Stop-bits', + 'uart.stop_bits.one' => 'One', + 'uart.stop_bits.one_and_half' => 'One and half', + 'uart.stop_bits.two' => 'Two', 'apply' => 'Apply!', 'enabled' => 'Enabled', diff --git a/html_orig/pages/cfg_admin.php b/html_orig/pages/cfg_admin.php deleted file mode 100644 index 986f83e..0000000 --- a/html_orig/pages/cfg_admin.php +++ /dev/null @@ -1,34 +0,0 @@ -
-
- -
- -
- - - -
- -
- -
- -
- - - -
-
- - diff --git a/html_orig/pages/cfg_network.php b/html_orig/pages/cfg_network.php index 00cf133..e31930a 100644 --- a/html_orig/pages/cfg_network.php +++ b/html_orig/pages/cfg_network.php @@ -12,7 +12,7 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
- +
@@ -43,9 +43,13 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
- - -  (min) + + required> +
+ +
+ + required>
@@ -59,13 +63,9 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
- - required> -
- -
- - required> + + +  min
@@ -86,10 +86,13 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"'; diff --git a/html_orig/pages/cfg_system.php b/html_orig/pages/cfg_system.php new file mode 100644 index 0000000..d0287a3 --- /dev/null +++ b/html_orig/pages/cfg_system.php @@ -0,0 +1,90 @@ +
+

+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + + +
+
+ + +
+

+ +
+ +
+ +
+ + +  bps +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ + diff --git a/html_orig/pages/cfg_app.php b/html_orig/pages/cfg_term.php similarity index 50% rename from html_orig/pages/cfg_app.php rename to html_orig/pages/cfg_term.php index d967641..3cc0e04 100644 --- a/html_orig/pages/cfg_app.php +++ b/html_orig/pages/cfg_term.php @@ -1,67 +1,69 @@ -
-

+ +

- +
- - -
- -
- - +
- - -
- - -
- + + +
+ +
+ + +
+ +
+
- +
- +
- +
- +
- +
@@ -69,3 +71,16 @@
+ + diff --git a/html_orig/pages/cfg_wifi.php b/html_orig/pages/cfg_wifi.php index cd8fe1c..2df7d0b 100644 --- a/html_orig/pages/cfg_wifi.php +++ b/html_orig/pages/cfg_wifi.php @@ -1,28 +1,28 @@

-
+
- +
-
+
-
+
-
+
-
+
-
+
@@ -45,16 +45,21 @@

-
+
- + +
+ +
+ +
-
+
-
+
-
@@ -85,24 +89,35 @@
- - diff --git a/html_orig/sass/_fontello.scss b/html_orig/sass/_fontello.scss index bbf60f7..3eae0aa 100644 --- a/html_orig/sass/_fontello.scss +++ b/html_orig/sass/_fontello.scss @@ -4,8 +4,8 @@ @font-face { font-family: 'fontello'; - src: url('data:application/octet-stream;base64,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') format('woff'), - url('data:application/octet-stream;base64,AAEAAAAPAIAAAwBwR1NVQiCLJXoAAAD8AAAAVE9TLzJ8JWGYAAABUAAAAFZjbWFwTGjuqQAAAagAAAIaY3Z0IAc5/2gAABiQAAAAIGZwZ22KkZBZAAAYsAAAC3BnYXNwAAAAEAAAGIgAAAAIZ2x5ZhgKlUQAAAPEAAAQqGhlYWQOv2gyAAAUbAAAADZoaGVhB+MEGQAAFKQAAAAkaG10eCvN//kAABTIAAAAMGxvY2EYfBK+AAAU+AAAABptYXhwAVINngAAFRQAAAAgbmFtZcydHR8AABU0AAACzXBvc3QWfEFKAAAYBAAAAIRwcmVw5UErvAAAJCAAAACGAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAEDpgGQAAUAAAJ6ArwAAACMAnoCvAAAAeAAMQECAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQCYF//8DhP+cAFoDhABkAAAAAQAAAAAAAAAAAAUAAAADAAAALAAAAAQAAAGGAAEAAAAAAIAAAwABAAAALAADAAoAAAGGAAQAVAAAAA4ACAACAAYmBSZ8JxQnUydkJ27//wAAJgUmfCcUJ1MnZCdu//8AAAAAAAAAAAAAAAAAAQAOAA4ADgAOAA4ADgAAAAEAAgADAAQABQAGAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAACUAAAAAAAAAAsAACYFAAAmBQAAAAEAACZ8AAAmfAAAAAIAACcUAAAnFAAAAAMAACdTAAAnUwAAAAQAACdkAAAnZAAAAAUAACduAAAnbgAAAAYAAfMNAAHzDQAAAAcAAfQxAAH0MQAAAAgAAfS+AAH0vgAAAAkAAfT2AAH09gAAAAoAAfWzAAH1swAAAAsAAAABAAD//AOhA3IAHwA1QAoSDwoEAwUAAgFHS7AcUFhADAEBAAIAcAACAgwCSRtACgACAAJvAQEAAGZZtR0UFwMFFysBFA8BExUUDgEvAQcGIiY1NDcTJyY1NDclNzYyHwEFFgOhD8owDBUM+/oMFgwBMMsOHwEYfgsgDH0BGCACGwwPxf7pDAsQAQeEhAcSCgQIARfFDwwVBSj+Fxf+KAUAAQAA/+MDWQM9ADEAPkA7KgEDBSUdAgQDAkcABAMBAwQBbQABAgMBAmsABQADBAUDYAACAAACVAACAgBYAAACAEwpNRcjFyQGBRorARQOAgciJicmND8BNhYXHgEzMj4DLgIiBgcXFgYrASImJzU0Nh8BPgEzMh4CA1lEcqBWYK48BAVMBhEEKXZDOmhQKgIuTGxvZChNERMX+g8UASwRSDyaUleedEIBkFeedEICUkkGDgRNBQEGNTouTGp0akwuKCVNEC0WDvoYExJIOT5EdJ4AAAABAAAAAAOlAsoAFQAdQBoPAQABAUcAAgECbwABAAFvAAAAZhQXFAMFFysBFAcBBiInASY0PwE2Mh8BATYyHwEWA6UQ/iAQLBD+6g8PTBAsEKQBbhAsEEwQAkgWEP4gDw8BFhAsEEwQEKUBbxAQTA8AA//9/+MDXwM9AA8ANwBEAEhARSkBBQMJAQIBAAJHAAQCAwIEA20AAwUCAwVrAAcAAgQHAmAABQAAAQUAYAABBgYBVAABAQZYAAYBBkwVHisTFiYmIwgFHCslNTQmKwEiBh0BFBY7ATI2EzQuASMiBwYfARYzMjc+ATIWFRQGBw4BFxUUFjsBMjY0Nj8BPgMXFA4BIi4CPgEyHgEB9AoIawgKCghrCAqPPlwxiEcJDUoEBgkFHiU4KhYbIzwBCghrCAoYEhwKHhQM13LG6MhuBnq89Lp+hGsICgoIawgKCgF/MVQudw0LNwQHJhseEhUaDA9CJRQICgoSIgsQBhocKFJ1xHR0xOrEdHTEAAEAAP/jA+gDPgAcACFAHhEBAAEBRwIBAQABbwMBAABmAQAXFQ0LABwBHAQFFCsFIicBJy4DNTQ2NzIeAhc+AxcyFhQHAQYB9A4L/qQPCioiGo59Ikg+LhMULEBGI32OgP6lCh0KAVAPCjY2UCV7igEYKiIVFCQoGgGM9YD+sQoAAQAA//ICmAN2ABQALbUBAQABAUdLsCRQWEALAAABAHAAAQEMAUkbQAkAAQABbwAAAGZZtBcXAgUWKwkCFhQPAQYiJwEmNDcBNjIfARYUAo7+1wEpCgpdCxwL/mILCwGeCh4KXQoC3P7Y/tcKHgpdCgoBnwoeCgGeCwtdCh4AAAAD//3/4wNZAz0ADAG9AfcCd0uwCVBYQTwAvQC7ALgAnwCWAIgABgADAAAAjwABAAIAAwDaANMAbQBZAFEAQgA+ADMAIAAZAAoABwACAZ4BmAGWAYwBiwF6AXUBZQFjAQMA4QDgAAwABgAHAVMBTQEoAAMACAAGAfQB2wHRAcsBwAG+ATgBMwAIAAEACAAGAEcbS7AKUFhBQwC7ALgAnwCIAAQABQAAAL0AAQADAAUAjwABAAIAAwDaANMAbQBZAFEAQgA+ADMAIAAZAAoABwACAZ4BmAGWAYwBiwF6AXUBZQFjAQMA4QDgAAwABgAHAVMBTQEoAAMACAAGAfQB2wHRAcsBwAG+ATgBMwAIAAEACAAHAEcAlgABAAUAAQBGG0E8AL0AuwC4AJ8AlgCIAAYAAwAAAI8AAQACAAMA2gDTAG0AWQBRAEIAPgAzACAAGQAKAAcAAgGeAZgBlgGMAYsBegF1AWUBYwEDAOEA4AAMAAYABwFTAU0BKAADAAgABgH0AdsB0QHLAcABvgE4ATMACAABAAgABgBHWVlLsAlQWEA1AAIDBwMCB20ABwYDBwZrAAYIAwYIawAIAQMIAWsAAQFuCQEAAwMAVAkBAAADWAUEAgMAA0wbS7AKUFhAOgQBAwUCBQNlAAIHBQIHawAHBgUHBmsABggFBghrAAgBBQgBawABAW4JAQAFBQBUCQEAAAVWAAUABUobQDUAAgMHAwIHbQAHBgMHBmsABggDBghrAAgBAwgBawABAW4JAQADAwBUCQEAAANYBQQCAwADTFlZQRkAAQAAAdgB1gG5AbcBVwFWAMcAxQC1ALQAsQCuAHkAdgAHAAYAAAAMAAEADAAKAAUAFCsBMh4BFA4BIi4CPgEBDgEHMj4BNT4BNzYXJjY/ATY/AQYmNRQHNCYGNS4ELwEmNC8BBwYUKgEUIgYiBzYnJiM2JiczLgInLgEHBhQfARYGHgEHBg8BBhYXFhQGIg8BBiYnJicmByYnJgcyJgc+ASM2PwE2JxY/ATY3NjIWMxY0JzInJicmBwYXIg8BBi8BJiciBzYmIzYnJiIPAQYeATIXFgciBiIGFgcuAScWJyMiBiInJjc0FycGBzI2PwE2FzcXJgcGBxYHJy4BJyIHBgceAhQ3FgcyFxYXFgcnJgYWMyIPAQYfAQYWNwYfAx4CFwYWByIGNR4CFBY3NicuAjUzMh8BBh4CMx4BBzIeBB8DFjI/ATYWFxY3Ih8BHgEVHgEXNjUGFjM2NQYvASY0JjYXMjYuAicGJicUBhUjNjQ/ATYvASYHIgcOAyYnLgE0PwE2JzY/ATY7ATI0NiYjFjYXFjcnJjcWNx4CHwEWNjcWFx4BPgEmNSc1LgE2NzQ2PwE2JzI3JyYiNzYnPgEzFjYnPgE3FjYmPgEVNzYjFjc2JzYmJzMyNTYnJgM2NyYiLwE2Ji8BJi8BJg8BIg8BFSYnIi4BDgEPASY2JgYPAQY2BhUOARUuATceARcWBwYHBhcUBhYBrXTGcnLG6MhuBnq8ARMCCAMBAgQDERUTCgEMAggGAwEHBgQECgUGBAEIAQIBAwMEBAQEBgEGAggJBQQGAgQDAQgMAQUcBAMCAgEIAQ4BAgcJAwQEAQQCAwEHCgIEBQ0DAxQOEwQIBgECAQIFCQIBEwkGBAIFBgoDCAQHBQIDBgkEBgEFCQQFAwMCBQQBDgcLDwQQAwMBCAQIAQgDAQgEAwICAwQCBBIFAwwMAQMDAgwZGwMGBQUTBQMLBA0LAQQCBgQIBAkEUTIEBQIGBQMBGAoBAgcFBAMEBAQBAgEBAQIKBwcSBAcJBAMIBAIOAQECAg4CBAICDwgDBAMCAwUBBAoKAQQIBAUMBwIDCAMJBxYGBgUICBAEFAoBAgQCBgMOAwQBCgUIEQoCAgICAQUCBAEKAgMMAwIIAQIIAwEDAgcLBAECAggUAwgKAQIBBAIDBQIBAwIBAwEEGAMJAwEBAQMNAg4EAgMBBAMFAgYIBAICAQgEBAcIBQcMBAQCAgIGAQUEAwIDBQwEAhIBBAICBQ4JAgIKCAUJAgYGBwUJDAppc1ABDAENAQQDFQEDBQIDAgIBBQwIAwYGBgYBAQQIBAoBBwYCCgIEAQwBAQICBAsPAQIJCgEDPXTE6sR0dMTqxHT+3QEIAgYGAQQIAwULAQwBAwICDAEKBwIDBAIEAQIGDAUGAwMCBAEBAwMEAgQBAwMCAggEAgYEAQMEAQQEBgcDCAcKBwQFBgUMAwECBAIBAwwJDgMEBQcIBQMRAgMOCAUMAwEDCQkGBAMGAQ4ECgQBAgUCAgYKBAcHBwEJBQgHCAMCBwMCBAIGAgQFCgMDDgIFAgIFBAcCAQoIDwIDAwcDAg4DAgMEBgQGBAQBAS1PBAEIBAMEBg8KAgYEBQQFDgkUCwIBBhoCARcFBAYDBRQDAxAFAgEECAUIBAELGA0FDAICBAQMCA4EDgEKCxQHCAEFAw0CAQIBEgMKBAQJBQYCAwoDAgMFDAIQCBIDAwQEBgIECgcOAQUCBAEEAgIQBQ8FAgUDAgsCCAQEAgIEGA4JDgUJAQQGAQIDAgEEAwYHBgUCDwoBBAECAwECAwgFFwQCCAgDBQ4CCgoFAQIDBAsJBQICAgIGAgoGCgQEBAMBBAoEBgEHAgEHBgUEAgMBBQQC/g0VVQICBQQGAg8BAQIBAgEBAwIKAwYCAgUGBwMOBgIBBQQCCAECCAICAgIFHAgRCQ4JDAIEEAcABAAA/+MDoQL1AAwAGQAzAFoAS0BIWVJORwQCCA0AAgADAkcJAQcIB28ACAIIbwQBAgMCbwADAANvAQEABQBvAAUGBgVUAAUFBlgABgUGTFVUIx1LNyISKxwTCgUdKyUUDgEuAz4CHgEFFA4BLgM+Ah4BFzQmIyIHBiInJiMiBgcUHgM3MzI+AzcUBw4EByIuBCcmNTQ3JjU0NzIWFzYzMhc+ATcWFRQHFgFlDiIuJAwCECAyHhIBYw4iLiQMAhAgMh4SWE5BF1YoYCdVGEJMASQ2UkouXi5KUjgifiIWSlRqVjIrSFxOTDoTI0wPHD1aPVJaU0o6XDsdD0zdFi4oAiQyKDQiBCosGBYuKAIkMig0IgQqLBhDXgwGBgxeQzFILBYMAggaKEySdEUrPiIUBAEEChgiOCRFdIRZLTJAOSwvFBIuKgE5QDEtWQAEAAD/4wNZAz0AAwAhADEARQBRQE4rKiMiBAgEAUcNAQQGAQgCRgAKBwEECAoEYAAIAAMGCANgAAYAAQAGAV4FAgIACQkAUgUCAgAACVgACQAJTEA9ODUXJjMREzsRERALBR0rNyE1IQUzETQmLwEuAQcVFAYjISImJzUjETM1NDYzITIWBwM1NCYrASIGFxUUFjczMjYFERQGIyEiJicRNDYzITIWHwEeAdYBrf5TAfRIDAWdBRwIHhf+vhYeAUhIIBUB0RYgAdYKCGsHDAEKCGsHDAFkHhf9EhceASAWAgUXNg+cEBYr1tYB9AgaB5wGDAHoFiAgFuj9NugWICAWAR6yCAoKCLIHDAEKCv36FiAgFgLuFiAYDp0PNgAAAAAEAAAAAARfAz0ACgAgADoAUgCLQIhHAQsILwEEBhUBAgcDAQABBEcRDQILCAYICwZtEAkCBwQCBAcCbQ8FAgMCAQIDAW0ADAAKCAwKYAAIAAYECAZgAAQAAgMEAmAAAQAAAVQAAQEAWA4BAAEATDs7ISELCwEAO1I7UkxLRUNAPyE6ITo0My0rJyULIAsgGhkTEg8OBgUACgEKEgUUKyUiJic0PgEWBxQGNyIuASIGDwEiJjU0Nz4CFhcWFRQGNyInLgEHIg4DIyImNTQ3PgEeARcWFRQGNyInLgIGBwYjIiYnNDc2JCAEFxYVFAYCOwtQAUYsSAFSjAEqSEhGFhYKVAUsgoKEKwVUjgYGTIJVL2BGOCACCVQGStDY0kkGVI4GB2PY/tZkBwYJVAEGaAEgASwBImcFVDJSCxIYAhwQC1KXHBwcDg5UCgcGKzACNCkGBwpUmAU6OAEYIiQYVAoHBUpSAk5MBQcKVJcFWFgCXFYFVAoHBmhycmgGBwpUAAAC////4wQvA4QADwAvADBALQkBAgEAIAEDAgJHAAMCA3AAAQQBAgMBAmAAAAAFWAAFBQwASTUmNiYmFAYFGisBETQmJyEiBgcRFBYzITI2ExEUBgchFB4BFxQGIyEiJic0PgE1ISImNxE0NjMhMhYD6AoI/IMHCgEMBgN9BwxGNCX+0RIQARQP/uIPFAESEv7QJDYBNCUDfSU0AVoB0QcKAQwG/i8HCgoB2P2hJTQBFC4iBw4WFg4IIiwVNiQCXyU0NAAAAQAAAAEAAE1y57NfDzz1AAsD6AAAAADVohHzAAAAANWiEfP//f/jBF8DhAAAAAgAAgAAAAAAAAABAAADhP+cAAAEdv/9//oEXwABAAAAAAAAAAAAAAAAAAAADAPoAAADoAAAA1kAAAPoAAADWf/9A+gAAALKAAADWf/9A6AAAANZAAAEdgAABC///wAAAAAAUAC6APIBeAG4AfgF/AaiBzIH8ghUAAAAAQAAAAwB+AAEAAAAAAACACQANABzAAAAqgtwAAAAAAAAABIA3gABAAAAAAAAADUAAAABAAAAAAABAAgANQABAAAAAAACAAcAPQABAAAAAAADAAgARAABAAAAAAAEAAgATAABAAAAAAAFAAsAVAABAAAAAAAGAAgAXwABAAAAAAAKACsAZwABAAAAAAALABMAkgADAAEECQAAAGoApQADAAEECQABABABDwADAAEECQACAA4BHwADAAEECQADABABLQADAAEECQAEABABPQADAAEECQAFABYBTQADAAEECQAGABABYwADAAEECQAKAFYBcwADAAEECQALACYByUNvcHlyaWdodCAoQykgMjAxNyBieSBvcmlnaW5hbCBhdXRob3JzIEAgZm9udGVsbG8uY29tZm9udGVsbG9SZWd1bGFyZm9udGVsbG9mb250ZWxsb1ZlcnNpb24gMS4wZm9udGVsbG9HZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuaHR0cDovL2ZvbnRlbGxvLmNvbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAAMgAwADEANwAgAGIAeQAgAG8AcgBpAGcAaQBuAGEAbAAgAGEAdQB0AGgAbwByAHMAIABAACAAZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AZgBvAG4AdABlAGwAbABvAFIAZQBnAHUAbABhAHIAZgBvAG4AdABlAGwAbABvAGYAbwBuAHQAZQBsAGwAbwBWAGUAcgBzAGkAbwBuACAAMQAuADAAZgBvAG4AdABlAGwAbABvAEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAAAACAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwBAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0ABWFib3V0B3Jlc3RvcmUCb2sEaGVscAZkb25hdGUEYmFjawduZXR3b3JrBmdpdGh1YgdwZXJzaXN0BHdpZmkIdGVybWluYWwAAAABAAH//wAPAAAAAAAAAAAAAAAAAAAAAAAYABgAGAAYA4T/nAOE/5ywACwgsABVWEVZICBLuAAOUUuwBlNaWLA0G7AoWWBmIIpVWLACJWG5CAAIAGNjI2IbISGwAFmwAEMjRLIAAQBDYEItsAEssCBgZi2wAiwgZCCwwFCwBCZasigBCkNFY0VSW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCxAQpDRWNFYWSwKFBYIbEBCkNFY0UgsDBQWCGwMFkbILDAUFggZiCKimEgsApQWGAbILAgUFghsApgGyCwNlBYIbA2YBtgWVlZG7ABK1lZI7AAUFhlWVktsAMsIEUgsAQlYWQgsAVDUFiwBSNCsAYjQhshIVmwAWAtsAQsIyEjISBksQViQiCwBiNCsQEKQ0VjsQEKQ7ABYEVjsAMqISCwBkMgiiCKsAErsTAFJbAEJlFYYFAbYVJZWCNZISCwQFNYsAErGyGwQFkjsABQWGVZLbAFLLAHQyuyAAIAQ2BCLbAGLLAHI0IjILAAI0JhsAJiZrABY7ABYLAFKi2wBywgIEUgsAtDY7gEAGIgsABQWLBAYFlmsAFjYESwAWAtsAgssgcLAENFQiohsgABAENgQi2wCSywAEMjRLIAAQBDYEItsAosICBFILABKyOwAEOwBCVgIEWKI2EgZCCwIFBYIbAAG7AwUFiwIBuwQFlZI7AAUFhlWbADJSNhRESwAWAtsAssICBFILABKyOwAEOwBCVgIEWKI2EgZLAkUFiwABuwQFkjsABQWGVZsAMlI2FERLABYC2wDCwgsAAjQrILCgNFWCEbIyFZKiEtsA0ssQICRbBkYUQtsA4ssAFgICCwDENKsABQWCCwDCNCWbANQ0qwAFJYILANI0JZLbAPLCCwEGJmsAFjILgEAGOKI2GwDkNgIIpgILAOI0IjLbAQLEtUWLEEZERZJLANZSN4LbARLEtRWEtTWLEEZERZGyFZJLATZSN4LbASLLEAD0NVWLEPD0OwAWFCsA8rWbAAQ7ACJUKxDAIlQrENAiVCsAEWIyCwAyVQWLEBAENgsAQlQoqKIIojYbAOKiEjsAFhIIojYbAOKiEbsQEAQ2CwAiVCsAIlYbAOKiFZsAxDR7ANQ0dgsAJiILAAUFiwQGBZZrABYyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsQAAEyNEsAFDsAA+sgEBAUNgQi2wEywAsQACRVRYsA8jQiBFsAsjQrAKI7ABYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wFCyxABMrLbAVLLEBEystsBYssQITKy2wFyyxAxMrLbAYLLEEEystsBkssQUTKy2wGiyxBhMrLbAbLLEHEystsBwssQgTKy2wHSyxCRMrLbAeLACwDSuxAAJFVFiwDyNCIEWwCyNCsAojsAFgQiBgsAFhtRAQAQAOAEJCimCxEgYrsHIrGyJZLbAfLLEAHistsCAssQEeKy2wISyxAh4rLbAiLLEDHistsCMssQQeKy2wJCyxBR4rLbAlLLEGHistsCYssQceKy2wJyyxCB4rLbAoLLEJHistsCksIDywAWAtsCosIGCwEGAgQyOwAWBDsAIlYbABYLApKiEtsCsssCorsCoqLbAsLCAgRyAgsAtDY7gEAGIgsABQWLBAYFlmsAFjYCNhOCMgilVYIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgbIVktsC0sALEAAkVUWLABFrAsKrABFTAbIlktsC4sALANK7EAAkVUWLABFrAsKrABFTAbIlktsC8sIDWwAWAtsDAsALABRWO4BABiILAAUFiwQGBZZrABY7ABK7ALQ2O4BABiILAAUFiwQGBZZrABY7ABK7AAFrQAAAAAAEQ+IzixLwEVKi2wMSwgPCBHILALQ2O4BABiILAAUFiwQGBZZrABY2CwAENhOC2wMiwuFzwtsDMsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYbABQ2M4LbA0LLECABYlIC4gR7AAI0KwAiVJiopHI0cjYSBYYhshWbABI0KyMwEBFRQqLbA1LLAAFrAEJbAEJUcjRyNhsAlDK2WKLiMgIDyKOC2wNiywABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyCwCEMgiiNHI0cjYSNGYLAEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYSMgILAEJiNGYTgbI7AIQ0awAiWwCENHI0cjYWAgsARDsAJiILAAUFiwQGBZZrABY2AjILABKyOwBENgsAErsAUlYbAFJbACYiCwAFBYsEBgWWawAWOwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbA3LLAAFiAgILAFJiAuRyNHI2EjPDgtsDgssAAWILAII0IgICBGI0ewASsjYTgtsDkssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbkIAAgAY2MjIFhiGyFZY7gEAGIgsABQWLBAYFlmsAFjYCMuIyAgPIo4IyFZLbA6LLAAFiCwCEMgLkcjRyNhIGCwIGBmsAJiILAAUFiwQGBZZrABYyMgIDyKOC2wOywjIC5GsAIlRlJYIDxZLrErARQrLbA8LCMgLkawAiVGUFggPFkusSsBFCstsD0sIyAuRrACJUZSWCA8WSMgLkawAiVGUFggPFkusSsBFCstsD4ssDUrIyAuRrACJUZSWCA8WS6xKwEUKy2wPyywNiuKICA8sAQjQoo4IyAuRrACJUZSWCA8WS6xKwEUK7AEQy6wKystsEAssAAWsAQlsAQmIC5HI0cjYbAJQysjIDwgLiM4sSsBFCstsEEssQgEJUKwABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyBHsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhsAIlRmE4IyA8IzgbISAgRiNHsAErI2E4IVmxKwEUKy2wQiywNSsusSsBFCstsEMssDYrISMgIDywBCNCIzixKwEUK7AEQy6wKystsEQssAAVIEewACNCsgABARUUEy6wMSotsEUssAAVIEewACNCsgABARUUEy6wMSotsEYssQABFBOwMiotsEcssDQqLbBILLAAFkUjIC4gRoojYTixKwEUKy2wSSywCCNCsEgrLbBKLLIAAEErLbBLLLIAAUErLbBMLLIBAEErLbBNLLIBAUErLbBOLLIAAEIrLbBPLLIAAUIrLbBQLLIBAEIrLbBRLLIBAUIrLbBSLLIAAD4rLbBTLLIAAT4rLbBULLIBAD4rLbBVLLIBAT4rLbBWLLIAAEArLbBXLLIAAUArLbBYLLIBAEArLbBZLLIBAUArLbBaLLIAAEMrLbBbLLIAAUMrLbBcLLIBAEMrLbBdLLIBAUMrLbBeLLIAAD8rLbBfLLIAAT8rLbBgLLIBAD8rLbBhLLIBAT8rLbBiLLA3Ky6xKwEUKy2wYyywNyuwOystsGQssDcrsDwrLbBlLLAAFrA3K7A9Ky2wZiywOCsusSsBFCstsGcssDgrsDsrLbBoLLA4K7A8Ky2waSywOCuwPSstsGossDkrLrErARQrLbBrLLA5K7A7Ky2wbCywOSuwPCstsG0ssDkrsD0rLbBuLLA6Ky6xKwEUKy2wbyywOiuwOystsHAssDorsDwrLbBxLLA6K7A9Ky2wciyzCQQCA0VYIRsjIVlCK7AIZbADJFB4sAEVMC0AS7gAyFJYsQEBjlmwAbkIAAgAY3CxAAVCsgABACqxAAVCswoCAQgqsQAFQrMOAAEIKrEABkK6AsAAAQAJKrEAB0K6AEAAAQAJKrEDAESxJAGIUViwQIhYsQNkRLEmAYhRWLoIgAABBECIY1RYsQMARFlZWVmzDAIBDCq4Af+FsASNsQIARAAA') format('truetype'); + src: url('data:application/octet-stream;base64,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') format('woff'), + url('data:application/octet-stream;base64,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') format('truetype'); } %fontello-icon-base { @@ -52,6 +52,7 @@ $icon-codes: ( about: '\2605', restore: '\267c', + configure: '\2699', ok: '\2714', help: '\2753', donate: '\2764', @@ -68,6 +69,7 @@ $icon-codes: ( .icn-about::before { content: '\2605'; } .icn-restore::before { content: '\267c'; } +.icn-configure::before { content: '\2699'; } .icn-ok::before { content: '\2714'; } .icn-help::before { content: '\2753'; } .icn-donate::before { content: '\2764'; } diff --git a/html_orig/sass/form/_form_elements.scss b/html_orig/sass/form/_form_elements.scss index 1e35ab3..d66e94c 100755 --- a/html_orig/sass/form/_form_elements.scss +++ b/html_orig/sass/form/_form_elements.scss @@ -1,5 +1,13 @@ @import "buttons"; +#{$all-text-inputs}, select, label.select-wrap { + width: $form-field-w; +} + +input[type="number"], input.short, select.short { + width: $form-field-w/2; +} + #{$all-text-inputs}, select { border: 0 none; border-bottom: 2px solid $c-form-highlight; diff --git a/html_orig/sass/form/_form_layout.scss b/html_orig/sass/form/_form_layout.scss index ec373a7..5adc85e 100755 --- a/html_orig/sass/form/_form_layout.scss +++ b/html_orig/sass/form/_form_layout.scss @@ -1,14 +1,6 @@ // Unified Form wrapper form { @include naked(); } -#{$all-text-inputs}, select, label.select-wrap { - width: $form-field-w; -} - -input[type="number"], input.short { - width: $form-field-w/2; -} - .Box.errors { .list { color: crimson; @@ -45,7 +37,8 @@ input[type="number"], input.short { } } - &.buttons { + // buttons2 is the same style, but different selector for use in the admin page + &.buttons, &.buttons2 { margin: 16px auto; input, .button { margin-right: dist(-1); diff --git a/html_orig/sass/layout/_box.scss b/html_orig/sass/layout/_box.scss index a61c850..1ed9469 100755 --- a/html_orig/sass/layout/_box.scss +++ b/html_orig/sass/layout/_box.scss @@ -79,9 +79,19 @@ .Row.explain { max-width: 600px; margin-left: 0; + line-height: 1.2; + @include media($phone) { margin-top: 60px; } + + &.nomargintop { + margin-top: 12px !important; + } + + &.padleft { + + } } &.mobopen .Row.explain { margin-top: 12px; // default from .Row @@ -97,11 +107,12 @@ h2 { position: relative; cursor: pointer; - padding-right: 1.3rem; + padding: 2px 1.3rem 2px 5px; + margin: 0 -5px 0 -5px; &::after { position: absolute; - right: 0; + right: 4px; content: '▸'; top:50%; diff --git a/html_orig/sass/layout/_content.scss b/html_orig/sass/layout/_content.scss index b1d6b96..731c937 100755 --- a/html_orig/sass/layout/_content.scss +++ b/html_orig/sass/layout/_content.scss @@ -48,3 +48,13 @@ color: $c-form-label-fg; } } + +#content { + // fade in effect + opacity: 0; + transition: opacity 0.15s ease-in; +} + +#content.load { + opacity: 1; +} diff --git a/html_orig/sass/pages/_wifi.scss b/html_orig/sass/pages/_wifi.scss index 90a758d..b71f8dc 100755 --- a/html_orig/sass/pages/_wifi.scss +++ b/html_orig/sass/pages/_wifi.scss @@ -19,6 +19,7 @@ padding: dist(-2); margin-bottom: dist(-2); margin-top: dist(-2); + font-size: 110%; } #ap-noscan { diff --git a/include/uart_hw.h b/include/uart_hw.h- similarity index 100% rename from include/uart_hw.h rename to include/uart_hw.h- diff --git a/user/cgi_appcfg.h b/user/cgi_appcfg.h deleted file mode 100644 index 823a0f1..0000000 --- a/user/cgi_appcfg.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef CGIAPPCFG_H -#define CGIAPPCFG_H - -#include "httpd.h" - -httpd_cgi_state cgiAppCfgSetParams(HttpdConnData *connData); -httpd_cgi_state tplAppCfg(HttpdConnData *connData, char *token, void **arg); - -#endif diff --git a/user/cgi_ping.c b/user/cgi_ping.c deleted file mode 100755 index 5cde827..0000000 --- a/user/cgi_ping.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -#include "cgi_ping.h" - -httpd_cgi_state ICACHE_FLASH_ATTR cgiPing(HttpdConnData *connData) -{ - if (connData->conn==NULL) { - //Connection aborted. Clean up. - return HTTPD_CGI_DONE; - } - - httpdStartResponse(connData, 200); - httpdHeader(connData, "Content-Type", "text/plain"); - httpdEndHeaders(connData); - - httpdSend(connData, "pong\n", -1); - - return HTTPD_CGI_DONE; -} diff --git a/user/cgi_ping.h b/user/cgi_ping.h deleted file mode 100755 index c500697..0000000 --- a/user/cgi_ping.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef CGI_PING_H -#define CGI_PING_H - -#include -#include - -// this is used by the UI to check if server is already restarted and working again. - -httpd_cgi_state cgiPing(HttpdConnData *connData); - -#endif // CGI_PING_H diff --git a/user/cgi_reset.c b/user/cgi_reset.c deleted file mode 100755 index aea3f87..0000000 --- a/user/cgi_reset.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include - -#include "cgi_reset.h" - -static ETSTimer tmr; - -static void ICACHE_FLASH_ATTR tmrCb(void *arg) -{ - system_restart(); -} - -httpd_cgi_state ICACHE_FLASH_ATTR cgiResetDevice(HttpdConnData *connData) -{ - if (connData->conn==NULL) { - //Connection aborted. Clean up. - return HTTPD_CGI_DONE; - } - - httpdStartResponse(connData, 200); - httpdHeader(connData, "Content-Type", "text/plain"); - httpdEndHeaders(connData); - - os_timer_disarm(&tmr); - os_timer_setfn(&tmr, tmrCb, NULL); - os_timer_arm(&tmr, 100, false); - - httpdSend(connData, "system reset\n", -1); - - return HTTPD_CGI_DONE; -} diff --git a/user/cgi_reset.h b/user/cgi_reset.h deleted file mode 100755 index a7b6927..0000000 --- a/user/cgi_reset.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef CGI_RESET_H -#define CGI_RESET_H - -#include -#include - -httpd_cgi_state cgiResetDevice(HttpdConnData *connData); - -#endif // CGI_RESET_H diff --git a/user/cgi_system.c b/user/cgi_system.c new file mode 100755 index 0000000..f017112 --- /dev/null +++ b/user/cgi_system.c @@ -0,0 +1,164 @@ +#include +#include +#include + +#include "cgi_system.h" +#include "persist.h" +#include "syscfg.h" +#include "uart_driver.h" + +#define SET_REDIR_SUC "/cfg/system" +#define SET_REDIR_ERR SET_REDIR_SUC"?err=" + +static ETSTimer tmr; + +static void ICACHE_FLASH_ATTR tmrCb(void *arg) +{ + system_restart(); +} + +httpd_cgi_state ICACHE_FLASH_ATTR cgiResetDevice(HttpdConnData *connData) +{ + if (connData->conn==NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + + httpdStartResponse(connData, 200); + httpdHeader(connData, "Content-Type", "text/plain"); + httpdEndHeaders(connData); + + os_timer_disarm(&tmr); + os_timer_setfn(&tmr, tmrCb, NULL); + os_timer_arm(&tmr, 100, false); + + httpdSend(connData, "system reset\n", -1); + + return HTTPD_CGI_DONE; +} + +httpd_cgi_state ICACHE_FLASH_ATTR cgiPing(HttpdConnData *connData) +{ + if (connData->conn==NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + + httpdStartResponse(connData, 200); + httpdHeader(connData, "Content-Type", "text/plain"); + httpdEndHeaders(connData); + + httpdSend(connData, "pong\n", -1); + + return HTTPD_CGI_DONE; +} + +/** + * Universal CGI endpoint to set Terminal params. + */ +httpd_cgi_state ICACHE_FLASH_ATTR +cgiSystemCfgSetParams(HttpdConnData *connData) +{ + char buff[50]; + + char redir_url_buf[300]; + char *redir_url = redir_url_buf; + redir_url += sprintf(redir_url, SET_REDIR_ERR); + // we'll test if anything was printed by looking for \0 in failed_keys_buf + + if (connData->conn == NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + + if (GET_ARG("uart_baud")) { + dbg("Baud rate: %s", buff); + int baud = atoi(buff); + if (baud == BIT_RATE_300 || + baud == BIT_RATE_600 || + baud == BIT_RATE_1200 || + baud == BIT_RATE_2400 || + baud == BIT_RATE_4800 || + baud == BIT_RATE_9600 || + baud == BIT_RATE_19200 || + baud == BIT_RATE_38400 || + baud == BIT_RATE_57600 || + baud == BIT_RATE_74880 || + baud == BIT_RATE_115200 || + baud == BIT_RATE_230400 || + baud == BIT_RATE_460800 || + baud == BIT_RATE_921600 || + baud == BIT_RATE_1843200 || + baud == BIT_RATE_3686400) { + sysconf->uart_baudrate = (u32) baud; + } else { + warn("Bad baud rate %s", buff); + redir_url += sprintf(redir_url, "uart_baud,"); + } + } + + if (GET_ARG("uart_parity")) { + dbg("Parity: %s", buff); + int parity = atoi(buff); + if (parity >= 0 && parity <= 2) { + sysconf->uart_parity = (UartParityMode) parity; + } else { + warn("Bad parity %s", buff); + redir_url += sprintf(redir_url, "uart_parity,"); + } + } + + if (GET_ARG("uart_stopbits")) { + dbg("Stop bits: %s", buff); + int stopbits = atoi(buff); + if (stopbits >= 1 && stopbits <= 3) { + sysconf->uart_stopbits = (UartStopBitsNum) stopbits; + } else { + warn("Bad stopbits %s", buff); + redir_url += sprintf(redir_url, "uart_stopbits,"); + } + } + + if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) { + // All was OK + info("Set system params - success, saving..."); + + sysconf_apply_settings(); + persist_store(); + + httpdRedirect(connData, SET_REDIR_SUC); + } else { + warn("Some settings did not validate, asking for correction"); + // Some errors, appended to the URL as ?err= + httpdRedirect(connData, redir_url_buf); + } + return HTTPD_CGI_DONE; +} + + +httpd_cgi_state ICACHE_FLASH_ATTR +tplSystemCfg(HttpdConnData *connData, char *token, void **arg) +{ +#define BUFLEN 100 + char buff[BUFLEN]; + + if (token == NULL) { + // We're done + return HTTPD_CGI_DONE; + } + + strcpy(buff, ""); // fallback + + if (streq(token, "uart_baud")) { + sprintf(buff, "%d", sysconf->uart_baudrate); + } + else if (streq(token, "uart_parity")) { + sprintf(buff, "%d", sysconf->uart_parity); + } + else if (streq(token, "uart_stopbits")) { + sprintf(buff, "%d", sysconf->uart_stopbits); + } + + httpdSend(connData, buff, -1); + return HTTPD_CGI_DONE; +} diff --git a/user/cgi_system.h b/user/cgi_system.h new file mode 100755 index 0000000..b90c274 --- /dev/null +++ b/user/cgi_system.h @@ -0,0 +1,12 @@ +#ifndef CGI_PING_H +#define CGI_PING_H + +#include +#include + +httpd_cgi_state cgiPing(HttpdConnData *connData); +httpd_cgi_state cgiResetDevice(HttpdConnData *connData); +httpd_cgi_state cgiSystemCfgSetParams(HttpdConnData *connData); +httpd_cgi_state tplSystemCfg(HttpdConnData *connData, char *token, void **arg); + +#endif // CGI_PING_H diff --git a/user/cgi_appcfg.c b/user/cgi_term_cfg.c similarity index 95% rename from user/cgi_appcfg.c rename to user/cgi_term_cfg.c index e766139..f42c2c5 100644 --- a/user/cgi_appcfg.c +++ b/user/cgi_term_cfg.c @@ -3,19 +3,19 @@ Cgi/template routines for configuring non-wifi settings */ #include -#include "cgi_appcfg.h" +#include "cgi_term_cfg.h" #include "persist.h" #include "screen.h" #include "helpers.h" -#define SET_REDIR_SUC "/cfg/app" +#define SET_REDIR_SUC "/cfg/term" #define SET_REDIR_ERR SET_REDIR_SUC"?err=" /** * Universal CGI endpoint to set Terminal params. */ httpd_cgi_state ICACHE_FLASH_ATTR -cgiAppCfgSetParams(HttpdConnData *connData) +cgiTermCfgSetParams(HttpdConnData *connData) { char buff[50]; @@ -114,7 +114,7 @@ cgiAppCfgSetParams(HttpdConnData *connData) if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) { // All was OK - info("Set app params - success, saving..."); + info("Set term params - success, saving..."); terminal_apply_settings(); persist_store(); @@ -130,7 +130,7 @@ cgiAppCfgSetParams(HttpdConnData *connData) httpd_cgi_state ICACHE_FLASH_ATTR -tplAppCfg(HttpdConnData *connData, char *token, void **arg) +tplTermCfg(HttpdConnData *connData, char *token, void **arg) { #define BUFLEN 100 char buff[BUFLEN]; diff --git a/user/cgi_term_cfg.h b/user/cgi_term_cfg.h new file mode 100644 index 0000000..895a9c8 --- /dev/null +++ b/user/cgi_term_cfg.h @@ -0,0 +1,9 @@ +#ifndef CGIAPPCFG_H +#define CGIAPPCFG_H + +#include "httpd.h" + +httpd_cgi_state cgiTermCfgSetParams(HttpdConnData *connData); +httpd_cgi_state tplTermCfg(HttpdConnData *connData, char *token, void **arg); + +#endif diff --git a/user/cgi_wifi.c b/user/cgi_wifi.c index 653f928..9561f0e 100644 --- a/user/cgi_wifi.c +++ b/user/cgi_wifi.c @@ -183,9 +183,8 @@ static void ICACHE_FLASH_ATTR wifiStartScan(void) } /** - * This CGI is called from the bit of AJAX-code in wifi.tpl. It will initiate a - * scan for access points and if available will return the result of an earlier scan. - * The result is embedded in a bit of JSON parsed by the javascript in wifi.tpl. + * Start a scan and return a result of an earlier scan, if available. + * The STA is switched ON if disabled. */ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) { @@ -193,6 +192,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) int len; char buff[256]; + // auto-turn on STA + if ((wificonf->opmode & STATION_MODE) == 0) { + wificonf->opmode |= STATION_MODE; + wifimgr_apply_settings(); + } + // 2nd and following runs of the function via MORE: if (!cgiWifiAps.scanInProgress && pos != 0) { // Fill in json code for an access point diff --git a/user/persist.c b/user/persist.c index 857188b..a5d7cab 100644 --- a/user/persist.c +++ b/user/persist.c @@ -19,6 +19,7 @@ apply_live_settings(void) dbg("[Persist] Applying live settings..."); terminal_apply_settings(); wifimgr_apply_settings(); + sysconf_apply_settings(); // ... } @@ -27,6 +28,7 @@ restore_live_settings_to_hard_defaults(void) { wifimgr_restore_defaults(); terminal_restore_defaults(); + sysconf_restore_defaults(); // ... } @@ -41,7 +43,7 @@ restore_live_settings_to_hard_defaults(void) static uint32_t ICACHE_FLASH_ATTR calculateCRC32(const uint8_t *data, size_t length) { - uint32_t crc = 0xffffffff; + uint32_t crc = 0xffffffff + CHECKSUM_SALT; while (length--) { uint8_t c = *data++; for (uint32_t i = 0x80; i > 0; i >>= 1) { @@ -67,7 +69,8 @@ calculateCRC32(const uint8_t *data, size_t length) static uint32_t ICACHE_FLASH_ATTR compute_checksum(AppConfigBundle *bundle) { - return calculateCRC32((uint8_t *) bundle, sizeof(AppConfigBundle) - 4) ^ CHECKSUM_SALT; + // this should be the bundle without the checksum + return calculateCRC32((uint8_t *) bundle, sizeof(AppConfigBundle) - 4); } /** @@ -78,10 +81,13 @@ persist_load(void) { info("[Persist] Loading stored settings from FLASH..."); - dbg("sizeof(AppConfigBundle) = %d bytes", sizeof(AppConfigBundle)); - dbg("sizeof(PersistBlock) = %d bytes", sizeof(PersistBlock)); - dbg("sizeof(WiFiConfigBundle) = %d bytes", sizeof(WiFiConfigBundle)); - dbg("sizeof(TerminalConfigBundle) = %d bytes", sizeof(TerminalConfigBundle)); + dbg("sizeof(AppConfigBundle) = %d bytes", sizeof(AppConfigBundle)); + dbg("> sizeof(WiFiConfigBundle) = %d bytes", sizeof(WiFiConfigBundle)); + dbg("> sizeof(TerminalConfigBundle) = %d bytes", sizeof(TerminalConfigBundle)); + dbg("> sizeof(SystemConfigBundle) = %d bytes", sizeof(SystemConfigBundle)); + dbg("> sizeof(checksum) = %d bytes", sizeof(uint32_t)); + dbg("> filler = %d bytes", + sizeof(AppConfigBundle) - (sizeof(WiFiConfigBundle) + sizeof(TerminalConfigBundle) + sizeof(SystemConfigBundle))); bool hard_reset = false; diff --git a/user/persist.h b/user/persist.h index c5b6b87..9e110a8 100644 --- a/user/persist.h +++ b/user/persist.h @@ -12,19 +12,21 @@ #include "wifimgr.h" #include "screen.h" +#include "syscfg.h" // Changing this could be used to force-erase the config area // after a firmware upgrade -#define CHECKSUM_SALT 0x5F5F5F5F +#define CHECKSUM_SALT 1 + +#define APPCONF_SIZE 2048 /** Struct for current or default settings */ -typedef struct { +typedef struct { // the entire block should be 1024 bytes long (for compatibility across upgrades) WiFiConfigBundle wificonf; TerminalConfigBundle termconf; + SystemConfigBundle sysconf; // --- Space for future settings --- - // Original size: 1024 - // // The size must be appropriately reduced each time something is added, // and boolean flags defaulting to 0 should be used to detect unpopulated // sections that must be restored to defaults on load. @@ -32,7 +34,13 @@ typedef struct { // This ensures user settings are not lost each time they upgrade the firmware, // which would lead to a checksum mismatch if the structure was changed and // it grew to a different memory area. - uint8_t filler[1024]; + uint8_t filler[ + APPCONF_SIZE + - sizeof(uint32_t) // checksum + - sizeof(WiFiConfigBundle) + - sizeof(TerminalConfigBundle) + - sizeof(SystemConfigBundle) + ]; uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults. } AppConfigBundle; diff --git a/user/routes.c b/user/routes.c index ee2fcd7..264547f 100644 --- a/user/routes.c +++ b/user/routes.c @@ -6,12 +6,11 @@ #include "routes.h" #include "cgi_wifi.h" -#include "cgi_reset.h" -#include "cgi_ping.h" +#include "cgi_system.h" #include "cgi_main.h" #include "cgi_sockets.h" #include "cgi_network.h" -#include "cgi_appcfg.h" +#include "cgi_term_cfg.h" #include "cgi_persist.h" #define WIFI_PROTECT 0 @@ -54,13 +53,14 @@ HttpdBuiltInUrl routes[] = { ROUTE_TPL_FILE("/cfg/network/?", tplNetwork, "/cfg_network.tpl"), ROUTE_CGI("/cfg/network/set", cgiNetworkSetParams), - ROUTE_TPL_FILE("/cfg/app/?", tplAppCfg, "/cfg_app.tpl"), - ROUTE_CGI("/cfg/app/set", cgiAppCfgSetParams), + ROUTE_TPL_FILE("/cfg/term/?", tplTermCfg, "/cfg_term.tpl"), + ROUTE_CGI("/cfg/term/set", cgiTermCfgSetParams), - ROUTE_FILE("/cfg/admin/?", "/cfg_admin.tpl"), - ROUTE_CGI("/cfg/admin/write_defaults", cgiPersistWriteDefaults), - ROUTE_CGI("/cfg/admin/restore_defaults", cgiPersistRestoreDefaults), - ROUTE_CGI("/cfg/admin/restore_hard", cgiPersistRestoreHard), + ROUTE_TPL_FILE("/cfg/system/?", tplSystemCfg, "/cfg_system.tpl"), + ROUTE_CGI("/cfg/system/set", cgiSystemCfgSetParams), + ROUTE_CGI("/cfg/system/write_defaults", cgiPersistWriteDefaults), + ROUTE_CGI("/cfg/system/restore_defaults", cgiPersistRestoreDefaults), + ROUTE_CGI("/cfg/system/restore_hard", cgiPersistRestoreHard), ROUTE_FILESYSTEM(), ROUTE_END(), diff --git a/user/screen.h b/user/screen.h index 5ab2bc6..72bd207 100644 --- a/user/screen.h +++ b/user/screen.h @@ -34,17 +34,35 @@ * */ +// Size designed for the wifi config structure +// Must be constant to avoid corrupting user config after upgrade +#define TERMCONF_SIZE 200 + +#define TERM_BTN_LEN 10 +#define TERM_TITLE_LEN 64 + typedef struct { u32 width; u32 height; u8 default_bg; u8 default_fg; - char title[64]; - char btn1[10]; - char btn2[10]; - char btn3[10]; - char btn4[10]; - char btn5[10]; + char title[TERM_TITLE_LEN]; + char btn1[TERM_BTN_LEN]; + char btn2[TERM_BTN_LEN]; + char btn3[TERM_BTN_LEN]; + char btn4[TERM_BTN_LEN]; + char btn5[TERM_BTN_LEN]; + + u8 _filler[ + TERMCONF_SIZE + - 4 + - 4 + - 1 + - 1 + - TERM_TITLE_LEN + - TERM_BTN_LEN * 5 + ]; + } TerminalConfigBundle; // Live config diff --git a/user/serial.c b/user/serial.c index b5a07a2..f431333 100644 --- a/user/serial.c +++ b/user/serial.c @@ -2,21 +2,38 @@ #include "uart_driver.h" #include "uart_handler.h" #include "ansi_parser.h" - -// Here the bitrates are defined -#define UART0_BAUD BIT_RATE_115200 -#define UART1_BAUD BIT_RATE_115200 +#include "syscfg.h" /** * Init the serial ports */ -void ICACHE_FLASH_ATTR serialInit(void) +void ICACHE_FLASH_ATTR serialInitBase(void) { - UART_Init(UART0_BAUD, UART1_BAUD); + UART_Init(); + // debug port + UART_SetParity(UART1, PARITY_NONE); + UART_SetStopBits(UART1, ONE_STOP_BIT); + UART_SetBaudrate(UART1, BIT_RATE_115200); UART_SetPrintPort(UART1); UART_SetupAsyncReceiver(); } +/** + * Init the serial ports + */ +void ICACHE_FLASH_ATTR serialInit(void) +{ + UART_SetParity(UART0, (UartParityMode) sysconf->uart_parity); + UART_SetStopBits(UART0, (UartStopBitsNum) sysconf->uart_stopbits); + UART_SetBaudrate(UART0, sysconf->uart_baudrate); + + info("COM SERIAL: %d baud, %s parity, %s stopbit(s)", + sysconf->uart_baudrate, + (sysconf->uart_parity == PARITY_NONE ? "NONE" : (sysconf->uart_parity == PARITY_ODD ? "ODD" : "EVEN")), + (sysconf->uart_stopbits == ONE_STOP_BIT ? "1" : (sysconf->uart_stopbits == ONE_HALF_STOP_BIT ? "1.5" : "2")) + ); +} + /** * Handle a byte received from UART. * Might do some buffering here maybe diff --git a/user/serial.h b/user/serial.h index eda2e5b..cb2954c 100644 --- a/user/serial.h +++ b/user/serial.h @@ -1,6 +1,9 @@ #ifndef SERIAL_H #define SERIAL_H +/** Initial uart init (before sysconf is loaded) */ +void serialInitBase(void); + /** Init the uarts */ void serialInit(void); diff --git a/user/syscfg.c b/user/syscfg.c new file mode 100644 index 0000000..d45406f --- /dev/null +++ b/user/syscfg.c @@ -0,0 +1,24 @@ +// +// Created by MightyPork on 2017/07/29. +// + +#include "syscfg.h" +#include "persist.h" +#include "uart_driver.h" +#include "serial.h" + +SystemConfigBundle * const sysconf = &persist.current.sysconf; + +void ICACHE_FLASH_ATTR +sysconf_apply_settings(void) +{ + serialInit(); +} + +void ICACHE_FLASH_ATTR +sysconf_restore_defaults(void) +{ + sysconf->uart_parity = PARITY_NONE; + sysconf->uart_baudrate = BIT_RATE_115200; + sysconf->uart_stopbits = ONE_STOP_BIT; +} diff --git a/user/syscfg.h b/user/syscfg.h new file mode 100644 index 0000000..3fe65ed --- /dev/null +++ b/user/syscfg.h @@ -0,0 +1,33 @@ +// +// Created by MightyPork on 2017/07/29. +// + +#ifndef ESP_VT100_FIRMWARE_SYSCFG_H +#define ESP_VT100_FIRMWARE_SYSCFG_H + +#include + +// Size designed for the wifi config structure +// Must be constant to avoid corrupting user config after upgrade +#define SYSCONF_SIZE 200 + +typedef struct { + u32 uart_baudrate; + u8 uart_parity; + u8 uart_stopbits; + + u8 _filler[ + SYSCONF_SIZE + - 4 + - 1 + - 1 + ]; +} SystemConfigBundle; + +extern SystemConfigBundle * const sysconf; + +void sysconf_apply_settings(void); + +void sysconf_restore_defaults(void); + +#endif //ESP_VT100_FIRMWARE_SYSCFG_H diff --git a/user/uart_handler.c b/user/uart_handler.c index 86f35ac..beca884 100755 --- a/user/uart_handler.c +++ b/user/uart_handler.c @@ -32,22 +32,8 @@ void ICACHE_FLASH_ATTR clear_rxtx(int uart_no) } -/** - * @brief Configure UART 115200-8-N-1 - * @param uart_no - */ -static void ICACHE_FLASH_ATTR my_uart_init(UARTn uart_no, uint32 baud) -{ - UART_SetParity(uart_no, PARITY_NONE); - UART_SetStopBits(uart_no, ONE_STOP_BIT); - UART_SetWordLength(uart_no, EIGHT_BITS); - UART_SetBaudrate(uart_no, baud); - UART_ResetFifo(uart_no); -} - - /** Configure basic UART func and pins */ -void ICACHE_FLASH_ATTR UART_Init(uint32_t baud0, uint32_t baud1) +void ICACHE_FLASH_ATTR UART_Init(void) { // U0TXD PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); @@ -60,8 +46,10 @@ void ICACHE_FLASH_ATTR UART_Init(uint32_t baud0, uint32_t baud1) PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); // Configure the UART peripherals - my_uart_init(UART0, baud0); // main - my_uart_init(UART1, baud1); // debug (output only) + UART_SetWordLength(UART0, EIGHT_BITS); // main + UART_ResetFifo(UART0); + UART_SetWordLength(UART1, EIGHT_BITS); // debug (output only) + UART_ResetFifo(UART1); } /** Configure Rx on UART0 */ diff --git a/user/uart_handler.h b/user/uart_handler.h index 44fe854..2d5e57f 100755 --- a/user/uart_handler.h +++ b/user/uart_handler.h @@ -12,8 +12,8 @@ #include -/** Configure UART periphs and enable pins */ -void UART_Init(uint32_t baud0, uint32_t baud1); +/** Configure UART periphs and enable pins - does not set baud rate, parity and stopbits */ +void UART_Init(void); /** Configure async Rx on UART0 */ void UART_SetupAsyncReceiver(void); diff --git a/user/user_main.c b/user/user_main.c index 8730ff9..248db2a 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -86,12 +86,12 @@ void ICACHE_FLASH_ATTR user_init(void) static ETSTimer userStartTimer; static ETSTimer prHeapTimer; - serialInit(); + serialInitBase(); // Prevent WiFi starting and connecting by default // let wifi manager handle it wifi_station_set_auto_connect(false); - wifi_set_opmode(NULL_MODE); // save to flash if changed - this might avoid the current spike on startup? + wifi_set_opmode(NULL_MODE); // saves to flash if changed - this might avoid the current spike on startup? printf("\r\n"); banner("====== ESP8266 Remote Terminal ======"); @@ -126,30 +126,16 @@ void ICACHE_FLASH_ATTR user_init(void) static void user_start(void *unused) { - // Change AP name if AI-THINKER found (means un-initialized device) -// struct softap_config apconf; -// wifi_softap_get_config(&apconf); -// if (strstarts((char *) apconf.ssid, "AI-THINKER")) { -// warn("Un-initialized device, performing factory reset."); -// apars_handle_OSC_FactoryReset(); -// return; -// } - // Load and apply stored settings, or defaults if stored settings are invalid persist_load(); - // Captive portal (DNS redirector) + captdnsInit(); - // Server httpdInit(routes, 80); - - // The terminal screen screen_init(); // Print the CANCEL character to indicate the module has restarted // Critically important for client application if any kind of screen persistence / content re-use is needed UART_WriteChar(UART0, 24, UART_TIMEOUT_US); // 0x18 - 24 - CAN - - info("Listening on UART0, 115200-8-N-1!"); } // ---- unused funcs removed from sdk to save space --- diff --git a/user/wifimgr.c b/user/wifimgr.c index 4299b70..5cfe327 100644 --- a/user/wifimgr.c +++ b/user/wifimgr.c @@ -19,7 +19,7 @@ wifimgr_restore_defaults(void) u8 mac[6]; wifi_get_macaddr(SOFTAP_IF, mac); - wificonf->opmode = SOFTAP_MODE; + wificonf->opmode = STATIONAP_MODE; // Client+AP, so we can scan without having to enable Station wificonf->tpw = 20; wificonf->ap_channel = 1; sprintf((char *) wificonf->ap_ssid, "TERM-%02X%02X%02X", mac[3], mac[4], mac[5]); diff --git a/user/wifimgr.h b/user/wifimgr.h index 79a4246..165067d 100644 --- a/user/wifimgr.h +++ b/user/wifimgr.h @@ -13,6 +13,10 @@ #define SSID_LEN 32 #define PASSWORD_LEN 64 +// Size designed for the wifi config structure +// Must be constant to avoid corrupting user config after upgrade +#define WIFICONF_SIZE 340 + /** * A structure holding all configured WiFi parameters * and the active state. @@ -37,8 +41,28 @@ typedef struct { u8 sta_ssid[SSID_LEN]; u8 sta_password[PASSWORD_LEN]; bool sta_dhcp_enable; - struct ip_info sta_addr; + + u8 _filler[ + WIFICONF_SIZE + - 1 + - 1 + + - 1 + - SSID_LEN + - PASSWORD_LEN + - 1 + - 2 + - sizeof(struct dhcps_lease) + + - sizeof(struct ip_info) + + - SSID_LEN + - PASSWORD_LEN + - 1 + - sizeof(struct ip_info) + - 8 // padding? + ]; } WiFiConfigBundle; typedef struct {