зеркало из https://github.com/mozilla/vaani.setup.git
working version
This commit is contained in:
Родитель
ae7b7d5796
Коммит
9627e1e3b5
|
@ -4,6 +4,7 @@ oauthToken.json
|
|||
|
||||
# Ignore emacs backup files
|
||||
*~
|
||||
*#
|
||||
|
||||
# Logs
|
||||
logs
|
||||
|
|
44
README.md
44
README.md
|
@ -20,5 +20,47 @@ handles the first-time setup required to get the device working:
|
|||
|
||||
The code is Linux-specific and has so far only been tested on a
|
||||
Raspberry Pi 3. It also requires hostapd and udhcpd to be installed
|
||||
and properly configured.
|
||||
and properly configured. Here are the steps I followed to get my
|
||||
Raspberry Pi set up to run this server:
|
||||
|
||||
|
||||
## Step 1
|
||||
Install software we need to host an access point, but
|
||||
make sure it does not run by default each time we boot
|
||||
|
||||
```
|
||||
$ sudo apt-get install hostapd
|
||||
$ sudo apt-get install udhcpd
|
||||
$ sudo systemctl disable hostapd
|
||||
$ sudo systemctl disable udhcpd
|
||||
```
|
||||
## Step 2
|
||||
Next, configure the software:
|
||||
|
||||
- Edit /etc/default/hostapd to add the line:
|
||||
|
||||
```
|
||||
DAEMON_CONF="/etc/hostapd/hostapd.conf"
|
||||
```
|
||||
|
||||
- Copy `config/hostapd.conf` to `/etc/hostapd/hostapd.conf`
|
||||
|
||||
- Edit the file `/etc/default/udhcpd` and comment out the line:
|
||||
|
||||
```
|
||||
DHCPD_ENABLED="no"
|
||||
```
|
||||
|
||||
- Copy `config/udhcpd.conf` to `/etc/udhcp.conf`
|
||||
|
||||
## Step 3
|
||||
|
||||
Finally, set up your system to run this server each time it boots up
|
||||
Do this by editing `/etc/rc.local` to add this line, editing the path
|
||||
as appropriate to refer to the start.sh script in this repo.
|
||||
|
||||
```
|
||||
/home/pi/vaani.setup/start.sh &
|
||||
```
|
||||
|
||||
See `config/rc.local` for a startup script that work for me.
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
interface=wlan0
|
||||
driver=nl80211
|
||||
ssid=VaaniSetup
|
||||
hw_mode=g
|
||||
# or 1 or 11
|
||||
channel=6
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# rc.local
|
||||
#
|
||||
# This script is executed at the end of each multiuser runlevel.
|
||||
# Make sure that the script will "exit 0" on success or any other
|
||||
# value on error.
|
||||
#
|
||||
# In order to enable or disable this script just change the execution
|
||||
# bits.
|
||||
#
|
||||
# By default this script does nothing.
|
||||
|
||||
# Print the IP address
|
||||
#_IP=$(hostname -I) || true
|
||||
#if [ "$_IP" ]; then
|
||||
# printf "My IP address is %s\n" "$_IP"
|
||||
#fi
|
||||
|
||||
/home/pi/vaani.setup/start.sh &
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,118 @@
|
|||
# The start and end of the IP lease block
|
||||
start 10.0.0.2 #default: 192.168.0.20
|
||||
end 10.0.0.99 #default: 192.168.0.254
|
||||
|
||||
# The interface that udhcpd will use
|
||||
interface wlan0 #default: eth0
|
||||
opt subnet 255.255.255.0
|
||||
opt router 10.0.0.1
|
||||
|
||||
# I wonder if I need this. The only time we'll be running is when
|
||||
# there is no internet connection, so we won't be able to reach this server
|
||||
# opt dns 8.8.8.8
|
||||
|
||||
|
||||
# I think this might interfere with normal mDNS .local
|
||||
#opt domain local
|
||||
|
||||
|
||||
# The maximim number of leases (includes addressesd reserved
|
||||
# by OFFER's, DECLINE's, and ARP conficts
|
||||
|
||||
#max_leases 254 #default: 254
|
||||
|
||||
|
||||
# If remaining is true (default), udhcpd will store the time
|
||||
# remaining for each lease in the udhcpd leases file. This is
|
||||
# for embedded systems that cannot keep time between reboots.
|
||||
# If you set remaining to no, the absolute time that the lease
|
||||
# expires at will be stored in the dhcpd.leases file.
|
||||
|
||||
#remaining yes #default: yes
|
||||
|
||||
|
||||
# The time period at which udhcpd will write out a dhcpd.leases
|
||||
# file. If this is 0, udhcpd will never automatically write a
|
||||
# lease file. (specified in seconds)
|
||||
|
||||
#auto_time 7200 #default: 7200 (2 hours)
|
||||
|
||||
|
||||
# The amount of time that an IP will be reserved (leased) for if a
|
||||
# DHCP decline message is received (seconds).
|
||||
|
||||
#decline_time 3600 #default: 3600 (1 hour)
|
||||
|
||||
|
||||
# The amount of time that an IP will be reserved (leased) for if an
|
||||
# ARP conflct occurs. (seconds
|
||||
|
||||
#conflict_time 3600 #default: 3600 (1 hour)
|
||||
|
||||
|
||||
# How long an offered address is reserved (leased) in seconds
|
||||
|
||||
#offer_time 60 #default: 60 (1 minute)
|
||||
|
||||
# If a lease to be given is below this value, the full lease time is
|
||||
# instead used (seconds).
|
||||
|
||||
#min_lease 60 #defult: 60
|
||||
|
||||
|
||||
# The location of the leases file
|
||||
|
||||
#lease_file /var/lib/misc/udhcpd.leases #defualt: /var/lib/misc/udhcpd.leases
|
||||
|
||||
# The location of the pid file
|
||||
#pidfile /var/run/udhcpd.pid #default: /var/run/udhcpd.pid
|
||||
|
||||
# Everytime udhcpd writes a leases file, the below script will be called.
|
||||
# Useful for writing the lease file to flash every few hours.
|
||||
|
||||
#notify_file #default: (no script)
|
||||
|
||||
#notify_file dumpleases # <--- useful for debugging
|
||||
|
||||
# The following are bootp specific options, setable by udhcpd.
|
||||
|
||||
#siaddr 192.168.0.22 #default: 0.0.0.0
|
||||
|
||||
#sname zorak #default: (none)
|
||||
|
||||
#boot_file /var/nfs_root #default: (none)
|
||||
|
||||
# The remainer of options are DHCP options and can be specifed with the
|
||||
# keyword 'opt' or 'option'. If an option can take multiple items, such
|
||||
# as the dns option, they can be listed on the same line, or multiple
|
||||
# lines. The only option with a default is 'lease'.
|
||||
|
||||
# Currently supported options, for more info, see options.c
|
||||
#opt subnet
|
||||
#opt timezone
|
||||
#opt router
|
||||
#opt timesrv
|
||||
#opt namesrv
|
||||
#opt dns
|
||||
#opt logsrv
|
||||
#opt cookiesrv
|
||||
#opt lprsrv
|
||||
#opt bootsize
|
||||
#opt domain
|
||||
#opt swapsrv
|
||||
#opt rootpath
|
||||
#opt ipttl
|
||||
#opt mtu
|
||||
#opt broadcast
|
||||
#opt wins
|
||||
#opt lease
|
||||
#opt ntpsrv
|
||||
#opt tftp
|
||||
#opt bootfile
|
||||
#opt wpad
|
||||
|
||||
# Static leases map
|
||||
#static_lease 00:60:08:11:CE:4E 192.168.0.54
|
||||
#static_lease 00:60:08:11:CE:3E 192.168.0.44
|
||||
|
||||
|
72
index.js
72
index.js
|
@ -1,27 +1,31 @@
|
|||
var wifi = require('./wifi.js');
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
var fs = require('fs');
|
||||
var Express = require('express');
|
||||
var Handlebars = require('handlebars');
|
||||
var Evernote = require('evernote').Evernote;
|
||||
var bodyParser = require('body-parser');
|
||||
var fs = require('fs');
|
||||
var wifi = require('./wifi.js');
|
||||
var wait = require('./wait.js');
|
||||
var evernoteConfig = require('./evernoteConfig.json');
|
||||
|
||||
// Start running the server, then determine whether we need to
|
||||
// to start a private AP so the user can connect
|
||||
// Start running the server, then, if we don't have a wifi connection after
|
||||
// 15 seconds, start a private access point that the user can connect to.
|
||||
startServer();
|
||||
wifi.getStatus().then(status => {
|
||||
// If we don't have a wifi connection, broadcast our own wifi network.
|
||||
// If we don't do that, no one will be able to connect to the server!
|
||||
console.log('wifi status:', status);
|
||||
if (status !== 'COMPLETED') {
|
||||
wifi.startAP();
|
||||
console.log('Started private wifi network VaaniSetup');
|
||||
}
|
||||
})
|
||||
|
||||
wait(15000)
|
||||
.then(() => wifi.getStatus())
|
||||
.then(status => {
|
||||
// If we don't have a wifi connection, broadcast our own wifi network.
|
||||
// If we don't do that, no one will be able to connect to the server!
|
||||
console.log('wifi status:', status);
|
||||
if (status !== 'COMPLETED') {
|
||||
wifi.startAP();
|
||||
console.log('Started private wifi network VaaniSetup');
|
||||
}
|
||||
});
|
||||
|
||||
function startServer(wifiStatus) {
|
||||
// Now start up the express server
|
||||
var server = express();
|
||||
var server = Express();
|
||||
|
||||
// When we get POSTs, handle the body like this
|
||||
server.use(bodyParser.urlencoded({extended:false}));
|
||||
|
@ -56,7 +60,6 @@ var statusTemplate = getTemplate('./templates/status.hbs');
|
|||
// This function handles requests for the root URL '/'.
|
||||
// We display a different page depending on what stage of setup we're at
|
||||
function handleRoot(request, response) {
|
||||
console.log('handleRoot');
|
||||
wifi.getStatus().then(status => {
|
||||
console.log("wifi status", status);
|
||||
|
||||
|
@ -102,24 +105,24 @@ function handleConnecting(request, response) {
|
|||
var password = request.body.password.trim();
|
||||
response.send(connectingTemplate({ssid: ssid}));
|
||||
|
||||
// XXX: another problem. I think I need to wait a bit after sending the
|
||||
// response to be sure it gets through. Now that I'm calling stopAP first
|
||||
// the network went down before I received the response in my browser.
|
||||
// Wait before switching networks to make sure the response gets through.
|
||||
// And also wait to be sure that the access point is fully down before
|
||||
// defining the new network.
|
||||
wait(2000)
|
||||
.then(() => wifi.stopAP())
|
||||
.then(() => wait(2000))
|
||||
.then(() => wifi.defineNetwork(ssid, password));
|
||||
|
||||
// XXX I've got a problem here. This brings up the new network, and
|
||||
// we can connect to the device over local wifi. But the device
|
||||
// still thinks it is 10.0.0.1 instead of using the IP address
|
||||
// assigned by dhcp and somehow that means that it can't get out to
|
||||
// the internet. (At least when I'm testing from home where
|
||||
// 10.0.0.1 is my router) Rebooting fixes things, but I somehow need
|
||||
// stopAP() to relinquish 10.0.0.1 and get the right address. XXX
|
||||
// Maybe calling stopAP first before defining the network would
|
||||
// help? No, that doesn't seem to help with the ip address problem
|
||||
wifi.stopAP().then(out => wifi.defineNetwork(ssid, password));
|
||||
// XXX: it would be cool to monitor the network connection and
|
||||
// beep (or blink leds) when the network has switched over and the
|
||||
// user can click the continue button.
|
||||
// Whether or not I should do that, I should at least modify the
|
||||
// template so it has a JS-based countdown that makes the user wait
|
||||
// 20 seconds or something before enabling the continue button.
|
||||
}
|
||||
|
||||
function handleOauthSetup(request, response) {
|
||||
response.send(oauthSetupTemplate({}));
|
||||
response.send(oauthSetupTemplate());
|
||||
}
|
||||
|
||||
// We hold our oauth state here. If this was a server that ever had
|
||||
|
@ -186,5 +189,12 @@ function handleOauthCallback(request, response) {
|
|||
}
|
||||
|
||||
function handleStatus(request, response) {
|
||||
// XXX
|
||||
// I want to expand the status template so that it actually displays
|
||||
// the current wifi and oauth status and displays buttons that take
|
||||
// the user back to the /wifiSetup and /oauthSetup pages. In order to
|
||||
// do that, this function will need to determine the current network
|
||||
// and oauth status (e.g. the expiration date of the token) and pass
|
||||
// those to the template.
|
||||
response.send(statusTemplate())
|
||||
}
|
||||
|
|
5
start.sh
5
start.sh
|
@ -1,3 +1,6 @@
|
|||
#!/bin/sh
|
||||
# This script starts the server and is suitable for use from /etc/rc.local
|
||||
# The script assumes it is run with root privileges
|
||||
cd `dirname $0`
|
||||
/usr/local/bin/node index.js > stdout.log 2> stderr.log
|
||||
/usr/local/bin/node index.js &> `date +%F-%H-%M-%S`.log
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = function wait(milliseconds) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
setTimeout(resolve, milliseconds);
|
||||
});
|
||||
};
|
7
wifi.js
7
wifi.js
|
@ -156,15 +156,12 @@ function startAP() {
|
|||
* this point, the AP should be in the process of stopping but may not
|
||||
* yet be completely down.
|
||||
*
|
||||
* Note that this function does not change the local IP address from 10.0.0.1
|
||||
* back to whatever it was before startAP() was called. As far as I can tell
|
||||
* this does not actually cause any problems.
|
||||
*
|
||||
* Note that this function requires root privileges to work
|
||||
*/
|
||||
function stopAP() {
|
||||
return run('systemctl stop udhcpd')
|
||||
.then(output => run('systemctl stop hostapd'));
|
||||
.then(output => run('systemctl stop hostapd'))
|
||||
.then(output => run('ifconfig wlan0 0.0.0.0'));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче