#!/usr/bin/python3.4
# -*- coding: utf-8 -*-
# from typing import List
import asyncio
from jinja2 import Environment, PackageLoader
from flask import Flask
import flask
import os
import sys
import errno
import logging
#import subprocess
from subprocess import Popen,call,PIPE
import shlex
import time
import threading
import json
from collections import namedtuple
import sqlite3
from jinja2 import FileSystemLoader
FileInfo = namedtuple('FileInfo', ['relative_path', 'target_path', 'filename', 'context'], verbose=True)
app = Flask(__name__)
# env = Environment(loader=FileSystemLoader('.'))
# env = Environment(loader=PackageLoader('yourapplication', 'templates'))
script_lock = threading.Lock()
class clientThread(threading.Thread):
def __init__(self, ssid, passwd):
threading.Thread.__init__(self)
self.ssid = ssid
self.passwd = passwd
def run(self):
if not is_associated() :
run_script('config_client')
connect_to_network(self.ssid,self.passwd)
class apThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
configure('config_ap', dict())
class checkUSBThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
cmd ="su pi -c 'mono /home/pi/yodiwo/wisperFactoryReset/wisperFactoryReset.exe > /home/pi/yodiwo/wisperFactoryReset.log' &"
run_wpa_cli_cmd(cmd)
class WiFiNet:
def __init__(self, essid, mac,encryption,authsuites):
self.essid = essid
self.mac= mac
self.encryption = encryption
self.authsuites = authsuites
@app.route("/")
def hello():
return "Hello World!"
@app.route("/render")
def render():
return "Hello World!"
@app.route('/config_client', methods=['GET', 'POST'])
def config_client():
ssid = flask.request.args.get('config_wifi_ssid')
password = flask.request.args.get('config_wifi_password')
if not password:
password = ""
if not ssid:
return "Invalid parameters", 400
else:
thread1 = clientThread(ssid,password)
thread1.start()
return "Ok"
@app.route('/client_mode', methods=['GET', 'POST'])
def client_mode():
run_script('config_client')
return "Ok"
@app.route('/config_ap', methods=['GET', 'POST'])
def config_ap():
thread1 = apThread()
thread1.start()
return "Ok"
# vars = {
# }
# configure('config_ap', vars)
@app.route('/purge_wifi_settings', methods=['GET', 'POST'])
def purge_wifi_settings():
configure('config_ap', dict(), 1)
return "Ok"
@app.route('/scan', methods=['GET', 'POST'])
def scan():
essid_list = []
j = 0
cmd = "sudo iwlist wlan0 scan"
res = run_wpa_cli_cmd(cmd)
res = res.strip()
cells= res.decode("utf-8").split('Cell')
print (cells[1])
foundessid= False
foundaddress= False
foundencryption=False
foundauthsuites= False;
authenticationsuites=[]
cells.pop(0)
for cell in cells:
lines= cell.split('\n')
for line in lines:
if "ESSID" in line:
essid = line.strip().split(':')[1]
elif "Encryption" in line:
encryption = line.strip().split(':')[1]
elif "Address" in line:
address = line.strip().split(': ')[1]
elif "Authentication Suites" in line:
auth = line.strip().split(': ')[1]
authenticationsuites.append(auth)
print ("Construct wifi net")
authsuites = ",".join(authenticationsuites)
wifinet= WiFiNet(essid,address,encryption,authsuites)
authenticationsuites=[]
authsuites=''
essid_list.append(wifinet)
res_json = json.dumps([ob.__dict__ for ob in essid_list])
return (res_json)
@app.route('/check_usb')
def check_usb():
thread1 = checkUSBThread()
thread1.start()
return "Ok"
@app.route('/connectinfo',methods=['GET', 'POST'])
def connectinfo():
try:
cmd = "sudo iwconfig wlan0"
res = run_wpa_cli_cmd(cmd)
print(res)
#res = res.strip()
lines = res.decode("utf-8").split('\n')
for line in lines:
if ("ESSID" in line):
essid = line.strip().split('ESSID:')[1]
return essid
return "None"
except:
return "Unexpected Error"
@app.route('/reboot')
def reboot():
cmd = "sudo reboot"
run_wpa_cli_cmd(cmd)
return "Ok"
@app.route('/removeflic', methods=['GET', 'POST'])
def removeflic():
try:
bdaddr = flask.request.args.get('bdaddr')
print(bdaddr)
if bdaddr is None:
removeallflics()
res=stopflicd()
print(res)
time.sleep(3)
res=startflicd()
print(res)
else:
removesingleflic(bdaddr)
res=stopflicd()
print(res)
time.sleep(3)
startflicd()
print(res)
return "OK"
except Exception as e:
print ("Oops, exception while removing flic buttons")
print(str(e))
return "Bad Request"
def stopflicd():
try:
print ("Stop Flicd")
run_wpa_cli_cmd("sudo killall flicd")
#os.system("sudo killall flicd")
return "OK"
except Exception as e:
print ("Oops, exception while stopping flicd ")
print(str(e))
return "Bad Request"
def startflicd():
try:
print ("StartFlicd")
run_wpa_cli_cmd("sudo /home/pi/extools/flic/flicd -d -f /home/pi/extools/flic/flic.sqlite3 -s 0.0.0.0 -l /tmp/log_flicd &")
#os.system("sudo /home/pi/extools/flic/flicd -d -f /home/pi/extools/flic/flic.sqlite3 -s 0.0.0.0 -l /tmp/log_flicd &")
return "OK"
except Exception as e:
print ("Oops, exception while stopping flicd ")
print(str(e))
return "Bad Request"
def removeallflics():
print("Remove All Flics")
try:
conn=sqlite3.connect('/home/pi/extools/flic/flic.sqlite3')
curs=conn.cursor()
curs.execute("DELETE FROM buttons")
conn.commit()
except Exception as e:
print (str(e))
def removesingleflic(bdaddr):
print("Remove Single Flic")
try:
conn=sqlite3.connect('/home/pi/extools/flic/flic.sqlite3')
curs=conn.cursor()
query = 'DELETE FROM buttons WHERE bdaddr=?'
curs.execute(query, (bdaddr.strip(),))
#curs.execute("DELETE FROM buttons WHERE bdaddr='" + bdaddr +"'")
conn.commit()
except Exception as e:
print (str(e))
def configure(context, vars = None, flag = None):
make_config(context, vars, flag)
run_script(context)
def make_config(context, vars = None, flag = None):
file_infos = get_files(context)
for info in file_infos:
"""
do nothing with wpa_supplicant.conf
"""
if info.relative_path == "config_ap/etc/wpa_supplicant" and flag!=1:
continue
else:
# processed = render_file(os.path.join(info.relative_path, info.filename), vars)
processed = render_file(info.relative_path, info.filename, vars)
print (info.relative_path)
with open(os.path.join(info.target_path, info.filename), 'w') as f:
f.write(processed)
# @asyncio.coroutine
def run_script(context):
script = os.path.join('.', context + '.sh')
print (script)
call([script])
#Popen([script])
#t1 = threading.Thread(target=run_script_inner, args=[script])
#t1.start()
#def run_script_inner(filename):
# with script_lock:
# subprocess.call([filename])
def get_files(context):# -> List[FileInfo]:
dirs = os.walk(context)
files = []
for d in dirs:
targetpath = d[0].split(context, 1)[1]
new = [FileInfo(d[0], targetpath, f, context) for f in d[2]]
files.extend(new)
return files
def render_file(path, filename, vars = None):
# with open(filename, 'r') as f:
# template_string = f.read()
# template = Environment().from_string(template_string)
template = Environment(loader=FileSystemLoader(path)).get_template(filename)
return template.render(**vars)
def run_wpa_cli_cmd(rcmd):
"""
Runs a program, and it's paramters (e.g. rcmd="ls -lh /var/www")
Returns output if successful, or None and logs error if not.
"""
cmd = shlex.split(rcmd)
executable = cmd[0]
executable_options=cmd[1:]
try:
proc = Popen(([executable] + executable_options), stdout=PIPE, stderr=PIPE)
response = proc.communicate()
response_stdout, response_stderr = response[0], response[1]
except OSError(e):
if e.errno == errno.ENOENT:
logging.debug( "Unable to locate '%s' program. Is it in your path?" % executable )
else:
logging.error( "O/S error occured when trying to run '%s': \"%s\"" % (executable, str(e)) )
except ValueError(e):
logging.debug( "Value error occured. Check your parameters." )
else:
if proc.wait() != 0:
logging.debug( "Executable '%s' returned with the error: \"%s\"" %(executable,response_stderr) )
return response
else:
logging.debug( "Executable '%s' returned successfully. First line of response was \"%s\"" %(executable, response_stdout.decode("utf-8").split('\n')[0] ))
return response_stdout
def get_net_number(ssid):
"""
Returns the number of existing network
"""
cmd = "wpa_cli -i wlan0 list_net"
res = run_wpa_cli_cmd(cmd)
nets = res.decode("utf-8").split('\n')
print(len(nets))
for i in range(1, (len(nets)-1)) :
found = nets[i].count(ssid)
if found:
break
return i
def check_network_exist(ssid):
"""
Check if a network already exists, in order to avoid duplicate entry
in wpa_supplicant.conf
"""
try:
cmd = "wpa_cli -i wlan0 list_net"
res = run_wpa_cli_cmd(cmd)
tmp = res.decode("utf-8").find(ssid)
if ( tmp == -1 ):
return tmp
else:
net_no = get_net_number(ssid)
return net_no
except:
return -1
'''
For future use in order to implement temporary disable nets
'''
# def check_enabled_net():
# """
# Check if active networks exist
# """
# try:
# cmd = "wpa_cli -i wlan0 list_net"
# res = run_wpa_cli_cmd(cmd)
# nets = res.decode("utf-8").split('\n')
# print(len(nets))
#
# for i in range(1, (len(nets)-1)) :
# found = nets[i].count("CURRENT")
# if found:
# return i
# except:
# return -1
def connect_to_network(ssid, password):
netw = check_network_exist(ssid)
if netw == -1 :
print ("Network is NOT found , add it to conf")
cmd_add_net = "wpa_cli -i wlan0 add_network"
res = run_wpa_cli_cmd(cmd_add_net)
print (cmd_add_net)
print (res.strip())
cmd_set_ssid = "wpa_cli -i wlan0 set_network %d ssid \\\"%s\\\"" % (int(res),ssid)
resp = run_wpa_cli_cmd(cmd_set_ssid)
print(cmd_set_ssid)
print(resp.strip())
if password != "":
cmd_set_mgmt = "wpa_cli -i wlan0 set_network %d key_mgmt WPA-PSK" % (int(res))
resp = run_wpa_cli_cmd(cmd_set_mgmt)
print(cmd_set_mgmt)
print(resp.strip())
cmd_set_key = "wpa_cli -i wlan0 set_network %d psk \\\"%s\\\"" % (int(res),password)
resp = run_wpa_cli_cmd(cmd_set_key)
print(cmd_set_key)
print(resp.strip())
else:
cmd_set_mgmt = "wpa_cli -i wlan0 set_network %d key_mgmt NONE" % (int(res))
resp = run_wpa_cli_cmd(cmd_set_mgmt)
print(cmd_set_mgmt)
print(resp.strip())
# active_net = check_enabled_net()
# if(active_net):
# cmd_disable = "wpa_cli -i wlan0 disable_network %d" % (int(active_net)-1)
# resp = run_wpa_cli_cmd(cmd_disable)
cmd_enable = "wpa_cli -i wlan0 enable_network %d" % (int(res))
resp = run_wpa_cli_cmd(cmd_enable)
time.sleep(5)
print (cmd_enable)
print(resp.strip())
#cmd_save = "wpa_cli -i wlan0 save_config"
#resp = run_wpa_cli_cmd(cmd_save)
#print (cmd_save)
#print(resp.strip())
else:
# active_net = check_enabled_net()
# if active_net :
# cmd_disable = "wpa_cli -i wlan0 disable_network %d" % (int(active_net)-1)
# resp = run_wpa_cli_cmd(cmd_disable)
# print (cmd_disable)
# print(resp.strip())
cmd_enable = "wpa_cli -i wlan0 enable_network %d" % (int(netw)-1)
resp = run_wpa_cli_cmd(cmd_enable)
time.sleep(5)
print (cmd_enable)
print(resp.strip())
#time.sleep(10)
cnt = 0
while not is_associated():
if cnt < 60 :
time.sleep(1)
print("*")
cnt = cnt + 1
else :
break
if cnt == 60 :
configure('config_ap',dict())
else :
cmd_save = "wpa_cli -i wlan0 save_config"
resp = run_wpa_cli_cmd(cmd_save)
print (cmd_save)
print(resp.strip())
return True
def is_associated():
"""
Check if we're associated to a network.
"""
try:
res = run_wpa_cli_cmd("wpa_cli -i wlan0 status | grep wpa_state")
#print (res)
tmp = res.decode("utf-8").find('COMPLETED')
#tmp = res.strip().decode("utf-8").split('=')[1]
print(tmp)
if tmp != -1:
print ("Connected !!!!!!!!!!!!!!!!!!!!!!!")
return True
except:
return False
if __name__ == "__main__":
# make_config('config_client', {'config_wifi_ssid': 'asdf', 'config_wifi_password': 'zxcv'})
# files = get_files('config_ap')
if len(sys.argv) == 1:
app.run(host="0.0.0.0", port=8080, debug=True)
else:
if 'config_client' in sys.argv[1] and len(sys.argv) >= 4:
print('configuring client')
thread1 = clientThread(sys.argv[2],sys.argv[3])
thread1.start()
# if not is_associated() :
# run_script('config_client')
# connect_to_network(sys.argv[2],sys.argv[3])
elif 'config_ap' in sys.argv[1] :
print('configuring ap')
configure('config_ap', dict())
elif 'scan' in sys.argv[1] :
essid_list = []
print("Start scanning")
cmd = "sudo iwlist wlan0 scan"
res = run_wpa_cli_cmd(cmd)
resp = res.decode("utf-8").split('\n')
j = 0
for i in range(1, len(resp)):
if "ESSID" in resp[i]:
essid_list.insert(j,resp[i].strip().split(':')[1])
j = j + 1
res_json = json.dumps(essid_list)
print(res_json)
elif 'purge_wifi_settings' in sys.argv[1] :
configure('config_ap',dict(),1)