Skip to content

Commit

Permalink
AP mode implementation, webGUI password partial avoidance option
Browse files Browse the repository at this point in the history
  • Loading branch information
enesbcs committed Oct 1, 2019
1 parent d545ba1 commit 286caa7
Show file tree
Hide file tree
Showing 9 changed files with 368 additions and 16 deletions.
33 changes: 32 additions & 1 deletion RPIEasy.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ def signal_handler(signal, frame):
timer1s = 0
timer2s = 0
timer30s = 0
init_ok = False
init_ok = False
prevminute = -1
netmode = False
lastdisconntime = 0

def hardwareInit():
#print("Init hardware...")
Expand Down Expand Up @@ -276,6 +278,7 @@ def runon2seconds():
t.start()
except:
pass
checkNetwork()
if len(procarr)>0:
for process in procarr:
process.join()
Expand Down Expand Up @@ -315,6 +318,34 @@ def checkSensors():
process2.join()
return True

def checkNetwork():
global netmode, lastdisconntime
try:
if Settings.NetMan.APMode not in [-1,100]:
if Settings.NetMan.WifiDevWatch>=0 and Settings.NetMan.WifiDevNum>=0:
if Settings.NetworkDevices[Settings.NetMan.WifiDevWatch].apmode==0:
anetmode = Settings.NetworkDevices[Settings.NetMan.WifiDevWatch].isconnected()
if anetmode!=netmode: # network mode changed
netmode=anetmode
if netmode: # if connected
lastdisconntime = 0 # forgive last disconnect time
commands.rulesProcessing("WiFi#Connected",rpieGlobals.RULE_SYSTEM)
return True
else:
lastdisconntime = time.time() # store last disconnect time
commands.rulesProcessing("WiFi#Disconnected",rpieGlobals.RULE_SYSTEM)
return True
elif anetmode==False: # otherwise, if in disconnect state
if lastdisconntime!=0:
if (time.time()-lastdisconntime)>int(Settings.NetMan.APModeTime):
from linux_network import AP_start
AP_start(Settings.NetMan.WifiDevNum)
lastdisconntime = 0 # forgive last disconnect time
else:
lastdisconntime = time.time() # store last disconnect time
except Exception as e:
print(e)

def mainloop():
global timer100ms, timer20ms, timer1s, timer2s, timer30s, init_ok, prevminute
while init_ok:
Expand Down
6 changes: 5 additions & 1 deletion _C020_LoraDirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ def webform_load(self):
webserver.addFormFloatNumberBox("Frequency","freq",self.freq,433,928)
webserver.addUnit("Mhz")
if self.lora is not None:
webserver.addFormNote("Current frequency: "+str(self.lora.get_freq())+" Mhz")
try:
afreq = self.lora.get_freq()
except:
afreq = "UNINITIALIZED"
webserver.addFormNote("Current frequency: "+str(afreq)+" Mhz")
webserver.addFormNote("Please check local regulations for your selected frequency!")

options = ["10%","1%","0.1%"]
Expand Down
18 changes: 16 additions & 2 deletions commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,22 @@ def doExecuteCommand(cmdline,Parse=True):
else:
commandfound = False
return commandfound
elif cmdarr[0] == "wifiapmode": # implement it
commandfound = False
elif cmdarr[0] == "wifiapmode":
if int(Settings.NetMan.WifiDevNum)>=0:
apdev = int(Settings.NetMan.WifiDevNum)
else:
apdev = Settings.NetMan.getfirstwirelessdevnum()
Network.AP_start(apdev)
commandfound = True
return commandfound
elif cmdarr[0] == "wifistamode":
Settings.NetMan.APMode = -1
if int(Settings.NetMan.WifiDevNum)>=0:
apdev = int(Settings.NetMan.WifiDevNum)
else:
apdev = Settings.NetMan.getfirstwirelessdevnum()
Network.AP_stop(apdev)
commandfound = True
return commandfound
elif cmdarr[0] == "wificonnect": # implement it
commandfound = False
Expand Down
96 changes: 96 additions & 0 deletions lib/scripts/ap_start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/sh
#MIT License
#Copyright (c) 2019 VTRUST
#Modified by Alexander Nagy for RPIEasy

#1st command line parameter is the WiFi device name for example: wlan0
#2nd parameter is the AP name to create
#3rd parameter is the WiFi password
#4th parameter is the WiFi channel number (1-13)

#sudo apt install dnsmasq hostapd
#sudo systemctl disable dnsmasq
#sudo systemctl disable hostapd

if test $# -ne 4
then
echo "Illegal number of parameters: 1:wifi_device_name 2:AP_name 3:AP_passw 4: wifi_channel"
exit 2
fi
WLAN=$1
AP=$2
PASS=$3
CHAN=$4

if test -d /etc/NetworkManager; then
echo "Backing up NetworkManager.cfg..."
sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf.backup

cat <<- EOF > /etc/NetworkManager/NetworkManager.conf
[main]
plugins=keyfile
[keyfile]
unmanaged-devices=interface-name:$WLAN
EOF

