From c2d95438aa4f99553f5b93cf1f0648561918baea Mon Sep 17 00:00:00 2001 From: otidev Date: Thu, 25 Apr 2013 20:15:54 -0400 Subject: [PATCH 01/20] added node status to reboot page --- etc/config/quickstart | 60 ++----------------- .../lua/luci/view/QS/module/applyreboot.htm | 55 ++++++++++++++++- 2 files changed, 60 insertions(+), 55 deletions(-) diff --git a/etc/config/quickstart b/etc/config/quickstart index af7b6e9..46dacf2 100644 --- a/etc/config/quickstart +++ b/etc/config/quickstart @@ -8,9 +8,10 @@ config page 'welcome' option pageTitle 'Welcome' option topheader 'Welcome to the Commotion Quick Start wizard' list modules 'welcome' + list modules 'name' list modules 'adminPassword' list buttons 'noBack' - list buttons '2:settingsFile,|Manual Configuration >,| ,| ' + list buttons '2:settingsFile,|Use a pre-built network file >,| ,| ' list buttons '3:makeItWork,|Just Make it Work >,| ,| ' config page 'settingsFile' @@ -36,7 +37,7 @@ config page 'accessPoint' option topheader 'Setup an Open Access Point' option subheading '' list modules 'accessPoint' - list buttons '2:internetCheck,|Save >,|Continue with this setting,| ,|' + list buttons '2:keyfilesAndSecurity,|Save >,|Continue with this setting,| ,|' list buttons '4:startOver,|<< Start Over,| ,|plus' config page 'secAccessPoint' @@ -44,41 +45,7 @@ config page 'secAccessPoint' option topheader 'Setup a Private Access Point' option subheading '' list modules 'secAccessPoint' - list buttons '2:internetCheck,|Save >,|Continue with this setting,| ,|' - list buttons '4:startOver,|<< Start Over,| ,|plus' - -config page 'internetCheck' - option pageTitle 'Internet Connectivity' - option topheader 'Internet Connectivity' - option subheading 'Are you planning to connect a cable between this Router and your home or business Internet connection?' - list buttons '2:internetSharing,|Yes >,|Configure your internet gateway,| ,|' - list buttons '3:splashPage,|No >,|Skip this step,| ,|' - list buttons '4:startOver,|<< Start Over,| ,|plus' - -config page 'internetSharing' - option pageTitle 'Sharing your Internet Connection' - option topheader 'Sharing your Internet Connection' - option subheading 'Internet access will be available to those that connect to the mesh.
You may choose to advertise it to the mesh, or keep it hidden.' - list buttons '2:splashPage,|Please advertise my Internet access. >,|,| ,|' - list buttons "3:gatewayShareOff,|Please DON'T advertise my Internet access. >,|Note that access will still be available, just not advertised,| ,|" - list buttons '4:startOver,|<< Start Over,| ,|plus' - -config page 'splashPage' - option pageTitle 'Setup a Splash Page' - option topheader 'Setup a Splash Page' - option subheading 'Would you like people connecting to your node to first see a splash page on their web browser?
This is the only way to ask people connecting to the node to agree to a Community Standards agreement or Terms of Service.' - list modules 'splashPage' - list buttons '2:meshApplications,|Submit Splash Text>,|Use the above for your nodes splash page,| ,|' - list buttons '3:noSplash,|No >,|Skip this step,| ,|' - list buttons '4:startOver,|<< Start Over,| ,|plus' - -config page 'meshApplications' - option pageTitle 'Setup Mesh Application Advertising' - option topheader 'Setup Mesh Application Advertising' - option subheading 'Would you like to advertise mesh applications to people connected to your node?
You will be alerted when new applications are available and need approval.' - list modules 'applications' - list buttons '2:netSec,|Yes >,|I would like to create an application portal,| ,|' - list buttons "3:noApplications,|No >,|I don't want to let me node advertise applications,| ,|" + list buttons '2:keyfilesAndSecurity,|Save >,|Continue with this setting,| ,|' list buttons '4:startOver,|<< Start Over,| ,|plus' config page 'keyfilesAndSecurity' @@ -97,7 +64,7 @@ config page 'naming' option pageTitle 'Please Choose your Mesh Names' option topheader 'Please Choose your Mesh Names' list modules 'nodeNaming' - list buttons '3:yourNetwork,|Continue >,|Set this name for your node and continue,| ,|' + list buttons '3:finish,|Finish >,|Set this name for your node and finish,| ,|' list buttons '4:startOver,|<< Start Over,| ,|plus' config page 'makeItNaming' @@ -105,20 +72,5 @@ config page 'makeItNaming' option topheader 'Please Choose your Mesh Names' list modules 'nodeNaming' list modules 'accessPoint' - list buttons '3:yourNetwork,|Continue >,|Set this name for your node and continue,| ,|' + list buttons '3:finish,|Finish >,|Set this name for your node and finish,| ,|' list buttons '4:startOver,|<< Start Over,| ,|plus' - -config page 'yourNetwork' - option pageTitle 'Your Network' - option topheader 'Your Network' - list modules 'yourNetwork' - list buttons '3:setupComplete,|Continue >,|Apply these settings to your node,| ,|' - list buttons '4:startOver,|<< Start Over,| ,|plus' - -config page 'setupComplete' - option pageTitle 'Setup is complete!' - option topheader 'Setup is complete!' - option subheading 'You have completed the Commotion quickstart. Check below to see if your node is connected to any other nodes in the area.' - list module 'complete' - list buttons '3:finish,|Finish >,|Go to node admin login,| ,|' - list buttons '4:startOver,|<< Start Over,| If there is a problem, Start Over,|plus' diff --git a/usr/lib/lua/luci/view/QS/module/applyreboot.htm b/usr/lib/lua/luci/view/QS/module/applyreboot.htm index 78b606c..df1ee80 100644 --- a/usr/lib/lua/luci/view/QS/module/applyreboot.htm +++ b/usr/lib/lua/luci/view/QS/module/applyreboot.htm @@ -1,6 +1,44 @@ <%=luci.sys.hostname()%> - <% if title then %><%=title%><% else %><%:Redirecting...%><% end %> +<%- + if luci.fs.isfile("/etc/commotion/profiles.d/quickstartAP") then + for line in io.lines("/etc/commotion/profiles.d/quickstartAP") do + b,c = string.find(line,"^ssid=.*") + if b then + apName = string.sub(line,b+5,c) + end + end + elseif luci.fs.isfile("/etc/commotion/profiles.d/quickstartSec") then + for line in io.lines("/etc/commotion/profiles.d/quickstartSec") do + b,c = string.find(line,"^ssid=.*") + if b then + apName = string.sub(line,b+5,c) + end + end + end + local uci = luci.model.uci.cursor() + --get hostname from system file + uci:foreach("system", "system", + function(s) + if s.hostname then + hostname = s.hostname + end + end) + if not luci.fs.isfile("/etc/commotion/profiles.d/quickstartMesh") then + luci.sys.call('cp /etc/commotion/profiles.d/defaultMesh /etc/commotion/profiles.d/quickstartMesh') + end + for line in io.lines("/etc/commotion/profiles.d/quickstartMesh") do + b,c = string.find(line,"^ssid=.*") + if b then + netName = string.sub(line,b+5,c) + end + end + + local meshName = netName + local nodeName = hostname +end +-%> diff --git a/usr/lib/lua/luci/view/QS/module/complete.htm b/usr/lib/lua/luci/view/QS/module/complete.htm new file mode 100644 index 0000000..6db5aa7 --- /dev/null +++ b/usr/lib/lua/luci/view/QS/module/complete.htm @@ -0,0 +1 @@ + diff --git a/usr/lib/lua/luci/view/QS/module/name.htm b/usr/lib/lua/luci/view/QS/module/name.htm new file mode 100644 index 0000000..5bdb6dd --- /dev/null +++ b/usr/lib/lua/luci/view/QS/module/name.htm @@ -0,0 +1,39 @@ +<%- + if pv.errorMsg then + if pv.errorMsg.name then + nameErr = pv.errorMsg.name + end + end + nodeID = luci.sys.exec("commotion nodeid") +-%> + + + +
+
+ + +

