diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py index 77ae2a59db2..c91d17364ce 100644 --- a/addons/hw_escpos/controllers/main.py +++ b/addons/hw_escpos/controllers/main.py @@ -193,6 +193,8 @@ class EscposDriver(Thread): def print_status(self,eprint): localips = ['0.0.0.0','127.0.0.1','127.0.1.1'] + hosting_ap = os.system('pgrep hostapd') == 0 + ssid = subprocess.check_output('iwconfig 2>&1 | grep \'ESSID:"\' | sed \'s/.*"\\(.*\\)"/\\1/\'', shell=True).rstrip() ips = [ c.split(':')[1].split(' ')[0] for c in commands.getoutput("/sbin/ifconfig").split('\n') if 'inet addr' in c ] ips = [ ip for ip in ips if ip not in localips ] eprint.text('\n\n') @@ -201,6 +203,11 @@ class EscposDriver(Thread): eprint.text('\n') eprint.set(align='center') + if hosting_ap: + eprint.text('Wireless network:\nPosbox\n\n') + elif ssid: + eprint.text('Wireless network:\n' + ssid + '\n\n') + if len(ips) == 0: eprint.text('ERROR: Could not connect to LAN\n\nPlease check that the PosBox is correc-\ntly connected with a network cable,\n that the LAN is setup with DHCP, and\nthat network addresses are available') elif len(ips) == 1: diff --git a/addons/hw_posbox_homepage/controllers/main.py b/addons/hw_posbox_homepage/controllers/main.py index a021986bee7..26509d8d58a 100644 --- a/addons/hw_posbox_homepage/controllers/main.py +++ b/addons/hw_posbox_homepage/controllers/main.py @@ -2,6 +2,8 @@ import logging import os import time +import werkzeug +import subprocess from os import listdir import openerp @@ -43,6 +45,9 @@ index_template = """ to the hardware status page.

+ Wi-Fi can be configured by visiting the Wi-Fi configuration page. +

+

The PosBox software installed on this posbox is version 13, the posbox version number is independent from Odoo. You can upgrade the software on the upgrade page. @@ -60,4 +65,100 @@ class PosboxHomepage(openerp.addons.web.controllers.main.Home): def index(self): #return request.render('hw_posbox_homepage.index',mimetype='text/html') return index_template - + + @http.route('/wifi', type='http', auth='none', website=True) + def wifi(self): + wifi_template = """ + + + + Wifi configuration + + + +

Configure wifi

+

+ Here you can configure how the posbox should connect to wireless networks. + Currently only Open and WPA networks are supported. When enabling the persistent checkbox, + the chosen network will be saved and the posbox will attempt to connect to it every time it boots. +

+
+ + + + + + + + + + + + + + + + +
+ ESSID: + + +
+ Password: + + +
+ Persistent: + + +
+ + +
+
+

+ You can clear the persistent configuration by clicking below: +

+ +
+