echo "Restarting NetworkManager..."
sudo service network-manager restart
fi

echo "Stopping network services..."
sudo systemctl stop hostapd.service
sudo systemctl stop dnsmasq.service
sudo systemctl stop dhcpcd.service
sudo killall wpa_supplicant > /dev/null 2>&1

sudo ifconfig $WLAN up

echo "Backing up /etc/dnsmasq.conf..."
sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.backup


echo "Writing dnsmasq config file..."
echo "Creating new /etc/dnsmasq.conf..."
cat <<- EOF >/etc/dnsmasq.conf
# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
# Interface to bind to
interface=$WLAN
#Specify starting_range,end_range,lease_time
dhcp-range=192.168.4.2,192.168.4.250,12h
# dns addresses to send to the clients
server=192.168.4.1
address=/rpieasy.local/192.168.4.1
EOF

echo "Writing hostapd config file..."
cat <<- EOF >/etc/hostapd/hostapd.conf
interface=$WLAN
driver=nl80211
ssid=$AP
hw_mode=g
channel=$CHAN
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=$PASS
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
EOF

echo "Configuring AP interface..."
sudo ifconfig $WLAN up 192.168.4.1 netmask 255.255.255.0

echo "Starting DNSMASQ server..."
sudo /etc/init.d/dnsmasq stop > /dev/null 2>&1
sudo pkill dnsmasq
sudo dnsmasq
sudo sysctl -w net.ipv4.ip_forward=1 > /dev/null 2>&1
sudo ip route add 192.168.4.0/24 dev $WLAN

echo "Starting AP on $WLAN..."
#sudo hostapd /etc/hostapd/hostapd.conf
sudo systemctl start hostapd.service
30 changes: 30 additions & 0 deletions lib/scripts/ap_stop.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh
#MIT License
#Copyright (c) 2019 VTRUST
#Modified by Alexander Nagy for RPIEasy

#1st command line parameter is the WiFi device name for example: wlan0

if test $# -ne 1
then
echo "Illegal number of parameters: 1:wifi_device_name"
exit 2
fi
WLAN=$1

systemctl stop hostapd.service
sudo killall hostapd 2>&1

if test -d /etc/NetworkManager; then
sudo rm /etc/NetworkManager/NetworkManager.conf > /dev/null 2>&1
sudo mv /etc/NetworkManager/NetworkManager.conf.backup /etc/NetworkManager/NetworkManager.conf
sudo service network-manager restart
fi
systemctl stop dnsmasq.service
sudo pkill dnsmasq
sudo rm /etc/dnsmasq.conf > /dev/null 2>&1
sudo mv /etc/dnsmasq.conf.backup /etc/dnsmasq.conf > /dev/null 2>&1
sudo rm /etc/dnsmasq.hosts > /dev/null 2>&1
sudo ifconfig $WLAN 0.0.0.0

sudo service dhcpcd restart
105 changes: 100 additions & 5 deletions linux_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
from collections import namedtuple
import re
import subprocess
import shlex
import os
import Settings
import time
import misc
import rpieGlobals
import linux_os as OS