What would you like to name your node?

+

This value is used by other users and devices to find your network wirelessly and over the mesh..

+

<%=nameErr%>

+ + <%=nodeID%> + + +
+

Password

+

This password is for your access point. Choose a password that is between 9 and 30 characters. This name can be numbers, letters, and special characters.

+ +

Retype your password here

+ +
+
+
From 32879ebc82bfe6c6ca41ea04b089d48046ab8b46 Mon Sep 17 00:00:00 2001 From: s2e Date: Wed, 1 May 2013 16:31:55 -0400 Subject: [PATCH 06/20] completed make it work completion without error on all possibilities. --- etc/config/quickstart | 4 +- usr/lib/lua/luci/controller/QS/QS.lua | 5 +- usr/lib/lua/luci/controller/QS/buttons.lua | 6 +- usr/lib/lua/luci/controller/QS/modules.lua | 125 +++++++++++------- .../lua/luci/view/QS/module/adminPassword.htm | 2 +- .../lua/luci/view/QS/module/applyreboot.htm | 27 ++-- usr/lib/lua/luci/view/QS/module/name.htm | 36 ++--- 7 files changed, 115 insertions(+), 90 deletions(-) diff --git a/etc/config/quickstart b/etc/config/quickstart index f8104f8..1f9694a 100644 --- a/etc/config/quickstart +++ b/etc/config/quickstart @@ -1,4 +1,4 @@ -OBconfig quickstart options +config quickstart options option pageNo 'welcome' option lastPg 'welcome' option complete 'false' @@ -6,7 +6,7 @@ OBconfig quickstart options config page 'welcome' option pageTitle 'Welcome' - option topheader 'Welcome to the Commotion Quick Start Wizard' + option topheader 'Welcome to the Commotion Quick Start' list modules 'name' list modules 'adminPassword' list buttons 'noBack' diff --git a/usr/lib/lua/luci/controller/QS/QS.lua b/usr/lib/lua/luci/controller/QS/QS.lua index b64ec19..215393f 100644 --- a/usr/lib/lua/luci/controller/QS/QS.lua +++ b/usr/lib/lua/luci/controller/QS/QS.lua @@ -123,7 +123,6 @@ function wirelessController(profiles) function(s) table.insert(dev, s['.name']) end) - --Create interfaces for devNum,device in ipairs(dev) do --Make sure wireless devices are on... because it starts them disabled for some reason @@ -204,8 +203,8 @@ function parseSubmit(returns) pages('next', button) end if next(errors) ~= nil then - log("errors HERE") - log(errors) + --log("errors HERE") + --log(errors) pages('next','back') return(errors) end diff --git a/usr/lib/lua/luci/controller/QS/buttons.lua b/usr/lib/lua/luci/controller/QS/buttons.lua index 0c0cba1..9b3ce65 100644 --- a/usr/lib/lua/luci/controller/QS/buttons.lua +++ b/usr/lib/lua/luci/controller/QS/buttons.lua @@ -6,7 +6,7 @@ end function networkSecuritySettings(modules) local QS = luci.controller.QS.QS local error = luci.controller.QS.QS.keyCheck() - QS:log(error) + --QS:log(error) return(modules) end @@ -115,7 +115,7 @@ function continueInsecure(modules) end function noConfigUploaded(modules) - luci.controller.QS.QS.log(modules) + --luci.controller.QS.QS.log(modules) for i,x in ipairs(modules) do if x == 'upload' then rem = i @@ -127,7 +127,7 @@ function noConfigUploaded(modules) end function noSplash(modules) - luci.controller.QS.QS.log(modules) + --luci.controller.QS.QS.log(modules) for i,x in ipairs(modules) do if x == 'splashPage' then rem = i diff --git a/usr/lib/lua/luci/controller/QS/modules.lua b/usr/lib/lua/luci/controller/QS/modules.lua index 474043e..25335b9 100644 --- a/usr/lib/lua/luci/controller/QS/modules.lua +++ b/usr/lib/lua/luci/controller/QS/modules.lua @@ -5,6 +5,7 @@ function index() --This function is required for LuCI --we don't need to define any pages in this file end + function welcomeRenderer() return 'true' end @@ -18,73 +19,72 @@ function completeRenderer() end function nameRenderer() - if not luci.fs.isfile("/etc/commotion/profiles.d/quickstartAP") then - luci.sys.call('cp /etc/commotion/profiles.d/defaultAP /etc/commotion/profiles.d/quickstartAP') - end - if luci.fs.isfile("/etc/commotion/profiles.d/quickstartSettings") then - luci.sys.call("echo "" > /etc/commotion/profiles.d/quickstartSettings") - end + luci.sys.call("echo '' > /etc/commotion/profiles.d/quickstartSettings") return 'true' end function nameParser() + local QS = luci.controller.QS.QS + QS.log("nameParser running") errors = nil local val = luci.http.formvalue() + --QS.log(val) if val.nodeName and val.nodeName ~= "" and string.len(val.nodeName) < 20 then nodeID = luci.sys.exec("commotion nodeid") --luci.controller.QS.QS.log(val.nodeName) name = tostring(val.nodeName) .. nodeID - file = io.open("/etc/commotion/profiles.d/quickstartSettings", a) + --QS.log(name) + file = io.open("/etc/commotion/profiles.d/quickstartSettings", "a") file:write("hostname="..name.."\n") - if val.secure then + --QS.log("wrote hostname") + if val.secure == 'true' then + --QS.log("passwords:"..val.pwd1.." & "..val.pwd2) pass = checkPass(val.pwd1, val.pwd2) if pass == nil then - file:write("pwd="..pass.."\n") + if not luci.fs.isfile("/etc/commotion/profiles.d/quickstartSec") then + luci.sys.call('cp /etc/commotion/profiles.d/defaultAP /etc/commotion/profiles.d/quickstartSec') + end + file:write("pwd="..val.pwd1.."\n") file:write("SSIDSec="..name.."\n") else return pass end else - file:write("SSID="..name.."\n") + if not luci.fs.isfile("/etc/commotion/profiles.d/quickstartAP") then + luci.sys.call('cp /etc/commotion/profiles.d/defaultAP /etc/commotion/profiles.d/quickstartAP') + end + file:write("SSID="..name.."\n") end file:close() else errors = "Please enter a name that is greater than 0 and less than 20 chars." end - if val. if errors ~= nil then return errors end end -function setValues(setting, value) - --[=[ This function activates the setting value setting functions for defined values. - --]=] - settings = { - "ssid" = setAccessPoint, - "host" = setHostName - } - settings[setting](value) -end +function setAPPassword(pass) + local QS = luci.controller.QS.QS + QS.log("setAPPassword started") -function setValues(setting, value) - --TODO how do we deal with functions that take multiple values??? pass a table? - local settings = { - ssid=setAccessPoint, - host=setHostName, - } - settings[setting](value) + local file = "/etc/commotion/profiles.d/quickstartSec" + local find = '^wpakey=.*' + local replacement = "wpakey="..pass + replaceLine(file, find, replacement) end -function checkSettings(filename) - --[=[ Checks the quickstart settings file and returns a table with setting, value pairs. - --]=] - for line in io.lines("/etc/commotion/profiles.d/quickstartSettings") do - setting = line:split("=") - setValue(setting[1], setting[2]) - end +function setSecAccessPoint(SSID) + local QS = luci.controller.QS.QS + QS.log("setSecAccessPoint started") + + local file = "/etc/commotion/profiles.d/quickstartSec" + local find = "^ssid=.*" + local replacement = 'ssid='..SSID + replaceLine(file, find, replacement) end + function string.split(str, pat) local t = {} if pat == nil then pat=' ' end @@ -96,8 +96,7 @@ function string.split(str, pat) table.insert(t,cap) end last_end = e+1 - s, e, cap = str:find(fpat, last_end) - end + s, e, cap = str:find(fpat, last_end) end if last_end <= #str then cap = str:sub(last_end) table.insert(t, cap) @@ -107,6 +106,8 @@ end function setHostName(hostNamen) + local QS = luci.controller.QS.QS + QS.log("setHostName started") local uci = luci.model.uci.cursor() uci:foreach("system", "system", function(s) @@ -116,11 +117,13 @@ function setHostName(hostNamen) uci:save("system") end end) + QS.log("almost done") hostnameWorks = luci.sys.call("echo " .. hostNamen .. " > /proc/sys/kernel/hostname") end function setAccessPoint(SSID) - QS = luci.controller.QS.QS + local QS = luci.controller.QS.QS + QS.log("setAccessPoint started") local file = "/etc/commotion/profiles.d/quickstartAP" local find = "^ssid=.*" local replacement = 'ssid='..SSID @@ -128,6 +131,9 @@ function setAccessPoint(SSID) end function loadingPage() + local QS = luci.controller.QS.QS + QS.log("loadingPage started") + environment = luci.http.getenv("SERVER_NAME") if not environment then environment = "thisnode" @@ -136,19 +142,46 @@ function loadingPage() luci.http.close() end +function setValues(setting, value) + --[=[ This function activates the setting value setting functions for defined values. + --]=] + --TODO how do we deal with functions that take multiple values? Lua allows passing of muiltiple values, may just need to make more ways to submit. + local QS = luci.controller.QS.QS + QS.log("setValue started") + settings = { + SSID = setAccessPoint, + hostname = setHostName, + pwd = setAPPassword, + SSIDSec = setSecAccessPoint, + } + settings[setting](value) + return +end + +function checkSettings() + --[=[ Checks the quickstart settings file and returns a table with setting, value pairs.--]=] + local QS = luci.controller.QS.QS + QS.log("checkSetttings started") + for line in io.lines("/etc/commotion/profiles.d/quickstartSettings") do + setting = line:split("=") + if setting[1] ~= "" and setting[1] ~= nil then + setValues(setting[1], setting[2]) + end + end + return true +end + function completeParser() --[=[ This function controls the final settings process--]=] - loadingPage() - --This may be where we split the finction into smaller components local QS = luci.controller.QS.QS + QS.log("completeParser started") local uci = luci.model.uci.cursor() - settings = checkSettings() - for i,x in settings do - setValues(i,x) - end + loadingPage() + --This may be where we split the finction into smaller components + checkSettings() files = {{"mesh","quickstartMesh"}, {"secAp","quickstartSec"}, {"ap","quickstartAP"}} QS.wirelessController(files) - --QS.log("Quickstart restarting network") + QS.log("Quickstart restarting network") --set quickstart to done so that it no longer allows access to these tools without admin password luci.sys.call("/etc/init.d/commotiond restart") luci.sys.call("sleep 2; /etc/init.d/network restart") @@ -156,11 +189,11 @@ function completeParser() uci:save('quickstart') uci:commit('quickstart') luci.sys.call("sleep 5 && servald stop && servald start &") + QS.log("it is done") end - function readProfile(name, obj) --[=[ This function takes a profile name and the value desired and returns the result of that value. --]=] @@ -538,7 +571,7 @@ function networkSecurityRenderer() if d then --I bet I could find an even more difficult set of variables to differentiate than b and d, but ill leave it at this :) servald = string.sub(line,d+8,e) - luci.controller.QS.QS.log('servald = '..servald) + --luci.controller.QS.QS.log('servald = '..servald) end end if servald=='true' then diff --git a/usr/lib/lua/luci/view/QS/module/adminPassword.htm b/usr/lib/lua/luci/view/QS/module/adminPassword.htm index db86a64..550ee84 100644 --- a/usr/lib/lua/luci/view/QS/module/adminPassword.htm +++ b/usr/lib/lua/luci/view/QS/module/adminPassword.htm @@ -1,5 +1,5 @@ <%- - if pv.errorMsg then + if pv.errorMsg and pv.errorMsg.adminPassword then if pv.errorMsg.adminPassword.pw then pwErr = pv.errorMsg.adminPassword.pw end end -%> diff --git a/usr/lib/lua/luci/view/QS/module/applyreboot.htm b/usr/lib/lua/luci/view/QS/module/applyreboot.htm index e34e37c..65a9d99 100644 --- a/usr/lib/lua/luci/view/QS/module/applyreboot.htm +++ b/usr/lib/lua/luci/view/QS/module/applyreboot.htm @@ -2,29 +2,21 @@ <%=luci.sys.hostname()%> - <% if title then %><%=title%><% else %><%:Redirecting...%><% end %> <%- - if luci.fs.isfile("/etc/commotion/profiles.d/quickstartAP") then - for line in io.lines("/etc/commotion/profiles.d/quickstartAP") do - b,c = string.find(line,"^ssid=.*") + if luci.fs.isfile("/etc/commotion/profiles.d/quickstartSettings") then + for line in io.lines("/etc/commotion/profiles.d/quickstartSettings") do + b,c = string.find(line,"^SSID=.*") + d,e = string.find(line, "^SSIDSec=.*") + f,g = string.find(line, "^hostname=.*") if b then apName = string.sub(line,b+5,c) + elseif d then + apName = string.sub(line,d+8,e) end - end - elseif luci.fs.isfile("/etc/commotion/profiles.d/quickstartSec") then - for line in io.lines("/etc/commotion/profiles.d/quickstartSec") do - b,c = string.find(line,"^ssid=.*") - if b then - apName = string.sub(line,b+5,c) + if f then + hostname = string.sub(line,f+9,g) end end end - local uci = luci.model.uci.cursor() - --get hostname from system file - uci:foreach("system", "system", - function(s) - if s.hostname then - hostname = s.hostname - end - end) if not luci.fs.isfile("/etc/commotion/profiles.d/quickstartMesh") then luci.sys.call('cp /etc/commotion/profiles.d/defaultMesh /etc/commotion/profiles.d/quickstartMesh') end @@ -34,7 +26,6 @@ netName = string.sub(line,b+5,c) end end - local meshName = netName local nodeName = hostname -%> diff --git a/usr/lib/lua/luci/view/QS/module/name.htm b/usr/lib/lua/luci/view/QS/module/name.htm index 5bdb6dd..f5c3075 100644 --- a/usr/lib/lua/luci/view/QS/module/name.htm +++ b/usr/lib/lua/luci/view/QS/module/name.htm @@ -11,29 +11,31 @@ function toggleVisibility(cb) { var x = document.getElementById("secureAP"); - if(cb.checked==false) - x.style.visibility = "hidden"; // or x.style.display = "none"; + if(cb.checked==true) + x.style.display = "block"; else - x.style.visibility = "visible"; //or x.style.display = "block"; + x.style.display = "none"; } - + +

