OpenWrt Forum Archive

Topic: custom Luci page to change SSID and passphrase only

The content of this topic has been archived on 13 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi all, I'm not sure I'm posting in the correct area but wasn't sure where to start.

I'll try and keep the background info brief, I'm using a TP-link MR3020 as a local wifi access point into an Ethernet enabled device (PLC) for diagnostic purposes, fault display, error logging and so on using your smartphone as the screen. In this mode there is no internet available.

This TP-link router can be switch using the slider switch to 'guest' mode (WISP) which then connects to a predefined SSID and passphrase, in this mode the router gains internet access from the wifi hotspot (most likely the same smartphone hotspot). The router then initiates an OpenVPN connection back to a server, at this point direct remote access can be gained to the Ethernet device, at which point anything can get be changed or updated as if local to the device, using routing tables and so on.

The above process seems to work ok, BUT with the acceptation that each smartphones SSID and pass must be changed to match the predefined one as stated above. This is a bit of a pain with some smartphones.

What I want to try to implement is a custom Luci page showing only the SSID and passphrase text fields that can be changed to suit the new users phones SSID and pass. These changes would have to be carried out with the router in AP mode, so it would be a different wireless config file than the one that would be running. Also after every reboot the router would return to either AP mode or 'guest' mode (depending on slider) with predefined SSID.

Is it even possible to change a config file that is not currently running? How do you make a custom page with only two text fields and submit button? Also I build my firmware images using ImageGenerator (ImageBuilder) so the custom page might have to be copied from /etc folder to /luci folder, maybe...

Any help would be awesome, the CBI or View (Template) seems to required a different way to compile the firmware other than ImageGenerator, which I'm not familiar with.

Thanks heaps,

You don't need to compile model/cbi files at all, you can include them (as well as a controller file) as files with the image builder. They go into directories under /usr/lib/lua/luci/.

Luci API page + code from existing wireless config page (I believe it's under system_network somewhere) should help you. I'm not a programmer and I've done something similar in the past.

Thanks for your suggestions Stangri, I'm already including files into my image like /etc/config/, I didn't realise you could include other things like /usr/lib/lua/luci. i'll do that thanks.

You wouldn't know how to install the development environment into say Ubuntu so I can test different code examples without having to flash the firmware into the target device for every change?

you wouldn't have an example I could follow by any chance?

Thanks again

Well, if you checked documentation, there's this: http://luci.subsignal.org/trac/wiki/Doc … nmentHowTo
For my modest needs tho, I just scp files I want to test to the router and try them live.

(Last edited by stangri on 9 Mar 2017, 01:42)

--update--

I've managed to use then 'Scheduled Tasks' page as an example to copy which reads a file and allows changes to be made, then submit button writes the file back.

This works great except that it allows the whole file to be modified. it would be better if I could appended two lines to the end of the file, SSID and passphrase.

The nixio.fs doesn't seem to allow 'append', are there any examples of taking textbox input and appending to the end of a file?

tks,

You can use the 'a' mode to append to the end of the file....

local function append_file(str) -- str is the string to be appended
  local filename = "some_file"  -- path to file to be appended
  local file = assert(io.open(filename, "a"))  -- open file in append mode
  file:write(str) -- append string to end of file
  file:flush()  -- save the file
  file:close() -- close the file
 return
end

(Last edited by hostle19 on 16 Mar 2017, 13:54)

Thanks everyone for there suggestions, with all the info I have managed to find a solution that allows me to extract the two required fields and place them in f:field(Value,.,.,.) CBI objects.

To do this I first read the file and search for required field for example 'ssid', see below example (experimental code hack)

function read_field(strobject, length)
        data = tostring(fs.readfile(hotspotfile))
        start = data:find("option " .. strobject,1) + 9 + length
        ends = data:find("'", start) - 1
        return data:sub(start,ends)
end

You call this function when you want something out of the file like this:

function ssid.cfgvalue()
        return read_field("ssid", 4)  -- note the 4 is the length of the string
end

(Question, how do you determine the length of a string? What's the syntax?)

The write event looks like this:

function ssid.write(self, section, value)
        Value.write(self,section, value)
        data = tostring(fs.readfile(hotspotfile))
        foundtext = read_field("ssid", 4)
        data = data:gsub(foundtext, value)
        fs.writefile(hotspotfile, data:gsub("\r\n", "\n"))
end

The gsub is the key here, it substitutes the text found in the file with the text from value field.

Again thanks everyone and hope it might help someone else, maybe...

(Last edited by zonared on 22 Mar 2017, 03:56)

Is there a reason you're not using a map to wifi config with model/cbi and coding everything in Lua?
For the string length -- did you google "lua string length" or "lua string library"?

because I don't know what 'a map to wifi config' is ? smile

I don't want to change the currently running wifi config, I want to change the config of a file that will become the running wifi after the slider switch has been changed and router rebooted.

I couldn't find another way to do it with my the VERY limited knowledge and short time constraints, I had to get something up and working.

I thought I Googled lots of ways to find string length but maybe not that exact search,
I tried strobject.len() which is the example from the first result using your Google search and I receive this error:
A runtime error occured: ...ib/lua/luci/model/cbi/admin_network/wifi_support.lua:12: bad argument #1 to 'len' (string expected, got no value)

Thanks

You're welcome to continue on the path you've started already, but if I were you, I'd:
1. Create a CBI file with map to WiFi config letting user edit STA WiFi interface with the disabled default state.
2. On a slider switch -- enable/disable STA interface.
3. On boot up -- disable/enable STA interface based on the slider position.

Even at my very modest skill level it's a single day job at most.

Post your e-mail and I can send you the code I've mentioned in my first reply in this thread.

zonared wrote:

because I don't know what 'a map to wifi config' is ? smile

I don't want to change the currently running wifi config, I want to change the config of a file that will become the running wifi after the slider switch has been changed and router rebooted.

I couldn't find another way to do it with my the VERY limited knowledge and short time constraints, I had to get something up and working.

I thought I Googled lots of ways to find string length but maybe not that exact search,
I tried strobject.len() which is the example from the first result using your Google search and I receive this error:
A runtime error occured: ...ib/lua/luci/model/cbi/admin_network/wifi_support.lua:12: bad argument #1 to 'len' (string expected, got no value)

Thanks

to get the length of a string in lua the syntax is ...

local str = "some string" -- example string ... must not be nil or an error will occur
 
local length = str:len() -- get the length

print(length) -- print the length




wink

(Last edited by hostle19 on 25 Mar 2017, 14:37)

Thanks everyone, I have a working solution for now. I appreciate all the suggestions.

Stangri, also thanks for the offer to send example CBI file, but i'll stick with what i have so far. it works and I've got bigger fish to fry.

hostle19, i'll change my hack function to measure the string length correctly as you suggest.

The discussion might have continued from here.