+
+ + +""" + return wifi_template + + @http.route('/wifi_connect', type='http', auth='none', cors='*') + def connect_to_wifi(self, essid, password, persistent=False): + if persistent: + persistent = "1" + else: + persistent = "" + + subprocess.call(['/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh', essid, password, persistent]) + return "connecting to " + essid + + @http.route('/wifi_clear', type='http', auth='none', cors='*') + def clear_wifi_configuration(self): + os.system('/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/clear_wifi_configuration.sh') + return "configuration cleared" diff --git a/addons/point_of_sale/tools/posbox/configuration/clear_wifi_configuration.sh b/addons/point_of_sale/tools/posbox/configuration/clear_wifi_configuration.sh new file mode 100755 index 00000000000..c989c48309a --- /dev/null +++ b/addons/point_of_sale/tools/posbox/configuration/clear_wifi_configuration.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +logger -t posbox_clear_wifi_configuration "Clearing the wifi configuration" +sudo mount -o remount,rw / +sudo rm -f /home/pi/wifi_network.txt +sudo mount -o remount,ro / diff --git a/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh b/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh new file mode 100755 index 00000000000..1f847104dbb --- /dev/null +++ b/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# call with ESSID and optionally a password +# when called without an ESSID, it will attempt +# to reconnect to a previously chosen network +function connect () { + WPA_PASS_FILE="/tmp/wpa_pass.txt" + PERSISTENT_WIFI_NETWORK_FILE="/home/pi/wifi_network.txt" + CURRENT_WIFI_NETWORK_FILE="/tmp/current_wifi_network.txt" # used to repair connection when we lose it + ESSID="${1}" + PASSWORD="${2}" + PERSIST="${3}" + + sleep 3 + + sudo pkill -f keep_wifi_alive.sh + + # make network choice persistent + if [ -n "${ESSID}" ] ; then + if [ -n "${PERSIST}" ] ; then + logger -t posbox_connect_to_wifi "Making network selection permanent" + sudo mount -o remount,rw / + echo "${ESSID}" > ${PERSISTENT_WIFI_NETWORK_FILE} + echo "${PASSWORD}" >> ${PERSISTENT_WIFI_NETWORK_FILE} + sudo mount -o remount,ro / + fi + else + logger -t posbox_connect_to_wifi "Reading configuration from ${PERSISTENT_WIFI_NETWORK_FILE}" + ESSID=$(head -n 1 "${PERSISTENT_WIFI_NETWORK_FILE}" | tr -d '\n') + PASSWORD=$(tail -n 1 "${PERSISTENT_WIFI_NETWORK_FILE}" | tr -d '\n') + fi + + echo "${ESSID}" > ${CURRENT_WIFI_NETWORK_FILE} + echo "${PASSWORD}" >> ${CURRENT_WIFI_NETWORK_FILE} + + logger -t posbox_connect_to_wifi "Connecting to ${ESSID}" + sudo service hostapd stop + sudo service isc-dhcp-server stop + + sudo pkill wpa_supplicant + sudo ifconfig wlan0 down + sudo ifconfig wlan0 0.0.0.0 # this is how you clear the interface's configuration + sudo ifconfig wlan0 up + + if [ -z "${PASSWORD}" ] ; then + sudo iwconfig wlan0 essid "${ESSID}" + else + sudo wpa_passphrase "${ESSID}" "${PASSWORD}" > "${WPA_PASS_FILE}" + sudo wpa_supplicant -B -i wlan0 -c "${WPA_PASS_FILE}" + fi + + sudo service dhcpcd restart + + # give dhcp some time + timeout 30 sh -c 'until ifconfig wlan0 | grep "inet addr:" ; do sleep 0.1 ; done' + + if [ $? -eq 124 ] ; then + logger -t posbox_connect_to_wifi "Failed to connect, forcing Posbox AP" + sudo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh "force" & + else + logger -t posbox_connect_to_wifi "Restarting odoo" + sudo service odoo restart + + logger -t posbox_connect_to_wifi "Starting wifi keep alive script" + /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh & + fi +} + +connect "${1}" "${2}" "${3}" & diff --git a/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh b/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh new file mode 100755 index 00000000000..5f69451feff --- /dev/null +++ b/addons/point_of_sale/tools/posbox/configuration/keep_wifi_alive.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +CURRENT_WIFI_NETWORK_FILE="/tmp/current_wifi_network.txt" +while true ; do + if [ -z "$(cat <(ifconfig eth0) <(ifconfig wlan0) | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}';)" ] ; then + ESSID=$(head -n 1 "${CURRENT_WIFI_NETWORK_FILE}" | tr -d '\n') + PASSWORD=$(tail -n 1 "${CURRENT_WIFI_NETWORK_FILE}" | tr -d '\n') + + logger -t posbox_keep_wifi_alive "Lost wifi, trying to reconnect to ${ESSID}" + + sudo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh "${ESSID}" "${PASSWORD}" + + sleep 30 + fi + + sleep 2 +done diff --git a/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh b/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh new file mode 100755 index 00000000000..bf7a3427f69 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +FORCE_HOST_AP="${1}" +WIRED_IP=$(ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}';) +WIFI_NETWORK_FILE="/home/pi/wifi_network.txt" + +# if there is no wired ip, attempt to start an AP through wireless interface +if [ -z "${WIRED_IP}" ] ; then + logger -t posbox_wireless_ap "No wired IP" + + ifconfig wlan0 down + ifconfig wlan0 up + + # wait for wlan0 to come up + sleep 5 + + # we cannot scan for networks while in Master mode + # so first scan and save the networks to a list + iwlist wlan0 scan | grep 'ESSID:' | sed 's/.*ESSID:"\(.*\)"/\1/' > /tmp/scanned_networks.txt + + # only do it when there is a wireless interface + if [ -n "$(iw list)" ] ; then + if [ -f "${WIFI_NETWORK_FILE}" ] && [ -z "${FORCE_HOST_AP}" ] ; then + logger -t posbox_wireless_ap "Loading persistently saved setting" + /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/connect_to_wifi.sh & + else + logger -t posbox_wireless_ap "Starting AP" + + service hostapd restart + + ip addr add 10.10.0.1/24 dev wlan0 + + service isc-dhcp-server restart + + service odoo restart + fi + # no wired, no wireless + else + service odoo restart + fi +# wired +else + service odoo restart +fi diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/hostapd b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/hostapd new file mode 100644 index 00000000000..7e97ae99328 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/hostapd @@ -0,0 +1,20 @@ +# Defaults for hostapd initscript +# +# See /usr/share/doc/hostapd/README.Debian for information about alternative +# methods of managing hostapd. +# +# Uncomment and set DAEMON_CONF to the absolute path of a hostapd configuration +# file and hostapd will be started during system boot. An example configuration +# file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz +# +DAEMON_CONF="/etc/hostapd/hostapd.conf" + +# Additional daemon options to be appended to hostapd command:- +# -d show more debug messages (-dd for even more) +# -K include key data in debug messages +# -t include timestamps in some debug messages +# +# Note that -B (daemon mode) and -P (pidfile) options are automatically +# configured by the init.d script and must not be added to DAEMON_OPTS. +# +DAEMON_OPTS="-d" diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/ifplugd b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/ifplugd new file mode 100644 index 00000000000..cf4331971bc --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/default/ifplugd @@ -0,0 +1,17 @@ +# This file may be changed either manually or by running dpkg-reconfigure. +# +# N.B.: dpkg-reconfigure deletes everything from this file except for +# the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and +# SUSPEND_ACTION. When run it uses the current values of those variables +# as their default values, thus preserving the administrator's changes. +# +# This file is sourced by both the init script /etc/init.d/ifplugd and +# the udev script /lib/udev/ifplugd.agent to give default values. +# The init script starts ifplugd for all interfaces listed in +# INTERFACES, and the udev script starts ifplugd for all interfaces +# listed in HOTPLUG_INTERFACES. The special value all starts one +# ifplugd for all interfaces being present. +INTERFACES="eth0" # auto +HOTPLUG_INTERFACES="eth0" # all +ARGS="-q -f -u0 -d10 -w -I" +SUSPEND_ACTION="stop" diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcp/dhcpd.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcp/dhcpd.conf new file mode 100644 index 00000000000..054b4b4477f --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcp/dhcpd.conf @@ -0,0 +1,113 @@ +# +# Sample configuration file for ISC dhcpd for Debian +# +# + +# The ddns-updates-style parameter controls whether or not the server will +# attempt to do a DNS update when a lease is confirmed. We default to the +# behavior of the version 2 packages ('none', since DHCP v2 didn't +# have support for DDNS.) +ddns-update-style none; + +# option definitions common to all supported networks... +#option domain-name "example.org"; +#option domain-name-servers ns1.example.org, ns2.example.org; + +#default-lease-time 600; +#max-lease-time 7200; + +# If this DHCP server is the official DHCP server for the local +# network, the authoritative directive should be uncommented. +#authoritative; + +# Use this to send dhcp log messages to a different log file (you also +# have to hack syslog.conf to complete the redirection). +# log-facility local7; + +# No service will be given on this subnet, but declaring it helps the +# DHCP server to understand the network topology. + +#subnet 10.152.187.0 netmask 255.255.255.0 { +#} + +# This is a very basic subnet declaration. + +#subnet 10.254.239.0 netmask 255.255.255.224 { +# range 10.254.239.10 10.254.239.20; +# option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org; +#} + +subnet 10.10.0.0 netmask 255.255.255.0 { + range 10.10.0.2 10.10.0.254; + option domain-name-servers 8.8.8.8, 208.67.222.222; + option routers 10.10.0.1; +} + +# This declaration allows BOOTP clients to get dynamic addresses, +# which we don't really recommend. + +#subnet 10.254.239.32 netmask 255.255.255.224 { +# range dynamic-bootp 10.254.239.40 10.254.239.60; +# option broadcast-address 10.254.239.31; +# option routers rtr-239-32-1.example.org; +#} + +# A slightly different configuration for an internal subnet. +#subnet 10.5.5.0 netmask 255.255.255.224 { +# range 10.5.5.26 10.5.5.30; +# option domain-name-servers ns1.internal.example.org; +# option domain-name "internal.example.org"; +# option routers 10.5.5.1; +# option broadcast-address 10.5.5.31; +# default-lease-time 600; +# max-lease-time 7200; +#} + +# Hosts which require special configuration options can be listed in +# host statements. If no address is specified, the address will be +# allocated dynamically (if possible), but the host-specific information +# will still come from the host declaration. + +#host passacaglia { +# hardware ethernet 0:0:c0:5d:bd:95; +# filename "vmunix.passacaglia"; +# server-name "toccata.fugue.com"; +#} + +# Fixed IP addresses can also be specified for hosts. These addresses +# should not also be listed as being available for dynamic assignment. +# Hosts for which fixed IP addresses have been specified can boot using +# BOOTP or DHCP. Hosts for which no fixed address is specified can only +# be booted with DHCP, unless there is an address range on the subnet +# to which a BOOTP client is connected which has the dynamic-bootp flag +# set. +#host fantasia { +# hardware ethernet 08:00:07:26:c0:a5; +# fixed-address fantasia.fugue.com; +#} + +# You can declare a class of clients and then do address allocation +# based on that. The example below shows a case where all clients +# in a certain class get addresses on the 10.17.224/24 subnet, and all +# other clients get addresses on the 10.0.29/24 subnet. + +#class "foo" { +# match if substring (option vendor-class-identifier, 0, 4) = "SUNW"; +#} + +#shared-network 224-29 { +# subnet 10.17.224.0 netmask 255.255.255.0 { +# option routers rtr-224.example.org; +# } +# subnet 10.0.29.0 netmask 255.255.255.0 { +# option routers rtr-29.example.org; +# } +# pool { +# allow members of "foo"; +# range 10.17.224.10 10.17.224.250; +# } +# pool { +# deny members of "foo"; +# range 10.0.29.10 10.0.29.230; +# } +#} diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcpcd.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcpcd.conf new file mode 100644 index 00000000000..00a1d04f28f --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/dhcpcd.conf @@ -0,0 +1,45 @@ +# A sample configuration for dhcpcd. +# See dhcpcd.conf(5) for details. + +# Allow users of this group to interact with dhcpcd via the control socket. +#controlgroup wheel + +# Inform the DHCP server of our hostname for DDNS. +hostname + +# Use the hardware address of the interface for the Client ID. +#clientid +# or +# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361. +duid + +# Persist interface configuration when dhcpcd exits. +persistent + +# Rapid commit support. +# Safe to enable by default because it requires the equivalent option set +# on the server to actually work. +option rapid_commit + +# A list of options to request from the DHCP server. +option domain_name_servers, domain_name, domain_search, host_name +option classless_static_routes +# Most distributions have NTP support. +option ntp_servers +# Respect the network MTU. +# Some interface drivers reset when changing the MTU so disabled by default. +#option interface_mtu + +# A ServerID is required by RFC2131. +require dhcp_server_identifier + +# Generate Stable Private IPv6 Addresses instead of hardware based ones +slaac private + +# A hook script is provided to lookup the hostname if not set by the DHCP +# server, but it should not be run by default. +nohook lookup-hostname + +# dhcpcd will assign zeroconf 169.254.*.* addresses when +# it can't connect, which we don't want +noipv4ll diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/hostapd/hostapd.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/hostapd/hostapd.conf new file mode 100644 index 00000000000..c1cf6f5f386 --- /dev/null +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/hostapd/hostapd.conf @@ -0,0 +1,3 @@ +interface=wlan0 +ssid=Posbox +channel=1 diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local index dab16e3b415..4c4739b4aeb 100755 --- a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local +++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/rc.local @@ -21,5 +21,6 @@ mkdir -p /var/run/odoo chown pi:pi /var/run/odoo /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/led_status.sh & +/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/wireless_ap.sh & exit 0 diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh index 6838f7fa78c..cda4dfbd6b1 100755 --- a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh +++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh @@ -31,7 +31,7 @@ apt-get -y autoremove apt-get update apt-get -y dist-upgrade -PKGS_TO_INSTALL="adduser postgresql-client python python-dateutil python-decorator python-docutils python-feedparser python-imaging python-jinja2 python-ldap python-libxslt1 python-lxml python-mako python-mock python-openid python-passlib python-psutil python-psycopg2 python-pybabel python-pychart python-pydot python-pyparsing python-pypdf python-reportlab python-requests python-simplejson python-tz python-unittest2 python-vatnumber python-vobject python-werkzeug python-xlwt python-yaml postgresql python-gevent python-serial python-pip python-dev localepurge vim mc mg screen" +PKGS_TO_INSTALL="adduser postgresql-client python python-dateutil python-decorator python-docutils python-feedparser python-imaging python-jinja2 python-ldap python-libxslt1 python-lxml python-mako python-mock python-openid python-passlib python-psutil python-psycopg2 python-pybabel python-pychart python-pydot python-pyparsing python-pypdf python-reportlab python-requests python-simplejson python-tz python-unittest2 python-vatnumber python-vobject python-werkzeug python-xlwt python-yaml postgresql python-gevent python-serial python-pip python-dev localepurge vim mc mg screen iw hostapd isc-dhcp-server" apt-get -y install ${PKGS_TO_INSTALL} @@ -64,7 +64,8 @@ chmod 644 /etc/logrotate.conf echo "* * * * * rm /var/run/odoo/sessions/*" | crontab - -update-rc.d odoo defaults +update-rc.d -f hostapd remove +update-rc.d -f isc-dhcp-server remove # https://www.raspberrypi.org/forums/viewtopic.php?p=79249 # to not have "setting up console font and keymap" during boot take ages diff --git a/addons/point_of_sale/tools/posbox/posbox_create_image.sh b/addons/point_of_sale/tools/posbox/posbox_create_image.sh index 5b860c65043..111f6797f4c 100755 --- a/addons/point_of_sale/tools/posbox/posbox_create_image.sh +++ b/addons/point_of_sale/tools/posbox/posbox_create_image.sh @@ -41,7 +41,6 @@ odoo.py" | tee --append .git/info/sparse-checkout > /dev/null git read-tree -mu HEAD cd "${__dir}" -# rc.local LOOP_MAPPER_PATH=$(kpartx -av posbox.img | tail -n 1 | cut -d ' ' -f 3) LOOP_MAPPER_PATH="/dev/mapper/${LOOP_MAPPER_PATH}" mkdir "${MOUNT_POINT}"