<%=nameErr%>

- -

What would you like to name your node?

-

This value is used by other users and devices to find your network wirelessly and over the mesh..

-

<%=nameErr%>

- + <%=nodeID%> - - -
-

Password

-

This password is for your access point. Choose a password that is between 9 and 30 characters. This name can be numbers, letters, and special characters.

- -

Retype your password here

- +
+ +

This value is used by other users and devices to find your network wirelessly and over the mesh..

+ + Require a password for others to connect to your node. +
+
From 0c81fafce6fc9115a88cbc5403433662a2c43e18 Mon Sep 17 00:00:00 2001 From: s2e Date: Thu, 2 May 2013 12:47:48 -0400 Subject: [PATCH 07/20] made node addition text sit next to input field, and added help text to the upload module --- etc/config/quickstart | 2 +- usr/lib/lua/luci/view/QS/module/name.htm | 5 +++-- usr/lib/lua/luci/view/QS/module/upload.htm | 10 ++++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/etc/config/quickstart b/etc/config/quickstart index 1f9694a..90dcf71 100644 --- a/etc/config/quickstart +++ b/etc/config/quickstart @@ -16,7 +16,7 @@ config page 'welcome' config page 'settingsFile' option pageTitle 'Using a Settings File' option topheader 'Using a Settings File' - option subheading 'Do you have a settings file? Your network administrator may have provided a settings file. If you have a settings file, please upload it below. Or, you can enter the settings manually.' + option subheading 'If you have a settings file, please upload it below.' option fileType 'config' list modules 'upload' list buttons '4:finish,|Upload and Finish,|,| ,|' diff --git a/usr/lib/lua/luci/view/QS/module/name.htm b/usr/lib/lua/luci/view/QS/module/name.htm index f5c3075..dc1e598 100644 --- a/usr/lib/lua/luci/view/QS/module/name.htm +++ b/usr/lib/lua/luci/view/QS/module/name.htm @@ -18,14 +18,15 @@ } +

<%=nameErr%>

- +

This value is used by other users and devices to find your network wirelessly and over the mesh..

- +
+<%=nodeID%>
Require a password for others to connect to your node.

- +
diff --git a/usr/lib/lua/luci/view/QS/module/name.htm b/usr/lib/lua/luci/view/QS/module/name.htm index dc1e598..266134a 100644 --- a/usr/lib/lua/luci/view/QS/module/name.htm +++ b/usr/lib/lua/luci/view/QS/module/name.htm @@ -25,14 +25,14 @@

<%=nameErr%>

-

This value is used by other users and devices to find your network wirelessly and over the mesh..

+

This value is used by other users and devices to find your network wirelessly and over the mesh.

+<%=nodeID%>
Require a password for others to connect to your node.