cellNumberRe = re.compile(r"^Cell\s+(?P<cellnumber>.+)\s+-\s+Address:\s(?P<mac>.+)$")
regexps = [
Expand Down Expand Up @@ -137,15 +139,15 @@ def __init__(self):
self.gw = ""
self.dns = "" # /etc/resolv.conf
self.dnsserver = False
self.apmode = 0 # 0-no,1-on connection error,2-always
self.apmode = 0 # 0-no,1-yes
self.enabled=True
self.connectiontype=0 # 1-wired,2-wireless
self.connected = False
self.lastconnectiontest=0
self.netdevorder=-1

def isconnected(self):
if time.time()-self.lastconnectiontest>5:
if time.time()-self.lastconnectiontest>=4:
conn = False
try:
with open('/sys/class/net/'+self.devicename.strip()+'/carrier') as f:
Expand Down Expand Up @@ -185,6 +187,11 @@ def iswireless(self):
break
except:
pass
if wless==False:
try:
wless = os.path.exists("/sys/class/net/"+str(self.devicename)+"/wireless")
except:
pass
if wless:
self.connectiontype=2
else:
Expand Down Expand Up @@ -220,9 +227,14 @@ def __init__(self): # general init
self.WifiKey = ""
self.WifiSSID2 = ""
self.WifiKey2 = ""
self.APMode = 1 # 0-ap mode do not starts automatically, 1-ap mode starts automatically
self.WifiAPKey = "rpieasy"
self.dhcpcd_inuse = False
self.APMode = 99 # -1:never, 0: on primary device fail, 1: on secondary device fail, 99: if first wifi fail, 100: always
self.APModeDev = 99 # 0: primary, 1: secondary, 99 first wifi
self.APModeTime = 30 # in seconds
self.WifiAPKey = "configrpi"
self.WifiAPChannel = 1
self.WifiDevWatch = -1
self.WifiDevNum = -1
self.dhcpcd_inuse = False

def networkinit(self):
ipi = getipinfos()
Expand Down Expand Up @@ -377,6 +389,43 @@ def networkinit(self):
if Settings.NetworkDevices[dc].gw == "" and Settings.NetworkDevices[dc].ip!="":
Settings.NetworkDevices[dc].gw = getgw(Settings.NetworkDevices[dc].devicename)
Settings.NetworkDevices[dc].connectiontype = 0 # reset iswireless value in case of device name change!
Settings.NetworkDevices[dc].iswireless()
if (OS.is_command_found('hostapd')==False or OS.is_command_found('dnsmasq')==False):
self.APMode = -1
self.setAPconf(True)

def setAPconf(self,startup=False):
try:
if self.APModeDev:
pass
except:
self.APModeDev = 99
self.APMode = 99
try:
if self.APModeTime:
pass
except:
self.APModeTime = 30
if self.APModeDev==99: # set device idx to manage
self.WifiDevNum = self.getfirstwirelessdevnum()
elif self.APModeDev==0:
self.WifiDevNum = self.getprimarydevice()
elif self.APModeDev==1:
self.WifiDevNum = self.getsecondarydevice()
else:
return False
if self.WifiDevNum>=0:
if startup:
AP_stop(self.WifiDevNum) # try to stop it just for sure
if self.APMode== 99: # set device idx to watch
self.WifiDevWatch = self.getfirstwirelessdevnum()
elif self.APMode == 0:
self.WifiDevWatch = self.getprimarydevice()
elif self.APMode == 1:
self.WifiDevWatch = self.getsecondarydevice()
elif self.APMode == 100:
if startup:
AP_start(self.WifiDevNum)

def getdevicenames(self):
rs = []
Expand All @@ -397,6 +446,18 @@ def getfirstwirelessdev(self):
return False
return False

def getfirstwirelessdevnum(self):
try:
pd = self.getprimarydevice()
if Settings.NetworkDevices[pd].iswireless():
return pd
pd = self.getsecondarydevice()
if Settings.NetworkDevices[pd].iswireless():
return pd
except:
return -1
return -1

def getprimarydevice(self):
rs = 0
if len(Settings.NetworkDevices)>0:
Expand Down Expand Up @@ -592,3 +653,37 @@ def cidr_to_netmask(cidr):
def netmask_to_cidr(netmask):
return sum([bin(int(x)).count("1") for x in netmask.split(".")])

def AP_start(ndi): # index in NetworkDevices array
ndi = int(ndi)
if ndi>=len(Settings.NetworkDevices) or ndi<0:
print("NetworkDevice "+str(ndi)+" not found")
return False
if Settings.NetworkDevices[ndi].ip=="192.168.4.1" or Settings.NetworkDevices[ndi].apmode==1:
return False # already in apmode
APName = Settings.Settings["Name"]
if APName == "RPIEasy":
APName += "-"+str(Settings.Settings["Unit"])
try:
chan = Settings.NetMan.WifiAPChannel
except:
chan = 1
if len(Settings.NetMan.WifiAPKey.strip())<8: # wpa password can not be shorter than 8 character
Settings.NetMan.WifiAPKey = "configrpi"
cmdline = 'sudo lib/scripts/ap_start.sh '+str(Settings.NetworkDevices[ndi].devicename)+" "+str(APName)+" "+str(Settings.NetMan.WifiAPKey)+" "+str(chan)
# print(cmdline) # debug
subprocess.call(shlex.split(OS.cmdline_rootcorrect(cmdline)))
Settings.NetworkDevices[ndi].apmode = 1
return True

def AP_stop(ndi): # index in NetworkDevices array
ndi = int(ndi)
if ndi>=len(Settings.NetworkDevices) or ndi<0:
print("NetworkDevice "+str(ndi)+" not found")
return False
if Settings.NetworkDevices[ndi].ip!="192.168.4.1" and Settings.NetworkDevices[ndi].apmode==0:
return False # not in apmode
cmdline = 'sudo lib/scripts/ap_stop.sh '+str(Settings.NetworkDevices[ndi].devicename)
# print(cmdline) # debug
subprocess.call(shlex.split(OS.cmdline_rootcorrect(cmdline)))
Settings.NetworkDevices[ndi].apmode = 0
return True
5 changes: 5 additions & 0 deletions plugindeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@
"pip": ["blynklib"],
"testcmd": "import blynklib",
"installed":-1},
{"name":"wifiap",
"apt": ["hostapd","dnsmasq"],
"testcmd" : "if (OS.is_command_found('hostapd')==False or OS.is_command_found('dnsmasq')==False):\n raise Exception('hostapd/dnsmasq not found')",
"installcmd" : "sudo systemctl disable dnsmasq hostapd && sudo systemctl unmask hostapd",
"installed":-1},

]

Expand Down
Loading

0 comments on commit 286caa7

Please sign in to comment.