Connect to open Wifi and accept terms

Were trying to set up a device in location which has open wifi access over the whole city. Once connected to the wifi it automatically opens a captive portal listing terms of use. In order to get internet connection we need to “click” the “Accept terms” button.

After talking it over with the IT people on their end, they have provided us with .har file outlining the process. From the looks of it, all we need to do is send an HTTP POST request to a static IP with payload ‘{“buttonClicked”: 4, “err_flag”: 0}’ every hour in order for it to work, and for WiFi acess to persist.

After reading the Networking docs and also looking at a couple of projects such as wifi-connect I am not certain how to actually go about it. It does not seem something that is supported via the resin-wifi file, not do I see an example code on how to achieve something like this in Python or Node.

Does anyone have a similar issue and could share a project or code snippet on how they approached this issue. I am certain I am not the only one here considering this kind of problem.

I’m not sure that I fully understand the issue. It seems like you’re saying that you just need to POST to a url once an hour to keep your connection alive. In that case it can be achieved through Python, NodeJS, or simply using the curl command and a scheduler of some kind (cron, systemd, etc).

Using curl:

curl -d '{“buttonClicked”: 4, “err_flag”: 0}' -H "Content-Type: application/json" -X POST http://yourStaticIpAddress:port/endpoint

Scheduling it with Cron would be simple. Create a text file called keepConnectionAlive.txt with the contents something like this

1 * * * * curl -d '{“buttonClicked”: 4, “err_flag”: 0}' -H "Content-Type: application/json" -X POST http://yourStaticIpAddress:port/endpoint

and in your Dockerfile put

RUN crontab keepConnectionAlive.txt

Using NodeJS you could use any number of libraries. Axios, request, request-promise, etc. That might look something like this:

const axios = require('axios')

axios
.post('http://yourStaticIpAddress:port/endpoint', {“buttonClicked”: 4, “err_flag”: 0})
.then(res => {
  console.log(`statusCode: ${res.statusCode}`)
})
.catch(console.log)

You could use crontab to schedule running the Javascript file too. Python would be very similar.

The OP description reminds me of the web page forms that pop-up when we connect to an open WiFi network, asking us to fill in personal details and/or username and password to connect. It sounds to me like the objective is to have a balenaOS device automatically login (as if it had filled and submitted the web form).

It’s been clarified that submitting the POST request would achieve the login; perhaps the pending question is when to do it, or how to trigger the POST request. I’ve come across NetworkManager “dispatcher scripts” that run in response to events:

I see that balenaOS comes a few relevant folders:

root@6983a3f:~# find /etc/NetworkManager/dispatcher.d/
/etc/NetworkManager/dispatcher.d/
/etc/NetworkManager/dispatcher.d/pre-up.d
/etc/NetworkManager/dispatcher.d/no-wait.d
/etc/NetworkManager/dispatcher.d/99dhcp_ntp
/etc/NetworkManager/dispatcher.d/pre-down.d

But it’s a read-only filesystem, so adding files there may not be the way to go about it. Perhaps it would be possible to use the DBUS interface to modify the dispatcher actions, or to respond to events:

I am not yet clear which DBUS call it would be, though. Another potential option, perhaps easier although less elegant, might be poll for a valid internet connection every 30 seconds or so. If one is not detected, send a POST request (which may fail or succeed depending on the WiFi link status), and wait another 30 seconds.

1 Like

I think a more general solution would be to bridge the network until an Internet connection is established. Then, you could use the phone/whatever is being used to give the SSID/password to wifi-connect to also give login information to the network it connects to.

I don’t know exactly how to do this, but I think the functional process would be:

  1. Use the UI provided SSID/password to log into the upstream WiFi.
  2. Test for an Internet connection once on the upstream WiFi. If it exists, go ahead and exit like it does now. If it doesn’t exist, bridge the upstream WiFi to the access point WiFi created by wifi-connect.
  3. Intermittently test for an Internet connection. If it exists, exit and remove the access point WiFi along with the associated bridge.

The bridged connection will allow the web UI to provided the login interface. It might be necessary to redirect the browser after login to a known-good location (without https) that will trigger the UI to present the upstream captive portal login page.

Thoughts?